mirror of https://github.com/siddontang/go.git
iterator add offset and limit, reviterator bug fix
This commit is contained in:
parent
8994b2aabd
commit
af4507fc51
|
@ -116,7 +116,7 @@ func (db *DB) Destroy() {
|
|||
}
|
||||
|
||||
func (db *DB) Clear() {
|
||||
it := db.Iterator(nil, nil, 0, -1)
|
||||
it := db.Iterator(nil, nil, 0, 0, -1)
|
||||
for ; it.Valid(); it.Next() {
|
||||
db.Delete(it.Key())
|
||||
}
|
||||
|
@ -142,13 +142,15 @@ func (db *DB) NewWriteBatch() *WriteBatch {
|
|||
}
|
||||
|
||||
//limit < 0, unlimit
|
||||
func (db *DB) Iterator(min []byte, max []byte, rangeType uint8, limit int) *Iterator {
|
||||
return newIterator(db, db.iteratorOpts, NewRange(min, max, rangeType), limit, IteratorForward)
|
||||
//offset must >= 0, if < 0, will get nothing
|
||||
func (db *DB) Iterator(min []byte, max []byte, rangeType uint8, offset int, limit int) *Iterator {
|
||||
return newIterator(db, db.iteratorOpts, NewRange(min, max, rangeType), offset, limit, IteratorForward)
|
||||
}
|
||||
|
||||
//limit < 0, unlimit
|
||||
func (db *DB) RevIterator(min []byte, max []byte, rangeType uint8, limit int) *Iterator {
|
||||
return newIterator(db, db.iteratorOpts, NewRange(min, max, rangeType), limit, IteratorBackward)
|
||||
//offset must >= 0, if < 0, will get nothing
|
||||
func (db *DB) RevIterator(min []byte, max []byte, rangeType uint8, offset int, limit int) *Iterator {
|
||||
return newIterator(db, db.iteratorOpts, NewRange(min, max, rangeType), offset, limit, IteratorBackward)
|
||||
}
|
||||
|
||||
func (db *DB) NewSnapshot() *Snapshot {
|
||||
|
|
|
@ -39,7 +39,8 @@ type Iterator struct {
|
|||
|
||||
r *Range
|
||||
|
||||
limit int
|
||||
offset int
|
||||
limit int
|
||||
|
||||
step int
|
||||
|
||||
|
@ -47,16 +48,21 @@ type Iterator struct {
|
|||
direction uint8
|
||||
}
|
||||
|
||||
func newIterator(db *DB, opts *levigo.ReadOptions, r *Range, limit int, direction uint8) *Iterator {
|
||||
func newIterator(db *DB, opts *levigo.ReadOptions, r *Range, offset int, limit int, direction uint8) *Iterator {
|
||||
it := new(Iterator)
|
||||
it.it = db.db.NewIterator(opts)
|
||||
|
||||
it.r = r
|
||||
it.offset = offset
|
||||
it.limit = limit
|
||||
it.direction = direction
|
||||
|
||||
it.step = 0
|
||||
|
||||
if offset < 0 {
|
||||
return it
|
||||
}
|
||||
|
||||
if direction == IteratorForward {
|
||||
if r.Min == nil {
|
||||
it.it.SeekToFirst()
|
||||
|
@ -64,7 +70,7 @@ func newIterator(db *DB, opts *levigo.ReadOptions, r *Range, limit int, directio
|
|||
it.it.Seek(r.Min)
|
||||
|
||||
if r.Type&RangeLOpen > 0 {
|
||||
if it.Valid() && bytes.Equal(it.Key(), r.Min) {
|
||||
if it.it.Valid() && bytes.Equal(it.it.Key(), r.Min) {
|
||||
it.it.Next()
|
||||
}
|
||||
}
|
||||
|
@ -74,9 +80,13 @@ func newIterator(db *DB, opts *levigo.ReadOptions, r *Range, limit int, directio
|
|||
it.it.SeekToLast()
|
||||
} else {
|
||||
it.it.Seek(r.Max)
|
||||
if it.Valid() && !bytes.Equal(it.Key(), r.Max) {
|
||||
//key must bigger than max, so we must go prev
|
||||
it.it.Prev()
|
||||
|
||||
if !it.it.Valid() {
|
||||
it.it.SeekToLast()
|
||||
} else {
|
||||
if !bytes.Equal(it.it.Key(), r.Max) {
|
||||
it.it.Prev()
|
||||
}
|
||||
}
|
||||
|
||||
if r.Type&RangeROpen > 0 {
|
||||
|
@ -87,15 +97,21 @@ func newIterator(db *DB, opts *levigo.ReadOptions, r *Range, limit int, directio
|
|||
}
|
||||
}
|
||||
|
||||
for i := 0; i < offset; i++ {
|
||||
if it.Valid() {
|
||||
it.Next()
|
||||
}
|
||||
}
|
||||
|
||||
return it
|
||||
}
|
||||
|
||||
func (it *Iterator) Valid() bool {
|
||||
if !it.it.Valid() {
|
||||
if it.offset < 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if it.limit >= 0 && it.step >= it.limit {
|
||||
} else if !it.it.Valid() {
|
||||
return false
|
||||
} else if it.limit >= 0 && it.step >= it.limit {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -136,14 +152,6 @@ func (it *Iterator) Next() {
|
|||
}
|
||||
}
|
||||
|
||||
func (it *Iterator) Skip(offset int64) {
|
||||
for i := int64(0); i < offset; i++ {
|
||||
if it.Valid() {
|
||||
it.Next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (it *Iterator) Key() []byte {
|
||||
return it.it.Key()
|
||||
}
|
||||
|
|
|
@ -146,52 +146,52 @@ func TestIterator(t *testing.T) {
|
|||
return []byte(fmt.Sprintf("key_%d", i))
|
||||
}
|
||||
|
||||
it = db.Iterator(k(1), k(5), RangeClose, -1)
|
||||
it = db.Iterator(k(1), k(5), RangeClose, 0, -1)
|
||||
if err := checkIterator(it, 1, 2, 3, 4, 5); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.Iterator(k(1), k(5), RangeClose, 3)
|
||||
if err := checkIterator(it, 1, 2, 3); err != nil {
|
||||
it = db.Iterator(k(1), k(5), RangeClose, 1, 3)
|
||||
if err := checkIterator(it, 2, 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.Iterator(k(1), k(5), RangeLOpen, -1)
|
||||
it = db.Iterator(k(1), k(5), RangeLOpen, 0, -1)
|
||||
if err := checkIterator(it, 2, 3, 4, 5); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.Iterator(k(1), k(5), RangeROpen, -1)
|
||||
it = db.Iterator(k(1), k(5), RangeROpen, 0, -1)
|
||||
if err := checkIterator(it, 1, 2, 3, 4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.Iterator(k(1), k(5), RangeOpen, -1)
|
||||
it = db.Iterator(k(1), k(5), RangeOpen, 0, -1)
|
||||
if err := checkIterator(it, 2, 3, 4); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.RevIterator(k(1), k(5), RangeClose, -1)
|
||||
it = db.RevIterator(k(1), k(5), RangeClose, 0, -1)
|
||||
if err := checkIterator(it, 5, 4, 3, 2, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.RevIterator(k(1), k(5), RangeClose, 3)
|
||||
if err := checkIterator(it, 5, 4, 3); err != nil {
|
||||
it = db.RevIterator(k(1), k(5), RangeClose, 1, 3)
|
||||
if err := checkIterator(it, 4, 3); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.RevIterator(k(1), k(5), RangeLOpen, -1)
|
||||
it = db.RevIterator(k(1), k(5), RangeLOpen, 0, -1)
|
||||
if err := checkIterator(it, 5, 4, 3, 2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.RevIterator(k(1), k(5), RangeROpen, -1)
|
||||
it = db.RevIterator(k(1), k(5), RangeROpen, 0, -1)
|
||||
if err := checkIterator(it, 4, 3, 2, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
it = db.RevIterator(k(1), k(5), RangeOpen, -1)
|
||||
it = db.RevIterator(k(1), k(5), RangeOpen, 0, -1)
|
||||
if err := checkIterator(it, 4, 3, 2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -37,12 +37,12 @@ func (s *Snapshot) Get(key []byte) ([]byte, error) {
|
|||
return s.db.db.Get(s.readOpts, key)
|
||||
}
|
||||
|
||||
func (s *Snapshot) Iterator(min []byte, max []byte, rangeType uint8, limit int) *Iterator {
|
||||
return newIterator(s.db, s.iteratorOpts, NewRange(min, max, rangeType), limit, IteratorForward)
|
||||
func (s *Snapshot) Iterator(min []byte, max []byte, rangeType uint8, offset int, limit int) *Iterator {
|
||||
return newIterator(s.db, s.iteratorOpts, NewRange(min, max, rangeType), offset, limit, IteratorForward)
|
||||
}
|
||||
|
||||
func (s *Snapshot) RevIterator(min []byte, max []byte, rangeType uint8, limit int) *Iterator {
|
||||
return newIterator(s.db, s.iteratorOpts, NewRange(min, max, rangeType), limit, IteratorBackward)
|
||||
func (s *Snapshot) RevIterator(min []byte, max []byte, rangeType uint8, offset int, limit int) *Iterator {
|
||||
return newIterator(s.db, s.iteratorOpts, NewRange(min, max, rangeType), offset, limit, IteratorBackward)
|
||||
}
|
||||
|
||||
func (s *Snapshot) GetInt(key []byte) (int64, error) {
|
||||
|
|
Loading…
Reference in New Issue