public BPlusTreeNode(BPlusTreeNodeSortedLinks <TKey, TValue> links, BPlusTreeNode <TKey, TValue> parentNode, BPlusTreeNode <TKey, TValue> rightNode, BPlusTreeNode <TKey, TValue> leftNode, BPlusTree <TKey, TValue> parentTree, bool isRoot) { Links = links; ParentNode = parentNode; RightNode = rightNode; LeftNode = leftNode; ParentTree = parentTree; IsLeaf = false; IsRoot = isRoot; }
public void CopyTo(BPlusTreeNodeSortedLinks <TKey, TValue> links, int copyFromIndex, int copyToIndex) { try { for (int i = copyFromIndex; i < copyToIndex; i++) { links.Add(this.Keys[i], this.Values[i]); } } catch (Exception) { throw new IndexOutOfRangeException("Index run out of range while coping BPlusTreeNodeSortedLinks."); } }
protected void PullNodes(BPlusTreeNode <TKey, TValue> nodeToPull, BPlusTreeNode <TKey, TValue> nodeFromPull) { int numberOfLinksToPull = nodeToPull.KeysCount + (nodeFromPull.KeysCount - nodeToPull.KeysCount) / 2; if (nodeToPull.RightNode == nodeFromPull) { BPlusTreeNodeSortedLinks <TKey, TValue> pulledLinks = new BPlusTreeNodeSortedLinks <TKey, TValue>(); for (int i = 0; i < numberOfLinksToPull; i++) { pulledLinks.Add(nodeFromPull.Links.Keys[0], nodeFromPull.Links.Values[0]); nodeFromPull.Links.RemoveAt(0); } TKey oldKey = nodeToPull.Links.Keys.Max(); nodeToPull.Links.AddRange(nodeToPull, pulledLinks); nodeToPull.ParentNode.Links.Remove(oldKey); nodeToPull.ParentNode.Links.Add(nodeToPull.Links.Keys.Max(), nodeToPull); } else { BPlusTreeNodeSortedLinks <TKey, TValue> pulledLinks = new BPlusTreeNodeSortedLinks <TKey, TValue>(); TKey oldKey = nodeFromPull.Links.Keys.Max(); for (int i = 0; i < numberOfLinksToPull; i++) { pulledLinks.Add(nodeFromPull.Links.Keys[nodeFromPull.KeysCount - 1], nodeFromPull.Links.Values[nodeFromPull.KeysCount - 1]); nodeFromPull.Links.RemoveAt(nodeFromPull.KeysCount - 1); } nodeToPull.Links.AddRange(nodeToPull, pulledLinks); nodeFromPull.ParentNode.Links.Remove(oldKey); nodeFromPull.ParentNode.Links.Add(nodeFromPull.Links.Keys.Max(), nodeFromPull); } }
protected void MergeNodes(BPlusTreeNode <TKey, TValue> leftNodeToMerge, BPlusTreeNode <TKey, TValue> rightNodeToMerge) { NodesCount--; BPlusTreeNode <TKey, TValue> newNode = new BPlusTreeNode <TKey, TValue>(new BPlusTreeNodeSortedLinks <TKey, TValue>(), null, null, null, leftNodeToMerge.ParentTree, false); BPlusTreeNodeSortedLinks <TKey, TValue> mergedLinks = new BPlusTreeNodeSortedLinks <TKey, TValue>(); mergedLinks.AddRange(newNode, leftNodeToMerge.Links); mergedLinks.AddRange(newNode, rightNodeToMerge.Links); newNode.Links = mergedLinks; newNode.ParentNode = rightNodeToMerge.ParentNode; newNode.LeftNode = leftNodeToMerge.LeftNode; newNode.RightNode = rightNodeToMerge.RightNode; if (newNode.RightNode != null) { newNode.RightNode.LeftNode = newNode; } if (newNode.LeftNode != null) { newNode.LeftNode.RightNode = newNode; } newNode.ParentNode.Links.Remove(rightNodeToMerge.Links.Keys.Max()); newNode.ParentNode.Links.Add(newNode.Links.Keys.Max(), newNode); leftNodeToMerge.ParentNode.Links.Remove(leftNodeToMerge.Links.Keys.Max()); if (leftNodeToMerge.ParentNode != rightNodeToMerge.ParentNode) { leftNodeToMerge.ParentNode.ParentNode.Links.Remove(leftNodeToMerge.Links.Keys.Max()); leftNodeToMerge.ParentNode.ParentNode.Links.Add(leftNodeToMerge.ParentNode.Links.Keys.Max(), leftNodeToMerge.ParentNode); if (leftNodeToMerge.ParentNode.KeysCount < MinDegree && !leftNodeToMerge.ParentNode.IsRoot) { MergeOrPullNode(leftNodeToMerge.ParentNode); } } if (newNode.ParentNode.KeysCount < MinDegree && !newNode.ParentNode.IsRoot) { MergeOrPullNode(newNode.ParentNode); } else if (newNode.ParentNode.IsRoot && newNode.ParentNode.KeysCount == 1) { newNode.IsRoot = true; newNode.ParentNode = null; Head = newNode; NodesCount--; } }
protected void SplitNode(BPlusTreeNode <TKey, TValue> nodeToSplit) { int pivotIndex = nodeToSplit.Links.Count / 2; BPlusTreeNodeSortedLinks <TKey, TValue> leftLinks = new BPlusTreeNodeSortedLinks <TKey, TValue>(); BPlusTreeNodeSortedLinks <TKey, TValue> rightLinks = new BPlusTreeNodeSortedLinks <TKey, TValue>(); nodeToSplit.Links.CopyTo(leftLinks, 0, pivotIndex + 1); nodeToSplit.Links.CopyTo(rightLinks, pivotIndex + 1, nodeToSplit.Links.Count); BPlusTreeNode <TKey, TValue> leftNode = new BPlusTreeNode <TKey, TValue>(leftLinks, nodeToSplit.ParentNode, null, null, nodeToSplit.ParentTree, false); BPlusTreeNode <TKey, TValue> rightNode = new BPlusTreeNode <TKey, TValue>(rightLinks, nodeToSplit.ParentNode, null, null, nodeToSplit.ParentTree, false); leftNode.RightNode = rightNode; leftNode.LeftNode = nodeToSplit.LeftNode; rightNode.LeftNode = leftNode; rightNode.RightNode = nodeToSplit.RightNode; if (nodeToSplit.LeftNode != null) { nodeToSplit.LeftNode.RightNode = leftNode; } if (nodeToSplit.RightNode != null) { nodeToSplit.RightNode.LeftNode = rightNode; } if (!nodeToSplit.IsRoot) { nodeToSplit.ParentNode.Links.Remove(nodeToSplit.Links.Keys.Max()); nodeToSplit.ParentNode.Links.Add(rightNode.Links.Keys.Last(), rightNode); nodeToSplit.ParentNode.Links.Add(leftNode.Links.Keys.Last(), leftNode); } else { BPlusTreeNode <TKey, TValue> newRoot = new BPlusTreeNode <TKey, TValue>(new BPlusTreeNodeSortedLinks <TKey, TValue>(), null, null, null, nodeToSplit.ParentTree, true); leftNode.ParentNode = newRoot; rightNode.ParentNode = newRoot; newRoot.Links.Add(leftNode.Links.Keys.Last(), leftNode); newRoot.Links.Add(rightNode.Links.Keys.Last(), rightNode); Head = newRoot; NodesCount++; } if (leftNode.ParentNode.KeysCount > MaxDegree) { Split(leftNode.ParentNode); } }