public override object GetValueAt(NeoDatis.Btree.IBTreeNode node, int currentIndex ) { if (currentValue == null) { currentValue = (System.Collections.IList)node.GetValueAsObjectAt(currentIndex); } int listSize = currentValue.Count; if (listSize > currenListIndex) { object 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> /// 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(NeoDatis.Btree.IBTreeNode node) { NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(this); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(node); CheckIfCanMergeWith(node); int j = nbKeys; for (int 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(); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(this); }
/// <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> protected virtual object InternalDelete(NeoDatis.Btree.IBTreeNode node, NeoDatis.Btree.IKeyAndValue keyAndValue) { int position = node.GetPositionOfKey(keyAndValue.GetKey()); bool keyIsHere = position > 0; int realPosition = -1; NeoDatis.Btree.IBTreeNode leftNode = null; NeoDatis.Btree.IBTreeNode rightNode = null; try { if (node.IsLeaf()) { if (keyIsHere) { object deletedValue = node.DeleteKeyForLeafNode(keyAndValue); GetPersister().SaveNode(node); return(deletedValue); } // key does not exist return(null); } if (!keyIsHere) { // descend realPosition = -position - 1; NeoDatis.Btree.IBTreeNode child = node.GetChildAt(realPosition, true); if (child.GetNbKeys() == degree - 1) { node = PrepareForDelete(node, child, realPosition); return(InternalDelete(node, keyAndValue)); } return(InternalDelete(child, keyAndValue)); } // Here,the node is not a leaf and contains the key realPosition = position - 1; System.IComparable currentKey = node.GetKeyAt(realPosition); object currentValue = node.GetValueAsObjectAt(realPosition); // case 2a leftNode = node.GetChildAt(realPosition, true); if (leftNode.GetNbKeys() >= degree) { NeoDatis.Btree.IKeyAndValue prev = GetBiggest(leftNode, true); node.SetKeyAndValueAt(prev, realPosition); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(node, node == root); GetPersister().SaveNode(node); return(currentValue); } // case 2b rightNode = node.GetChildAt(realPosition + 1, true); if (rightNode.GetNbKeys() >= degree) { NeoDatis.Btree.IKeyAndValue next = GetSmallest(rightNode, true); node.SetKeyAndValueAt(next, realPosition); NeoDatis.Btree.Tool.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 NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(node, node == root); } persister.DeleteNode(rightNode); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(leftNode, leftNode == root); GetPersister().SaveNode(node); GetPersister().SaveNode(leftNode); return(InternalDelete(leftNode, keyAndValue)); } finally { } }