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.

384 lines
6.8 KiB

  1. /**
  2. * @file
  3. * @copyright defined in aergo/LICENSE.txt
  4. */
  5. package db
  6. import (
  7. "bytes"
  8. "container/list"
  9. "encoding/gob"
  10. "os"
  11. "path"
  12. "sort"
  13. "sync"
  14. )
  15. // This function is always called first
  16. func init() {
  17. dbConstructor := func(dir string) (DB, error) {
  18. return newMemoryDB(dir)
  19. }
  20. registorDBConstructor(MemoryImpl, dbConstructor)
  21. }
  22. func newMemoryDB(dir string) (DB, error) {
  23. var db map[string][]byte
  24. filePath := path.Join(dir, "database")
  25. file, err := os.Open(filePath)
  26. if err == nil {
  27. decoder := gob.NewDecoder(file) //
  28. err = decoder.Decode(&db)
  29. if err != nil {
  30. return nil, err
  31. }
  32. }
  33. file.Close()
  34. if db == nil {
  35. db = make(map[string][]byte)
  36. }
  37. database := &memorydb{
  38. db: db,
  39. dir: filePath,
  40. }
  41. return database, nil
  42. }
  43. //=========================================================
  44. // DB Implementation
  45. //=========================================================
  46. // Enforce database and transaction implements interfaces
  47. var _ DB = (*memorydb)(nil)
  48. type memorydb struct {
  49. lock sync.Mutex
  50. db map[string][]byte
  51. dir string
  52. }
  53. func (db *memorydb) Type() string {
  54. return "memorydb"
  55. }
  56. func (db *memorydb) Set(key, value []byte) {
  57. db.lock.Lock()
  58. defer db.lock.Unlock()
  59. key = convNilToBytes(key)
  60. value = convNilToBytes(value)
  61. db.db[string(key)] = value
  62. }
  63. func (db *memorydb) Delete(key []byte) {
  64. db.lock.Lock()
  65. defer db.lock.Unlock()
  66. key = convNilToBytes(key)
  67. delete(db.db, string(key))
  68. }
  69. func (db *memorydb) Get(key []byte) []byte {
  70. db.lock.Lock()
  71. defer db.lock.Unlock()
  72. key = convNilToBytes(key)
  73. return db.db[string(key)]
  74. }
  75. func (db *memorydb) Exist(key []byte) bool {
  76. db.lock.Lock()
  77. defer db.lock.Unlock()
  78. key = convNilToBytes(key)
  79. _, ok := db.db[string(key)]
  80. return ok
  81. }
  82. func (db *memorydb) Close() {
  83. db.lock.Lock()
  84. defer db.lock.Unlock()
  85. file, err := os.OpenFile(db.dir, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
  86. if err == nil {
  87. encoder := gob.NewEncoder(file)
  88. encoder.Encode(db.db)
  89. }
  90. file.Close()
  91. }
  92. func (db *memorydb) NewTx() Transaction {
  93. return &memoryTransaction{
  94. db: db,
  95. opList: list.New(),
  96. isDiscard: false,
  97. isCommit: false,
  98. }
  99. }
  100. func (db *memorydb) NewBulk() Bulk {
  101. return &memoryBulk{
  102. db: db,
  103. opList: list.New(),
  104. isDiscard: false,
  105. isCommit: false,
  106. }
  107. }
  108. //=========================================================
  109. // Transaction Implementation
  110. //=========================================================
  111. type memoryTransaction struct {
  112. txLock sync.Mutex
  113. db *memorydb
  114. opList *list.List
  115. isDiscard bool
  116. isCommit bool
  117. }
  118. type txOp struct {
  119. isSet bool
  120. key []byte
  121. value []byte
  122. }
  123. func (transaction *memoryTransaction) Set(key, value []byte) {
  124. transaction.txLock.Lock()
  125. defer transaction.txLock.Unlock()
  126. key = convNilToBytes(key)
  127. value = convNilToBytes(value)
  128. transaction.opList.PushBack(&txOp{true, key, value})
  129. }
  130. func (transaction *memoryTransaction) Delete(key []byte) {
  131. transaction.txLock.Lock()
  132. defer transaction.txLock.Unlock()
  133. key = convNilToBytes(key)
  134. transaction.opList.PushBack(&txOp{false, key, nil})
  135. }
  136. func (transaction *memoryTransaction) Commit() {
  137. transaction.txLock.Lock()
  138. defer transaction.txLock.Unlock()
  139. if transaction.isDiscard {
  140. panic("Commit after dicard tx is not allowed")
  141. } else if transaction.isCommit {
  142. panic("Commit occures two times")
  143. }
  144. db := transaction.db
  145. db.lock.Lock()
  146. defer db.lock.Unlock()
  147. for e := transaction.opList.Front(); e != nil; e = e.Next() {
  148. op := e.Value.(*txOp)
  149. if op.isSet {
  150. db.db[string(op.key)] = op.value
  151. } else {
  152. delete(db.db, string(op.key))
  153. }
  154. }
  155. transaction.isCommit = true
  156. }
  157. func (transaction *memoryTransaction) Discard() {
  158. transaction.txLock.Lock()
  159. defer transaction.txLock.Unlock()
  160. transaction.isDiscard = true
  161. }
  162. //=========================================================
  163. // Bulk Implementation
  164. //=========================================================
  165. type memoryBulk struct {
  166. txLock sync.Mutex
  167. db *memorydb
  168. opList *list.List
  169. isDiscard bool
  170. isCommit bool
  171. }
  172. func (bulk *memoryBulk) Set(key, value []byte) {
  173. bulk.txLock.Lock()
  174. defer bulk.txLock.Unlock()
  175. key = convNilToBytes(key)
  176. value = convNilToBytes(value)
  177. bulk.opList.PushBack(&txOp{true, key, value})
  178. }
  179. func (bulk *memoryBulk) Delete(key []byte) {
  180. bulk.txLock.Lock()
  181. defer bulk.txLock.Unlock()
  182. key = convNilToBytes(key)
  183. bulk.opList.PushBack(&txOp{false, key, nil})
  184. }
  185. func (bulk *memoryBulk) Flush() {
  186. bulk.txLock.Lock()
  187. defer bulk.txLock.Unlock()
  188. if bulk.isDiscard {
  189. panic("Commit after dicard tx is not allowed")
  190. } else if bulk.isCommit {
  191. panic("Commit occures two times")
  192. }
  193. db := bulk.db
  194. db.lock.Lock()
  195. defer db.lock.Unlock()
  196. for e := bulk.opList.Front(); e != nil; e = e.Next() {
  197. op := e.Value.(*txOp)
  198. if op.isSet {
  199. db.db[string(op.key)] = op.value
  200. } else {
  201. delete(db.db, string(op.key))
  202. }
  203. }
  204. bulk.isCommit = true
  205. }
  206. func (bulk *memoryBulk) DiscardLast() {
  207. bulk.txLock.Lock()
  208. defer bulk.txLock.Unlock()
  209. bulk.isDiscard = true
  210. }
  211. //=========================================================
  212. // Iterator Implementation
  213. //=========================================================
  214. type memoryIterator struct {
  215. start []byte
  216. end []byte
  217. reverse bool
  218. keys []string
  219. isInvalid bool
  220. cursor int
  221. db *memorydb
  222. }
  223. func isKeyInRange(key []byte, start []byte, end []byte, reverse bool) bool {
  224. if reverse {
  225. if start != nil && bytes.Compare(start, key) < 0 {
  226. return false
  227. }
  228. if end != nil && bytes.Compare(key, end) <= 0 {
  229. return false
  230. }
  231. return true
  232. }
  233. if bytes.Compare(key, start) < 0 {
  234. return false
  235. }
  236. if end != nil && bytes.Compare(end, key) <= 0 {
  237. return false
  238. }
  239. return true
  240. }
  241. func (db *memorydb) Iterator(start, end []byte) Iterator {
  242. db.lock.Lock()
  243. defer db.lock.Unlock()
  244. var reverse bool
  245. // if end is bigger then start, then reverse order
  246. if bytes.Compare(start, end) == 1 {
  247. reverse = true
  248. } else {
  249. reverse = false
  250. }
  251. var keys sort.StringSlice
  252. for key := range db.db {
  253. if isKeyInRange([]byte(key), start, end, reverse) {
  254. keys = append(keys, key)
  255. }
  256. }
  257. if reverse {
  258. sort.Sort(sort.Reverse(keys))
  259. } else {
  260. sort.Strings(keys)
  261. }
  262. return &memoryIterator{
  263. start: start,
  264. end: end,
  265. reverse: reverse,
  266. isInvalid: false,
  267. keys: keys,
  268. cursor: 0,
  269. db: db,
  270. }
  271. }
  272. func (iter *memoryIterator) Next() {
  273. if !iter.Valid() {
  274. panic("Iterator is Invalid")
  275. }
  276. iter.cursor++
  277. }
  278. func (iter *memoryIterator) Valid() bool {
  279. // Once invalid, forever invalid.
  280. if iter.isInvalid {
  281. return false
  282. }
  283. return 0 <= iter.cursor && iter.cursor < len(iter.keys)
  284. }
  285. func (iter *memoryIterator) Key() (key []byte) {
  286. if !iter.Valid() {
  287. panic("Iterator is Invalid")
  288. }
  289. return []byte(iter.keys[iter.cursor])
  290. }
  291. func (iter *memoryIterator) Value() (value []byte) {
  292. if !iter.Valid() {
  293. panic("Iterator is Invalid")
  294. }
  295. key := []byte(iter.keys[iter.cursor])
  296. return iter.db.Get(key)
  297. }