/// <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); }
/// <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); }
/// <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); } }
/// <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); }