Example #1
0
        // Commented by Olivier 05/11/2007
        // persister.flush();
        private void InsertNonFull(NeoDatis.Btree.IBTreeNode node, System.IComparable key
                                   , object value)
        {
            if (node.IsLeaf())
            {
                node.InsertKeyAndValue(key, value);
                persister.SaveNode(node);
                return;
            }
            int position = node.GetPositionOfKey(key);
            // return an index starting
            // from 1 instead of 0
            int realPosition = -position - 1;

            // If position is positive, the key must be inserted in this node
            if (position >= 0)
            {
                realPosition = position - 1;
                node.InsertKeyAndValue(key, value);
                persister.SaveNode(node);
                return;
            }
            // descend
            NeoDatis.Btree.IBTreeNode nodeToDescend = node.GetChildAt(realPosition, true);
            if (nodeToDescend.IsFull())
            {
                Split(node, nodeToDescend, realPosition);
                if (node.GetKeyAt(realPosition).CompareTo(key) < 0)
                {
                    nodeToDescend = node.GetChildAt(realPosition + 1, true);
                }
            }
            InsertNonFull(nodeToDescend, key, value);
        }
        /// <summary>
        /// Can only merge node without intersection =&gt; 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"
                                                                         );
     }
 }
Example #4
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>
        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
            {
            }
        }