Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }