github.com/turingchain2020/turingchain@v1.1.21/common/db/go_badger_db.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package db 6 7 import ( 8 "bytes" 9 10 log "github.com/turingchain2020/turingchain/common/log/log15" 11 "github.com/turingchain2020/turingchain/types" 12 "github.com/dgraph-io/badger" 13 "github.com/dgraph-io/badger/options" 14 ) 15 16 var blog = log.New("module", "db.gobadgerdb") 17 18 //GoBadgerDB db 19 type GoBadgerDB struct { 20 BaseDB 21 db *badger.DB 22 } 23 24 func init() { 25 dbCreator := func(name string, dir string, cache int) (DB, error) { 26 return NewGoBadgerDB(name, dir, cache) 27 } 28 registerDBCreator(goBadgerDBBackendStr, dbCreator, false) 29 } 30 31 //NewGoBadgerDB new 32 func NewGoBadgerDB(name string, dir string, cache int) (*GoBadgerDB, error) { 33 opts := badger.DefaultOptions(dir) 34 if cache <= 128 { 35 opts.ValueLogLoadingMode = options.FileIO 36 //opts.MaxTableSize = int64(cache) << 18 // cache = 128, MaxTableSize = 32M 37 opts.NumCompactors = 1 38 opts.NumMemtables = 1 39 opts.NumLevelZeroTables = 1 40 opts.NumLevelZeroTablesStall = 2 41 opts.TableLoadingMode = options.MemoryMap 42 opts.ValueLogFileSize = 1 << 28 // 256M 43 } 44 45 db, err := badger.Open(opts) 46 if err != nil { 47 blog.Error("NewGoBadgerDB", "error", err) 48 return nil, err 49 } 50 51 return &GoBadgerDB{db: db}, nil 52 } 53 54 //Get get 55 func (db *GoBadgerDB) Get(key []byte) ([]byte, error) { 56 var val []byte 57 err := db.db.View(func(txn *badger.Txn) error { 58 item, err := txn.Get(key) 59 if err != nil { 60 if err == badger.ErrKeyNotFound { 61 return ErrNotFoundInDb 62 } 63 blog.Error("Get", "txn.Get.error", err) 64 return err 65 66 } 67 //xxxx 68 val, err = item.ValueCopy(nil) 69 if err != nil { 70 blog.Error("Get", "item.Value.error", err) 71 return err 72 } 73 74 // 兼容leveldb 75 if val == nil { 76 val = make([]byte, 0) 77 } 78 return nil 79 }) 80 81 if err != nil { 82 return nil, err 83 } 84 85 return val, nil 86 } 87 88 //Set set 89 func (db *GoBadgerDB) Set(key []byte, value []byte) error { 90 err := db.db.Update(func(txn *badger.Txn) error { 91 err := txn.Set(key, value) 92 return err 93 }) 94 95 if err != nil { 96 blog.Error("Set", "error", err) 97 return err 98 } 99 return nil 100 } 101 102 //SetSync 同步 103 func (db *GoBadgerDB) SetSync(key []byte, value []byte) error { 104 err := db.db.Update(func(txn *badger.Txn) error { 105 err := txn.Set(key, value) 106 return err 107 }) 108 109 if err != nil { 110 blog.Error("SetSync", "error", err) 111 return err 112 } 113 return nil 114 } 115 116 //Delete 删除 117 func (db *GoBadgerDB) Delete(key []byte) error { 118 err := db.db.Update(func(txn *badger.Txn) error { 119 err := txn.Delete(key) 120 return err 121 }) 122 123 if err != nil { 124 blog.Error("Delete", "error", err) 125 return err 126 } 127 return nil 128 } 129 130 //DeleteSync 删除同步 131 func (db *GoBadgerDB) DeleteSync(key []byte) error { 132 err := db.db.Update(func(txn *badger.Txn) error { 133 err := txn.Delete(key) 134 return err 135 }) 136 137 if err != nil { 138 blog.Error("DeleteSync", "error", err) 139 return err 140 } 141 return nil 142 } 143 144 //DB db 145 func (db *GoBadgerDB) DB() *badger.DB { 146 return db.db 147 } 148 149 //Close 关闭 150 func (db *GoBadgerDB) Close() { 151 err := db.db.Close() 152 if err != nil { 153 return 154 } 155 } 156 157 //Print 打印 158 func (db *GoBadgerDB) Print() { 159 // TODO: Returns statistics of the underlying DB 160 err := db.db.View(func(txn *badger.Txn) error { 161 opts := badger.DefaultIteratorOptions 162 opts.PrefetchSize = 10 163 it := txn.NewIterator(opts) 164 165 for it.Rewind(); it.Valid(); it.Next() { 166 item := it.Item() 167 k := item.Key() 168 v, err := item.ValueCopy(nil) 169 if err != nil { 170 return err 171 } 172 blog.Info("Print", "key", string(k), "value", string(v)) 173 //blog.Info("Print", "key", string(item.Key())) 174 } 175 return nil 176 }) 177 if err != nil { 178 blog.Error("Print", err) 179 } 180 } 181 182 //Stats ... 183 func (db *GoBadgerDB) Stats() map[string]string { 184 //TODO 185 return nil 186 } 187 188 //Iterator 迭代器 189 func (db *GoBadgerDB) Iterator(start, end []byte, reverse bool) Iterator { 190 txn := db.db.NewTransaction(false) 191 opts := badger.DefaultIteratorOptions 192 opts.Reverse = reverse 193 it := txn.NewIterator(opts) 194 if end == nil { 195 end = bytesPrefix(start) 196 } 197 if bytes.Equal(end, types.EmptyValue) { 198 end = nil 199 } 200 if reverse { 201 it.Seek(end) 202 } else { 203 it.Seek(start) 204 } 205 return &goBadgerDBIt{it, itBase{start, end, reverse}, txn, nil} 206 } 207 208 type goBadgerDBIt struct { 209 *badger.Iterator 210 itBase 211 txn *badger.Txn 212 err error 213 } 214 215 //Next next 216 func (it *goBadgerDBIt) Next() bool { 217 it.Iterator.Next() 218 return it.Valid() 219 } 220 221 //Rewind ... 222 func (it *goBadgerDBIt) Rewind() bool { 223 if it.reverse { 224 it.Seek(it.end) 225 } else { 226 it.Seek(it.start) 227 } 228 return it.Valid() 229 } 230 231 //Seek 查找 232 func (it *goBadgerDBIt) Seek(key []byte) bool { 233 it.Iterator.Seek(key) 234 return it.Valid() 235 } 236 237 //Close 关闭 238 func (it *goBadgerDBIt) Close() { 239 it.Iterator.Close() 240 it.txn.Discard() 241 } 242 243 //Valid 是否合法 244 func (it *goBadgerDBIt) Valid() bool { 245 return it.Iterator.Valid() && it.checkKey(it.Key()) 246 } 247 248 func (it *goBadgerDBIt) Key() []byte { 249 return it.Item().Key() 250 } 251 252 func (it *goBadgerDBIt) Value() []byte { 253 value, err := it.Item().ValueCopy(nil) 254 if err != nil { 255 it.err = err 256 } 257 return value 258 } 259 260 func (it *goBadgerDBIt) ValueCopy() []byte { 261 value, err := it.Item().ValueCopy(nil) 262 if err != nil { 263 it.err = err 264 } 265 return value 266 } 267 268 func (it *goBadgerDBIt) Error() error { 269 return it.err 270 } 271 272 //GoBadgerDBBatch batch 273 type GoBadgerDBBatch struct { 274 db *GoBadgerDB 275 batch *badger.Txn 276 //wop *opt.WriteOptions 277 size int 278 len int 279 } 280 281 //NewBatch new 282 func (db *GoBadgerDB) NewBatch(sync bool) Batch { 283 batch := db.db.NewTransaction(true) 284 return &GoBadgerDBBatch{db, batch, 0, 0} 285 } 286 287 //Set set 288 func (mBatch *GoBadgerDBBatch) Set(key, value []byte) { 289 err := mBatch.batch.Set(key, value) 290 if err != nil { 291 blog.Error("Set", "error", err) 292 } 293 mBatch.size += len(value) 294 mBatch.size += len(key) 295 mBatch.len += len(value) 296 } 297 298 //Delete 设置 299 func (mBatch *GoBadgerDBBatch) Delete(key []byte) { 300 err := mBatch.batch.Delete(key) 301 if err != nil { 302 blog.Error("Delete", "error", err) 303 } 304 mBatch.size += len(key) 305 mBatch.len++ 306 } 307 308 //Write 写入 309 func (mBatch *GoBadgerDBBatch) Write() error { 310 defer mBatch.batch.Discard() 311 312 if err := mBatch.batch.Commit(); err != nil { 313 blog.Error("Write", "error", err) 314 return err 315 } 316 return nil 317 } 318 319 //ValueSize batch大小 320 func (mBatch *GoBadgerDBBatch) ValueSize() int { 321 return mBatch.size 322 } 323 324 //ValueLen batch数量 325 func (mBatch *GoBadgerDBBatch) ValueLen() int { 326 return mBatch.len 327 } 328 329 //Reset 重置 330 func (mBatch *GoBadgerDBBatch) Reset() { 331 if nil != mBatch.db && nil != mBatch.db.db { 332 mBatch.batch = mBatch.db.db.NewTransaction(true) 333 } 334 mBatch.size = 0 335 mBatch.len = 0 336 } 337 338 // UpdateWriteSync ... 339 func (mBatch *GoBadgerDBBatch) UpdateWriteSync(sync bool) { 340 }