// Delete element already found at path. private void Delete(TreePath <TKey, TValue> path) { int leafIndex = path.TopNodeIndex; Leaf <TKey, TValue> leaf = (Leaf <TKey, TValue>)path.TopNode; leaf.Remove(leafIndex); --Count; if (leafIndex == 0) { if (leaf.KeyCount != 0) { path.SetPivot(path.TopNode.GetKey(0)); } else { Debug.Assert(leaf.RightLeaf == null, "only the rightmost leaf should ever be emptied"); // Leaf is empty. Prune it unless it is the only leaf in the tree. Leaf <TKey, TValue> leftLeaf = (Leaf <TKey, TValue>)path.GetLeftNode(); if (leftLeaf != null) { leftLeaf.RightLeaf = leaf.RightLeaf; Demote(path); } return; } } // Leaf underflow? if (leaf.KeyCount < leaf.KeyCapacity / 2) { Leaf <TKey, TValue> rightLeaf = leaf.RightLeaf; if (rightLeaf != null) { if (leaf.KeyCount + rightLeaf.KeyCount > leaf.KeyCapacity) { // Balance leaves by shifting pairs from right leaf. int shifts = leaf.KeyCapacity - (leaf.KeyCount + rightLeaf.KeyCount - 1) / 2; leaf.Add(rightLeaf, 0, shifts); rightLeaf.Remove(0, shifts); path.TraverseRight(); path.SetPivot(path.TopNode.GetKey(0)); } else { // Coalesce right leaf to current leaf and prune right leaf. leaf.Add(rightLeaf, 0, rightLeaf.KeyCount); leaf.RightLeaf = rightLeaf.RightLeaf; path.TraverseRight(); Demote(path); } } } }
// Insert element at preseeked path. private void Insert(TreePath <TKey, TValue> path, TKey key, TValue value) { Leaf <TKey, TValue> leaf = (Leaf <TKey, TValue>)path.TopNode; int leafIndex = path.TopNodeIndex; if (leaf.NotFull) { leaf.Insert(leafIndex, key, value); ++Count; return; } // Leaf overflow. Right split a new leaf. Leaf <TKey, TValue> newLeaf = new Leaf <TKey, TValue>(leaf); if (newLeaf.RightLeaf == null && leafIndex == leaf.KeyCount) { // Densify sequential loads. newLeaf.Add(key, value); } else { int halfway = leaf.KeyCount / 2 + 1; if (leafIndex < halfway) { // Left-side insert: Copy right side to the split leaf. newLeaf.Add(leaf, halfway - 1, leaf.KeyCount); leaf.Truncate(halfway - 1); leaf.Insert(leafIndex, key, value); } else { // Right-side insert: Copy split leaf parts and new key. newLeaf.Add(leaf, halfway, leafIndex); newLeaf.Add(key, value); newLeaf.Add(leaf, leafIndex, leaf.KeyCount); leaf.Truncate(halfway); } } // Promote anchor of split leaf. ++Count; Promote(path, newLeaf.GetKey(0), (Node <TKey>)newLeaf); }