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  }