9 "github.com/vapor/database/db"
13 db.RegisterDBCreator(db.MemDBBackendStr, func(name string, dir string) (db.DB, error) {
14 return NewMemDB(), nil
23 func NewMemDB() *MemDB {
24 database := &MemDB{db: make(map[string][]byte)}
28 func (db *MemDB) Get(key []byte) []byte {
31 return db.db[string(key)]
34 func (db *MemDB) Set(key []byte, value []byte) {
37 db.db[string(key)] = value
40 func (db *MemDB) SetSync(key []byte, value []byte) {
43 db.db[string(key)] = value
46 func (db *MemDB) Delete(key []byte) {
49 delete(db.db, string(key))
52 func (db *MemDB) DeleteSync(key []byte) {
55 delete(db.db, string(key))
58 func (db *MemDB) Close() {
59 // Close is a noop since for an in-memory
60 // database, we don't have a destination
61 // to flush contents to nor do we want
62 // any data loss on invoking Close()
63 // See the discussion in https://github.com/tendermint/tmlibs/pull/56
66 func (db *MemDB) Print() {
69 for key, value := range db.db {
70 fmt.Printf("[%X]:\t[%X]\n", []byte(key), value)
74 func (db *MemDB) Stats() map[string]string {
75 stats := make(map[string]string)
76 stats["database.type"] = "memDB"
80 type memDBIterator struct {
86 func newMemDBIterator() *memDBIterator {
87 return &memDBIterator{}
90 func (it *memDBIterator) Next() bool {
91 if it.last >= len(it.keys)-1 {
98 func (it *memDBIterator) Key() []byte {
99 return []byte(it.keys[it.last])
102 func (it *memDBIterator) Value() []byte {
103 return it.db.Get(it.Key())
106 func (it *memDBIterator) Seek(point []byte) bool {
107 for i, key := range it.keys {
108 if key >= string(point) {
116 func (it *memDBIterator) Release() {
121 func (it *memDBIterator) Error() error {
125 func (db *MemDB) Iterator() db.Iterator {
126 return db.IteratorPrefix([]byte{})
129 func (db *MemDB) IteratorPrefix(prefix []byte) db.Iterator {
130 it := newMemDBIterator()
135 defer db.mtx.Unlock()
137 // unfortunately we need a copy of all of the keys
138 for key, _ := range db.db {
139 if strings.HasPrefix(key, string(prefix)) {
140 it.keys = append(it.keys, key)
143 // and we need to sort them
144 sort.Strings(it.keys)
148 func (db *MemDB) NewBatch() db.Batch {
149 return &memDBBatch{db, nil}
152 //--------------------------------------------------------------------------------
154 type memDBBatch struct {
166 type operation struct {
172 func (mBatch *memDBBatch) Set(key, value []byte) {
173 mBatch.ops = append(mBatch.ops, operation{opTypeSet, key, value})
176 func (mBatch *memDBBatch) Delete(key []byte) {
177 mBatch.ops = append(mBatch.ops, operation{opTypeDelete, key, nil})
180 func (mBatch *memDBBatch) Write() {
182 defer mBatch.db.mtx.Unlock()
184 for _, op := range mBatch.ops {
185 if op.opType == opTypeSet {
186 mBatch.db.db[string(op.key)] = op.value
187 } else if op.opType == opTypeDelete {
188 delete(mBatch.db.db, string(op.key))