public void Delete(long id) { int size; var ptr = DirectRead(id, out size); if (ptr == null) { return; } var stats = (TableSchemaStats *)_tableTree.DirectAdd(TableSchema.Stats, 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); 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); }