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