示例#1
0
        private void UpdateStackProperties(int sizeDiff)
        {
            StackFrame frame = StackEnd(0);
            int        sz    = FrameCount;

            // Walk the stack from the end
            for (int i = 1; i < sz; ++i)
            {
                int childIndex = frame.ChildIndex;
                frame = StackEnd(i);

                NodeId     nodeId = frame.NodeId;
                TreeBranch branch = (TreeBranch)FetchNode(nodeId);
                branch.SetChildLeafElementCount(branch.GetChildLeafElementCount(childIndex) + sizeDiff, childIndex);
            }
        }
示例#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
        public void SetupForPosition(Key key, long posit)
        {
            // If the current leaf is set
            if (currentLeaf != null)
            {
                StackFrame frame     = StackEnd(0);
                long       leafStart = frame.Offset;
                long       leafEnd   = leafStart + currentLeaf.Length;
                // If the position is at the leaf end, or if the keys aren't equal, we
                // need to reset the stack.  This ensures that we correctly place the
                // pointer.
                if (!key.Equals(Key.Tail) &&
                    (posit == leafEnd || !key.Equals(currentLeafKey)))
                {
                    StackClear();
                    currentLeaf    = null;
                    currentLeafKey = null;
                }
                else
                {
                    // Check whether the position is within the bounds of the current leaf
                    // If 'posit' is within this leaf
                    if (posit >= leafStart && posit < leafEnd)
                    {
                        // If the position is within the current leaf, set up the internal
                        // vars as necessary.
                        leafOffset = (int)(posit - leafStart);
                        return;
                    }

                    // If it's not, we reset the stack and start fresh,
                    StackClear();

                    currentLeaf    = null;
                    currentLeafKey = null;
                }
            }

            // ISSUE: It appears looking at the code above, the stack will always be
            //   empty and current_leaf will always be null if we get here.

            // If the stack is empty, push the root node,
            if (StackEmpty)
            {
                // Push the root node onto the top of the stack.
                StackPush(-1, 0, RootNodeId);
                // Set up the current_leaf_key to the default value
                currentLeafKey = Key.Head;
            }
            // Otherwise, we need to setup by querying the BTree.
            while (true)
            {
                if (StackEmpty)
                {
                    throw new ApplicationException("Position out of bounds.  p = " + posit);
                }

                // Pop the last stack frame,
                StackFrame frame          = StackPop();
                NodeId     nodePointer    = frame.NodeId;
                long       leftSideOffset = frame.Offset;
                int        nodeChildIndex = frame.ChildIndex;

                // Relative offset within this node
                long relativeOffset = posit - leftSideOffset;

                // If the node is not on the heap,
                if (!IsHeapNode(nodePointer))
                {
                    // The node is not on the heap. We optimize here.
                    // If we know the node is going to be a leaf node, we set up a
                    // temporary leaf node object with as much information as we know.

                    // Check if we know this is a leaf
                    int treeHeight = TreeHeight;
                    if (treeHeight != -1 &&
                        (stackSize / StackFrameSize) + 1 == treeHeight)
                    {
                        // Fetch the parent node,
                        frame = StackEnd(0);
                        NodeId     twigNodePointer = frame.NodeId;
                        TreeBranch twig            = (TreeBranch)FetchNode(twigNodePointer);
                        long       leafSize        =
                            twig.GetChildLeafElementCount(nodeChildIndex);

                        // This object holds off fetching the contents of the leaf node
                        // unless it's absolutely required.
                        TreeLeaf leaf =
                            new PlaceholderLeaf(ts, nodePointer, (int)leafSize);

                        currentLeaf = leaf;
                        StackPush(nodeChildIndex, leftSideOffset, nodePointer);
                        // Set up the leaf offset and return
                        leafOffset = (int)relativeOffset;

                        return;
                    }
                }

                // Fetch the node
                ITreeNode node = FetchNode(nodePointer);
                if (node is TreeLeaf)
                {
                    // Node is a leaf node
                    TreeLeaf leaf = (TreeLeaf)node;

                    currentLeaf = leaf;
                    StackPush(nodeChildIndex, leftSideOffset, nodePointer);
                    // Set up the leaf offset and return
                    leafOffset = (int)relativeOffset;

                    // Update the tree_height value,
                    TreeHeight = stackSize / StackFrameSize;
                    return;
                }

                // Node is a branch node
                TreeBranch branch     = (TreeBranch)node;
                int        childIndex = branch.IndexOfChild(key, relativeOffset);
                if (childIndex != -1)
                {
                    // Push the current details,
                    StackPush(nodeChildIndex, leftSideOffset, nodePointer);
                    // Found child so push the details
                    StackPush(childIndex,
                              branch.GetChildOffset(childIndex) + leftSideOffset,
                              branch.GetChild(childIndex));
                    // Set up the left key
                    if (childIndex > 0)
                    {
                        currentLeafKey = branch.GetKey(childIndex);
                    }
                }
            }             // while (true)
        }
示例#4
0
        public void InsertLeaf(Key newLeafKey, TreeLeaf newLeaf, bool before)
        {
            int leafSize = newLeaf.Length;

            if (leafSize <= 0)
            {
                throw new ArgumentException("size <= 0");
            }

            // The current absolute position and key
            Key newKey = newLeafKey;

            // The frame at the end of the stack,
            StackFrame frame = StackEnd(0);

            object[] info;
            object[] rInfo = new object[5];
            Key      leftKey;
            long     curAbsolutePos;

            // If we are inserting the new leaf after,
            if (!before)
            {
                info = new object[] {
                    currentLeaf.Id,
                    (long)currentLeaf.Length,
                    newLeafKey,
                    newLeaf.Id,
                    (long)newLeaf.Length
                };
                leftKey        = null;
                curAbsolutePos = frame.Offset + currentLeaf.Length;
            }
            // Otherwise we are inserting the new leaf before,
            else
            {
                // If before and current_leaf key is different than new_leaf key, we
                // generate an error
                if (!currentLeafKey.Equals(newLeafKey))
                {
                    throw new InvalidOperationException("Can't insert different new key before.");
                }

                info = new Object[] {
                    newLeaf.Id,
                    (long)newLeaf.Length,
                    currentLeafKey,
                    currentLeaf.Id,
                    (long)currentLeaf.Length
                };
                leftKey        = newLeafKey;
                curAbsolutePos = frame.Offset - 1;
            }

            bool insertTwoNodes = true;

            int sz = FrameCount;

            // Walk the stack from the end
            for (int i = 1; i < sz; ++i)
            {
                // child_i is the previous frame's child_i
                int childIndex = frame.ChildIndex;
                frame = StackEnd(i);
                // The child ref of this stack element
                NodeId childId = frame.NodeId;
                // Fetch it
                TreeBranch branch = (TreeBranch)UnfreezeNode(FetchNode(childId));

                // Do we have two nodes to insert into the branch?
                if (insertTwoNodes)
                {
                    TreeBranch insertBranch;
                    int        insertIndex = childIndex;
                    // If the branch is full,
                    if (branch.IsFull)
                    {
                        // Create a new node,
                        TreeBranch leftBranch  = branch;
                        TreeBranch rightBranch = CreateBranch();
                        // Split the branch,
                        Key midpointKey = leftBranch.MidPointKey;
                        // And move half of this branch into the new branch
                        leftBranch.MoveLastHalfInto(rightBranch);
                        // We split so we need to return a split flag,
                        rInfo[0] = leftBranch.Id;
                        rInfo[1] = leftBranch.LeafElementCount;
                        rInfo[2] = midpointKey;
                        rInfo[3] = rightBranch.Id;
                        rInfo[4] = rightBranch.LeafElementCount;
                        // Adjust insert_n and insert_branch
                        if (insertIndex >= leftBranch.ChildCount)
                        {
                            insertIndex -= leftBranch.ChildCount;
                            insertBranch = rightBranch;
                            rInfo[4]     = (long)rInfo[4] + newLeaf.Length;
                            // If insert_n == 0, we change the midpoint value to the left
                            // key value,
                            if (insertIndex == 0 && leftKey != null)
                            {
                                rInfo[2] = leftKey;
                                leftKey  = null;
                            }
                        }
                        else
                        {
                            insertBranch = leftBranch;
                            rInfo[1]     = (long)rInfo[1] + newLeaf.Length;
                        }
                    }
                    // If it's not full,
                    else
                    {
                        insertBranch   = branch;
                        rInfo[0]       = insertBranch.Id;
                        insertTwoNodes = false;
                    }
                    // Insert the two children nodes
                    insertBranch.Insert((NodeId)info[0], (long)info[1],
                                        (Key)info[2],
                                        (NodeId)info[3], (long)info[4],
                                        insertIndex);
                    // Copy r_nfo to nfo
                    for (int p = 0; p < rInfo.Length; ++p)
                    {
                        info[p] = rInfo[p];
                    }

                    // Adjust the left key reference if necessary
                    if (leftKey != null && insertIndex > 0)
                    {
                        insertBranch.SetKeyToLeft(leftKey, insertIndex);
                        leftKey = null;
                    }
                }
                else
                {
                    branch.SetChild((NodeId)info[0], childIndex);
                    info[0] = branch.Id;
                    branch.SetChildLeafElementCount(
                        branch.GetChildLeafElementCount(childIndex) + leafSize, childIndex);

                    // Adjust the left key reference if necessary
                    if (leftKey != null && childIndex > 0)
                    {
                        branch.SetKeyToLeft(leftKey, childIndex);
                        leftKey = null;
                    }
                }
            }             // For all elements in the stack,

            // At the end, if we still have a split then we make a new root and
            // adjust the stack accordingly
            if (insertTwoNodes)
            {
                TreeBranch newRoot = CreateBranch();
                newRoot.Set((NodeId)info[0], (long)info[1],
                            (Key)info[2],
                            (NodeId)info[3], (long)info[4]);
                RootNodeId = newRoot.Id;
                if (TreeHeight != -1)
                {
                    TreeHeight = TreeHeight + 1;
                }
            }
            else
            {
                RootNodeId = (NodeId)info[0];
            }

            // Now reset the position,
            Reset();
            SetupForPosition(newKey, curAbsolutePos);
        }
示例#5
0
        private TreeGraph CreateRootGraph(Key leftKey, long reference)
        {
            // The node being returned
            TreeGraph graph;

            // Open the area
            IArea area = store.GetArea(reference);
            // What type of node is this?
            short nodeType = area.ReadInt2();
            // The version
            short ver = area.ReadInt2();
            if (nodeType == LeafType) {
                // Read the reference count,
                long refCount = area.ReadInt4();
                // The number of bytes in the leaf
                int leafSize = area.ReadInt4();

                // Set up the leaf node object
                graph = new TreeGraph("leaf", reference);
                graph.SetProperty("ver", ver);
                graph.SetProperty("key", leftKey.ToString());
                graph.SetProperty("reference_count", refCount);
                graph.SetProperty("leaf_size", leafSize);

            } else if (nodeType == BranchType) {
                // The data size area containing the children information
                int childDataSize = area.ReadInt4();
                long[] data = new long[childDataSize];
                for (int i = 0; i < childDataSize; ++i) {
                    data[i] = area.ReadInt8();
                }
                // Create the TreeBranch object to query it
                TreeBranch branch = new TreeBranch(reference, data, childDataSize);
                // Set up the branch node object
                graph = new TreeGraph("branch", reference);
                graph.SetProperty("ver", ver);
                graph.SetProperty("key", leftKey.ToString());
                graph.SetProperty("branch_size", branch.ChildCount);
                // Recursively add each child into the tree
                for (int i = 0; i < branch.ChildCount; ++i) {
                    long child_ref = branch.GetChild(i);
                    // If the ref is a special node, skip it
                    if ((child_ref & 0x01000000000000000L) != 0) {
                        // Should we record special nodes?
                    } else {
                        Key newLeftKey = (i > 0) ? branch.GetKey(i) : leftKey;
                        TreeGraph bn = new TreeGraph("child_meta", reference);
                        bn.SetProperty("extent", branch.GetChildLeafElementCount(i));
                        graph.AddChild(bn);
                        graph.AddChild(CreateRootGraph(newLeftKey, child_ref));
                    }
                }
            } else {
                throw new IOException("Unknown node type: " + nodeType);
            }

            return graph;
        }
示例#6
0
        private TreeReportNode CreateDiagnosticRootGraph(Key leftKey, NodeId id)
        {
            // The node being returned
            TreeReportNode node;

            // Open the area
            IArea area = nodeStore.GetArea(ToInt64StoreAddress(id));
            // What type of node is this?
            short nodeType = area.ReadInt2();
            // The version
            short ver = area.ReadInt2();

            if (nodeType == StoreLeafType)
            {
                // Read the reference count,
                long refCount = area.ReadInt4();
                // The number of bytes in the leaf
                int leafSize = area.ReadInt4();

                // Set up the leaf node object
                node = new TreeReportNode("leaf", id);
                node.SetProperty("VER", ver);
                node.SetProperty("key", leftKey.ToString());
                node.SetProperty("reference_count", refCount);
                node.SetProperty("leaf_size", leafSize);
            }
            else if (nodeType == StoreBranchType)
            {
                // The data size area containing the children information
                int    childDataSize = area.ReadInt4();
                long[] dataArr       = new long[childDataSize];
                for (int i = 0; i < childDataSize; ++i)
                {
                    dataArr[i] = area.ReadInt8();
                }
                // Create the TreeBranch object to query it
                TreeBranch branch = new TreeBranch(id, dataArr, childDataSize);
                // Set up the branch node object
                node = new TreeReportNode("branch", id);
                node.SetProperty("VER", ver);
                node.SetProperty("key", leftKey.ToString());
                node.SetProperty("branch_size", branch.ChildCount);
                // Recursively add each child into the tree
                for (int i = 0; i < branch.ChildCount; ++i)
                {
                    NodeId childId = branch.GetChild(i);
                    // If the id is a special node, skip it
                    if (childId.IsSpecial)
                    {
                        // Should we record special nodes?
                    }
                    else
                    {
                        Key            newLeftKey = (i > 0) ? branch.GetKey(i) : leftKey;
                        TreeReportNode bn         = new TreeReportNode("child_meta", id);
                        bn.SetProperty("extent", branch.GetChildLeafElementCount(i));
                        node.ChildNodes.Add(bn);
                        node.ChildNodes.Add(CreateDiagnosticRootGraph(newLeftKey, childId));
                    }
                }
            }
            else
            {
                throw new IOException("Unknown node type: " + nodeType);
            }

            return(node);
        }
示例#7
0
        private TreeReportNode CreateDiagnosticRootGraph(Key leftKey, NodeId id)
        {
            // The node being returned
            TreeReportNode node;

            // Open the area
            IArea area = nodeStore.GetArea(ToInt64StoreAddress(id));
            // What type of node is this?
            short nodeType = area.ReadInt2();
            // The version
            short ver = area.ReadInt2();
            if (nodeType == StoreLeafType) {
                // Read the reference count,
                long refCount = area.ReadInt4();
                // The number of bytes in the leaf
                int leafSize = area.ReadInt4();

                // Set up the leaf node object
                node = new TreeReportNode("leaf", id);
                node.SetProperty("VER", ver);
                node.SetProperty("key", leftKey.ToString());
                node.SetProperty("reference_count", refCount);
                node.SetProperty("leaf_size", leafSize);

            } else if (nodeType == StoreBranchType) {
                // The data size area containing the children information
                int childDataSize = area.ReadInt4();
                long[] dataArr = new long[childDataSize];
                for (int i = 0; i < childDataSize; ++i) {
                    dataArr[i] = area.ReadInt8();
                }
                // Create the TreeBranch object to query it
                TreeBranch branch = new TreeBranch(id, dataArr, childDataSize);
                // Set up the branch node object
                node = new TreeReportNode("branch", id);
                node.SetProperty("VER", ver);
                node.SetProperty("key", leftKey.ToString());
                node.SetProperty("branch_size", branch.ChildCount);
                // Recursively add each child into the tree
                for (int i = 0; i < branch.ChildCount; ++i) {
                    NodeId childId = branch.GetChild(i);
                    // If the id is a special node, skip it
                    if (childId.IsSpecial) {
                        // Should we record special nodes?
                    } else {
                        Key newLeftKey = (i > 0) ? branch.GetKey(i) : leftKey;
                        TreeReportNode bn = new TreeReportNode("child_meta", id);
                        bn.SetProperty("extent", branch.GetChildLeafElementCount(i));
                        node.ChildNodes.Add(bn);
                        node.ChildNodes.Add(CreateDiagnosticRootGraph(newLeftKey, childId));
                    }
                }

            } else {
                throw new IOException("Unknown node type: " + nodeType);
            }

            return node;
        }