12 registerDBCreator(MemDBBackendStr, func(name string, dir string) (DB, error) {
13 return NewMemDB(), nil
22 func NewMemDB() *MemDB {
23 database := &MemDB{db: make(map[string][]byte)}
27 func (db *MemDB) Get(key []byte) []byte {
30 return db.db[string(key)]
33 func (db *MemDB) Set(key []byte, value []byte) {
36 db.db[string(key)] = value
39 func (db *MemDB) SetSync(key []byte, value []byte) {
42 db.db[string(key)] = value
45 func (db *MemDB) Delete(key []byte) {
48 delete(db.db, string(key))
51 func (db *MemDB) DeleteSync(key []byte) {
54 delete(db.db, string(key))
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
65 func (db *MemDB) Print() {
68 for key, value := range db.db {
69 fmt.Printf("[%X]:\t[%X]\n", []byte(key), value)
73 func (db *MemDB) Stats() map[string]string {
74 stats := make(map[string]string)
75 stats["database.type"] = "memDB"
79 type memDBIterator struct {
87 func newMemDBIterator() *memDBIterator {
88 return &memDBIterator{}
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{
105 func (it *memDBIterator) Next() bool {
106 if it.last >= len(it.keys)-1 {
113 func (it *memDBIterator) Key() []byte {
117 return []byte(it.keys[it.last])
120 func (it *memDBIterator) Value() []byte {
121 return it.db.Get(it.Key())
124 func (it *memDBIterator) Seek(point []byte) bool {
125 for i, key := range it.keys {
126 if key >= string(point) {
134 func (it *memDBIterator) Release() {
139 func (it *memDBIterator) Error() error {
143 func (db *MemDB) Iterator() Iterator {
144 return db.IteratorPrefix([]byte{})
147 func (db *MemDB) IteratorPrefix(prefix []byte) Iterator {
148 it := newMemDBIterator()
153 defer db.mtx.Unlock()
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)
161 // and we need to sort them
162 sort.Strings(it.keys)
166 func (db *MemDB) IteratorPrefixWithStart(Prefix, start []byte) Iterator {
168 defer db.mtx.Unlock()
170 keys := db.getSortedKeys(start)
171 return newMemDBIteratorWithArgs(db, keys, start)
174 func (db *MemDB) NewBatch() Batch {
175 return &memDBBatch{db, nil}
178 func (db *MemDB) getSortedKeys(start []byte) []string {
180 for key := range db.db {
181 if bytes.Compare([]byte(key), start) < 0 {
184 keys = append(keys, key)
190 //--------------------------------------------------------------------------------
192 type memDBBatch struct {
204 type operation struct {
210 func (mBatch *memDBBatch) Set(key, value []byte) {
211 mBatch.ops = append(mBatch.ops, operation{opTypeSet, key, value})
214 func (mBatch *memDBBatch) Delete(key []byte) {
215 mBatch.ops = append(mBatch.ops, operation{opTypeDelete, key, nil})
218 func (mBatch *memDBBatch) Write() {
220 defer mBatch.db.mtx.Unlock()
222 for _, op := range mBatch.ops {
223 if op.opType == opTypeSet {
224 mBatch.db.db[string(op.key)] = op.value
225 } else if op.opType == opTypeDelete {
226 delete(mBatch.db.db, string(op.key))