protected BPlusTreeNode <TKey, TValue> GetRightSibling(bool mustHaveSameParent) { if (this.IsLeaf) { // use the rightsibling pointer BPlusTreeLeafNode <TKey, TValue> leaf = this as BPlusTreeLeafNode <TKey, TValue>; return(BPlusTreeNode <TKey, TValue> .Read(this.Tree, this.Parent, leaf.RightSiblingLocation)); } else { // look in parent for our smallest keyword, grab childlocation to the left of it int parentChildCount; int childLocationIndex = GetIndexInParent(out parentChildCount); if (childLocationIndex == -1) { // never found the index, or no parent (aka root). No sibling to return. return(null); } else { if (childLocationIndex < parentChildCount - 1) { // we know the right sibling is attached to the same parent. BPlusTreeNode <TKey, TValue> node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, this.Parent, Parent.ChildLocations[childLocationIndex + 1]); return(node); } else { // we are the rightmost child, as we're at the location that's 1 past the fanout size if (mustHaveSameParent) { // caller wants the sibling only if it's from the same parent, and it's not. return(null); } else { // we have to find the common ancestor between this and its right sibling. // spin up until we find the first node whose child index is <= Fanoutsize // then drill down the leftmost path until we're at the same depth as we started at int i = 0; int nodeChildLocationIndex = -1; BPlusTreeNode <TKey, TValue> node = this; while (node.Parent != null) { i++; // keep bubbling up until we're at a node whose parent has at least one child to our right. nodeChildLocationIndex = node.GetIndexInParent(out parentChildCount); if (nodeChildLocationIndex < parentChildCount - 1) { // this node is not the rightmost child of its parent. // we're done bubbling (node contains the ancestor node, nodeChildLocationIndex can tell us the subtree to search down) break; } else { node = node.Parent; } } if (nodeChildLocationIndex == parentChildCount - 1) { // the only common ancestor has our node being the rightmost node in the tree (at this depth). return(null); } // ok, node contains the ancestor somehwere up the tree that has the node we're looking for as its // leftmost descendent at the same depth. // So we just keep drilling down the leftmost path until we're at the same depth. node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, node as BPlusTreeIndexNode <TKey, TValue>, nodeChildLocationIndex + 1); while (i > 0) { BPlusTreeIndexNode <TKey, TValue> indexNode = node as BPlusTreeIndexNode <TKey, TValue>; node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, indexNode, indexNode.ChildLocations[0]); i--; } // node now contains the right sibling! return(node); } } } //// bounce up to the parent //if (Parent != null) { // TKey ourKey = FirstKeyword; // for (int i=0; i < Parent.Keywords.Count; i++) { // TKey parentKeyword = Parent.Keywords[i]; // if (parentKeyword.CompareTo(ourKey, KeywordMatchMode.ExactMatch, false) == 0) { // // follow right child // BPlusTreeNode<TKey, TValue> node = BPlusTreeNode<TKey, TValue>.Read(this.Tree, this.Parent, Parent.ChildLocations[i+1]); // return node; // } // } //} //return null; } }
protected BPlusTreeNode <TKey, TValue> GetLeftSibling(bool mustHaveSameParent) { // look in parent for our smallest keyword, grab childlocation to the left of it int parentChildCount; int childLocationIndex = GetIndexInParent(out parentChildCount); if (childLocationIndex == -1) { // never found the index, or no parent (aka root). No sibling to return. return(null); } else { if (childLocationIndex == 0) { if (mustHaveSameParent) { // caller wants the sibling only if it's from the same parent, and it's not. return(null); } else { // we have to find the parent of our left sibling. // spin up until we find the first node whose child index is > 0 // then drill down the rightmost path until we're at the same depth as we started at int i = 0; int nodeChildLocationIndex = -1; BPlusTreeNode <TKey, TValue> node = this; while (node.Parent != null) { i++; // keep bubbling up until we're at a node whose parent has at least one child to our left. nodeChildLocationIndex = node.GetIndexInParent(out parentChildCount); if (nodeChildLocationIndex > 0) { // this node is not the leftmost child of its parent. // we're done bubbling (node contains the ancestor node, nodeChildLocationIndex can tell us the subtree to search down) break; } else { node = node.Parent; } } if (nodeChildLocationIndex == 0) { // the only common ancestor has our node being the leftmost node in the tree (at this depth). return(null); } // ok, node contains the ancestor somehwere up the tree that has the node we're looking for as its // rightmost descendent at the same depth. // So we just keep drilling down until we're at the same depth. node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, node as BPlusTreeIndexNode <TKey, TValue>, nodeChildLocationIndex - 1); while (i > 0) { BPlusTreeIndexNode <TKey, TValue> indexNode = node as BPlusTreeIndexNode <TKey, TValue>; node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, indexNode, indexNode.LastChildLocation); i--; } // node now contains the left sibling! return(node); } } else { // we know the left sibling is attached to the same parent. BPlusTreeNode <TKey, TValue> node = BPlusTreeNode <TKey, TValue> .Read(this.Tree, this.Parent, Parent.ChildLocations[childLocationIndex - 1]); return(node); } } }