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" ); }