diff --git a/db/db.go b/db/db.go index aa8ff48a..8156c1e9 100644 --- a/db/db.go +++ b/db/db.go @@ -10,10 +10,11 @@ type DB interface { DeleteSync([]byte) Close() NewBatch() Batch + Iterator() Iterator + IteratorPrefix([]byte) Iterator // For debugging Print() - Iterator() Iterator Stats() map[string]string } @@ -28,6 +29,9 @@ type Iterator interface { Key() []byte Value() []byte + + Release() + Error() error } //----------------------------------------------------------------------------- diff --git a/db/go_level_db.go b/db/go_level_db.go index 54ae1149..f3ed79e3 100644 --- a/db/go_level_db.go +++ b/db/go_level_db.go @@ -6,7 +6,9 @@ import ( "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" . "github.com/tendermint/tmlibs/common" ) @@ -115,8 +117,34 @@ func (db *GoLevelDB) Stats() map[string]string { return stats } +type goLevelDBIterator struct { + iterator.Iterator +} + +// Key returns a copy of the current key. +func (it *goLevelDBIterator) Key() []byte { + key := it.Key() + k := make([]byte, len(key)) + copy(k, key) + + return k +} + +// Value returns a copy of the current value. +func (it *goLevelDBIterator) Value() []byte { + val := it.Value() + v := make([]byte, len(val)) + copy(v, val) + + return v +} + func (db *GoLevelDB) Iterator() Iterator { - return db.db.NewIterator(nil, nil) + return &goLevelDBIterator{db.db.NewIterator(nil, nil)} +} + +func (db *GoLevelDB) IteratorPrefix(prefix []byte) Iterator { + return &goLevelDBIterator{db.db.NewIterator(util.BytesPrefix(prefix), nil)} } func (db *GoLevelDB) NewBatch() Batch { diff --git a/db/mem_db.go b/db/mem_db.go index 58e74895..55d594fa 100644 --- a/db/mem_db.go +++ b/db/mem_db.go @@ -2,6 +2,7 @@ package db import ( "fmt" + "strings" "sync" ) @@ -99,7 +100,21 @@ func (it *memDBIterator) Value() []byte { return it.db.Get(it.Key()) } +func (it *memDBIterator) Release() { + it.db = nil + it.keys = nil + return +} + +func (it *memDBIterator) Error() error { + return nil +} + func (db *MemDB) Iterator() Iterator { + return db.IteratorPrefix([]byte{}) +} + +func (db *MemDB) IteratorPrefix(prefix []byte) Iterator { it := newMemDBIterator() it.db = db it.last = -1 @@ -109,7 +124,9 @@ func (db *MemDB) Iterator() Iterator { // unfortunately we need a copy of all of the keys for key, _ := range db.db { - it.keys = append(it.keys, key) + if strings.HasPrefix(key, string(prefix)) { + it.keys = append(it.keys, key) + } } return it }