You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

251 lines
4.7 KiB

9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
7 years ago
  1. package db
  2. import (
  3. "fmt"
  4. "sort"
  5. "sync"
  6. )
  7. func init() {
  8. registerDBCreator(MemDBBackend, func(name string, dir string) (DB, error) {
  9. return NewMemDB(), nil
  10. }, false)
  11. }
  12. var _ DB = (*MemDB)(nil)
  13. type MemDB struct {
  14. mtx sync.Mutex
  15. db map[string][]byte
  16. }
  17. func NewMemDB() *MemDB {
  18. database := &MemDB{
  19. db: make(map[string][]byte),
  20. }
  21. return database
  22. }
  23. // Implements atomicSetDeleter.
  24. func (db *MemDB) Mutex() *sync.Mutex {
  25. return &(db.mtx)
  26. }
  27. // Implements DB.
  28. func (db *MemDB) Get(key []byte) []byte {
  29. db.mtx.Lock()
  30. defer db.mtx.Unlock()
  31. key = nonNilBytes(key)
  32. return db.db[string(key)]
  33. }
  34. // Implements DB.
  35. func (db *MemDB) Has(key []byte) bool {
  36. db.mtx.Lock()
  37. defer db.mtx.Unlock()
  38. key = nonNilBytes(key)
  39. _, ok := db.db[string(key)]
  40. return ok
  41. }
  42. // Implements DB.
  43. func (db *MemDB) Set(key []byte, value []byte) {
  44. db.mtx.Lock()
  45. defer db.mtx.Unlock()
  46. db.SetNoLock(key, value)
  47. }
  48. // Implements DB.
  49. func (db *MemDB) SetSync(key []byte, value []byte) {
  50. db.mtx.Lock()
  51. defer db.mtx.Unlock()
  52. db.SetNoLock(key, value)
  53. }
  54. // Implements atomicSetDeleter.
  55. func (db *MemDB) SetNoLock(key []byte, value []byte) {
  56. db.SetNoLockSync(key, value)
  57. }
  58. // Implements atomicSetDeleter.
  59. func (db *MemDB) SetNoLockSync(key []byte, value []byte) {
  60. key = nonNilBytes(key)
  61. value = nonNilBytes(value)
  62. db.db[string(key)] = value
  63. }
  64. // Implements DB.
  65. func (db *MemDB) Delete(key []byte) {
  66. db.mtx.Lock()
  67. defer db.mtx.Unlock()
  68. db.DeleteNoLock(key)
  69. }
  70. // Implements DB.
  71. func (db *MemDB) DeleteSync(key []byte) {
  72. db.mtx.Lock()
  73. defer db.mtx.Unlock()
  74. db.DeleteNoLock(key)
  75. }
  76. // Implements atomicSetDeleter.
  77. func (db *MemDB) DeleteNoLock(key []byte) {
  78. db.DeleteNoLockSync(key)
  79. }
  80. // Implements atomicSetDeleter.
  81. func (db *MemDB) DeleteNoLockSync(key []byte) {
  82. key = nonNilBytes(key)
  83. delete(db.db, string(key))
  84. }
  85. // Implements DB.
  86. func (db *MemDB) Close() {
  87. // Close is a noop since for an in-memory
  88. // database, we don't have a destination
  89. // to flush contents to nor do we want
  90. // any data loss on invoking Close()
  91. // See the discussion in https://github.com/tendermint/tmlibs/pull/56
  92. }
  93. // Implements DB.
  94. func (db *MemDB) Print() {
  95. db.mtx.Lock()
  96. defer db.mtx.Unlock()
  97. for key, value := range db.db {
  98. fmt.Printf("[%X]:\t[%X]\n", []byte(key), value)
  99. }
  100. }
  101. // Implements DB.
  102. func (db *MemDB) Stats() map[string]string {
  103. db.mtx.Lock()
  104. defer db.mtx.Unlock()
  105. stats := make(map[string]string)
  106. stats["database.type"] = "memDB"
  107. stats["database.size"] = fmt.Sprintf("%d", len(db.db))
  108. return stats
  109. }
  110. // Implements DB.
  111. func (db *MemDB) NewBatch() Batch {
  112. db.mtx.Lock()
  113. defer db.mtx.Unlock()
  114. return &memBatch{db, nil}
  115. }
  116. //----------------------------------------
  117. // Iterator
  118. // Implements DB.
  119. func (db *MemDB) Iterator(start, end []byte) Iterator {
  120. db.mtx.Lock()
  121. defer db.mtx.Unlock()
  122. keys := db.getSortedKeys(start, end, false)
  123. return newMemDBIterator(db, keys, start, end)
  124. }
  125. // Implements DB.
  126. func (db *MemDB) ReverseIterator(start, end []byte) Iterator {
  127. db.mtx.Lock()
  128. defer db.mtx.Unlock()
  129. keys := db.getSortedKeys(end, start, true)
  130. return newMemDBIterator(db, keys, start, end)
  131. }
  132. // We need a copy of all of the keys.
  133. // Not the best, but probably not a bottleneck depending.
  134. type memDBIterator struct {
  135. db DB
  136. cur int
  137. keys []string
  138. start []byte
  139. end []byte
  140. }
  141. var _ Iterator = (*memDBIterator)(nil)
  142. // Keys is expected to be in reverse order for reverse iterators.
  143. func newMemDBIterator(db DB, keys []string, start, end []byte) *memDBIterator {
  144. return &memDBIterator{
  145. db: db,
  146. cur: 0,
  147. keys: keys,
  148. start: start,
  149. end: end,
  150. }
  151. }
  152. // Implements Iterator.
  153. func (itr *memDBIterator) Domain() ([]byte, []byte) {
  154. return itr.start, itr.end
  155. }
  156. // Implements Iterator.
  157. func (itr *memDBIterator) Valid() bool {
  158. return 0 <= itr.cur && itr.cur < len(itr.keys)
  159. }
  160. // Implements Iterator.
  161. func (itr *memDBIterator) Next() {
  162. itr.assertIsValid()
  163. itr.cur++
  164. }
  165. // Implements Iterator.
  166. func (itr *memDBIterator) Key() []byte {
  167. itr.assertIsValid()
  168. return []byte(itr.keys[itr.cur])
  169. }
  170. // Implements Iterator.
  171. func (itr *memDBIterator) Value() []byte {
  172. itr.assertIsValid()
  173. key := []byte(itr.keys[itr.cur])
  174. return itr.db.Get(key)
  175. }
  176. // Implements Iterator.
  177. func (itr *memDBIterator) Close() {
  178. itr.keys = nil
  179. itr.db = nil
  180. }
  181. func (itr *memDBIterator) assertIsValid() {
  182. if !itr.Valid() {
  183. panic("memDBIterator is invalid")
  184. }
  185. }
  186. //----------------------------------------
  187. // Misc.
  188. func (db *MemDB) getSortedKeys(start, end []byte, reverse bool) []string {
  189. keys := []string{}
  190. for key, _ := range db.db {
  191. if IsKeyInDomain([]byte(key), start, end, false) {
  192. keys = append(keys, key)
  193. }
  194. }
  195. sort.Strings(keys)
  196. if reverse {
  197. nkeys := len(keys)
  198. for i := 0; i < nkeys/2; i++ {
  199. keys[i] = keys[nkeys-i-1]
  200. }
  201. }
  202. return keys
  203. }