Пример #1
0
        private bool RedistributeBranchElements(TreeBranch branch, int childIndex, TreeBranch child)
        {
            // We distribute the nodes in the child branch with the branch
            // immediately to the right.  If that's not possible, then we distribute
            // with the left.

            // If branch has only a single value, return immediately
            int branchSize = branch.ChildCount;

            if (branchSize == 1)
            {
                return(false);
            }

            int        leftI, rightI;
            TreeBranch left, right;

            if (childIndex < branchSize - 1)
            {
                // Distribute with the right
                leftI  = childIndex;
                rightI = childIndex + 1;
                left   = child;
                right  = (TreeBranch)UnfreezeNode(FetchNode(branch.GetChild(childIndex + 1)));
                branch.SetChild(right.Id, childIndex + 1);
            }
            else
            {
                // Distribute with the left
                leftI  = childIndex - 1;
                rightI = childIndex;
                left   = (TreeBranch)UnfreezeNode(FetchNode(branch.GetChild(childIndex - 1)));
                right  = child;
                branch.SetChild(left.Id, childIndex - 1);
            }

            // Get the mid value key reference
            Key midKey = branch.GetKey(rightI);

            // Perform the merge,
            Key newMidKey = left.Merge(right, midKey);

            // Reset the leaf element count
            branch.SetChildLeafElementCount(left.LeafElementCount, leftI);
            branch.SetChildLeafElementCount(right.LeafElementCount, rightI);

            // If after the merge the right branch is empty, we need to remove it
            if (right.IsEmpty)
            {
                // Delete the node
                DeleteNode(right.Id);
                // And remove it from the branch,
                branch.RemoveChild(rightI);
                return(true);
            }

            // Otherwise set the key reference
            branch.SetKeyToLeft(newMidKey, rightI);
            return(false);
        }
Пример #2
0
        public void DeleteLeaf(Key key)
        {
            // Set up the state
            StackFrame frame          = StackEnd(0);
            NodeId     thisRef        = frame.NodeId;
            TreeBranch branchNode     = null;
            int        deleteNodeSize = -1;
            Key        leftKey        = null;

            // Walk back through the rest of the stack
            int sz = FrameCount;

            for (int i = 1; i < sz; ++i)
            {
                // Find the child_i for the child
                // This is the child_i of the child in the current branch
                int childIndex = frame.ChildIndex;

                // Move the stack frame,
                frame = StackEnd(i);

                NodeId childId = thisRef;
                thisRef = frame.NodeId;
                TreeBranch childBranch = branchNode;
                branchNode = (TreeBranch)UnfreezeNode(FetchNode(thisRef));

                if (deleteNodeSize == -1)
                {
                    deleteNodeSize =
                        (int)branchNode.GetChildLeafElementCount(childIndex);
                }

                // If the child branch is empty,
                if (childBranch == null || childBranch.IsEmpty)
                {
                    // Delete the reference to it,
                    if (childIndex == 0 && branchNode.ChildCount > 1)
                    {
                        leftKey = branchNode.GetKey(1);
                    }
                    branchNode.RemoveChild(childIndex);
                    // Delete the child branch,
                    DeleteNode(childId);
                }
                // Not empty,
                else
                {
                    // Replace with the new child node reference
                    branchNode.SetChild(childBranch.Id, childIndex);
                    // Set the element count
                    long newChildSize =
                        branchNode.GetChildLeafElementCount(childIndex) -
                        deleteNodeSize;
                    branchNode.SetChildLeafElementCount(newChildSize, childIndex);
                    // Can we set the left key reference?
                    if (childIndex > 0 && leftKey != null)
                    {
                        branchNode.SetKeyToLeft(leftKey, childIndex);
                        leftKey = null;
                    }

                    // Has the size of the child reached the lower threshold?
                    if (childBranch.ChildCount <= 2)
                    {
                        // If it has, we need to redistribute the children,
                        RedistributeBranchElements(branchNode, childIndex, childBranch);
                    }
                }
            }

            // Finally, set the root node
            // If the branch node is a single element, we set the root as the child,
            if (branchNode.ChildCount == 1)
            {
                // This shrinks the height of the tree,
                RootNodeId = branchNode.GetChild(0);
                DeleteNode(branchNode.Id);
                if (TreeHeight != -1)
                {
                    TreeHeight = TreeHeight - 1;
                }
            }
            else
            {
                // Otherwise, we set the branch node.
                RootNodeId = branchNode.Id;
            }

            // Reset the object
            Reset();
        }
Пример #3
0
        private bool RedistributeBranchElements(TreeBranch branch, int childIndex, TreeBranch child)
        {
            // We distribute the nodes in the child branch with the branch
            // immediately to the right.  If that's not possible, then we distribute
            // with the left.

            // If branch has only a single value, return immediately
            int branchSize = branch.ChildCount;
            if (branchSize == 1) {
                return false;
            }

            int leftI, rightI;
            TreeBranch left, right;
            if (childIndex < branchSize - 1) {
                // Distribute with the right
                leftI = childIndex;
                rightI = childIndex + 1;
                left = child;
                right = (TreeBranch)UnfreezeNode(FetchNode(branch.GetChild(childIndex + 1)));
                branch.SetChild(right.Id, childIndex + 1);
            } else {
                // Distribute with the left
                leftI = childIndex - 1;
                rightI = childIndex;
                left = (TreeBranch)UnfreezeNode(FetchNode(branch.GetChild(childIndex - 1)));
                right = child;
                branch.SetChild(left.Id, childIndex - 1);
            }

            // Get the mid value key reference
            Key midKey = branch.GetKey(rightI);

            // Perform the merge,
            Key newMidKey = left.Merge(right, midKey);
            // Reset the leaf element count
            branch.SetChildLeafElementCount(left.LeafElementCount, leftI);
            branch.SetChildLeafElementCount(right.LeafElementCount, rightI);

            // If after the merge the right branch is empty, we need to remove it
            if (right.IsEmpty) {
                // Delete the node
                DeleteNode(right.Id);
                // And remove it from the branch,
                branch.RemoveChild(rightI);
                return true;
            }

            // Otherwise set the key reference
            branch.SetKeyToLeft(newMidKey, rightI);
            return false;
        }