public List <long> GetAllIdsInSectionContaining(long id) { if (Contains(id) == false) { var posInPage = (int)(id % Constants.Storage.PageSize); var pageNumberInSection = (id - posInPage) / Constants.Storage.PageSize; var pageHeaderForId = PageHeaderFor(pageNumberInSection); // this is in another section, cannot free it directly, so we'll forward to the right section var sectionPageNumber = pageHeaderForId->PageNumber - pageHeaderForId->PageNumberInSection - 1; var actualSection = new RawDataSection(_tx, sectionPageNumber); if (actualSection._sectionHeader->SectionOwnerHash != _sectionHeader->SectionOwnerHash) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Cannot get all ids in section containing {id} because the raw data section starting in {sectionPageNumber} belongs to a different owner"); } return(actualSection.GetAllIdsInSectionContaining(id)); } var ids = new List <long>(_sectionHeader->NumberOfEntries); for (int i = 0; i < _sectionHeader->NumberOfPages && ids.Count < _sectionHeader->NumberOfEntries; i++) { FillAllIdsInPage(_sectionHeader->PageNumber + i, ids); } return(ids); }
public void DeleteSection(long sectionPageNumber) { if (_tx.Flags == TransactionFlags.Read) { ThrowReadOnlyTransaction(sectionPageNumber); } if (sectionPageNumber != _sectionHeader->PageNumber) { // this is in another section, cannot delete it directly, so we'll forward to the right section var actualSection = new RawDataSection(_tx, sectionPageNumber); if (actualSection._sectionHeader->SectionOwnerHash != _sectionHeader->SectionOwnerHash) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Cannot delete section because the raw data section starting in {sectionPageNumber} belongs to a different owner"); } actualSection.DeleteSection(sectionPageNumber); return; } for (int i = 0; i < _sectionHeader->NumberOfPages; i++) { _tx.FreePage(_sectionHeader->PageNumber + i + 1); } _tx.FreePage(_sectionHeader->PageNumber); }
public double Free(long id) { if (_tx.Flags == TransactionFlags.Read) { ThrowReadOnlyTransaction(id); } var posInPage = (int)(id % Constants.Storage.PageSize); var pageNumberInSection = (id - posInPage) / Constants.Storage.PageSize; var pageHeader = PageHeaderFor(pageNumberInSection); if (Contains(id) == false) { // this is in another section, cannot free it directly, so we'll forward to the right section var sectionPageNumber = pageHeader->PageNumber - pageHeader->PageNumberInSection - 1; var actualSection = new RawDataSection(_tx, sectionPageNumber); if (actualSection.Contains(id) == false) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Cannot delete {id} because the raw data section starting in {sectionPageNumber} with size {actualSection.AllocatedSize} doesn't own it. Possible data corruption?"); } if (actualSection._sectionHeader->SectionOwnerHash != _sectionHeader->SectionOwnerHash) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Cannot delete {id} because the raw data section starting in {sectionPageNumber} belongs to a different owner"); } return(actualSection.Free(id)); } pageHeader = ModifyPage(pageHeader); if (posInPage >= pageHeader->NextAllocation) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Asked to load a past the allocated values: {id} from page {pageHeader->PageNumber}"); } var sizes = (RawDataEntrySizes *)((byte *)pageHeader + posInPage); if (sizes->UsedSize < 0) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Asked to free a value that was already freed: {id} from page {pageHeader->PageNumber}"); } sizes->UsedSize = -1; Memory.Set((byte *)pageHeader + posInPage + sizeof(RawDataEntrySizes), 0, sizes->AllocatedSize); pageHeader->NumberOfEntries--; EnsureHeaderModified(); _sectionHeader->NumberOfEntries--; var sizeFreed = sizes->AllocatedSize + (sizeof(short) * 2); _sectionHeader->AllocatedSize -= sizeFreed; AvailableSpace[pageHeader->PageNumberInSection] += (ushort)sizeFreed; return(Density); }
public List <long> GetAllIdsInSectionContaining(long id) { if (Contains(id) == false) { var posInPage = (int)(id % Constants.Storage.PageSize); var pageNumberInSection = (id - posInPage) / Constants.Storage.PageSize; var pageHeaderForId = PageHeaderFor(pageNumberInSection); // this is in another section, cannot free it directly, so we'll forward to the right section var sectionPageNumber = pageHeaderForId->PageNumber - pageHeaderForId->PageNumberInSection - 1; var actualSection = new RawDataSection(_tx, sectionPageNumber); if (actualSection._sectionHeader->SectionOwnerHash != _sectionHeader->SectionOwnerHash) { VoronUnrecoverableErrorException.Raise(_tx.Environment, $"Cannot get all ids in section containing {id} because the raw data section starting in {sectionPageNumber} belongs to a different owner"); } return(actualSection.GetAllIdsInSectionContaining(id)); } var ids = new List <long>(_sectionHeader->NumberOfEntries); for (int i = 0; i < _sectionHeader->NumberOfPages && ids.Count < _sectionHeader->NumberOfEntries; i++) { var pageHeader = PageHeaderFor(_sectionHeader->PageNumber + i + 1); var offset = sizeof(RawDataSmallPageHeader); while (offset < Constants.Storage.PageSize) { var sizes = (RawDataEntrySizes *)((byte *)pageHeader + offset); if (sizes->UsedSize != -1) { var currentId = (pageHeader->PageNumber * Constants.Storage.PageSize) + offset; var posInPage = (int)(currentId % Constants.Storage.PageSize); if (posInPage >= pageHeader->NextAllocation) { break; } ids.Add(currentId); if (ids.Count == _sectionHeader->NumberOfEntries) { break; } } offset += sizeof(short) * 2 + sizes->AllocatedSize; } } return(ids); }
public void DeleteSection(long sectionPageNumber) { if (sectionPageNumber != _sectionHeader->PageNumber) { // this is in another section, cannot delete it directly, so we'll forward to the right section var actualSection = new RawDataSection(_tx, sectionPageNumber); if (actualSection._sectionHeader->SectionOwnerHash != _sectionHeader->SectionOwnerHash) { throw new InvalidDataException( $"Cannot delete section because the raw data section starting in {sectionPageNumber} belongs to a different owner"); } actualSection.DeleteSection(sectionPageNumber); return; } for (int i = 0; i < _sectionHeader->NumberOfPages; i++) { _tx.FreePage(_sectionHeader->PageNumber + i + 1); } _tx.FreePage(_sectionHeader->PageNumber); }