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 }