public TreePage Execute(TreePage page) { using (DisableFreeSpaceUsageIfSplittingRootTree()) { _tree.ClearPagesCache(); if (_cursor.PageCount <= 1) // the root page { RebalanceRoot(page); return(null); } _cursor.Pop(); var parentPage = _tree.ModifyPage(_cursor.CurrentPage); _cursor.Update(_cursor.Pages, parentPage); if (page.NumberOfEntries == 0) // empty page, just delete it and fixup parent { // need to change the implicit left page if (parentPage.LastSearchPosition == 0 && parentPage.NumberOfEntries > 2) { var newImplicit = parentPage.GetNode(1)->PageNumber; parentPage.RemoveNode(0); parentPage.ChangeImplicitRefPageNode(newImplicit); } else // will be set to rights by the next rebalance call { parentPage.RemoveNode(parentPage.LastSearchPositionOrLastEntry); } _tree.FreePage(page); return(parentPage); } if (page.IsBranch && page.NumberOfEntries == 1) { RemoveBranchWithOneEntry(page, parentPage); return(parentPage); } var minKeys = page.IsBranch ? 2 : 1; if ((page.UseMoreSizeThan(_tx.DataPager.PageMinSpace)) && page.NumberOfEntries >= minKeys) { return(null); // above space/keys thresholds } Debug.Assert(parentPage.NumberOfEntries >= 2); // if we have less than 2 entries in the parent, the tree is invalid var sibling = SetupMoveOrMerge(page, parentPage); Debug.Assert(sibling.PageNumber != page.PageNumber); if (page.TreeFlags != sibling.TreeFlags) { return(null); } if (sibling.IsCompressed) { return(null); } if (sibling.PageSize != page.PageSize) { // if the current page is compressed (but already opened), we need to // avoid merging it with the right (uncompressed) page return(null); } Debug.Assert(page.IsCompressed == false); minKeys = sibling.IsBranch ? 2 : 1; // branch must have at least 2 keys if (sibling.UseMoreSizeThan(_tx.DataPager.PageMinSpace) && sibling.NumberOfEntries > minKeys) { // neighbor is over the min size and has enough key, can move just one key to the current page if (page.IsBranch) { MoveBranchNode(parentPage, sibling, page); } else { MoveLeafNode(parentPage, sibling, page); } return(parentPage); } if (page.LastSearchPosition == 0) // this is the right page, merge left { if (TryMergePages(parentPage, sibling, page) == false) { return(null); } } else // this is the left page, merge right { if (TryMergePages(parentPage, page, sibling) == false) { return(null); } } return(parentPage); } }