github.com/klaytn/klaytn@v1.10.2/storage/database/memory_database.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from ethdb/memory_database.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package database 22 23 import ( 24 "errors" 25 "sort" 26 "strings" 27 "sync" 28 29 "github.com/klaytn/klaytn/common" 30 ) 31 32 // errMemorydbClosed is returned if a memory database was already closed at the 33 // invocation of a data access operation. 34 var errMemorydbClosed = errors.New("database closed") 35 36 /* 37 * This is a test memory database. Do not use for any production it does not get persisted 38 */ 39 type MemDB struct { 40 db map[string][]byte 41 lock sync.RWMutex 42 } 43 44 func NewMemDB() *MemDB { 45 return &MemDB{ 46 db: make(map[string][]byte), 47 } 48 } 49 50 func NewMemDBWithCap(size int) *MemDB { 51 return &MemDB{ 52 db: make(map[string][]byte, size), 53 } 54 } 55 56 // Close deallocates the internal map and ensures any consecutive data access op 57 // fails with an error. 58 func (db *MemDB) Close() { 59 db.lock.Lock() 60 defer db.lock.Unlock() 61 62 db.db = nil 63 } 64 65 func (db *MemDB) Type() DBType { 66 return MemoryDB 67 } 68 69 // Has retrieves if a key is present in the key-value store. 70 func (db *MemDB) Has(key []byte) (bool, error) { 71 db.lock.RLock() 72 defer db.lock.RUnlock() 73 74 if db.db == nil { 75 return false, errMemorydbClosed 76 } 77 _, ok := db.db[string(key)] 78 return ok, nil 79 } 80 81 // Get retrieves the given key if it's present in the key-value store. 82 func (db *MemDB) Get(key []byte) ([]byte, error) { 83 db.lock.RLock() 84 defer db.lock.RUnlock() 85 86 if db.db == nil { 87 return nil, errMemorydbClosed 88 } 89 if entry, ok := db.db[string(key)]; ok { 90 if entry == nil { 91 entry = []byte{} 92 } 93 return common.CopyBytes(entry), nil 94 } 95 return nil, dataNotFoundErr 96 } 97 98 // Put inserts the given value into the key-value store. 99 func (db *MemDB) Put(key []byte, value []byte) error { 100 db.lock.Lock() 101 defer db.lock.Unlock() 102 103 if db.db == nil { 104 return errMemorydbClosed 105 } 106 db.db[string(key)] = common.CopyBytes(value) 107 return nil 108 } 109 110 // Delete removes the key from the key-value store. 111 func (db *MemDB) Delete(key []byte) error { 112 db.lock.Lock() 113 defer db.lock.Unlock() 114 115 if db.db == nil { 116 return errMemorydbClosed 117 } 118 delete(db.db, string(key)) 119 return nil 120 } 121 122 func (db *MemDB) Keys() [][]byte { 123 db.lock.RLock() 124 defer db.lock.RUnlock() 125 126 keys := [][]byte{} 127 for key := range db.db { 128 keys = append(keys, []byte(key)) 129 } 130 return keys 131 } 132 133 func (db *MemDB) NewBatch() Batch { 134 return &memBatch{db: db} 135 } 136 137 // NewIterator creates a binary-alphabetical iterator over a subset 138 // of database content with a particular key prefix, starting at a particular 139 // initial key (or after, if it does not exist). 140 func (db *MemDB) NewIterator(prefix []byte, start []byte) Iterator { 141 db.lock.RLock() 142 defer db.lock.RUnlock() 143 144 var ( 145 pr = string(prefix) 146 st = string(append(prefix, start...)) 147 keys = make([]string, 0, len(db.db)) 148 values = make([][]byte, 0, len(db.db)) 149 ) 150 // Collect the keys from the memory database corresponding to the given prefix 151 // and start 152 for key := range db.db { 153 if !strings.HasPrefix(key, pr) { 154 continue 155 } 156 if key >= st { 157 keys = append(keys, key) 158 } 159 } 160 // Sort the items and retrieve the associated values 161 sort.Strings(keys) 162 for _, key := range keys { 163 values = append(values, db.db[key]) 164 } 165 return &iterator{ 166 keys: keys, 167 values: values, 168 } 169 } 170 171 // Stat returns a particular internal stat of the database. 172 func (db *MemDB) Stat(property string) (string, error) { 173 return "", errors.New("unknown property") 174 } 175 176 // Compact is not supported on a memory database, but there's no need either as 177 // a memory database doesn't waste space anyway. 178 func (db *MemDB) Compact(start []byte, limit []byte) error { 179 return nil 180 } 181 182 // Len returns the number of entries currently present in the memory database. 183 // 184 // Note, this method is only used for testing (i.e. not public in general) and 185 // does not have explicit checks for closed-ness to allow simpler testing code. 186 func (db *MemDB) Len() int { 187 db.lock.RLock() 188 defer db.lock.RUnlock() 189 190 return len(db.db) 191 } 192 193 func (db *MemDB) Meter(prefix string) { 194 logger.Warn("MemDB does not support metrics!") 195 } 196 197 // keyvalue is a key-value tuple tagged with a deletion field to allow creating 198 // memory-database write batches. 199 type keyvalue struct { 200 key []byte 201 value []byte 202 delete bool 203 } 204 205 // memBatch is a write-only memory batch that commits changes to its host 206 // database when Write is called. A batch cannot be used concurrently. 207 type memBatch struct { 208 db *MemDB 209 writes []keyvalue 210 size int 211 } 212 213 // Put inserts the given value into the batch for later committing. 214 func (b *memBatch) Put(key, value []byte) error { 215 b.writes = append(b.writes, keyvalue{common.CopyBytes(key), common.CopyBytes(value), false}) 216 b.size += len(value) 217 return nil 218 } 219 220 // Delete inserts the a key removal into the batch for later committing. 221 func (b *memBatch) Delete(key []byte) error { 222 b.writes = append(b.writes, keyvalue{common.CopyBytes(key), nil, true}) 223 b.size += 1 224 return nil 225 } 226 227 // ValueSize retrieves the amount of data queued up for writing. 228 func (b *memBatch) ValueSize() int { 229 return b.size 230 } 231 232 // Write flushes any accumulated data to the memory database. 233 func (b *memBatch) Write() error { 234 b.db.lock.Lock() 235 defer b.db.lock.Unlock() 236 237 for _, keyvalue := range b.writes { 238 if keyvalue.delete { 239 delete(b.db.db, string(keyvalue.key)) 240 continue 241 } 242 b.db.db[string(keyvalue.key)] = keyvalue.value 243 } 244 return nil 245 } 246 247 // Reset resets the batch for reuse. 248 func (b *memBatch) Reset() { 249 b.writes = b.writes[:0] 250 b.size = 0 251 } 252 253 // Replay replays the batch contents. 254 func (b *memBatch) Replay(w KeyValueWriter) error { 255 for _, keyvalue := range b.writes { 256 if keyvalue.delete { 257 if err := w.Delete(keyvalue.key); err != nil { 258 return err 259 } 260 continue 261 } 262 if err := w.Put(keyvalue.key, keyvalue.value); err != nil { 263 return err 264 } 265 } 266 return nil 267 } 268 269 // iterator can walk over the (potentially partial) keyspace of a memory key 270 // value store. Internally it is a deep copy of the entire iterated state, 271 // sorted by keys. 272 type iterator struct { 273 inited bool 274 keys []string 275 values [][]byte 276 } 277 278 // Next moves the iterator to the next key/value pair. It returns whether the 279 // iterator is exhausted. 280 func (it *iterator) Next() bool { 281 // If the iterator was not yet initialized, do it now 282 if !it.inited { 283 it.inited = true 284 return len(it.keys) > 0 285 } 286 // Iterator already initialize, advance it 287 if len(it.keys) > 0 { 288 it.keys = it.keys[1:] 289 it.values = it.values[1:] 290 } 291 return len(it.keys) > 0 292 } 293 294 // Error returns any accumulated error. Exhausting all the key/value pairs 295 // is not considered to be an error. A memory iterator cannot encounter errors. 296 func (it *iterator) Error() error { 297 return nil 298 } 299 300 // Key returns the key of the current key/value pair, or nil if done. The caller 301 // should not modify the contents of the returned slice, and its contents may 302 // change on the next call to Next. 303 func (it *iterator) Key() []byte { 304 if len(it.keys) > 0 { 305 return []byte(it.keys[0]) 306 } 307 return nil 308 } 309 310 // Value returns the value of the current key/value pair, or nil if done. The 311 // caller should not modify the contents of the returned slice, and its contents 312 // may change on the next call to Next. 313 func (it *iterator) Value() []byte { 314 if len(it.values) > 0 { 315 return it.values[0] 316 } 317 return nil 318 } 319 320 // Release releases associated resources. Release should always succeed and can 321 // be called multiple times without causing error. 322 func (it *iterator) Release() { 323 it.keys, it.values = nil, nil 324 }