예제 #1
0
        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;
        }
예제 #2
0
        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);
        }
예제 #3
0
        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());
        }
예제 #4
0
        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();
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
 public virtual void SetKeyAndValueAt(IKeyAndValue keyAndValue, int index, bool shiftIfAlreadyExist, bool incrementNbKeys)
 {
     SetKeyAndValueAt(keyAndValue.GetKey(), keyAndValue.GetValue(), index, shiftIfAlreadyExist, incrementNbKeys);
 }
예제 #8
0
 public virtual void SetKeyAndValueAt(IKeyAndValue keyAndValue, int index)
 {
     SetKeyAndValueAt(keyAndValue.GetKey(), keyAndValue.GetValue(), index);
 }
예제 #9
0
        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);
            }
        }
예제 #10
0
 public virtual void SetKeyAndValueAt(IKeyAndValue keyAndValue, int index, bool shiftIfAlreadyExist, bool incrementNbKeys)
 {
     SetKeyAndValueAt(keyAndValue.GetKey(), keyAndValue.GetValue(), index, shiftIfAlreadyExist, incrementNbKeys);
 }
예제 #11
0
 public virtual void SetKeyAndValueAt(IKeyAndValue keyAndValue, int index)
 {
     SetKeyAndValueAt(keyAndValue.GetKey(), keyAndValue.GetValue(), index);
 }