Ejemplo n.º 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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
        /// <summary>Creates a new node with the right part of this node.</summary>
        /// <remarks>
        /// Creates a new node with the right part of this node. This should only be
        /// called on a full node
        /// </remarks>
        public virtual NeoDatis.Btree.IBTreeNode ExtractRightPart()
        {
            if (!IsFull())
            {
                throw new NeoDatis.Btree.Exception.BTreeException("extract right part called on non full node"
                                                                  );
            }
            // Creates an empty new node
            NeoDatis.Btree.IBTreeNode rightPart = btree.BuildNode();
            int j = 0;

            for (int i = degree; i < maxNbKeys; i++)
            {
                rightPart.SetKeyAndValueAt(keys[i], values[i], j, false, false);
                keys[i]   = null;
                values[i] = null;
                rightPart.SetChildAt(this, i, j, false);
                // TODO must we load all nodes to set new parent
                NeoDatis.Btree.IBTreeNode c = rightPart.GetChildAt(j, false);
                if (c != null)
                {
                    c.SetParent(rightPart);
                }
                // rightPart.setChildAt(getChildAt(i,false), j);
                SetNullChildAt(i);
                j++;
            }
            // rightPart.setChildAt(getLastPositionChild(), j);
            rightPart.SetChildAt(this, GetMaxNbChildren() - 1, j, false);
            // correct father id
            NeoDatis.Btree.IBTreeNode c1 = rightPart.GetChildAt(j, false);
            if (c1 != null)
            {
                c1.SetParent(rightPart);
            }
            SetNullChildAt(maxNbChildren - 1);
            // resets last child
            keys[degree - 1] = null;
            // resets median element
            values[degree - 1] = null;
            // set numbers
            nbKeys = degree - 1;
            int originalNbChildren = nbChildren;

            nbChildren = System.Math.Min(nbChildren, degree);
            rightPart.SetNbKeys(degree - 1);
            rightPart.SetNbChildren(originalNbChildren - nbChildren);
            NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(this);
            NeoDatis.Btree.Tool.BTreeValidator.ValidateNode(rightPart);
            NeoDatis.Btree.Tool.BTreeValidator.CheckDuplicateChildren(this, rightPart);
            return(rightPart);
        }
 public override void SetChildAt(NeoDatis.Btree.IBTreeNode node, int childIndex, int
                                 index, bool throwExceptionIfDoesNotExist)
 {
     NeoDatis.Btree.IBTreeNode child = node.GetChildAt(childIndex, throwExceptionIfDoesNotExist
                                                       );
     children[index] = child;
     if (child != null)
     {
         child.SetParent(this);
     }
 }
Ejemplo n.º 6
0
 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);
 }
Ejemplo n.º 7
0
 private int IndexOfChild(NeoDatis.Btree.IBTreeNode parent, NeoDatis.Btree.IBTreeNode
                          child)
 {
     for (int i = 0; i < parent.GetNbChildren(); i++)
     {
         if (parent.GetChildAt(i, true).GetId() == child.GetId())
         {
             return(i);
         }
     }
     throw new System.Exception("parent " + parent + " does not have the specified child : "
                                + child);
 }
Ejemplo n.º 8
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!] ");
         }
     }
 }
Ejemplo n.º 9
0
 public static void CheckDuplicateChildren(NeoDatis.Btree.IBTreeNode node1, NeoDatis.Btree.IBTreeNode
                                           node2)
 {
     if (!on)
     {
         return;
     }
     for (int i = 0; i < node1.GetNbChildren(); i++)
     {
         NeoDatis.Btree.IBTreeNode child1 = node1.GetChildAt(i, true);
         for (int j = 0; j < node2.GetNbChildren(); j++)
         {
             if (child1 == node2.GetChildAt(j, true))
             {
                 throw new NeoDatis.Btree.Exception.BTreeNodeValidationException("Duplicated node : "
                                                                                 + child1);
             }
         }
     }
 }
Ejemplo n.º 10
0
        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());
                }
            }
        }
Ejemplo n.º 11
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
            {
            }
        }
Ejemplo n.º 12
0
 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"
                                                                     );
 }