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.

217 lines
4.0 KiB

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