|
@ -26,14 +26,16 @@ func NewMemDB() *MemDB { |
|
|
return database |
|
|
return database |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Get(key []byte) []byte { |
|
|
func (db *MemDB) Get(key []byte) []byte { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
|
key = nonNilBytes(key) |
|
|
key = nonNilBytes(key) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return db.db[string(key)] |
|
|
return db.db[string(key)] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Has(key []byte) bool { |
|
|
func (db *MemDB) Has(key []byte) bool { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -43,6 +45,7 @@ func (db *MemDB) Has(key []byte) bool { |
|
|
return ok |
|
|
return ok |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Set(key []byte, value []byte) { |
|
|
func (db *MemDB) Set(key []byte, value []byte) { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -50,6 +53,7 @@ func (db *MemDB) Set(key []byte, value []byte) { |
|
|
db.SetNoLock(key, value) |
|
|
db.SetNoLock(key, value) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) SetSync(key []byte, value []byte) { |
|
|
func (db *MemDB) SetSync(key []byte, value []byte) { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -57,7 +61,7 @@ func (db *MemDB) SetSync(key []byte, value []byte) { |
|
|
db.SetNoLock(key, value) |
|
|
db.SetNoLock(key, value) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// NOTE: Implements atomicSetDeleter
|
|
|
|
|
|
|
|
|
// Implements atomicSetDeleter.
|
|
|
func (db *MemDB) SetNoLock(key []byte, value []byte) { |
|
|
func (db *MemDB) SetNoLock(key []byte, value []byte) { |
|
|
key = nonNilBytes(key) |
|
|
key = nonNilBytes(key) |
|
|
value = nonNilBytes(value) |
|
|
value = nonNilBytes(value) |
|
@ -65,6 +69,7 @@ func (db *MemDB) SetNoLock(key []byte, value []byte) { |
|
|
db.db[string(key)] = value |
|
|
db.db[string(key)] = value |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Delete(key []byte) { |
|
|
func (db *MemDB) Delete(key []byte) { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -72,6 +77,7 @@ func (db *MemDB) Delete(key []byte) { |
|
|
db.DeleteNoLock(key) |
|
|
db.DeleteNoLock(key) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) DeleteSync(key []byte) { |
|
|
func (db *MemDB) DeleteSync(key []byte) { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -79,13 +85,14 @@ func (db *MemDB) DeleteSync(key []byte) { |
|
|
db.DeleteNoLock(key) |
|
|
db.DeleteNoLock(key) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// NOTE: Implements atomicSetDeleter
|
|
|
|
|
|
|
|
|
// Implements atomicSetDeleter.
|
|
|
func (db *MemDB) DeleteNoLock(key []byte) { |
|
|
func (db *MemDB) DeleteNoLock(key []byte) { |
|
|
key = nonNilBytes(key) |
|
|
key = nonNilBytes(key) |
|
|
|
|
|
|
|
|
delete(db.db, string(key)) |
|
|
delete(db.db, string(key)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Close() { |
|
|
func (db *MemDB) Close() { |
|
|
// Close is a noop since for an in-memory
|
|
|
// Close is a noop since for an in-memory
|
|
|
// database, we don't have a destination
|
|
|
// database, we don't have a destination
|
|
@ -94,6 +101,7 @@ func (db *MemDB) Close() { |
|
|
// See the discussion in https://github.com/tendermint/tmlibs/pull/56
|
|
|
// See the discussion in https://github.com/tendermint/tmlibs/pull/56
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Print() { |
|
|
func (db *MemDB) Print() { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -103,6 +111,7 @@ func (db *MemDB) Print() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Stats() map[string]string { |
|
|
func (db *MemDB) Stats() map[string]string { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -113,6 +122,10 @@ func (db *MemDB) Stats() map[string]string { |
|
|
return stats |
|
|
return stats |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
|
// Batch
|
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) NewBatch() Batch { |
|
|
func (db *MemDB) NewBatch() Batch { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -125,7 +138,9 @@ func (db *MemDB) Mutex() *sync.Mutex { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
//----------------------------------------
|
|
|
|
|
|
// Iterator
|
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) Iterator(start, end []byte) Iterator { |
|
|
func (db *MemDB) Iterator(start, end []byte) Iterator { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -134,6 +149,7 @@ func (db *MemDB) Iterator(start, end []byte) Iterator { |
|
|
return newMemDBIterator(db, keys, start, end) |
|
|
return newMemDBIterator(db, keys, start, end) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements DB.
|
|
|
func (db *MemDB) ReverseIterator(start, end []byte) Iterator { |
|
|
func (db *MemDB) ReverseIterator(start, end []byte) Iterator { |
|
|
db.mtx.Lock() |
|
|
db.mtx.Lock() |
|
|
defer db.mtx.Unlock() |
|
|
defer db.mtx.Unlock() |
|
@ -142,25 +158,6 @@ func (db *MemDB) ReverseIterator(start, end []byte) Iterator { |
|
|
return newMemDBIterator(db, keys, start, end) |
|
|
return newMemDBIterator(db, keys, start, end) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (db *MemDB) getSortedKeys(start, end []byte, reverse bool) []string { |
|
|
|
|
|
keys := []string{} |
|
|
|
|
|
for key, _ := range db.db { |
|
|
|
|
|
if IsKeyInDomain([]byte(key), start, end, false) { |
|
|
|
|
|
keys = append(keys, key) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
sort.Strings(keys) |
|
|
|
|
|
if reverse { |
|
|
|
|
|
nkeys := len(keys) |
|
|
|
|
|
for i := 0; i < nkeys/2; i++ { |
|
|
|
|
|
keys[i] = keys[nkeys-i-1] |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return keys |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var _ Iterator = (*memDBIterator)(nil) |
|
|
|
|
|
|
|
|
|
|
|
// We need a copy of all of the keys.
|
|
|
// We need a copy of all of the keys.
|
|
|
// Not the best, but probably not a bottleneck depending.
|
|
|
// Not the best, but probably not a bottleneck depending.
|
|
|
type memDBIterator struct { |
|
|
type memDBIterator struct { |
|
@ -171,6 +168,8 @@ type memDBIterator struct { |
|
|
end []byte |
|
|
end []byte |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var _ Iterator = (*memDBIterator)(nil) |
|
|
|
|
|
|
|
|
// Keys is expected to be in reverse order for reverse iterators.
|
|
|
// Keys is expected to be in reverse order for reverse iterators.
|
|
|
func newMemDBIterator(db DB, keys []string, start, end []byte) *memDBIterator { |
|
|
func newMemDBIterator(db DB, keys []string, start, end []byte) *memDBIterator { |
|
|
return &memDBIterator{ |
|
|
return &memDBIterator{ |
|
@ -182,30 +181,36 @@ func newMemDBIterator(db DB, keys []string, start, end []byte) *memDBIterator { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements Iterator.
|
|
|
func (itr *memDBIterator) Domain() ([]byte, []byte) { |
|
|
func (itr *memDBIterator) Domain() ([]byte, []byte) { |
|
|
return itr.start, itr.end |
|
|
return itr.start, itr.end |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements Iterator.
|
|
|
func (itr *memDBIterator) Valid() bool { |
|
|
func (itr *memDBIterator) Valid() bool { |
|
|
return 0 <= itr.cur && itr.cur < len(itr.keys) |
|
|
return 0 <= itr.cur && itr.cur < len(itr.keys) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements Iterator.
|
|
|
func (itr *memDBIterator) Next() { |
|
|
func (itr *memDBIterator) Next() { |
|
|
itr.assertIsValid() |
|
|
itr.assertIsValid() |
|
|
itr.cur++ |
|
|
itr.cur++ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements Iterator.
|
|
|
func (itr *memDBIterator) Key() []byte { |
|
|
func (itr *memDBIterator) Key() []byte { |
|
|
itr.assertIsValid() |
|
|
itr.assertIsValid() |
|
|
return []byte(itr.keys[itr.cur]) |
|
|
return []byte(itr.keys[itr.cur]) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements Iterator.
|
|
|
func (itr *memDBIterator) Value() []byte { |
|
|
func (itr *memDBIterator) Value() []byte { |
|
|
itr.assertIsValid() |
|
|
itr.assertIsValid() |
|
|
key := []byte(itr.keys[itr.cur]) |
|
|
key := []byte(itr.keys[itr.cur]) |
|
|
return itr.db.Get(key) |
|
|
return itr.db.Get(key) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Implements Iterator.
|
|
|
func (itr *memDBIterator) Close() { |
|
|
func (itr *memDBIterator) Close() { |
|
|
itr.keys = nil |
|
|
itr.keys = nil |
|
|
itr.db = nil |
|
|
itr.db = nil |
|
@ -215,4 +220,24 @@ func (itr *memDBIterator) assertIsValid() { |
|
|
if !itr.Valid() { |
|
|
if !itr.Valid() { |
|
|
panic("memDBIterator is invalid") |
|
|
panic("memDBIterator is invalid") |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
|
|
// Misc.
|
|
|
|
|
|
|
|
|
|
|
|
func (db *MemDB) getSortedKeys(start, end []byte, reverse bool) []string { |
|
|
|
|
|
keys := []string{} |
|
|
|
|
|
for key, _ := range db.db { |
|
|
|
|
|
if IsKeyInDomain([]byte(key), start, end, false) { |
|
|
|
|
|
keys = append(keys, key) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
sort.Strings(keys) |
|
|
|
|
|
if reverse { |
|
|
|
|
|
nkeys := len(keys) |
|
|
|
|
|
for i := 0; i < nkeys/2; i++ { |
|
|
|
|
|
keys[i] = keys[nkeys-i-1] |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return keys |
|
|
|
|
|
} |