/// <summary> /// Can only merge node without intersection => the greater key of this must be smaller than the smallest key of the node /// </summary> public virtual void MergeWith(IBTreeNode node) { BTreeValidator.ValidateNode(this); BTreeValidator.ValidateNode(node); CheckIfCanMergeWith(node); var j = NbKeys; for (var i = 0; i < node.GetNbKeys(); i++) { SetKeyAndValueAt(node.GetKeyAt(i), node.GetValueAsObjectAt(i), j, false, false); SetChildAt(node, i, j, false); j++; } // in this, we have to take the last child if (node.GetNbChildren() > node.GetNbKeys()) { SetChildAt(node, node.GetNbChildren() - 1, j, true); } NbKeys += node.GetNbKeys(); NbChildren += node.GetNbChildren(); BTreeValidator.ValidateNode(this); }
protected override object GetValueAt(IBTreeNode node, int currentIndex) { if (_currentValue == null) { _currentValue = (IList)node.GetValueAsObjectAt(currentIndex); } var listSize = _currentValue.Count; if (listSize > _currenListIndex) { var value = _currentValue[_currenListIndex]; _currenListIndex++; return(value); } // We have reached the end of the list or the list is empty // We must continue iterate in the current node / btree _currenListIndex = 0; _currentValue = null; return(null); }
/// <summary> /// Returns the value of the deleted key /// </summary> /// <param name="node"> </param> /// <param name="keyAndValue"> </param> /// <returns> </returns> /// <exception cref="System.Exception">System.Exception</exception> private object InternalDelete(IBTreeNode node, IKeyAndValue keyAndValue) { var positionOfKey = node.GetPositionOfKey(keyAndValue.GetKey()); var keyIsHere = positionOfKey > 0; if (node.IsLeaf()) { if (keyIsHere) { var deletedValue = node.DeleteKeyForLeafNode(keyAndValue); GetPersister().SaveNode(node); return(deletedValue); } // key does not exist return(null); } int realPosition; if (!keyIsHere) { // descend realPosition = -positionOfKey - 1; var childTreeNode = node.GetChildAt(realPosition, true); if (childTreeNode.GetNbKeys() == _degree - 1) { node = PrepareForDelete(node, childTreeNode, realPosition); return(InternalDelete(node, keyAndValue)); } return(InternalDelete(childTreeNode, keyAndValue)); } // Here,the node is not a leaf and contains the key realPosition = positionOfKey - 1; var currentKey = node.GetKeyAt(realPosition); var currentValue = node.GetValueAsObjectAt(realPosition); // case 2a var leftNode = node.GetChildAt(realPosition, true); if (leftNode.GetNbKeys() >= _degree) { var prevKeyAndValue = GetBiggest(leftNode, true); node.SetKeyAndValueAt(prevKeyAndValue, realPosition); BTreeValidator.ValidateNode(node, node == _root); GetPersister().SaveNode(node); return(currentValue); } // case 2b var rightNode = node.GetChildAt(realPosition + 1, true); if (rightNode.GetNbKeys() >= _degree) { var nextKeyAndValue = GetSmallest(rightNode, true); node.SetKeyAndValueAt(nextKeyAndValue, realPosition); BTreeValidator.ValidateNode(node, node == _root); GetPersister().SaveNode(node); return(currentValue); } // case 2c // Here, both left and right part have degree-1 keys // remove the element to be deleted from node (shifting left all // right // elements, link to right link does not exist anymore) // insert the key to be deleted in left child and merge the 2 nodes. // rightNode should be deleted // if node is root, then leftNode becomes the new root and node // should be deleted // node.DeleteKeyAndValueAt(realPosition, true); leftNode.InsertKeyAndValue(currentKey, currentValue); leftNode.MergeWith(rightNode); // If node is the root and is empty if (!node.HasParent() && node.GetNbKeys() == 0) { _persister.DeleteNode(node); _root = leftNode; leftNode.SetParent(null); // The height has been decreased. No need to save btree here. // The calling delete method will save it. _height--; } else { node.SetChildAt(leftNode, realPosition); // Node must only be validated if it is not the root BTreeValidator.ValidateNode(node, node == _root); } _persister.DeleteNode(rightNode); BTreeValidator.ValidateNode(leftNode, leftNode == _root); GetPersister().SaveNode(node); GetPersister().SaveNode(leftNode); return(InternalDelete(leftNode, keyAndValue)); }
/// <summary> /// Can only merge node without intersection => the greater key of this must be smaller than the smallest key of the node /// </summary> public virtual void MergeWith(IBTreeNode node) { BTreeValidator.ValidateNode(this); BTreeValidator.ValidateNode(node); CheckIfCanMergeWith(node); var j = NbKeys; for (var i = 0; i < node.GetNbKeys(); i++) { SetKeyAndValueAt(node.GetKeyAt(i), node.GetValueAsObjectAt(i), j, false, false); SetChildAt(node, i, j, false); j++; } // in this, we have to take the last child if (node.GetNbChildren() > node.GetNbKeys()) SetChildAt(node, node.GetNbChildren() - 1, j, true); NbKeys += node.GetNbKeys(); NbChildren += node.GetNbChildren(); BTreeValidator.ValidateNode(this); }