コード例 #1
0
        /// <summary>
        /// Update the data part of the key.
        /// </summary>
        /// <param name="keyWithNewData"></param>
        /// <returns></returns>
        public bool UpdateData(IKey keyWithNewData)
        {
            IKey result = null;

            BNode n        = m_top;
            bool  finished = false;
            int   pos      = -1;

            while (!finished)
            {
                if (n.Leaf)
                {
                    result = n.SearchKey(keyWithNewData, ref pos);
                    if (result != null)
                    {
                        n.ReplaceData(pos, keyWithNewData);
                        finished = true;
                    }
                    else
                    {
                        finished = true;
                    }
                }
                else
                {
                    result = n.SearchKey(keyWithNewData, ref pos);
                    if (result == null)
                    {
                        uint nextNodeId = n.GetChildAt(pos);

                        n = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                    }
                    else
                    {
                        n.ReplaceData(pos, keyWithNewData);
                        finished = true;
                    }
                }
            }

            return(result != null);
        }
コード例 #2
0
        /// <summary>
        /// Search for target int this b-tree. target may have data field to be null, the result should have it non-null.
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public IKey Search(IKey target)
        {
            IKey result = null;

            BNode n        = m_top;
            bool  finished = false;
            int   pos      = -1;

            while (!finished)
            {
                if (n.Leaf)
                {
                    result = n.SearchKey(target, ref pos);                     //if key is found, result is not null,
                                                                               //otherwise, result is null and pos is the possible node where the key may be in
                    if (result != null)
                    {
                        return(result);
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    result = n.SearchKey(target, ref pos);
                    if (result == null)
                    {
                        uint nextNodeId = n.GetChildAt(pos);
                        n = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                    }
                    else
                    {
                        return(result);
                    }
                }
            }
            return(null);
        }
コード例 #3
0
        /// <summary>
        /// Given a key, search the node where the key is stored in the tree with root as the root node.
        /// </summary>
        /// <param name="root"></param>
        /// <param name="key"></param>
        /// <param name="pos">the location the key is stored in</param>
        /// <param name="visisted">all the visisted parent is saved in the stack.</param>
        /// <returns></returns>
        public BNode FindNode(BNode root, IKey key, ref int pos, System.Collections.Stack visited, System.Collections.Stack via)
        {
            Debug.Assert(visited != null);

            BNode n = root;

            pos = -1;
            IKey temp = null;

            while (!n.Leaf)
            {
                temp = n.SearchKey(key, ref pos);
                if (temp == null)
                {
                    uint nextNodeId = n.GetChildAt(pos);
                    visited.Push(n);
                    via.Push(pos);

                    n = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                }
                else
                {
                    return(n);
                }
            }

            //n is leaf
            temp = n.SearchKey(key, ref pos);
            if (temp == null)
            {
                return(null);
            }
            else
            {
                return(n);
            }
        }
コード例 #4
0
        /// <summary>
        /// Insert the newKey into this B-tree,
        /// </summary>
        /// <param name="newKey"></param>
        /// <returns></returns>
        public bool Insert(IKey newKey)
        {
            //find the leaf where the newKey should be in
            BNode n = m_top;

            System.Collections.Stack visited = new System.Collections.Stack();
            int pos = -1;

            while (!n.Leaf)
            {
                IKey temp = n.SearchKey(newKey, ref pos);
                if (temp == null)
                {
                    uint nextNodeId = n.GetChildAt(pos);
                    visited.Push(n);

                    n = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                }
                else
                {
                    return(false);
                }
            }

            //now BNode n is the leaf where insert should happen
            IKey t_temp = n.SearchKey(newKey, ref pos);

            if (t_temp == null)
            {
                //not exists, go ahead to insert the new key
                if (!n.IsFull)
                {
                    n.InsertAtLeaf(newKey, pos);

                    return(true);
                }
                else
                {
                    //split needed for this node
                    BNode right = new BNode();
                    m_sgManager.GetNewSegment(right);
                    IKey median = null;
                    n.SplitAtLeaf(newKey, pos, ref median, ref right);                      //this split is at leaf

                    bool finished = false;
                    //now n holds the left half of the items,
                    //right holds the right half items, median is the middle key

                    while (!finished)
                    {
                        //parent is node middle key will be inserted
                        BNode parent = (visited.Count > 0 ? (BNode)visited.Pop() : null);

                        if (parent == null)
                        {
                            //new top node is needed
                            BNode new_top = new BNode();
                            m_sgManager.GetNewSegment(new_top);
                            new_top.SetOrder(m_top.Order);
                            new_top.Leaf = false;
                            new_top.InsertFirstKey(median, n.SegmentID, right.SegmentID);

                            this.m_top_sid = new_top.SegmentID;

                            return(true);
                        }
                        else
                        {
                            IKey tt = parent.SearchKey(median, ref pos);
                            if (tt != null)
                            {
                                return(false);
                            }

                            if (!parent.IsFull)
                            {
                                parent.InsertAtInternal(median, pos, right.SegmentID);
                                return(true);
                            }
                            else
                            {
                                //parent is full again
                                BNode newRight = new BNode();
                                m_sgManager.GetNewSegment(newRight);
                                newRight.SetOrder(parent.Order);
                                newRight.Leaf = parent.Leaf;
                                //this split will insert median into the parent, then split and new middle key is newMedian
                                IKey newMedian;
                                parent.SplitAtInternal(median, pos, right.SegmentID, out newMedian, newRight);

                                n      = parent;
                                median = newMedian;
                                right  = newRight;
                            }
                        }
                    }
                }
            }
            else
            {
                return(false);
            }

            return(false);
        }