defer os.RemoveAll(dir)
db.Set([]byte("1"), []byte("value_1"))
- itr := db.IteratorPrefixWithStart(nil, nil)
+ itr := db.IteratorPrefixWithStart(nil, nil, false)
require.Equal(t, []byte(""), itr.Key())
require.Equal(t, true, itr.Next())
require.Equal(t, []byte("1"), itr.Key())
db.SetSync([]byte("1"), []byte("value_1"))
db.SetSync([]byte("2"), []byte("value_1"))
- itr := db.IteratorPrefixWithStart(nil, []byte("1"))
+ itr := db.IteratorPrefixWithStart(nil, []byte("1"), false)
require.Equal(t, []byte("1"), itr.Key())
require.Equal(t, true, itr.Next())
- itr = db.IteratorPrefixWithStart(nil, []byte("2"))
+ itr = db.IteratorPrefixWithStart(nil, []byte("2"), false)
require.Equal(t, false, itr.Next())
})
db.SetSync([]byte("aaa22"), []byte("value_2"))
db.SetSync([]byte("bbb22"), []byte("value_3"))
- itr := db.IteratorPrefixWithStart([]byte("aaa"), []byte("aaa1"))
+ itr := db.IteratorPrefixWithStart([]byte("aaa"), []byte("aaa1"), false)
defer itr.Release()
require.Equal(t, true, itr.Next())
require.Equal(t, false, itr.Next())
- itr = db.IteratorPrefixWithStart([]byte("aaa"), nil)
+ itr = db.IteratorPrefixWithStart([]byte("aaa"), nil, false)
require.Equal(t, true, itr.Next())
require.Equal(t, []byte("aaa1"), itr.Key())
require.Equal(t, false, itr.Next())
- itr = db.IteratorPrefixWithStart([]byte("bbb"), []byte("aaa1"))
+ itr = db.IteratorPrefixWithStart([]byte("bbb"), []byte("aaa1"), false)
+ require.Equal(t, false, itr.Next())
+}
+
+func TestDBIteratorReverse(t *testing.T) {
+ dirname, err := ioutil.TempDir("", "db_common_test")
+ require.Nil(t, err)
+
+ db, err := NewGoLevelDB("testdb", dirname)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ defer func() {
+ db.Close()
+ os.RemoveAll(dirname)
+ }()
+
+ db.SetSync([]byte("aaa1"), []byte("value_1"))
+ db.SetSync([]byte("aaa22"), []byte("value_2"))
+ db.SetSync([]byte("bbb22"), []byte("value_3"))
+
+ itr := db.IteratorPrefixWithStart([]byte("aaa"), []byte("aaa22"), true)
+ defer itr.Release()
+
+ require.Equal(t, true, itr.Next())
+ require.Equal(t, []byte("aaa1"), itr.Key())
+
+ require.Equal(t, false, itr.Next())
+
+ itr = db.IteratorPrefixWithStart([]byte("aaa"), nil, true)
+
+ require.Equal(t, true, itr.Next())
+ require.Equal(t, []byte("aaa22"), itr.Key())
+
+ require.Equal(t, true, itr.Next())
+ require.Equal(t, []byte("aaa1"), itr.Key())
+
+ require.Equal(t, false, itr.Next())
+
+ require.Equal(t, false, itr.Next())
+
+ itr = db.IteratorPrefixWithStart([]byte("bbb"), []byte("aaa1"), true)
require.Equal(t, false, itr.Next())
}
}
type goLevelDBIterator struct {
- source iterator.Iterator
- start []byte
+ source iterator.Iterator
+ start []byte
+ isReverse bool
}
-func newGoLevelDBIterator(source iterator.Iterator, start []byte) *goLevelDBIterator {
+func newGoLevelDBIterator(source iterator.Iterator, start []byte, isReverse bool) *goLevelDBIterator {
if start != nil {
- source.Seek(start)
+ valid := source.Seek(start)
+ if !valid && isReverse {
+ source.Last()
+ source.Next()
+ }
+ } else if isReverse {
+ source.Last()
+ source.Next()
}
return &goLevelDBIterator{
- source: source,
- start: start,
+ source: source,
+ start: start,
+ isReverse: isReverse,
}
}
func (it *goLevelDBIterator) Next() bool {
it.assertNoError()
+ if it.isReverse {
+ return it.source.Prev()
+ }
return it.source.Next()
}
return &goLevelDBIterator{source: db.db.NewIterator(util.BytesPrefix(prefix), nil)}
}
-func (db *GoLevelDB) IteratorPrefixWithStart(Prefix, start []byte) Iterator {
+func (db *GoLevelDB) IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator {
itr := db.db.NewIterator(util.BytesPrefix(Prefix), nil)
- return newGoLevelDBIterator(itr, start)
+ return newGoLevelDBIterator(itr, start, isReverse)
}
func (db *GoLevelDB) NewBatch() Batch {