Exemple #1
0
        // 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);
                    }
                }
            }
        }
Exemple #2
0
        // 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);
        }