private BTreeNode AttachSingleNodeToParent(BTreeNode singleNode, BTreeNode parentNode) { if (parentNode == null) { return(singleNode); } BTreeNodeRecord singleNodeRecord = singleNode.Records[0]; parentNode.Records.Add(singleNodeRecord); parentNode.Records.Sort(); BTreeNodeRecord leftOf = parentNode.LeftOf(singleNodeRecord); BTreeNodeRecord rightOf = parentNode.RightOf(singleNodeRecord); if (leftOf != null) { leftOf.Right = singleNodeRecord.Left; } if (rightOf != null) { rightOf.Left = singleNodeRecord.Right; } return(parentNode); }
private BTreeNodeRecord FindRecord(BTreeNode start, K key, int depthRestriction, bool exactMatch) { if (this._root == null) { return(null); } BTreeNode containingNode = this.FindNode(start, key, depthRestriction, exactMatch); if (exactMatch && containingNode == null) { return(null); } BTreeNodeRecord found = containingNode.ClosestRecord(key); if (!exactMatch) { return(found); } if (found.Item.Key.Equals(key)) { return(found); } return(null); }
private void RemoveLeaf(K key) { BTreeNode foundNode = this.FindNode(this._root, key, -1, true); BTreeNodeRecord foundRecord = foundNode.ClosestRecord(key); foundNode.Records.Remove(foundRecord); this.Count--; }
public void Add(K key, V value) { if (this._root == null) { this._root = new BTreeNode(this.order, key, value); this.Count++; } else { BTreeNode parentNode = null; BTreeNode currentNode = this._root; while (!currentNode.IsLeaf || !currentNode.HasRoom) { if (!currentNode.HasRoom) { this.PushSidesDown(currentNode); currentNode = this.AttachSingleNodeToParent(currentNode, parentNode); } BTreeNodeRecord closest = currentNode.ClosestRecord(key); if (key.Equals(closest.Item.Key)) { closest.Item = new KeyValuePair <K, V>(key, value); return; } else { parentNode = currentNode; if (key.CompareTo(closest.Item.Key) < 0 && closest.Left != null) { currentNode = closest.Left; } else { currentNode = closest.Right; } } } if (currentNode.ContainsKey(key)) { currentNode.ClosestRecord(key).Item = new KeyValuePair <K, V>(key, value); } else { currentNode.Records.Add(new BTreeNodeRecord(key, value)); currentNode.Records.Sort(); this.Count++; } } }
private void RemoveInternal(K key) { BTreeNodeRecord found = this.FindRecord(this._root, key, -1, true); BTreeNodeRecord nextHighest = this.FindRecord(found.Right, key, -1, false); KeyValuePair <K, V> temp = nextHighest.Item; this.Remove(temp.Key); BTreeNodeRecord foundAnew = this.FindRecord(this._root, key, -1, true); foundAnew.Item = temp; }
public bool ContainsKey(K key) { BTreeNodeRecord recFound = this.ClosestRecord(key); if (recFound.Item.Key.Equals(key)) { return(true); } else { return(false); } }
public bool TryGetValue(K key, out V value) { value = default(V); BTreeNodeRecord found = this.FindRecord(this._root, key, -1, true); if (found != null) { value = found.Item.Value; return(true); } return(false); }
private BTreeNode FixSingle(BTreeNode parent, BTreeNode node) { K key = node.Records[0].Item.Key; int largerParentIdx = parent.Records.BinarySearch(new BTreeNodeRecord(key, default(V))); if (largerParentIdx < 0) { largerParentIdx = ~largerParentIdx; } BTreeNodeRecord parentRecordLeft = null; BTreeNodeRecord parentRecordRight = null; if (parent.IndexIsInRange(largerParentIdx - 1)) { parentRecordLeft = parent.Records[largerParentIdx - 1]; } if (parent.IndexIsInRange(largerParentIdx)) { parentRecordRight = parent.Records[largerParentIdx]; } BTreeNode nodeToReturn = null; if (parentRecordLeft != null && parentRecordLeft.Left != null && parentRecordLeft.Left.VulnerableToTheft) { nodeToReturn = this.RotateFromLeft(node, parentRecordLeft); } else if (parentRecordRight != null && parentRecordRight.Right != null && parentRecordRight.Right.VulnerableToTheft) { nodeToReturn = this.RotateFromRight(node, parentRecordRight); } else if (parent.VulnerableToTheft && parentRecordLeft != null) { nodeToReturn = this.FuseParentAndLeft(node, parent, parentRecordLeft, parentRecordRight); } else if (parent.VulnerableToTheft && parentRecordRight != null) { nodeToReturn = this.FuseParentAndRight(node, parent, parentRecordLeft, parentRecordRight); } else if (!parent.VulnerableToTheft && parent.Equals(this._root)) { nodeToReturn = this.FuseNewRoot(parent); } return(nodeToReturn); }
private BTreeNode FuseNewRoot(BTreeNode parentNode) { //_root == parentNode and has 1 key, so fuse self, root, sibling into 1 new root BTreeNodeRecord rootRecord = this._root.Records[0]; BTreeNodeRecord leftRecord = rootRecord.Left.Records[0]; BTreeNodeRecord rightRecord = rootRecord.Right.Records[0]; this._root.Records.Insert(0, leftRecord); this._root.Records.Add(rightRecord); rootRecord.Left = leftRecord.Right; rootRecord.Right = rightRecord.Left; return(this._root); }
public BTreeNodeRecord LeftOf(BTreeNodeRecord rec) { if (!this.Records.Contains(rec)) { return(null); } int idxOf = this.Records.IndexOf(rec); if (this.IndexIsInRange(idxOf - 1)) { return(this.Records[idxOf - 1]); } else { return(null); } }
public BTreeNodeRecord RightOf(BTreeNodeRecord rec) { BTreeNodeRecord recFound = this.ClosestRecord(rec.Item.Key); if (recFound.Item.Key.CompareTo(rec.Item.Key) != 0) { return(null); } int idxOf = this.Records.IndexOf(rec); if (this.IndexIsInRange(idxOf + 1)) { return(this.Records[idxOf + 1]); } else { return(null); } }
private BTreeNode RotateFromRight(BTreeNode node, BTreeNodeRecord parentRecordRight) { BTreeNode rightSiblingNode = parentRecordRight.Right; BTreeNodeRecord toRotateUp = rightSiblingNode.Records[0]; BTreeNodeRecord toPullDown = parentRecordRight; BTreeNode orphaned = toRotateUp.Left; KeyValuePair <K, V> keyValToRotateUp = toRotateUp.Item; KeyValuePair <K, V> keyValToPullDown = toPullDown.Item; rightSiblingNode.Records.RemoveAt(0); parentRecordRight.Item = keyValToRotateUp; node.Records.Add(new BTreeNodeRecord(keyValToPullDown.Key, keyValToPullDown.Value)); node.Records[node.Records.Count - 1].Left = node.Records[node.Records.Count - 2].Right; node.Records[node.Records.Count - 1].Right = orphaned; return(node); }
private BTreeNode RotateFromLeft(BTreeNode node, BTreeNodeRecord parentRecordLeft) { BTreeNode leftSiblingNode = parentRecordLeft.Left; BTreeNodeRecord toRotateUp = leftSiblingNode.Records[leftSiblingNode.Records.Count - 1]; BTreeNodeRecord toPullDown = parentRecordLeft; BTreeNode orphaned = toRotateUp.Right; KeyValuePair <K, V> keyValToRotateUp = toRotateUp.Item; KeyValuePair <K, V> keyValToPullDown = toPullDown.Item; leftSiblingNode.Records.RemoveAt(leftSiblingNode.Records.Count - 1); parentRecordLeft.Item = keyValToRotateUp; node.Records.Insert(0, new BTreeNodeRecord(keyValToPullDown.Key, keyValToPullDown.Value)); node.Records[0].Left = orphaned; node.Records[0].Right = node.Records[1].Left; return(node); }
private BTreeNode FuseParentAndRight(BTreeNode node, BTreeNode parentNode, BTreeNodeRecord parentRecordLeft, BTreeNodeRecord parentRecordRight) { //store BTreeNodeRecord rightSiblingNodeRecord = parentRecordRight.Right.Records[0]; BTreeNodeRecord nodeRecord = node.Records[0]; BTreeNodeRecord parentRecordRightRight = parentNode.RightOf(parentRecordRight); //remove what will be middle node from parent parentNode.Records.Remove(parentRecordRight); //break middle node child links parentRecordRight.Left = null; parentRecordRight.Right = null; //make node to fuse to BTreeNode fused = new BTreeNode(this.order); fused.Records.Add(nodeRecord); fused.Records.Add(parentRecordRight); fused.Records.Add(rightSiblingNodeRecord); //correct middle node child links parentRecordRight.Left = nodeRecord.Right; parentRecordRight.Right = rightSiblingNodeRecord.Left; //wire parents to the fused node if (parentRecordRightRight != null) { parentRecordRightRight.Left = fused; } if (parentRecordLeft != null) { parentRecordLeft.Right = fused; } return(fused); }
public bool ContainsKey(K key) { BTreeNodeRecord recFound = this.ClosestRecord(key); return(recFound.Item.Key.Equals(key)); }
private BTreeNode FindNode(BTreeNode start, K key, int depthRestriction, bool exactMatch) { if (this._root == null) { return(null); } BTreeNode currentNode = start; int depthTraversed = 0; while (currentNode != null) { BTreeNodeRecord currentRecord = currentNode.ClosestRecord(key); if (currentRecord.Item.Key.Equals(key)) { return(currentNode); } else if (depthTraversed == depthRestriction) { if (exactMatch) { return(null); } else { return(currentNode); } } else { depthTraversed++; if (key.CompareTo(currentRecord.Item.Key) < 0 && currentRecord.Left != null) { currentNode = currentRecord.Left; } else if (currentRecord.Right != null) { currentNode = currentRecord.Right; } else { if (exactMatch) { return(null); } else { return(currentNode); } } } } if (exactMatch) { return(null); } else { return(currentNode); } }