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); } }
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(); }
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) }
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); }
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; }
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); }
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; }