github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/neatdb/memorydb/memorydb.go (about) 1 package memorydb 2 3 import ( 4 "errors" 5 "sort" 6 "strings" 7 "sync" 8 9 "github.com/neatlab/neatio/neatdb" 10 "github.com/neatlab/neatio/utilities/common" 11 ) 12 13 var ( 14 errMemorydbClosed = errors.New("database closed") 15 16 errMemorydbNotFound = errors.New("not found") 17 ) 18 19 type Database struct { 20 db map[string][]byte 21 lock sync.RWMutex 22 } 23 24 func New() *Database { 25 return &Database{ 26 db: make(map[string][]byte), 27 } 28 } 29 30 func NewWithCap(size int) *Database { 31 return &Database{ 32 db: make(map[string][]byte, size), 33 } 34 } 35 36 func (db *Database) Close() error { 37 db.lock.Lock() 38 defer db.lock.Unlock() 39 40 db.db = nil 41 return nil 42 } 43 44 func (db *Database) Has(key []byte) (bool, error) { 45 db.lock.RLock() 46 defer db.lock.RUnlock() 47 48 if db.db == nil { 49 return false, errMemorydbClosed 50 } 51 _, ok := db.db[string(key)] 52 return ok, nil 53 } 54 55 func (db *Database) Get(key []byte) ([]byte, error) { 56 db.lock.RLock() 57 defer db.lock.RUnlock() 58 59 if db.db == nil { 60 return nil, errMemorydbClosed 61 } 62 if entry, ok := db.db[string(key)]; ok { 63 return common.CopyBytes(entry), nil 64 } 65 return nil, errMemorydbNotFound 66 } 67 68 func (db *Database) Put(key []byte, value []byte) error { 69 db.lock.Lock() 70 defer db.lock.Unlock() 71 72 if db.db == nil { 73 return errMemorydbClosed 74 } 75 db.db[string(key)] = common.CopyBytes(value) 76 return nil 77 } 78 79 func (db *Database) Delete(key []byte) error { 80 db.lock.Lock() 81 defer db.lock.Unlock() 82 83 if db.db == nil { 84 return errMemorydbClosed 85 } 86 delete(db.db, string(key)) 87 return nil 88 } 89 90 func (db *Database) NewBatch() neatdb.Batch { 91 return &batch{ 92 db: db, 93 } 94 } 95 96 func (db *Database) NewIterator() neatdb.Iterator { 97 return db.NewIteratorWithPrefix(nil) 98 } 99 100 func (db *Database) NewIteratorWithPrefix(prefix []byte) neatdb.Iterator { 101 db.lock.RLock() 102 defer db.lock.RUnlock() 103 104 var ( 105 pr = string(prefix) 106 keys = make([]string, 0, len(db.db)) 107 values = make([][]byte, 0, len(db.db)) 108 ) 109 110 for key := range db.db { 111 if strings.HasPrefix(key, pr) { 112 keys = append(keys, key) 113 } 114 } 115 116 sort.Strings(keys) 117 for _, key := range keys { 118 values = append(values, db.db[key]) 119 } 120 return &iterator{ 121 keys: keys, 122 values: values, 123 } 124 } 125 126 func (db *Database) Stat(property string) (string, error) { 127 return "", errors.New("unknown property") 128 } 129 130 func (db *Database) Compact(start []byte, limit []byte) error { 131 return errors.New("unsupported operation") 132 } 133 134 func (db *Database) Len() int { 135 db.lock.RLock() 136 defer db.lock.RUnlock() 137 138 return len(db.db) 139 } 140 141 type keyvalue struct { 142 key []byte 143 value []byte 144 delete bool 145 } 146 147 type batch struct { 148 db *Database 149 writes []keyvalue 150 size int 151 } 152 153 func (b *batch) Put(key, value []byte) error { 154 b.writes = append(b.writes, keyvalue{common.CopyBytes(key), common.CopyBytes(value), false}) 155 b.size += len(value) 156 return nil 157 } 158 159 func (b *batch) Delete(key []byte) error { 160 b.writes = append(b.writes, keyvalue{common.CopyBytes(key), nil, true}) 161 b.size += 1 162 return nil 163 } 164 165 func (b *batch) ValueSize() int { 166 return b.size 167 } 168 169 func (b *batch) Write() error { 170 b.db.lock.Lock() 171 defer b.db.lock.Unlock() 172 173 for _, keyvalue := range b.writes { 174 if keyvalue.delete { 175 delete(b.db.db, string(keyvalue.key)) 176 continue 177 } 178 b.db.db[string(keyvalue.key)] = keyvalue.value 179 } 180 return nil 181 } 182 183 func (b *batch) Reset() { 184 b.writes = b.writes[:0] 185 b.size = 0 186 } 187 188 func (b *batch) Replay(w neatdb.Writer) error { 189 for _, keyvalue := range b.writes { 190 if keyvalue.delete { 191 if err := w.Delete(keyvalue.key); err != nil { 192 return err 193 } 194 continue 195 } 196 if err := w.Put(keyvalue.key, keyvalue.value); err != nil { 197 return err 198 } 199 } 200 return nil 201 } 202 203 type iterator struct { 204 inited bool 205 keys []string 206 values [][]byte 207 } 208 209 func (it *iterator) Next() bool { 210 211 if !it.inited { 212 it.inited = true 213 return len(it.keys) > 0 214 } 215 216 if len(it.keys) > 0 { 217 it.keys = it.keys[1:] 218 it.values = it.values[1:] 219 } 220 return len(it.keys) > 0 221 } 222 223 func (it *iterator) Error() error { 224 return nil 225 } 226 227 func (it *iterator) Key() []byte { 228 if len(it.keys) > 0 { 229 return []byte(it.keys[0]) 230 } 231 return nil 232 } 233 234 func (it *iterator) Value() []byte { 235 if len(it.values) > 0 { 236 return it.values[0] 237 } 238 return nil 239 } 240 241 func (it *iterator) Release() { 242 it.keys, it.values = nil, nil 243 }