public virtual object DeleteKeyForLeafNode(IKeyAndValue keyAndValue) { var position = GetPositionOfKey(keyAndValue.GetKey()); if (position < 0) return null; var realPosition = position - 1; var value = Values[realPosition]; LeftShiftFrom(realPosition, false); NbKeys--; BTreeValidator.ValidateNode(this); return value; }
public virtual object DeleteKeyForLeafNode(IKeyAndValue keyAndValue) { var position = GetPositionOfKey(keyAndValue.GetKey()); if (position < 0) { return(null); } var realPosition = position - 1; var value = Values[realPosition]; LeftShiftFrom(realPosition, false); NbKeys--; BTreeValidator.ValidateNode(this); return(value); }
public override object DeleteKeyForLeafNode(IKeyAndValue keyAndValue) { var objectHasBeenFound = false; var positionOfKey = GetPositionOfKey(keyAndValue.GetKey()); if (positionOfKey < 0) { return(null); } var realPosition = positionOfKey - 1; // In Multiple Values per key, the value is a list var value = (IList)Values[realPosition]; // Here we must search for the right object. The list can contains more than 1 object var size = value.Count; for (var i = 0; i < size && !objectHasBeenFound; i++) { if (!value[i].Equals(keyAndValue.GetValue())) { continue; } value.Remove(i); objectHasBeenFound = true; } if (!objectHasBeenFound) { return(null); } // If after removal, the list is empty, then remove the key from the node if (value.Count == 0) { // If we get there LeftShiftFrom(realPosition, false); NbKeys--; } BTreeValidator.ValidateNode(this); return(keyAndValue.GetValue()); }
private static void CheckValuesOfChild(IKeyAndValue key, IBTreeNode node) { if (!OdbConfiguration.IsBTreeValidationEnabled()) { return; } if (node == null) { return; } for (int i = 0; i < node.GetNbKeys(); i++) { if (node.GetKeyAndValueAt(i).GetKey().CompareTo(key.GetKey()) >= 0) { throw new BTreeNodeValidationException("Left child with values bigger than pivot " + key + " : " + node); } } }
public override object DeleteKeyForLeafNode(IKeyAndValue keyAndValue) { var objectHasBeenFound = false; var positionOfKey = GetPositionOfKey(keyAndValue.GetKey()); if (positionOfKey < 0) return null; var realPosition = positionOfKey - 1; // In Multiple Values per key, the value is a list var value = (IList) Values[realPosition]; // Here we must search for the right object. The list can contains more than 1 object var size = value.Count; for (var i = 0; i < size && !objectHasBeenFound; i++) { if (!value[i].Equals(keyAndValue.GetValue())) continue; value.Remove(i); objectHasBeenFound = true; } if (!objectHasBeenFound) { return null; } // If after removal, the list is empty, then remove the key from the node if (value.Count == 0) { // If we get there LeftShiftFrom(realPosition, false); NbKeys--; } BTreeValidator.ValidateNode(this); return keyAndValue.GetValue(); }
/// <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)); }
public virtual void SetKeyAndValueAt(IKeyAndValue keyAndValue, int index, bool shiftIfAlreadyExist, bool incrementNbKeys) { SetKeyAndValueAt(keyAndValue.GetKey(), keyAndValue.GetValue(), index, shiftIfAlreadyExist, incrementNbKeys); }
public virtual void SetKeyAndValueAt(IKeyAndValue keyAndValue, int index) { SetKeyAndValueAt(keyAndValue.GetKey(), keyAndValue.GetValue(), index); }
private static void CheckValuesOfChild(IKeyAndValue key, IBTreeNode node) { if (!OdbConfiguration.IsBTreeValidationEnabled()) return; if (node == null) return; for (var i = 0; i < node.GetNbKeys(); i++) { if (node.GetKeyAndValueAt(i).GetKey().CompareTo(key.GetKey()) >= 0) throw new BTreeNodeValidationException("Left child with values bigger than pivot " + key + " : " + node); } }