github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/database/leveldb/mem_db.go (about) 1 package leveldb 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 "strings" 8 "sync" 9 ) 10 11 func init() { 12 registerDBCreator(MemDBBackendStr, func(name string, dir string) (DB, error) { 13 return NewMemDB(), nil 14 }, false) 15 } 16 17 type MemDB struct { 18 mtx sync.Mutex 19 db map[string][]byte 20 } 21 22 func NewMemDB() *MemDB { 23 database := &MemDB{db: make(map[string][]byte)} 24 return database 25 } 26 27 func (db *MemDB) Get(key []byte) []byte { 28 db.mtx.Lock() 29 defer db.mtx.Unlock() 30 return db.db[string(key)] 31 } 32 33 func (db *MemDB) Set(key []byte, value []byte) { 34 db.mtx.Lock() 35 defer db.mtx.Unlock() 36 db.db[string(key)] = value 37 } 38 39 func (db *MemDB) SetSync(key []byte, value []byte) { 40 db.mtx.Lock() 41 defer db.mtx.Unlock() 42 db.db[string(key)] = value 43 } 44 45 func (db *MemDB) Delete(key []byte) { 46 db.mtx.Lock() 47 defer db.mtx.Unlock() 48 delete(db.db, string(key)) 49 } 50 51 func (db *MemDB) DeleteSync(key []byte) { 52 db.mtx.Lock() 53 defer db.mtx.Unlock() 54 delete(db.db, string(key)) 55 } 56 57 func (db *MemDB) Close() { 58 // Close is a noop since for an in-memory 59 // database, we don't have a destination 60 // to flush contents to nor do we want 61 // any data loss on invoking Close() 62 // See the discussion in https://github.com/tendermint/tmlibs/pull/56 63 } 64 65 func (db *MemDB) Print() { 66 db.mtx.Lock() 67 defer db.mtx.Unlock() 68 for key, value := range db.db { 69 fmt.Printf("[%X]:\t[%X]\n", []byte(key), value) 70 } 71 } 72 73 func (db *MemDB) Stats() map[string]string { 74 stats := make(map[string]string) 75 stats["database.type"] = "memDB" 76 return stats 77 } 78 79 type memDBIterator struct { 80 last int 81 keys []string 82 db DB 83 84 start []byte 85 } 86 87 func newMemDBIterator() *memDBIterator { 88 return &memDBIterator{} 89 } 90 91 // Keys is expected to be in reverse order for reverse iterators. 92 func newMemDBIteratorWithArgs(db DB, keys []string, start []byte) *memDBIterator { 93 itr := &memDBIterator{ 94 db: db, 95 keys: keys, 96 start: start, 97 last: -1, 98 } 99 if start != nil { 100 itr.Seek(start) 101 } 102 return itr 103 } 104 105 func (it *memDBIterator) Next() bool { 106 if it.last >= len(it.keys)-1 { 107 return false 108 } 109 it.last++ 110 return true 111 } 112 113 func (it *memDBIterator) Key() []byte { 114 if it.last < 0 { 115 return []byte("") 116 } 117 return []byte(it.keys[it.last]) 118 } 119 120 func (it *memDBIterator) Value() []byte { 121 return it.db.Get(it.Key()) 122 } 123 124 func (it *memDBIterator) Seek(point []byte) bool { 125 for i, key := range it.keys { 126 if key >= string(point) { 127 it.last = i 128 return true 129 } 130 } 131 return false 132 } 133 134 func (it *memDBIterator) Release() { 135 it.db = nil 136 it.keys = nil 137 } 138 139 func (it *memDBIterator) Error() error { 140 return nil 141 } 142 143 func (db *MemDB) Iterator() Iterator { 144 return db.IteratorPrefix([]byte{}) 145 } 146 147 func (db *MemDB) IteratorPrefix(prefix []byte) Iterator { 148 it := newMemDBIterator() 149 it.db = db 150 it.last = -1 151 152 db.mtx.Lock() 153 defer db.mtx.Unlock() 154 155 // unfortunately we need a copy of all of the keys 156 for key, _ := range db.db { 157 if strings.HasPrefix(key, string(prefix)) { 158 it.keys = append(it.keys, key) 159 } 160 } 161 // and we need to sort them 162 sort.Strings(it.keys) 163 return it 164 } 165 166 func (db *MemDB) IteratorPrefixWithStart(Prefix, start []byte, isReverse bool) Iterator { 167 db.mtx.Lock() 168 defer db.mtx.Unlock() 169 170 keys := db.getSortedKeys(start, isReverse) 171 return newMemDBIteratorWithArgs(db, keys, start) 172 } 173 174 func (db *MemDB) NewBatch() Batch { 175 return &memDBBatch{db, nil} 176 } 177 178 func (db *MemDB) getSortedKeys(start []byte, reverse bool) []string { 179 keys := []string{} 180 for key := range db.db { 181 if bytes.Compare([]byte(key), start) < 0 { 182 continue 183 } 184 keys = append(keys, key) 185 } 186 sort.Strings(keys) 187 if reverse { 188 nkeys := len(keys) 189 for i := 0; i < nkeys/2; i++ { 190 temp := keys[i] 191 keys[i] = keys[nkeys-i-1] 192 keys[nkeys-i-1] = temp 193 } 194 } 195 return keys 196 } 197 198 //-------------------------------------------------------------------------------- 199 200 type memDBBatch struct { 201 db *MemDB 202 ops []operation 203 } 204 205 type opType int 206 207 const ( 208 opTypeSet = 1 209 opTypeDelete = 2 210 ) 211 212 type operation struct { 213 opType 214 key []byte 215 value []byte 216 } 217 218 func (mBatch *memDBBatch) Set(key, value []byte) { 219 mBatch.ops = append(mBatch.ops, operation{opTypeSet, key, value}) 220 } 221 222 func (mBatch *memDBBatch) Delete(key []byte) { 223 mBatch.ops = append(mBatch.ops, operation{opTypeDelete, key, nil}) 224 } 225 226 func (mBatch *memDBBatch) Write() { 227 mBatch.db.mtx.Lock() 228 defer mBatch.db.mtx.Unlock() 229 230 for _, op := range mBatch.ops { 231 if op.opType == opTypeSet { 232 mBatch.db.db[string(op.key)] = op.value 233 } else if op.opType == opTypeDelete { 234 delete(mBatch.db.db, string(op.key)) 235 } 236 } 237 238 }