Пример #1
0
        public virtual Bookmark <ValueTuple <K, V> >?PositionAt(K k)
        {
            SBookmark <K, V>?bmk = null;
            var cb = root;

            while (cb != null)
            {
                var bpos = cb.PositionFor(k, out bool b);
                bmk = new SBookmark <K, V>(cb, bpos, bmk);
                if (bpos == cb.count)
                {
                    var inr = cb as SInner <K, V>;
                    if (inr == null)
                    {
                        return(null);
                    }
                    cb = inr.gtr;
                }
                else
                {
                    cb = (cb.Slot(bpos).Item2 ?? throw new Exception("??")) as SBucket <K, V>;
                }
            }
            return((bmk == null)?null:new SDictBookmark <K, V>(bmk));
        }
Пример #2
0
        public static SBookmark <K, V>?Next(SBookmark <K, V>?stk, SDict <K, V>?tree = null)
        {
            SBucket <K, V>?         b;
            ValueTuple <K, object?> d;

            if (stk == null) // following Create or Reset
            {
                // if Tree is empty return null
                if (tree == null || tree.root == null || tree.Length == 0)
                {
                    return(null);
                }
                // The first entry is root.slots[0] or below
                stk = new SBookmark <K, V>(tree.root, 0, null);
                d   = tree.root.Slot(0);
                b   = d.Item2 as SBucket <K, V>;
            }
            else // guaranteed to be at a LEAF
            {
                var stkPos = stk._bpos;
                if (++stkPos == stk._bucket.count) // this is the right test for a leaf
                {
                    // at end of current bucket: pop till we aren't
                    for (; ;)
                    {
                        if (++stkPos <= stk._bucket.count)// this is the right test for a non-leaf; redundantly ok for first time (leaf)
                        {
                            break;
                        }
                        stk = stk._parent;
                        if (stk == null)
                        {
                            break;
                        }
                        stkPos = stk._bpos;
                    }
                    // we may run out of the BTree
                    if (stk == null)
                    {
                        return(null);
                    }
                }
                stk = new SBookmark <K, V>(stk._bucket, stkPos, stk._parent);
                if (stk._bpos == stk._bucket.count)
                {                                                      // will only happen for a non-leaf
                    b = ((SInner <K, V>)stk._bucket).gtr;
                    d = new ValueTuple <K, object?>(default(K), null); // or compiler complains
                }
                else // might be leaf or not
                {
                    d = stk._bucket.Slot(stkPos);
                    b = d.Item2 as SBucket <K, V>;
                }
            }
            while (b != null) // now ensure we are at a leaf
            {
                stk = new SBookmark <K, V>(b, 0, stk);
                d   = stk._bucket.Slot(0);
                b   = d.Item2 as SBucket <K, V>;
            }
            return(stk);
        }
Пример #3
0
 public SBookmark(SBucket <K, V> b, int bp, SBookmark <K, V>?n)
 {
     _bucket = b; _bpos = bp; _parent = n;
 }
Пример #4
0
 internal SDictBookmark(SBookmark <K, V> bmk) : base(bmk.position())
 {
     _bmk = bmk;
 }
Пример #5
0
 public override Bookmark <ValueTuple <K, V> >?First()
 {
     return((SBookmark <K, V> .Next(null, this) is SBookmark <K, V> b)?
            new SDictBookmark <K, V>(b):null);
 }