Example #1
0
        private long AllocateFromSmallActiveSection(int size)
        {
            long id;

            if (ActiveDataSmallSection.TryAllocate(size, out id) == false)
            {
                InactiveSections.Add(_activeDataSmallSection.PageNumber);

                using (var it = ActiveCandidateSection.Iterate())
                {
                    if (it.Seek(long.MinValue))
                    {
                        do
                        {
                            var sectionPageNumber = it.CurrentKey;
                            _activeDataSmallSection = new ActiveRawDataSmallSection(_tx.LowLevelTransaction,
                                                                                    sectionPageNumber);
                            _activeDataSmallSection.DataMoved += OnDataMoved;
                            if (_activeDataSmallSection.TryAllocate(size, out id))
                            {
                                ActiveCandidateSection.Delete(sectionPageNumber);
                                return(id);
                            }
                        } while (it.MoveNext());
                    }
                }

                var newNumberOfPages = Math.Max((ushort)(ActiveDataSmallSection.NumberOfPages * 2), ushort.MaxValue);
                _activeDataSmallSection            = ActiveRawDataSmallSection.Create(_tx.LowLevelTransaction, Name, newNumberOfPages);
                _activeDataSmallSection.DataMoved += OnDataMoved;
                Slice pageNumber;
                var   val = _activeDataSmallSection.PageNumber;
                using (Slice.External(_tx.Allocator, (byte *)&val, sizeof(long), out pageNumber))
                {
                    _tableTree.Add(TableSchema.ActiveSectionSlice, pageNumber);
                }

                var allocationResult = _activeDataSmallSection.TryAllocate(size, out id);

                Debug.Assert(allocationResult);
            }
            return(id);
        }
Example #2
0
        private long AllocateFromSmallActiveSection(int size)
        {
            long id;

            if (ActiveDataSmallSection.TryAllocate(size, out id) == false)
            {
                InactiveSections.Add(_activeDataSmallSection.PageNumber);

                using (var it = ActiveCandidateSection.Iterate())
                {
                    if (it.Seek(long.MinValue))
                    {
                        do
                        {
                            var sectionPageNumber = it.CurrentKey;
                            _activeDataSmallSection = new ActiveRawDataSmallSection(_tx.LowLevelTransaction,
                                                                                    sectionPageNumber);
                            if (_activeDataSmallSection.TryAllocate(size, out id))
                            {
                                ActiveCandidateSection.Delete(sectionPageNumber);
                                return(id);
                            }
                        } while (it.MoveNext());
                    }
                }

                _activeDataSmallSection = ActiveRawDataSmallSection.Create(_tx.LowLevelTransaction, Name);

                var pageNumber = Slice.From(_tx.Allocator, EndianBitConverter.Little.GetBytes(_activeDataSmallSection.PageNumber), ByteStringType.Immutable);
                _tableTree.Add(TableSchema.ActiveSection, pageNumber);

                var allocationResult = _activeDataSmallSection.TryAllocate(size, out id);

                Debug.Assert(allocationResult);
            }
            return(id);
        }
Example #3
0
        public void Delete(long id)
        {
            int size;
            var ptr = DirectRead(id, out size);

            if (ptr == null)
            {
                return;
            }

            var stats = (TableSchemaStats *)_tableTree.DirectAdd(TableSchema.StatsSlice, sizeof(TableSchemaStats));

            NumberOfEntries--;
            stats->NumberOfEntries = NumberOfEntries;

            DeleteValueFromIndex(id, new TableValueReader(ptr, size));

            var largeValue = (id % _pageSize) == 0;

            if (largeValue)
            {
                var page          = _tx.LowLevelTransaction.GetPage(id / _pageSize);
                var numberOfPages = _tx.LowLevelTransaction.DataPager.GetNumberOfOverflowPages(page.OverflowSize);
                _overflowPageCount      -= numberOfPages;
                stats->OverflowPageCount = _overflowPageCount;

                for (int i = 0; i < numberOfPages; i++)
                {
                    _tx.LowLevelTransaction.FreePage(page.PageNumber + i);
                }
                return;
            }

            var density = ActiveDataSmallSection.Free(id);

            if (ActiveDataSmallSection.Contains(id) || density > 0.5)
            {
                return;
            }

            var sectionPageNumber = ActiveDataSmallSection.GetSectionPageNumber(id);

            if (density > 0.15)
            {
                ActiveCandidateSection.Add(sectionPageNumber);
                return;
            }

            // move all the data to the current active section (maybe creating a new one
            // if this is busy)

            // if this is in the active candidate list, remove it so it cannot be reused if the current
            // active is full and need a new one
            ActiveCandidateSection.Delete(sectionPageNumber);

            var idsInSection = ActiveDataSmallSection.GetAllIdsInSectionContaining(id);

            foreach (var idToMove in idsInSection)
            {
                int itemSize;
                var pos   = ActiveDataSmallSection.DirectRead(idToMove, out itemSize);
                var newId = AllocateFromSmallActiveSection(itemSize);

                OnDataMoved(idToMove, newId, pos, itemSize);

                byte *writePos;
                if (ActiveDataSmallSection.TryWriteDirect(newId, itemSize, out writePos) == false)
                {
                    throw new InvalidDataException($"Cannot write to newly allocated size in {Name} during delete");
                }

                Memory.Copy(writePos, pos, itemSize);
            }

            ActiveDataSmallSection.DeleteSection(sectionPageNumber);
        }