示例#1
0
        private void Split(TwoFourTreeNode node)
        {
            var parent = node.Parent;

            Debug.Assert(node.IsKeyFull);
            var midKey  = node.Items[1];
            var newNode = node.Split();

            if (node == _root)
            {
                Debug.Assert(parent == null);
                var newRoot = new TwoFourTreeNode(midKey, node, newNode);
                _root = newRoot;
            }
            else
            {
                Debug.Assert(parent != null);
                var nodeIndex = node.GetChildIndex();
                Debug.Assert(parent.Children[nodeIndex] == node);
                parent.InsertItemChild(nodeIndex, midKey, newNode);
            }
        }
示例#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!");
            }
        }