示例#1
0
            public void MergeWithRight(int rightIndex, TwoFourTreeNode right)
            {
                Debug.Assert(_keyNum == 0 && right._keyNum == 1 ||
                             _keyNum == 1 && right._keyNum == 0);
                Debug.Assert(Parent != null);
                Debug.Assert(Parent == right.Parent);
                Debug.Assert(Parent.Children[rightIndex] == right);

                var pair = Parent.RemoveItemChild(rightIndex - 1);

                AppendItemChild(pair.Item, IsLeafNode ? null : right._children[0]);

                if (right._keyNum != 0)
                {
                    AppendItemChild(right._items[0], IsLeafNode ? null : right._children[1]);
                }

                right.Invalidate();
            }
示例#2
0
        private void AdjustNodeWhenRemove(TwoFourTreeNode node)
        {
            var parent = node.Parent;

            Debug.Assert(parent != null);
            var childIndex        = node.GetChildIndex();
            var leftSiblingIndex  = childIndex - 1;
            var rightSiblingIndex = childIndex + 1;

            // If a sibling on either side of this node is a 3-node or a 4-node (thus having more than 1 key)
            if (rightSiblingIndex <= parent.KeyNum && !parent.Children[rightSiblingIndex].IsKeyMin)
            {
                var sibling = parent.Children[rightSiblingIndex];
                var pair    = sibling.RemoveFirstItemChild();
                node.AppendItemChild(parent.Items[childIndex], pair.Node);
                parent.Items[childIndex] = pair.Item;
            }
            else if (leftSiblingIndex >= 0 && !parent.Children[leftSiblingIndex].IsKeyMin)
            {
                var sibling = parent.Children[leftSiblingIndex];
                var pair    = sibling.RemoveLastItemChild();
                node.PushFrontItemChild(parent.Items[leftSiblingIndex], pair.Node);
                parent.Items[leftSiblingIndex] = pair.Item;
            }
            // If all adjacent siblings are 2-nodes
            else if (rightSiblingIndex <= parent.KeyNum && parent.Children[rightSiblingIndex].IsKeyMin)
            {
                node.MergeWithRight(rightSiblingIndex, parent.Children[rightSiblingIndex]);
                if (parent.KeyNum == 0)
                {
                    if (parent == _root)
                    {
                        _root.Invalidate();
                        _root        = node;
                        _root.Parent = null;
                    }
                    else
                    {
                        AdjustNodeWhenRemove(parent);
                    }
                }
            }
            else if (leftSiblingIndex >= 0 && parent.Children[leftSiblingIndex].IsKeyMin)
            {
                var sibling = parent.Children[leftSiblingIndex];
                sibling.MergeWithRight(childIndex, node);
                if (parent.KeyNum == 0)
                {
                    if (parent == _root)
                    {
                        _root.Invalidate();
                        _root        = sibling;
                        _root.Parent = null;
                    }
                    else
                    {
                        AdjustNodeWhenRemove(parent);
                    }
                }
            }

            else
            {
                throw new Exception("cannot reach here!");
            }
        }