public override bool Find(ref KeyWalker key, CPEnumerator <T> e) { if (key.Left == 0) { MoveFirst(e); return(false); } byte k = key.Buffer[key.Offset]; if (key.Left == 1 && IsPresent(k)) { e.Stack.Add(new CPEnumerator <T> .Entry(this, k, e.Key.Offset)); ExtractCurrent(e, k); return(true); } else { int nextK = FindNextInUse(k); if (nextK >= 0) { e.Stack.Add(new CPEnumerator <T> .Entry(this, nextK, e.Key.Offset)); ExtractCurrent(e, (byte)nextK); } else { // code duplicated from CPSNode if (!e.Stack.IsEmpty) { e.Key.Reset(e.Stack.Last.KeyOffset); e.MoveNext(); } } return(false); } }
public override void MoveLast(CPEnumerator <T> e) { int k = LastKeyInUse(); e.Stack.Add(new CPEnumerator <T> .Entry(this, 0, e.Key.Offset)); ExtractCurrent(e, (byte)k); }
/// (1) Add()s an Entry to e.Stack pointing to the first (lowest) item in /// the node, using e.Key.Offset as the value of Entry.KeyOffset; /// (2) extracts the key to e.Key such that e.Key.Offset+e.Key.Left is the /// length of the complete key (if e.Key.Buffer is too small, it is /// copied to a larger buffer as needed); /// (3) if the current item points to a child, this method advances e.Key /// to the end of the key so that e.Key.Left is 0, and calls MoveFirst /// on the child; /// (4) otherwise, this method leaves e.Key.Offset equal to /// e.Stack.Last.KeyOffset, so that e.Key.Left is the number of bytes /// of the key that are stored in this node. public override void MoveFirst(CPEnumerator <T> e) { int k = FirstKeyInUse(); // No need to store the "index" on the stack; // just store the current key in e.Key. e.Stack.Add(new CPEnumerator <T> .Entry(this, 0, e.Key.Offset)); ExtractCurrent(e, (byte)k); }
public override bool MovePrev(CPEnumerator <T> e) { int k = e.Key[0]; if ((k = FindPrevInUse(k)) == -1) { return(false); } ExtractCurrent(e, (byte)k); return(true); }
public override void MoveLast(CPEnumerator <T> e) { for (int i = _children.Length - 1; i >= 0; i--) { if (_children[i] != null) { e.Stack.Add(new CPEnumerator <T> .Entry(this, i, e.Key.Offset)); _children[i].MoveLast(e); return; } } Debug.Assert(_zlk != NoZLK); e.Stack.Add(new CPEnumerator <T> .Entry(this, -1, e.Key.Offset)); return; }
public override bool MoveNext(CPEnumerator <T> e) { int top = e.Stack.Count - 1; Debug.Assert(e.Stack[top].Node == this); for (int i = e.Stack[top].Index + 1; i < _children.Length; i++) { if (_children[i] != null) { e.Stack.InternalArray[top].Index = i; _children[i].MoveFirst(e); return(true); } } return(false); }
private void ExtractCurrent(CPEnumerator <T> e, byte k) { Debug.Assert(IsPresent(k)); byte[] buf = e.Key.Buffer; int offs = e.Key.Offset; if (buf.Length == offs) { // out of buffer space in e.Key, only need one more byte! buf = InternalList.CopyToNewArray(buf, offs, offs + 1); } buf[offs] = k; e.Key.Reset(buf, offs, 1); e.CurrentValue = GetValueAt(k); }
public override void MoveFirst(CPEnumerator <T> e) { if (_zlk != NoZLK) { e.Stack.Add(new CPEnumerator <T> .Entry(this, -1, e.Key.Offset)); return; } for (int i = 0; i < _children.Length; i++) { if (_children[i] != null) { e.Stack.Add(new CPEnumerator <T> .Entry(this, i, e.Key.Offset)); _children[i].MoveFirst(e); return; } } }
public override bool MovePrev(CPEnumerator <T> e) { int top = e.Stack.Count - 1; Debug.Assert(e.Stack[top].Node == this); for (int i = e.Stack[top].Index - 1; i >= 0; i--) { if (_children[i] != null) { e.Stack.InternalArray[top].Index = i; _children[i].MoveLast(e); return(true); } } if (e.Stack[top].Index > -1 && _zlk != NoZLK) { e.Stack.InternalArray[top].Index = -1; return(true); } return(false); }
public override bool Find(ref KeyWalker key, CPEnumerator <T> e) { if (key.Left == 0) { MoveFirst(e); return(_zlk != NoZLK); } else { int i = key[0] >> 5; e.Stack.Add(new CPEnumerator <T> .Entry(this, i, e.Key.Offset)); if (_children[i] != null) { return(_children[i].Find(ref key, e)); } else { e.MoveNext(); return(false); } } }
/// <summary>Does the same thing as MovePrev except that it moves to the /// previous item instead of the next item.</summary> public abstract bool MovePrev(CPEnumerator <T> e);
/// <summary>Moves to the next item in the node.</summary> /// <returns>Returns true if the next item was extracted or false if the /// end of the node was reached.</returns> /// <remarks> /// Upon entry to this method, e.Stack.Last.Node == this /// and e.Stack.Last.KeyOffset == e.Key.Offset. /// <para/> /// This method /// (1) increases e.Stack.Last.Index to point to the next item in the node; /// (2) returns false if Index has advanced past the last item in the node; /// (3) otherwise, repeats steps (2)-(4) in the documentation of /// MoveFirst() and returns true. /// </remarks> public abstract bool MoveNext(CPEnumerator <T> e);
/// <summary>Does the same thing as MoveFirst except that the last item is /// retrieved instead of the first one.</summary> public abstract void MoveLast(CPEnumerator <T> e);
// Returns true if key exists public abstract bool Find(ref KeyWalker key, CPEnumerator <T> e);