protected virtual T NextAsc() { // Try to go down till a leaf while (!currentNode.IsLeaf()) { currentNode = currentNode.GetChildAt(currentKeyIndex, true); currentKeyIndex = 0; } // If leaf has more keys if (currentKeyIndex < currentNode.GetNbKeys()) { nbReturnedKeys++; nbReturnedElements++; object nodeValue = GetValueAt(currentNode, currentKeyIndex); currentKeyIndex++; return((T)nodeValue); } NeoDatis.Btree.IBTreeNode child = null; // else go up till a node with keys while (currentKeyIndex >= currentNode.GetNbKeys()) { child = currentNode; currentNode = currentNode.GetParent(); currentKeyIndex = IndexOfChild(currentNode, child); } nbReturnedElements++; nbReturnedKeys++; object value = GetValueAt(currentNode, currentKeyIndex); currentKeyIndex++; return((T)value); }
public virtual NeoDatis.Btree.IKeyAndValue GetBiggest(NeoDatis.Btree.IBTreeNode node , bool delete) { int lastKeyIndex = node.GetNbKeys() - 1; int lastChildIndex = node.GetNbChildren() - 1; if (lastChildIndex > lastKeyIndex) { NeoDatis.Btree.IBTreeNode child = node.GetChildAt(lastChildIndex, true); if (child.GetNbKeys() == degree - 1) { node = PrepareForDelete(node, child, lastChildIndex); } lastChildIndex = node.GetNbChildren() - 1; child = node.GetChildAt(lastChildIndex, true); return(GetBiggest(child, delete)); } NeoDatis.Btree.IKeyAndValue kav = node.GetKeyAndValueAt(lastKeyIndex); if (delete) { node.DeleteKeyAndValueAt(lastKeyIndex, false); persister.SaveNode(node); } return(kav); }
/// <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); }
private void CheckIfCanMergeWith(NeoDatis.Btree.IBTreeNode node) { if (nbKeys + node.GetNbKeys() > maxNbKeys) { throw new NeoDatis.Btree.Exception.BTreeException("Trying to merge two nodes with too many keys " + nbKeys + " + " + node.GetNbKeys() + " > " + maxNbKeys); } if (nbKeys > 0) { System.IComparable greatestOfThis = keys[nbKeys - 1]; System.IComparable smallestOfOther = node.GetKeyAt(0); if (greatestOfThis.CompareTo(smallestOfOther) >= 0) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Trying to merge two nodes that have intersections : " + ToString() + " / " + node); } } if (nbKeys < nbChildren) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Trying to merge two nodes where the first one has more children than keys" ); } }
// TODO Auto-generated method stub public override void Reset() { this.currentNode = btree.GetRoot(); if (orderByType.IsOrderByDesc()) { this.currentKeyIndex = currentNode.GetNbKeys(); } else { this.currentKeyIndex = 0; } nbReturnedElements = 0; nbReturnedKeys = 0; }
public AbstractBTreeIterator(NeoDatis.Btree.IBTree tree, NeoDatis.Odb.Core.OrderByConstants orderByType) { this.btree = tree; this.currentNode = tree.GetRoot(); this.orderByType = orderByType; if (orderByType.IsOrderByDesc()) { this.currentKeyIndex = currentNode.GetNbKeys(); } else { this.currentKeyIndex = 0; } }
private void BuildDisplay(NeoDatis.Btree.IBTreeNode node, int currentHeight, int childIndex, object parentId, bool withIds) { if (currentHeight > lines.Length - 1) { return; } // get string buffer of this line System.Text.StringBuilder line = lines[currentHeight]; if (withIds) { line.Append(node.GetId()).Append(":["); } else { line.Append("["); } for (int i = 0; i < node.GetNbKeys(); i++) { if (i > 0) { line.Append(" , "); } NeoDatis.Btree.IKeyAndValue kav = node.GetKeyAndValueAt(i); line.Append(kav.GetKey()); } if (withIds) { line.Append("]:").Append(node.GetParentId()).Append("/").Append(parentId).Append( " "); } else { line.Append("] "); } for (int i = 0; i < node.GetNbChildren(); i++) { NeoDatis.Btree.IBTreeNode child = node.GetChildAt(i, false); if (child != null) { BuildDisplay(child, currentHeight + 1, i, node.GetId(), withIds); } else { lines[currentHeight + 1].Append("[Child " + (i + 1) + " null!] "); } } }
private static void CheckValuesOfChild(NeoDatis.Btree.IKeyAndValue key, NeoDatis.Btree.IBTreeNode node) { if (!on) { return; } if (node == null) { return; } for (int i = 0; i < node.GetNbKeys(); i++) { if (node.GetKeyAndValueAt(i).GetKey().CompareTo(key.GetKey()) >= 0) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Left child with values bigger than pivot " + key + " : " + node.ToString()); } } }
public virtual NeoDatis.Btree.IKeyAndValue GetSmallest(NeoDatis.Btree.IBTreeNode node, bool delete) { if (!node.IsLeaf()) { NeoDatis.Btree.IBTreeNode child = node.GetChildAt(0, true); if (child.GetNbKeys() == degree - 1) { node = PrepareForDelete(node, child, 0); } child = node.GetChildAt(0, true); return(GetSmallest(child, delete)); } NeoDatis.Btree.IKeyAndValue kav = node.GetKeyAndValueAt(0); if (delete) { node.DeleteKeyAndValueAt(0, true); persister.SaveNode(node); } return(kav); }
public static void ValidateNode(NeoDatis.Btree.IBTreeNode node) { if (!on) { return; } int nbKeys = node.GetNbKeys(); if (node.HasParent() && nbKeys < node.GetDegree() - 1) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Node with less than " + (node.GetDegree() - 1) + " keys"); } int maxNbKeys = node.GetDegree() * 2 - 1; int nbChildren = node.GetNbChildren(); int maxNbChildren = node.GetDegree() * 2; if (nbChildren != 0 && nbKeys == 0) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Node with no key but with children : " + node); } for (int i = 0; i < nbKeys; i++) { if (node.GetKeyAndValueAt(i) == null) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Null key at " + i + " on node " + node.ToString()); } CheckValuesOfChild(node.GetKeyAndValueAt(i), node.GetChildAt(i, false)); } for (int i = nbKeys; i < maxNbKeys; i++) { if (node.GetKeyAndValueAt(i) != null) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Not Null key at " + i + " on node " + node.ToString()); } } NeoDatis.Btree.IBTreeNode previousNode = null; for (int i = 0; i < nbChildren; i++) { if (node.GetChildAt(i, false) == null) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Null child at index " + i + " on node " + node.ToString()); } if (previousNode != null && previousNode == node.GetChildAt(i, false)) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Two equals children at index " + i + " : " + previousNode.ToString()); } previousNode = node.GetChildAt(i, false); } for (int i = nbChildren; i < maxNbChildren; i++) { if (node.GetChildAt(i, false) != null) { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Not Null child at " + i + " on node " + node.ToString()); } } }
/// <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 { } }
private NeoDatis.Btree.IBTreeNode PrepareForDelete(NeoDatis.Btree.IBTreeNode parent , NeoDatis.Btree.IBTreeNode child, int childIndex) { NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(parent); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(child); // case 3a NeoDatis.Btree.IBTreeNode leftSibling = null; NeoDatis.Btree.IBTreeNode rightSibling = null; try { if (childIndex > 0 && parent.GetNbChildren() > 0) { leftSibling = parent.GetChildAt(childIndex - 1, false); } if (childIndex < parent.GetNbChildren() - 1) { rightSibling = parent.GetChildAt(childIndex + 1, false); } // case 3a left if (leftSibling != null && leftSibling.GetNbKeys() >= degree) { NeoDatis.Btree.IKeyAndValue elementToMoveDown = parent.GetKeyAndValueAt(childIndex - 1); NeoDatis.Btree.IKeyAndValue elementToMoveUp = leftSibling.GetLastKeyAndValue(); parent.SetKeyAndValueAt(elementToMoveUp, childIndex - 1); child.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); if (leftSibling.GetNbChildren() > leftSibling.GetNbKeys()) { // Take the last child of the left sibling and set it the // first child of the 'child' (incoming parameter) // child.setChildAt(leftSibling.getChildAt(leftSibling.getNbChildren() // - 1, true), 0); child.SetChildAt(leftSibling, leftSibling.GetNbChildren() - 1, 0, true); child.IncrementNbChildren(); } leftSibling.DeleteKeyAndValueAt(leftSibling.GetNbKeys() - 1, false); if (!leftSibling.IsLeaf()) { leftSibling.DeleteChildAt(leftSibling.GetNbChildren() - 1); } persister.SaveNode(parent); persister.SaveNode(child); persister.SaveNode(leftSibling); if (NeoDatis.Btree.Tool.BTreeValidator.IsOn()) { NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(parent, parent == root); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(child, false); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(leftSibling, false); NeoDatis.Btree.Tool.BTreeValidator.CheckDuplicateChildren(leftSibling, child); } return(parent); } // case 3a right if (rightSibling != null && rightSibling.GetNbKeys() >= degree) { NeoDatis.Btree.IKeyAndValue elementToMoveDown = parent.GetKeyAndValueAt(childIndex ); NeoDatis.Btree.IKeyAndValue elementToMoveUp = rightSibling.GetKeyAndValueAt(0); parent.SetKeyAndValueAt(elementToMoveUp, childIndex); child.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); if (rightSibling.GetNbChildren() > 0) { // Take the first child of the right sibling and set it the // last child of the 'child' (incoming parameter) child.SetChildAt(rightSibling, 0, child.GetNbChildren(), true); child.IncrementNbChildren(); } rightSibling.DeleteKeyAndValueAt(0, true); persister.SaveNode(parent); persister.SaveNode(child); persister.SaveNode(rightSibling); if (NeoDatis.Btree.Tool.BTreeValidator.IsOn()) { NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(parent, parent == root); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(child, false); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(rightSibling, false); NeoDatis.Btree.Tool.BTreeValidator.CheckDuplicateChildren(rightSibling, child); } return(parent); } // case 3b bool isCase3b = (leftSibling != null && leftSibling.GetNbKeys() == degree - 1) || (rightSibling != null && rightSibling.GetNbKeys() >= degree - 1); bool parentWasSetToNull = false; if (isCase3b) { // choose left sibling to execute merge if (leftSibling != null) { NeoDatis.Btree.IKeyAndValue elementToMoveDown = parent.GetKeyAndValueAt(childIndex - 1); leftSibling.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue ()); leftSibling.MergeWith(child); parent.DeleteKeyAndValueAt(childIndex - 1, true); if (parent.GetNbKeys() == 0) { // this is the root if (!parent.HasParent()) { root = leftSibling; root.SetParent(null); height--; parentWasSetToNull = true; } else { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Unexpected empty node that is node the root!" ); } } else { parent.SetChildAt(leftSibling, childIndex - 1); } if (parentWasSetToNull) { persister.DeleteNode(parent); } else { persister.SaveNode(parent); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(parent, parent == root); } // child was merged with another node it must be deleted persister.DeleteNode(child); persister.SaveNode(leftSibling); // Validator.validateNode(child, child == root); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(leftSibling, leftSibling == root); // Validator.checkDuplicateChildren(leftSibling, child); if (parentWasSetToNull) { return(root); } return(parent); } // choose right sibling to execute merge if (rightSibling != null) { NeoDatis.Btree.IKeyAndValue elementToMoveDown = parent.GetKeyAndValueAt(childIndex ); child.InsertKeyAndValue(elementToMoveDown.GetKey(), elementToMoveDown.GetValue()); child.MergeWith(rightSibling); parent.DeleteKeyAndValueAt(childIndex, true); if (parent.GetNbKeys() == 0) { // this is the root if (!parent.HasParent()) { root = child; root.SetParent(null); height--; parentWasSetToNull = true; } else { throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Unexpected empty root node!" ); } } else { parent.SetChildAt(child, childIndex); } if (parentWasSetToNull) { persister.DeleteNode(parent); } else { persister.SaveNode(parent); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(parent, parent == root); } persister.DeleteNode(rightSibling); persister.SaveNode(child); NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(child, child == root); // Validator.validateNode(rightSibling, rightSibling == // root); // Validator.checkDuplicateChildren(rightSibling, child); if (parentWasSetToNull) { return(root); } return(parent); } throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("deleting case 3b but no non null sibling!" ); } } finally { } throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Unexpected case in executing prepare for delete" ); }