Beispiel #1
0
            public bool MoveNext()
            {
                m_current_key_no++;
                if (m_current_key_no < m_current_node.KeyNums)
                {
                    m_current = m_current_node.GetKeyAt(m_current_key_no);
                }
                else
                {
                    //this node is used up, try next one
                    if (m_to_be_visited.Count > 0)
                    {
                        m_current_node = (BNode)m_tree.m_sgManager.GetSegment(
                            (uint)m_to_be_visited.Dequeue(),
                            m_tree.m_nodeFactory,
                            m_tree.m_keyFactory);
                        Debug.Assert(m_current_node.KeyNums > 0);
                        if (!m_current_node.Leaf)
                        {
                            for (int i = 0; i <= m_current_node.KeyNums; i++)
                            {
                                Debug.Assert(m_current_node.GetChildAt(i) >= 0);
                                m_to_be_visited.Enqueue(m_current_node.GetChildAt(i));
                            }
                        }
                        //locate the current to be the first one in the new node
                        m_current_key_no = 0;
                        m_current        = m_current_node.GetKeyAt(0);
                    }
                    else
                    {
                        m_current = null;
                    }
                }

                return(m_current != null);
            }
Beispiel #2
0
			public bool MoveNext() 
			{
				m_current_key_no ++;
				if (m_current_key_no < m_current_node.KeyNums)
				{
					m_current = m_current_node.GetKeyAt(m_current_key_no);
				}
				else
				{
					//this node is used up, try next one
					if (m_to_be_visited.Count >0)
					{
						m_current_node = (BNode)m_tree.m_sgManager.GetSegment(
							(uint)m_to_be_visited.Dequeue(),
							m_tree.m_nodeFactory,
							m_tree.m_keyFactory);
						Debug.Assert(m_current_node.KeyNums>0);
						if (!m_current_node.Leaf)
						{
							for (int i=0; i<=m_current_node.KeyNums; i++)
							{
								Debug.Assert(m_current_node.GetChildAt(i) >= 0);
								m_to_be_visited.Enqueue(m_current_node.GetChildAt(i));
							}
						}
						//locate the current to be the first one in the new node
						m_current_key_no = 0;
						m_current = m_current_node.GetKeyAt(0);
					}
					else
						m_current = null;
				}

				return m_current != null;
			}
Beispiel #3
0
        /// <summary>
        /// Remove the key from the tree.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Delete(IKey key)
        {
            int pos = -1;

            System.Collections.Stack visited  = new System.Collections.Stack();
            System.Collections.Stack viaLinks = new System.Collections.Stack();

            //find the node which contains the key
            BNode n = FindNode(m_top, key, ref pos, visited, viaLinks);

            if (n == null)
            {
                return(false);
            }
            else
            {
                if (n.Leaf)
                {
                    n.RemoveAtLeaf(key, pos);
                }
                else
                {
                    visited.Push(n);
                    uint nextNodeId = n.GetChildAt(pos + 1);
                    viaLinks.Push(pos + 1);
                    BNode t_node = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                    //find the leaf most leaf in its right sub-tree
                    while (!t_node.Leaf)
                    {
                        visited.Push(t_node);
                        nextNodeId = t_node.GetChildAt(0);
                        viaLinks.Push(0);
                        t_node = (BNode)m_sgManager.GetSegment(nextNodeId, m_nodeFactory, m_keyFactory);
                    }
                    Debug.Assert(t_node.Leaf);

                    IKey successor = t_node.GetKeyAt(0);

                    //replace the key&data in n with the successor
                    n.ReplaceKeyDataWSuccessor(key, successor, pos);

                    //remove successor from the leaf node
                    t_node.RemoveAtLeaf(successor, 0);

                    n = t_node;
                }
            }

            //now n is the leaf node where the real deletion happens
            //visited keep all the parents visited so far, viaLinks keeps which links we followed
            while (n.IsUnderflow && n.SegmentID != m_top_sid)
            {
                BNode parent = (BNode)visited.Pop();
                //get left/right brother
                int   followed = (int)viaLinks.Pop();
                BNode left     = (followed > 0? (BNode)m_sgManager.GetSegment(parent.GetChildAt(followed - 1), m_nodeFactory, m_keyFactory) : null);
                BNode right    = (followed < parent.KeyNums ? (BNode)m_sgManager.GetSegment(parent.GetChildAt(followed + 1), m_nodeFactory, m_keyFactory) : null);

                Debug.Assert(left != null || right != null);

                bool combined = false;
                //try combin with right first
                if (right != null && right.KeyNums == right.ReqMinimum)
                {
                    //combine with the right
                    parent.CombineChildren(followed, n, right);
                    Debug.Assert(right.KeyNums == 0);
                    Debug.Assert(n.KeyNums > n.ReqMinimum);
                    m_sgManager.FreeSegment(right);

                    combined = true;

                    if (parent.KeyNums == 0)
                    {
                        Debug.Assert(parent.Leaf == false);
                        Debug.Assert(parent.SegmentID == this.m_top_sid);
                        //tree will shrink
                        this.m_top_sid = n.SegmentID;
                        m_sgManager.FreeSegment(parent);
                        break;
                    }
                }
                else if (left != null && left.KeyNums == left.ReqMinimum)
                {
                    //combine with the left
                    parent.CombineChildren(followed - 1, left, n);
                    Debug.Assert(n.KeyNums == 0);
                    Debug.Assert(left.KeyNums > left.ReqMinimum);
                    m_sgManager.FreeSegment(n);

                    combined = true;

                    if (parent.KeyNums == 0)
                    {
                        Debug.Assert(parent.Leaf == false);
                        Debug.Assert(parent.SegmentID == this.m_top_sid);
                        //tree will shrink
                        this.m_top_sid = left.SegmentID;
                        m_sgManager.FreeSegment(parent);
                        break;
                    }
                }
                if (!combined)
                {
                    //try redistrubute if combine is not possible
                    if (right != null && right.KeyNums > right.ReqMinimum)
                    {
                        //redistribute one entry from right node
                        parent.RedistributeRight2Left(followed, n, right);
                    }
                    else if (left != null && left.KeyNums > left.ReqMinimum)
                    {
                        //redistribute with left
                        parent.RedistributeLeft2Right(followed - 1, left, n);
                    }
                }

                else
                {
                    n = parent;
                }
            }

            return(true);
        }