github.com/turingchain2020/turingchain@v1.1.21/common/db/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 数据库操作底层接口定义以及实现包括:leveldb、
     6  // memdb、mvcc、badgerdb、pegasus、ssdb
     7  package db
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  
    13  	"github.com/turingchain2020/turingchain/types"
    14  	lru "github.com/hashicorp/golang-lru"
    15  )
    16  
    17  //ErrNotFoundInDb error
    18  var ErrNotFoundInDb = types.ErrNotFound
    19  
    20  //Lister 列表接口
    21  type Lister interface {
    22  	List(prefix, key []byte, count, direction int32) ([][]byte, error)
    23  	PrefixCount(prefix []byte) int64
    24  }
    25  
    26  //TxKV transaction Key Value
    27  type TxKV interface {
    28  	KV
    29  	IteratorDB
    30  }
    31  
    32  //KV kv
    33  type KV interface {
    34  	Get(key []byte) ([]byte, error)
    35  	Set(key []byte, value []byte) (err error)
    36  	Begin()
    37  	Commit() error
    38  	Rollback()
    39  }
    40  
    41  //KVDB kvdb
    42  type KVDB interface {
    43  	KV
    44  	Lister
    45  }
    46  
    47  //DB db
    48  type DB interface {
    49  	KV
    50  	IteratorDB
    51  	SetSync([]byte, []byte) error
    52  	Delete([]byte) error
    53  	DeleteSync([]byte) error
    54  	Close()
    55  	NewBatch(sync bool) Batch
    56  	BeginTx() (TxKV, error)
    57  	CompactRange(start, limit []byte) error
    58  	// For debugging
    59  	Print()
    60  	Stats() map[string]string
    61  	SetCacheSize(size int)
    62  	GetCache() *lru.ARCCache
    63  }
    64  
    65  //KVDBList list
    66  type KVDBList struct {
    67  	DB
    68  	list *ListHelper
    69  }
    70  
    71  //List 列表
    72  func (l *KVDBList) List(prefix, key []byte, count, direction int32) ([][]byte, error) {
    73  	vals := l.list.List(prefix, key, count, direction)
    74  	if vals == nil {
    75  		return nil, types.ErrNotFound
    76  	}
    77  	return vals, nil
    78  }
    79  
    80  //PrefixCount 前缀长度
    81  func (l *KVDBList) PrefixCount(prefix []byte) int64 {
    82  	return l.list.PrefixCount(prefix)
    83  }
    84  
    85  //NewKVDB new
    86  func NewKVDB(db DB) KVDB {
    87  	return &KVDBList{DB: db, list: NewListHelper(db)}
    88  }
    89  
    90  //Batch batch
    91  type Batch interface {
    92  	Set(key, value []byte)
    93  	Delete(key []byte)
    94  	Write() error
    95  	ValueSize() int            // size of data in the batch
    96  	ValueLen() int             // amount of data in the batch
    97  	Reset()                    // Reset resets the batch for reuse
    98  	UpdateWriteSync(sync bool) // update write sync
    99  }
   100  
   101  // MustWrite must write correct
   102  func MustWrite(batch Batch) {
   103  	err := batch.Write()
   104  	if err != nil {
   105  		panic(fmt.Sprint("batch write err", err))
   106  	}
   107  }
   108  
   109  //IteratorSeeker ...
   110  type IteratorSeeker interface {
   111  	Rewind() bool
   112  	// 返回false, 表示系统中没有指定的key,Iterator会指向key附近
   113  	Seek(key []byte) bool
   114  	Next() bool
   115  }
   116  
   117  //Iterator 迭代器
   118  type Iterator interface {
   119  	IteratorSeeker
   120  	Valid() bool
   121  	Key() []byte
   122  	Value() []byte
   123  	ValueCopy() []byte
   124  	Error() error
   125  	Prefix() []byte
   126  	IsReverse() bool
   127  	Close()
   128  }
   129  
   130  type itBase struct {
   131  	start   []byte
   132  	end     []byte
   133  	reverse bool
   134  }
   135  
   136  func (it *itBase) checkKey(key []byte) bool {
   137  	//key must in start and end
   138  	var startok = true
   139  	var endok = true
   140  	if it.start != nil {
   141  		startok = bytes.Compare(key, it.start) >= 0
   142  	}
   143  	if it.end != nil {
   144  		endok = bytes.Compare(key, it.end) <= 0
   145  	}
   146  	ok := startok && endok
   147  	return ok
   148  }
   149  
   150  //Prefix 前缀
   151  func (it *itBase) Prefix() []byte {
   152  	return nil
   153  }
   154  
   155  func (it *itBase) IsReverse() bool {
   156  	return it.reverse
   157  }
   158  
   159  //IteratorDB 迭代
   160  type IteratorDB interface {
   161  	Iterator(start []byte, end []byte, reserver bool) Iterator
   162  }
   163  
   164  func bytesPrefix(prefix []byte) []byte {
   165  	var limit []byte
   166  	for i := len(prefix) - 1; i >= 0; i-- {
   167  		c := prefix[i]
   168  		if c < 0xff {
   169  			limit = make([]byte, i+1)
   170  			copy(limit, prefix)
   171  			limit[i] = c + 1
   172  			break
   173  		}
   174  	}
   175  	return limit
   176  }
   177  
   178  const (
   179  	levelDBBackendStr     = "leveldb" // legacy, defaults to goleveldb.
   180  	goLevelDBBackendStr   = "goleveldb"
   181  	memDBBackendStr       = "memdb"
   182  	goBadgerDBBackendStr  = "gobadgerdb"
   183  	ssDBBackendStr        = "ssdb"
   184  	goPegasusDbBackendStr = "pegasus"
   185  )
   186  
   187  type dbCreator func(name string, dir string, cache int) (DB, error)
   188  
   189  var backends = map[string]dbCreator{}
   190  
   191  func registerDBCreator(backend string, creator dbCreator, force bool) {
   192  	_, ok := backends[backend]
   193  	if !force && ok {
   194  		return
   195  	}
   196  	backends[backend] = creator
   197  }
   198  
   199  //NewDB new
   200  func NewDB(name string, backend string, dir string, cache int32) DB {
   201  	dbCreator, ok := backends[backend]
   202  	if !ok {
   203  		fmt.Printf("Error initializing DB: %v\n", backend)
   204  		panic("initializing DB error")
   205  	}
   206  	db, err := dbCreator(name, dir, int(cache))
   207  	if err != nil {
   208  		fmt.Printf("Error initializing DB: %v\n", err)
   209  		panic("initializing DB error")
   210  	}
   211  	return db
   212  }
   213  
   214  //BaseDB 交易缓存
   215  type BaseDB struct {
   216  	cache *lru.ARCCache
   217  }
   218  
   219  //GetCache 获取缓存
   220  func (db *BaseDB) GetCache() *lru.ARCCache {
   221  	return db.cache
   222  }
   223  
   224  //SetCacheSize 设置缓存大小
   225  func (db *BaseDB) SetCacheSize(size int) {
   226  	if db.cache != nil {
   227  		return
   228  	}
   229  	var err error
   230  	db.cache, err = lru.NewARC(size)
   231  	if err != nil {
   232  		panic(err)
   233  	}
   234  }
   235  
   236  //Begin call panic when Begin not rewrite
   237  func (db *BaseDB) Begin() {
   238  	panic("Begin not impl")
   239  }
   240  
   241  //Commit call panic when Commit not rewrite
   242  func (db *BaseDB) Commit() error {
   243  	panic("Commit not impl")
   244  }
   245  
   246  //Rollback call panic when Rollback not rewrite
   247  func (db *BaseDB) Rollback() {
   248  	panic("Rollback not impl")
   249  }
   250  
   251  //BeginTx call panic when BeginTx not rewrite
   252  func (db *BaseDB) BeginTx() (TxKV, error) {
   253  	panic("BeginTx not impl")
   254  }
   255  
   256  //CompactRange call panic when CompactRange not rewrite
   257  func (db *BaseDB) CompactRange(start, limit []byte) error {
   258  	panic("CompactRange not impl")
   259  }