7 "github.com/syndtr/goleveldb/leveldb"
8 "github.com/syndtr/goleveldb/leveldb/errors"
9 "github.com/syndtr/goleveldb/leveldb/iterator"
10 "github.com/syndtr/goleveldb/leveldb/opt"
11 "github.com/syndtr/goleveldb/leveldb/util"
13 . "github.com/tendermint/tmlibs/common"
17 dbCreator := func(name string, dir string) (DB, error) {
18 return NewGoLevelDB(name, dir)
20 registerDBCreator(LevelDBBackendStr, dbCreator, false)
21 registerDBCreator(GoLevelDBBackendStr, dbCreator, false)
24 type GoLevelDB struct {
28 func NewGoLevelDB(name string, dir string) (*GoLevelDB, error) {
29 dbPath := path.Join(dir, name+".db")
30 db, err := leveldb.OpenFile(dbPath, nil)
34 database := &GoLevelDB{db: db}
38 func (db *GoLevelDB) Get(key []byte) []byte {
39 res, err := db.db.Get(key, nil)
41 if err == errors.ErrNotFound {
50 func (db *GoLevelDB) Set(key []byte, value []byte) {
51 err := db.db.Put(key, value, nil)
57 func (db *GoLevelDB) SetSync(key []byte, value []byte) {
58 err := db.db.Put(key, value, &opt.WriteOptions{Sync: true})
64 func (db *GoLevelDB) Delete(key []byte) {
65 err := db.db.Delete(key, nil)
71 func (db *GoLevelDB) DeleteSync(key []byte) {
72 err := db.db.Delete(key, &opt.WriteOptions{Sync: true})
78 func (db *GoLevelDB) DB() *leveldb.DB {
82 func (db *GoLevelDB) Close() {
86 func (db *GoLevelDB) Print() {
87 str, _ := db.db.GetProperty("leveldb.stats")
88 fmt.Printf("%v\n", str)
90 iter := db.db.NewIterator(nil, nil)
94 fmt.Printf("[%X]:\t[%X]\n", key, value)
98 func (db *GoLevelDB) Stats() map[string]string {
100 "leveldb.num-files-at-level{n}",
104 "leveldb.cachedblock",
105 "leveldb.openedtables",
106 "leveldb.alivesnaps",
107 "leveldb.aliveiters",
110 stats := make(map[string]string)
111 for _, key := range keys {
112 str, err := db.db.GetProperty(key)
120 type goLevelDBIterator struct {
121 source iterator.Iterator
126 func newGoLevelDBIterator(source iterator.Iterator, start []byte, isReverse bool) *goLevelDBIterator {
128 valid := source.Seek(start)
129 if !valid && isReverse {
133 } else if isReverse {
138 return &goLevelDBIterator{
141 isReverse: isReverse,
145 // Key returns a copy of the current key.
146 func (it *goLevelDBIterator) Key() []byte {
147 key := it.source.Key()
148 k := make([]byte, len(key))
154 // Value returns a copy of the current value.
155 func (it *goLevelDBIterator) Value() []byte {
156 val := it.source.Value()
157 v := make([]byte, len(val))
163 func (it *goLevelDBIterator) Seek(point []byte) bool {
164 return it.source.Seek(point)
167 func (it *goLevelDBIterator) Error() error {
168 return it.source.Error()
171 func (it *goLevelDBIterator) Next() bool {
174 return it.source.Prev()
176 return it.source.Next()
179 func (it *goLevelDBIterator) Release() {
183 func (it *goLevelDBIterator) assertNoError() {
184 if err := it.source.Error(); err != nil {
189 func (db *GoLevelDB) Iterator() Iterator {
190 return &goLevelDBIterator{source: db.db.NewIterator(nil, nil)}
193 func (db *GoLevelDB) IteratorPrefix(prefix []byte) Iterator {
194 return &goLevelDBIterator{source: db.db.NewIterator(util.BytesPrefix(prefix), nil)}
197 func (db *GoLevelDB) IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator {
198 itr := db.db.NewIterator(util.BytesPrefix(Prefix), nil)
199 return newGoLevelDBIterator(itr, start, isReverse)
202 func (db *GoLevelDB) NewBatch() Batch {
203 batch := new(leveldb.Batch)
204 return &goLevelDBBatch{db, batch}
207 //--------------------------------------------------------------------------------
209 type goLevelDBBatch struct {
214 func (mBatch *goLevelDBBatch) Set(key, value []byte) {
215 mBatch.batch.Put(key, value)
218 func (mBatch *goLevelDBBatch) Delete(key []byte) {
219 mBatch.batch.Delete(key)
222 func (mBatch *goLevelDBBatch) Write() {
223 err := mBatch.db.db.Write(mBatch.batch, nil)