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.

199 lines
3.5 KiB

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