private void DeleteOnCompressedPage(TreePage page, Slice keyToDelete, ref TreeCursorConstructor cursorConstructor) { var tombstoneNodeSize = page.GetRequiredSpace(keyToDelete, 0); page = ModifyPage(page); if (page.HasSpaceFor(_llt, tombstoneNodeSize)) { if (page.LastMatch == 0) { RemoveLeafNode(page); } page.AddCompressionTombstoneNode(page.LastSearchPosition, keyToDelete); return; } var decompressed = DecompressPage(page, usage: DecompressionUsage.Write); try { decompressed.Search(_llt, keyToDelete); if (decompressed.LastMatch != 0) { return; } State.NumberOfEntries--; RemoveLeafNode(decompressed); using (var cursor = cursorConstructor.Build(keyToDelete)) { var treeRebalancer = new TreeRebalancer(_llt, this, cursor); var changedPage = (TreePage)decompressed; while (changedPage != null) { changedPage = treeRebalancer.Execute(changedPage); } } page.DebugValidate(this, State.RootPageNumber); } finally { decompressed.CopyToOriginal(_llt, defragRequired: true, wasModified: true, this); } }
public void Delete(Slice key) { if (_llt.Flags == (TransactionFlags.ReadWrite) == false) { throw new ArgumentException("Cannot delete a value in a read only transaction"); } State.IsModified = true; Func <Slice, TreeCursor> cursorConstructor; TreeNodeHeader * node; var page = FindPageFor(key, node: out node, cursor: out cursorConstructor, allowCompressed: true); if (page.IsCompressed) { DeleteOnCompressedPage(page, key, cursorConstructor); return; } if (page.LastMatch != 0) { return; // not an exact match, can't delete } page = ModifyPage(page); State.NumberOfEntries--; RemoveLeafNode(page); using (var cursor = cursorConstructor(key)) { var treeRebalancer = new TreeRebalancer(_llt, this, cursor); var changedPage = page; while (changedPage != null) { changedPage = treeRebalancer.Execute(changedPage); } } page.DebugValidate(this, State.RootPageNumber); }
public void Delete(Slice key, ushort?version = null) { if (_llt.Flags == (TransactionFlags.ReadWrite) == false) { throw new ArgumentException("Cannot delete a value in a read only transaction"); } State.IsModified = true; Func <TreeCursor> cursorConstructor; TreeNodeHeader * node; var page = FindPageFor(key, out node, out cursorConstructor); if (page.LastMatch != 0) { return; // not an exact match, can't delete } page = ModifyPage(page); State.NumberOfEntries--; ushort nodeVersion; RemoveLeafNode(page, out nodeVersion); CheckConcurrency(key, version, nodeVersion, TreeActionType.Delete); using (var cursor = cursorConstructor()) { var treeRebalancer = new TreeRebalancer(_llt, this, cursor); var changedPage = page; while (changedPage != null) { changedPage = treeRebalancer.Execute(changedPage); } } page.DebugValidate(_llt, State.RootPageNumber); }