github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/database/leveldb/go_level_db.go (about) 1 package leveldb 2 3 import ( 4 "fmt" 5 "path" 6 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" 12 13 . "github.com/tendermint/tmlibs/common" 14 ) 15 16 func init() { 17 dbCreator := func(name string, dir string) (DB, error) { 18 return NewGoLevelDB(name, dir) 19 } 20 registerDBCreator(LevelDBBackendStr, dbCreator, false) 21 registerDBCreator(GoLevelDBBackendStr, dbCreator, false) 22 } 23 24 type GoLevelDB struct { 25 db *leveldb.DB 26 } 27 28 func NewGoLevelDB(name string, dir string) (*GoLevelDB, error) { 29 dbPath := path.Join(dir, name+".db") 30 db, err := leveldb.OpenFile(dbPath, nil) 31 if err != nil { 32 return nil, err 33 } 34 database := &GoLevelDB{db: db} 35 return database, nil 36 } 37 38 func (db *GoLevelDB) Get(key []byte) []byte { 39 res, err := db.db.Get(key, nil) 40 if err != nil { 41 if err == errors.ErrNotFound { 42 return nil 43 } else { 44 PanicCrisis(err) 45 } 46 } 47 return res 48 } 49 50 func (db *GoLevelDB) Set(key []byte, value []byte) { 51 err := db.db.Put(key, value, nil) 52 if err != nil { 53 PanicCrisis(err) 54 } 55 } 56 57 func (db *GoLevelDB) SetSync(key []byte, value []byte) { 58 err := db.db.Put(key, value, &opt.WriteOptions{Sync: true}) 59 if err != nil { 60 PanicCrisis(err) 61 } 62 } 63 64 func (db *GoLevelDB) Delete(key []byte) { 65 err := db.db.Delete(key, nil) 66 if err != nil { 67 PanicCrisis(err) 68 } 69 } 70 71 func (db *GoLevelDB) DeleteSync(key []byte) { 72 err := db.db.Delete(key, &opt.WriteOptions{Sync: true}) 73 if err != nil { 74 PanicCrisis(err) 75 } 76 } 77 78 func (db *GoLevelDB) DB() *leveldb.DB { 79 return db.db 80 } 81 82 func (db *GoLevelDB) Close() { 83 db.db.Close() 84 } 85 86 func (db *GoLevelDB) Print() { 87 str, _ := db.db.GetProperty("leveldb.stats") 88 fmt.Printf("%v\n", str) 89 90 iter := db.db.NewIterator(nil, nil) 91 for iter.Next() { 92 key := iter.Key() 93 value := iter.Value() 94 fmt.Printf("[%X]:\t[%X]\n", key, value) 95 } 96 } 97 98 func (db *GoLevelDB) Stats() map[string]string { 99 keys := []string{ 100 "leveldb.num-files-at-level{n}", 101 "leveldb.stats", 102 "leveldb.sstables", 103 "leveldb.blockpool", 104 "leveldb.cachedblock", 105 "leveldb.openedtables", 106 "leveldb.alivesnaps", 107 "leveldb.aliveiters", 108 } 109 110 stats := make(map[string]string) 111 for _, key := range keys { 112 str, err := db.db.GetProperty(key) 113 if err == nil { 114 stats[key] = str 115 } 116 } 117 return stats 118 } 119 120 type goLevelDBIterator struct { 121 source iterator.Iterator 122 start []byte 123 isReverse bool 124 } 125 126 func newGoLevelDBIterator(source iterator.Iterator, start []byte, isReverse bool) *goLevelDBIterator { 127 if start != nil { 128 valid := source.Seek(start) 129 if !valid && isReverse { 130 source.Last() 131 source.Next() 132 } 133 } else if isReverse { 134 source.Last() 135 source.Next() 136 } 137 138 return &goLevelDBIterator{ 139 source: source, 140 start: start, 141 isReverse: isReverse, 142 } 143 } 144 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)) 149 copy(k, key) 150 151 return k 152 } 153 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)) 158 copy(v, val) 159 160 return v 161 } 162 163 func (it *goLevelDBIterator) Seek(point []byte) bool { 164 return it.source.Seek(point) 165 } 166 167 func (it *goLevelDBIterator) Error() error { 168 return it.source.Error() 169 } 170 171 func (it *goLevelDBIterator) Next() bool { 172 it.assertNoError() 173 if it.isReverse { 174 return it.source.Prev() 175 } 176 return it.source.Next() 177 } 178 179 func (it *goLevelDBIterator) Release() { 180 it.source.Release() 181 } 182 183 func (it *goLevelDBIterator) assertNoError() { 184 if err := it.source.Error(); err != nil { 185 panic(err) 186 } 187 } 188 189 func (db *GoLevelDB) Iterator() Iterator { 190 return &goLevelDBIterator{source: db.db.NewIterator(nil, nil)} 191 } 192 193 func (db *GoLevelDB) IteratorPrefix(prefix []byte) Iterator { 194 return &goLevelDBIterator{source: db.db.NewIterator(util.BytesPrefix(prefix), nil)} 195 } 196 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) 200 } 201 202 func (db *GoLevelDB) NewBatch() Batch { 203 batch := new(leveldb.Batch) 204 return &goLevelDBBatch{db, batch} 205 } 206 207 //-------------------------------------------------------------------------------- 208 209 type goLevelDBBatch struct { 210 db *GoLevelDB 211 batch *leveldb.Batch 212 } 213 214 func (mBatch *goLevelDBBatch) Set(key, value []byte) { 215 mBatch.batch.Put(key, value) 216 } 217 218 func (mBatch *goLevelDBBatch) Delete(key []byte) { 219 mBatch.batch.Delete(key) 220 } 221 222 func (mBatch *goLevelDBBatch) Write() { 223 err := mBatch.db.db.Write(mBatch.batch, nil) 224 if err != nil { 225 PanicCrisis(err) 226 } 227 }