// Copyright (c) 2014 ql Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Plain memory storage back end. package ql import ( "bytes" "fmt" "io" "math/big" "time" ) var ( _ btreeIndex = (*memIndex)(nil) _ btreeIterator = (*memBTreeIterator)(nil) _ indexIterator = (*xenumerator2)(nil) _ storage = (*mem)(nil) _ temp = (*memTemp)(nil) ) type memIndex struct { m *mem t *xtree unique bool } func newMemIndex(m *mem, unique bool) *memIndex { r := &memIndex{t: xtreeNew(), unique: unique, m: m} //dbg("newMemIndex %p, %p", r, m) return r } func (x *memIndex) Clear() error { //dbg("memIndex(%p, %p).Clear", x, x.m) x.m.newUndo(undoClearX, 0, []interface{}{x, x.t}) x.t = xtreeNew() return nil } func (x *memIndex) Create(indexedValues []interface{}, h int64) error { //dbg("memIndex(%p, %p).Create %v, %v", x, x.m, indexedValues, h) t := x.t switch { case !x.unique: k := indexKey{indexedValues, h} x.m.newUndo(undoCreateX, 0, []interface{}{x, k}) //TODO why is old value, if any, not saved? t.Set(k, 0) case isIndexNull(indexedValues): // unique, NULL k := indexKey{nil, h} x.m.newUndo(undoCreateX, 0, []interface{}{x, k}) //TODO why is old value, if any, not saved? t.Set(k, 0) default: // unique, non NULL k := indexKey{indexedValues, 0} if _, ok := t.Get(k); ok { //LATER need .Put return fmt.Errorf("cannot insert into unique index: duplicate value(s): %v", indexedValues) } x.m.newUndo(undoCreateX, 0, []interface{}{x, k}) //TODO why is old value, if any, not saved? t.Set(k, int(h)) } return nil } func (x *memIndex) Delete(indexedValues []interface{}, h int64) error { //dbg("memIndex(%p, %p).Delete %v, %v", x, x.m, indexedValues, h) t := x.t var k indexKey var v interface{} var ok, okv bool switch { case !x.unique: k = indexKey{indexedValues, h} v, okv = t.Get(k) ok = t.delete(k) case isIndexNull(indexedValues): // unique, NULL k = indexKey{nil, h} v, okv = t.Get(k) ok = t.delete(k) default: // unique, non NULL k = indexKey{indexedValues, 0} v, okv = t.Get(k) ok = t.delete(k) } if ok { if okv { x.m.newUndo(undoDeleteX, int64(v.(int)), []interface{}{x, k}) } return nil } return fmt.Errorf("internal error 047") } func (x *memIndex) Drop() error { x.m.newUndo(undoDropX, 0, []interface{}{x, *x}) *x = memIndex{} return nil } func (x *memIndex) Seek(indexedValues []interface{}) (indexIterator, bool, error) { it, hit := x.t.Seek(indexKey{indexedValues, 0}) return &xenumerator2{*it, x.unique}, hit, nil } func (x *memIndex) SeekFirst() (iter indexIterator, err error) { it, err := x.t.SeekFirst() if err != nil { return nil, err } return &xenumerator2{*it, x.unique}, nil } func (x *memIndex) SeekLast() (iter indexIterator, err error) { it, err := x.t.SeekLast() if err != nil { return nil, err } return &xenumerator2{*it, x.unique}, nil } type xenumerator2 struct { it xenumerator unique bool } func (it *xenumerator2) Next() ([]interface{}, int64, error) { k, h, err := it.it.Next() if err != nil { return nil, -1, err } switch it.unique { case true: if k.value == nil { return nil, k.h, nil } return k.value, h, nil default: return k.value, k.h, nil } } func (it *xenumerator2) Prev() ([]interface{}, int64, error) { k, h, err := it.it.Prev() if err != nil { return nil, -1, err } switch it.unique { case true: if k.value == nil { return nil, k.h, nil } return k.value, h, nil default: return k.value, k.h, nil } } type memBTreeIterator enumerator func (it *memBTreeIterator) Next() (k, v []interface{}, err error) { return (*enumerator)(it).Next() } type memTemp struct { tree *tree store *mem } func (t *memTemp) BeginTransaction() (err error) { return nil } func (t *memTemp) Get(k []interface{}) (v []interface{}, err error) { v, _ = t.tree.Get(k) return } func (t *memTemp) Create(data ...interface{}) (h int64, err error) { s := t.store switch n := len(s.recycler); { case n != 0: h = int64(s.recycler[n-1]) s.recycler = s.recycler[:n-1] s.data[h] = s.clone(data...) default: h = int64(len(s.data)) s.data = append(s.data, s.clone(data...)) } return } func (t *memTemp) Read(dst []interface{}, h int64, cols ...*col) (data []interface{}, err error) { return t.store.Read(dst, h, cols...) } func (*memTemp) Drop() (err error) { return } func (t *memTemp) Set(k, v []interface{}) (err error) { t.tree.Set(append([]interface{}(nil), k...), t.store.clone(v...)) return } func (t *memTemp) SeekFirst() (e btreeIterator, err error) { en, err := t.tree.SeekFirst() if err != nil { return } return (*memBTreeIterator)(en), nil } const ( undoCreateNewHandle = iota undoCreateRecycledHandle undoUpdate undoDelete undoClearX // {0: *memIndex, 1: *xtree} undoCreateX // {0: *memIndex, 1: indexKey} undoDeleteX // {0: *memIndex, 1: indexKey} undoDropX // {0: *memIndex, 1: memIndex} ) type undo struct { tag int h int64 data []interface{} } type undos struct { list []undo parent *undos } type mem struct { data [][]interface{} id int64 recycler []int tnl int rollback *undos } func newMemStorage() (s *mem, err error) { s = &mem{data: [][]interface{}{nil}} if err = s.BeginTransaction(); err != nil { return nil, err } h, err := s.Create() if h != 1 { panic("internal error 048") } if err = s.Commit(); err != nil { return nil, err } return } func (s *mem) OpenIndex(unique bool, handle int64) (btreeIndex, error) { // Never called on the memory backend. panic("internal error 049") } func (s *mem) newUndo(tag int, h int64, data []interface{}) { s.rollback.list = append(s.rollback.list, undo{tag, h, data}) } func (s *mem) Acid() bool { return false } func (s *mem) Close() (err error) { if s.tnl != 0 { return fmt.Errorf("cannot close DB while open transaction exist") } *s = mem{} return } func (s *mem) CreateIndex(unique bool) ( /* handle */ int64, btreeIndex, error) { return -1, newMemIndex(s, unique), nil // handle of memIndex should never be used } func (s *mem) Name() string { return fmt.Sprintf("/proc/self/mem/%p", s) } // fake, non existing name // OpenMem returns a new, empty DB backed by the process' memory. The back end // has no limits on field/record/table/DB size other than memory available to // the process. func OpenMem() (db *DB, err error) { s, err := newMemStorage() if err != nil { return } if db, err = newDB(s); err != nil { return nil, err } db.isMem = true return db, nil } func (s *mem) Verify() (allocs int64, err error) { for _, v := range s.recycler { if s.data[v] != nil { return 0, fmt.Errorf("corrupted: non nil free handle %d", s.data[v]) } } for _, v := range s.data { if v != nil { allocs++ } } if allocs != int64(len(s.data))-1-int64(len(s.recycler)) { return 0, fmt.Errorf("corrupted: len(data) %d, len(recycler) %d, allocs %d", len(s.data), len(s.recycler), allocs) } return } func (s *mem) String() string { var b bytes.Buffer for i, v := range s.data { b.WriteString(fmt.Sprintf("s.data[%d] %#v\n", i, v)) } for i, v := range s.recycler { b.WriteString(fmt.Sprintf("s.recycler[%d] %v\n", i, v)) } return b.String() } func (s *mem) CreateTemp(asc bool) (_ temp, err error) { st, err := newMemStorage() if err != nil { return } return &memTemp{ tree: treeNew(collators[asc]), store: st, }, nil } func (s *mem) ResetID() (err error) { s.id = 0 return } func (s *mem) ID() (id int64, err error) { s.id++ return s.id, nil } func (s *mem) clone(data ...interface{}) []interface{} { r := make([]interface{}, len(data)) for i, v := range data { switch x := v.(type) { case nil: // nop case idealComplex: r[i] = complex128(x) case idealFloat: r[i] = float64(x) case idealInt: r[i] = int64(x) case idealRune: r[i] = int32(x) case idealUint: r[i] = uint64(x) case bool: r[i] = x case complex64: r[i] = x case complex128: r[i] = x case float32: r[i] = x case float64: r[i] = x case int: r[i] = int64(x) case int8: r[i] = x case int16: r[i] = x case int32: r[i] = x case int64: r[i] = x case string: r[i] = x case uint: r[i] = uint64(x) case uint8: r[i] = x case uint16: r[i] = x case uint32: r[i] = x case uint64: r[i] = x case []byte: r[i] = append([]byte(nil), x...) case *big.Int: r[i] = big.NewInt(0).Set(x) case *big.Rat: r[i] = big.NewRat(1, 2).Set(x) case time.Time: t := x r[i] = t case time.Duration: r[i] = x case map[string]interface{}: // map of ids of a cross join r[i] = x default: panic("internal error 050") } } return r } func (s *mem) Create(data ...interface{}) (h int64, err error) { switch n := len(s.recycler); { case n != 0: h = int64(s.recycler[n-1]) s.recycler = s.recycler[:n-1] s.data[h] = s.clone(data...) r := s.rollback r.list = append(r.list, undo{ tag: undoCreateRecycledHandle, h: h, }) default: h = int64(len(s.data)) s.data = append(s.data, s.clone(data...)) r := s.rollback r.list = append(r.list, undo{ tag: undoCreateNewHandle, h: h, }) } return } func (s *mem) Read(dst []interface{}, h int64, cols ...*col) (data []interface{}, err error) { if i := int(h); i != 0 && i < len(s.data) { d := s.clone(s.data[h]...) if cols == nil { return d, nil } for n, dn := len(cols)+2, len(d); dn < n; dn++ { d = append(d, nil) } return d, nil } return nil, errNoDataForHandle } func (s *mem) UpdateRow(h int64, _ []*col, data ...interface{}) (err error) { return s.Update(h, data...) } func (s *mem) Update(h int64, data ...interface{}) (err error) { r := s.rollback r.list = append(r.list, undo{ tag: undoUpdate, h: h, data: s.data[h], }) s.data[h] = s.clone(data...) return } func (s *mem) Delete(h int64, _ ...*col) (err error) { r := s.rollback r.list = append(r.list, undo{ tag: undoDelete, h: h, data: s.data[h], }) s.recycler = append(s.recycler, int(h)) s.data[h] = nil return } func (s *mem) BeginTransaction() (err error) { s.rollback = &undos{parent: s.rollback} s.tnl++ return nil } func (s *mem) Rollback() (err error) { if s.tnl == 0 { return errRollbackNotInTransaction } list := s.rollback.list for i := len(list) - 1; i >= 0; i-- { undo := list[i] switch h, data := int(undo.h), undo.data; undo.tag { case undoCreateNewHandle: d := s.data s.data = d[:len(d)-1] case undoCreateRecycledHandle: s.data[h] = nil r := s.recycler s.recycler = append(r, h) case undoUpdate: s.data[h] = data case undoDelete: s.data[h] = data s.recycler = s.recycler[:len(s.recycler)-1] case undoClearX: x, t := data[0].(*memIndex), data[1].(*xtree) x.t = t case undoCreateX: x, k := data[0].(*memIndex), data[1].(indexKey) x.t.delete(k) case undoDeleteX: x, k := data[0].(*memIndex), data[1].(indexKey) x.t.Set(k, h) case undoDropX: x, v := data[0].(*memIndex), data[1].(memIndex) *x = v default: panic("internal error 051") } } s.tnl-- s.rollback = s.rollback.parent return nil } func (s *mem) Commit() (err error) { if s.tnl == 0 { return errCommitNotInTransaction } s.tnl-- s.rollback = s.rollback.parent return nil } // Transaction index B+Tree //LATER make it just a wrapper of the implementation in btree.go. type ( xd struct { // data page c int xd [2*kd + 1]xde n *xd p *xd } xde struct { // xd element k indexKey v int } // xenumerator captures the state of enumerating a tree. It is returned // from the Seek* methods. The enumerator is aware of any mutations // made to the tree in the process of enumerating it and automatically // resumes the enumeration at the proper key, if possible. // // However, once an xenumerator returns io.EOF to signal "no more // items", it does no more attempt to "resync" on tree mutation(s). In // other words, io.EOF from an Enumaretor is "sticky" (idempotent). xenumerator struct { err error hit bool i int k indexKey q *xd t *xtree ver int64 } // xtree is a B+tree. xtree struct { c int first *xd last *xd r interface{} ver int64 } xxe struct { // xx element ch interface{} sep *xd } xx struct { // index page c int xx [2*kx + 2]xxe } ) func (a *indexKey) cmp(b *indexKey) int { r := collate(a.value, b.value) if r != 0 { return r } return int(a.h) - int(b.h) } var ( // R/O zero values zxd xd zxde xde zxx xx zxxe xxe ) func xclr(q interface{}) { switch xx := q.(type) { case *xx: for i := 0; i <= xx.c; i++ { // Ch0 Sep0 ... Chn-1 Sepn-1 Chn xclr(xx.xx[i].ch) } *xx = zxx // GC case *xd: *xx = zxd // GC } } // -------------------------------------------------------------------------- xx func xnewX(ch0 interface{}) *xx { r := &xx{} r.xx[0].ch = ch0 return r } func (q *xx) extract(i int) { q.c-- if i < q.c { copy(q.xx[i:], q.xx[i+1:q.c+1]) q.xx[q.c].ch = q.xx[q.c+1].ch q.xx[q.c].sep = nil // GC q.xx[q.c+1] = zxxe // GC } } func (q *xx) insert(i int, xd *xd, ch interface{}) *xx { c := q.c if i < c { q.xx[c+1].ch = q.xx[c].ch copy(q.xx[i+2:], q.xx[i+1:c]) q.xx[i+1].sep = q.xx[i].sep } c++ q.c = c q.xx[i].sep = xd q.xx[i+1].ch = ch return q } func (q *xx) siblings(i int) (l, r *xd) { if i >= 0 { if i > 0 { l = q.xx[i-1].ch.(*xd) } if i < q.c { r = q.xx[i+1].ch.(*xd) } } return } // -------------------------------------------------------------------------- xd func (l *xd) mvL(r *xd, c int) { copy(l.xd[l.c:], r.xd[:c]) copy(r.xd[:], r.xd[c:r.c]) l.c += c r.c -= c } func (l *xd) mvR(r *xd, c int) { copy(r.xd[c:], r.xd[:r.c]) copy(r.xd[:c], l.xd[l.c-c:]) r.c += c l.c -= c } // ----------------------------------------------------------------------- xtree // xtreeNew returns a newly created, empty xtree. The compare function is used // for key collation. func xtreeNew() *xtree { return &xtree{} } // Clear removes all K/V pairs from the tree. func (t *xtree) Clear() { if t.r == nil { return } xclr(t.r) t.c, t.first, t.last, t.r = 0, nil, nil, nil t.ver++ } func (t *xtree) cat(p *xx, q, r *xd, pi int) { t.ver++ q.mvL(r, r.c) if r.n != nil { r.n.p = q } else { t.last = q } q.n = r.n if p.c > 1 { p.extract(pi) p.xx[pi].ch = q } else { t.r = q } } func (t *xtree) catX(p, q, r *xx, pi int) { t.ver++ q.xx[q.c].sep = p.xx[pi].sep copy(q.xx[q.c+1:], r.xx[:r.c]) q.c += r.c + 1 q.xx[q.c].ch = r.xx[r.c].ch if p.c > 1 { p.c-- pc := p.c if pi < pc { p.xx[pi].sep = p.xx[pi+1].sep copy(p.xx[pi+1:], p.xx[pi+2:pc+1]) p.xx[pc].ch = p.xx[pc+1].ch p.xx[pc].sep = nil // GC p.xx[pc+1].ch = nil // GC } return } t.r = q } //Delete removes the k's KV pair, if it exists, in which case Delete returns //true. func (t *xtree) delete(k indexKey) (ok bool) { pi := -1 var p *xx q := t.r if q == nil { return } for { var i int i, ok = t.find(q, k) if ok { switch xx := q.(type) { case *xx: dp := xx.xx[i].sep switch { case dp.c > kd: t.extract(dp, 0) default: if xx.c < kx && q != t.r { t.underflowX(p, &xx, pi, &i) } pi = i + 1 p = xx q = xx.xx[pi].ch ok = false continue } case *xd: t.extract(xx, i) if xx.c >= kd { return } if q != t.r { t.underflow(p, xx, pi) } else if t.c == 0 { t.Clear() } } return } switch xx := q.(type) { case *xx: if xx.c < kx && q != t.r { t.underflowX(p, &xx, pi, &i) } pi = i p = xx q = xx.xx[i].ch case *xd: return } } } func (t *xtree) extract(q *xd, i int) { // (r int64) { t.ver++ //r = q.xd[i].v // prepared for Extract q.c-- if i < q.c { copy(q.xd[i:], q.xd[i+1:q.c+1]) } q.xd[q.c] = zxde // GC t.c-- return } func (t *xtree) find(q interface{}, k indexKey) (i int, ok bool) { var mk indexKey l := 0 switch xx := q.(type) { case *xx: h := xx.c - 1 for l <= h { m := (l + h) >> 1 mk = xx.xx[m].sep.xd[0].k switch cmp := k.cmp(&mk); { case cmp > 0: l = m + 1 case cmp == 0: return m, true default: h = m - 1 } } case *xd: h := xx.c - 1 for l <= h { m := (l + h) >> 1 mk = xx.xd[m].k switch cmp := k.cmp(&mk); { case cmp > 0: l = m + 1 case cmp == 0: return m, true default: h = m - 1 } } } return l, false } // First returns the first item of the tree in the key collating order, or // (nil, nil) if the tree is empty. func (t *xtree) First() (k indexKey, v int) { if q := t.first; q != nil { q := &q.xd[0] k, v = q.k, q.v } return } // Get returns the value associated with k and true if it exists. Otherwise Get // returns (nil, false). func (t *xtree) Get(k indexKey) (v int, ok bool) { q := t.r if q == nil { return } for { var i int if i, ok = t.find(q, k); ok { switch xx := q.(type) { case *xx: return xx.xx[i].sep.xd[0].v, true case *xd: return xx.xd[i].v, true } } switch xx := q.(type) { case *xx: q = xx.xx[i].ch default: return } } } func (t *xtree) insert(q *xd, i int, k indexKey, v int) *xd { t.ver++ c := q.c if i < c { copy(q.xd[i+1:], q.xd[i:c]) } c++ q.c = c q.xd[i].k, q.xd[i].v = k, v t.c++ return q } // Last returns the last item of the tree in the key collating order, or (nil, // nil) if the tree is empty. func (t *xtree) Last() (k indexKey, v int) { if q := t.last; q != nil { q := &q.xd[q.c-1] k, v = q.k, q.v } return } // Len returns the number of items in the tree. func (t *xtree) Len() int { return t.c } func (t *xtree) overflow(p *xx, q *xd, pi, i int, k indexKey, v int) { t.ver++ l, r := p.siblings(pi) if l != nil && l.c < 2*kd { l.mvL(q, 1) t.insert(q, i-1, k, v) return } if r != nil && r.c < 2*kd { if i < 2*kd { q.mvR(r, 1) t.insert(q, i, k, v) } else { t.insert(r, 0, k, v) } return } t.split(p, q, pi, i, k, v) } // Seek returns an xenumerator positioned on a an item such that k >= item's // key. ok reports if k == item.key The xenumerator's position is possibly // after the last item in the tree. func (t *xtree) Seek(k indexKey) (e *xenumerator, ok bool) { q := t.r if q == nil { e = &xenumerator{nil, false, 0, k, nil, t, t.ver} return } for { var i int if i, ok = t.find(q, k); ok { switch xx := q.(type) { case *xx: e = &xenumerator{nil, ok, 0, k, xx.xx[i].sep, t, t.ver} return case *xd: e = &xenumerator{nil, ok, i, k, xx, t, t.ver} return } } switch xx := q.(type) { case *xx: q = xx.xx[i].ch case *xd: e = &xenumerator{nil, ok, i, k, xx, t, t.ver} return } } } // SeekFirst returns an enumerator positioned on the first KV pair in the tree, // if any. For an empty tree, err == io.EOF is returned and e will be nil. func (t *xtree) SeekFirst() (e *xenumerator, err error) { q := t.first if q == nil { return nil, io.EOF } return &xenumerator{nil, true, 0, q.xd[0].k, q, t, t.ver}, nil } // SeekLast returns an enumerator positioned on the last KV pair in the tree, // if any. For an empty tree, err == io.EOF is returned and e will be nil. func (t *xtree) SeekLast() (e *xenumerator, err error) { q := t.last if q == nil { return nil, io.EOF } return &xenumerator{nil, true, q.c - 1, q.xd[q.c-1].k, q, t, t.ver}, nil } // Set sets the value associated with k. func (t *xtree) Set(k indexKey, v int) { pi := -1 var p *xx q := t.r if q != nil { for { i, ok := t.find(q, k) if ok { switch xx := q.(type) { case *xx: xx.xx[i].sep.xd[0].v = v case *xd: xx.xd[i].v = v } return } switch xx := q.(type) { case *xx: if xx.c > 2*kx { t.splitX(p, &xx, pi, &i) } pi = i p = xx q = xx.xx[i].ch case *xd: switch { case xx.c < 2*kd: t.insert(xx, i, k, v) default: t.overflow(p, xx, pi, i, k, v) } return } } } z := t.insert(&xd{}, 0, k, v) t.r, t.first, t.last = z, z, z return } func (t *xtree) split(p *xx, q *xd, pi, i int, k indexKey, v int) { t.ver++ r := &xd{} if q.n != nil { r.n = q.n r.n.p = r } else { t.last = r } q.n = r r.p = q copy(r.xd[:], q.xd[kd:2*kd]) for i := range q.xd[kd:] { q.xd[kd+i] = zxde } q.c = kd r.c = kd if pi >= 0 { p.insert(pi, r, r) } else { t.r = xnewX(q).insert(0, r, r) } if i > kd { t.insert(r, i-kd, k, v) return } t.insert(q, i, k, v) } func (t *xtree) splitX(p *xx, pp **xx, pi int, i *int) { t.ver++ q := *pp r := &xx{} copy(r.xx[:], q.xx[kx+1:]) q.c = kx r.c = kx if pi >= 0 { p.insert(pi, q.xx[kx].sep, r) } else { t.r = xnewX(q).insert(0, q.xx[kx].sep, r) } q.xx[kx].sep = nil for i := range q.xx[kx+1:] { q.xx[kx+i+1] = zxxe } if *i > kx { *pp = r *i -= kx + 1 } } func (t *xtree) underflow(p *xx, q *xd, pi int) { t.ver++ l, r := p.siblings(pi) if l != nil && l.c+q.c >= 2*kd { l.mvR(q, 1) } else if r != nil && q.c+r.c >= 2*kd { q.mvL(r, 1) r.xd[r.c] = zxde // GC } else if l != nil { t.cat(p, l, q, pi-1) } else { t.cat(p, q, r, pi) } } func (t *xtree) underflowX(p *xx, pp **xx, pi int, i *int) { t.ver++ var l, r *xx q := *pp if pi >= 0 { if pi > 0 { l = p.xx[pi-1].ch.(*xx) } if pi < p.c { r = p.xx[pi+1].ch.(*xx) } } if l != nil && l.c > kx { q.xx[q.c+1].ch = q.xx[q.c].ch copy(q.xx[1:], q.xx[:q.c]) q.xx[0].ch = l.xx[l.c].ch q.xx[0].sep = p.xx[pi-1].sep q.c++ *i++ l.c-- p.xx[pi-1].sep = l.xx[l.c].sep return } if r != nil && r.c > kx { q.xx[q.c].sep = p.xx[pi].sep q.c++ q.xx[q.c].ch = r.xx[0].ch p.xx[pi].sep = r.xx[0].sep copy(r.xx[:], r.xx[1:r.c]) r.c-- rc := r.c r.xx[rc].ch = r.xx[rc+1].ch r.xx[rc].sep = nil r.xx[rc+1].ch = nil return } if l != nil { *i += l.c + 1 t.catX(p, l, q, pi-1) *pp = l return } t.catX(p, q, r, pi) } // ----------------------------------------------------------------- xenumerator // Next returns the currently enumerated item, if it exists and moves to the // next item in the key collation order. If there is no item to return, err == // io.EOF is returned. func (e *xenumerator) Next() (k indexKey, v int64, err error) { if err = e.err; err != nil { return } if e.ver != e.t.ver { f, hit := e.t.Seek(e.k) if !e.hit && hit { if err = f.next(); err != nil { return } } *e = *f } if e.q == nil { e.err, err = io.EOF, io.EOF return } if e.i >= e.q.c { if err = e.next(); err != nil { return } } i := e.q.xd[e.i] k, v = i.k, int64(i.v) e.k, e.hit = k, false e.next() return } func (e *xenumerator) next() error { if e.q == nil { e.err = io.EOF return io.EOF } switch { case e.i < e.q.c-1: e.i++ default: if e.q, e.i = e.q.n, 0; e.q == nil { e.err = io.EOF } } return e.err } // Prev returns the currently enumerated item, if it exists and moves to the // previous item in the key collation order. If there is no item to return, err // == io.EOF is returned. func (e *xenumerator) Prev() (k indexKey, v int64, err error) { if err = e.err; err != nil { return } if e.ver != e.t.ver { f, hit := e.t.Seek(e.k) if !e.hit && hit { if err = f.prev(); err != nil { return } } *e = *f } if e.q == nil { e.err, err = io.EOF, io.EOF return } if e.i >= e.q.c { if err = e.next(); err != nil { return } } i := e.q.xd[e.i] k, v = i.k, int64(i.v) e.k, e.hit = k, false e.prev() return } func (e *xenumerator) prev() error { if e.q == nil { e.err = io.EOF return io.EOF } switch { case e.i > 0: e.i-- default: if e.q = e.q.p; e.q == nil { e.err = io.EOF break } e.i = e.q.c - 1 } return e.err }