diff --git a/database/leveldb.go b/database/leveldb.go index 8a5f9daa..d07ccf5b 100644 --- a/database/leveldb.go +++ b/database/leveldb.go @@ -2,6 +2,7 @@ package database import ( + "bytes" "errors" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/filter" @@ -17,6 +18,7 @@ var ( type Storage interface { Get(key []byte) ([]byte, error) Put(key []byte, value []byte) error + FetchByPrefix(prefix []byte) [][]byte Close() error } @@ -58,6 +60,25 @@ func (l *levelDB) Put(key []byte, value []byte) error { return l.db.Put(key, value, nil) } +func (l *levelDB) FetchByPrefix(prefix []byte) [][]byte { + result := make([][]byte, 0, 20) + + iterator := l.db.NewIterator(nil) + if iterator.Seek(prefix) { + for bytes.HasPrefix(iterator.Key(), prefix) { + val := iterator.Value() + valc := make([]byte, len(val)) + copy(valc, val) + result = append(result, valc) + if !iterator.Next() { + break + } + } + } + + return result +} + func (l *levelDB) Close() error { return l.db.Close() } diff --git a/database/leveldb_test.go b/database/leveldb_test.go index b52e44c1..165ec126 100644 --- a/database/leveldb_test.go +++ b/database/leveldb_test.go @@ -44,3 +44,20 @@ func (s *LevelDBSuite) TestGetPut(c *C) { c.Assert(err, IsNil) c.Assert(result, DeepEquals, value) } + +func (s *LevelDBSuite) TestFetchByPrefix(c *C) { + c.Check(s.db.FetchByPrefix([]byte{0x80}), DeepEquals, [][]byte{}) + + s.db.Put([]byte{0x80, 0x01}, []byte{0x01}) + s.db.Put([]byte{0x80, 0x03}, []byte{0x03}) + s.db.Put([]byte{0x80, 0x02}, []byte{0x02}) + c.Check(s.db.FetchByPrefix([]byte{0x80}), DeepEquals, [][]byte{[]byte{0x01}, []byte{0x02}, []byte{0x03}}) + + s.db.Put([]byte{0x90, 0x01}, []byte{0x04}) + c.Check(s.db.FetchByPrefix([]byte{0x80}), DeepEquals, [][]byte{[]byte{0x01}, []byte{0x02}, []byte{0x03}}) + + s.db.Put([]byte{0x00, 0x01}, []byte{0x05}) + c.Check(s.db.FetchByPrefix([]byte{0x80}), DeepEquals, [][]byte{[]byte{0x01}, []byte{0x02}, []byte{0x03}}) + + c.Check(s.db.FetchByPrefix([]byte{0xa0}), DeepEquals, [][]byte{}) +}