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.

152 lines
3.8 KiB

4 years ago
4 years ago
  1. package memory
  2. import (
  3. "bytes"
  4. "github.com/iden3/go-merkletree"
  5. "sort"
  6. )
  7. // Storage implements the db.Storage interface
  8. type Storage struct {
  9. prefix []byte
  10. kv merkletree.KvMap
  11. currentRoot *merkletree.Hash
  12. }
  13. // StorageTx implements the db.Tx interface
  14. type StorageTx struct {
  15. s *Storage
  16. kv merkletree.KvMap
  17. currentRoot *merkletree.Hash
  18. }
  19. // NewMemoryStorage returns a new Storage
  20. func NewMemoryStorage() *Storage {
  21. kvmap := make(merkletree.KvMap)
  22. return &Storage{[]byte{}, kvmap, nil}
  23. }
  24. // WithPrefix implements the method WithPrefix of the interface db.Storage
  25. func (m *Storage) WithPrefix(prefix []byte) merkletree.Storage {
  26. return &Storage{merkletree.Concat(m.prefix, prefix), m.kv, nil}
  27. }
  28. // NewTx implements the method NewTx of the interface db.Storage
  29. func (m *Storage) NewTx() (merkletree.Tx, error) {
  30. return &StorageTx{m, make(merkletree.KvMap), nil}, nil
  31. }
  32. // Get retrieves a value from a key in the db.Storage
  33. func (m *Storage) Get(key []byte) (*merkletree.Node, error) {
  34. if v, ok := m.kv.Get(merkletree.Concat(m.prefix, key[:])); ok {
  35. return &v, nil
  36. }
  37. return nil, merkletree.ErrNotFound
  38. }
  39. func (m *Storage) GetRoot() (*merkletree.Hash, error) {
  40. if m.currentRoot != nil {
  41. return m.currentRoot, nil
  42. }
  43. return nil, merkletree.ErrNotFound
  44. }
  45. // Iterate implements the method Iterate of the interface db.Storage
  46. func (m *Storage) Iterate(f func([]byte, *merkletree.Node) (bool, error)) error {
  47. kvs := make([]merkletree.KV, 0)
  48. for _, v := range m.kv {
  49. if len(v.K) < len(m.prefix) ||
  50. !bytes.Equal(v.K[:len(m.prefix)], m.prefix) {
  51. continue
  52. }
  53. localkey := v.K[len(m.prefix):]
  54. kvs = append(kvs, merkletree.KV{K: localkey, V: v.V})
  55. }
  56. sort.SliceStable(kvs, func(i, j int) bool {
  57. return bytes.Compare(kvs[i].K, kvs[j].K) < 0
  58. })
  59. for _, kv := range kvs {
  60. if cont, err := f(kv.K, &kv.V); err != nil {
  61. return err
  62. } else if !cont {
  63. break
  64. }
  65. }
  66. return nil
  67. }
  68. // Get implements the method Get of the interface db.Tx
  69. func (tx *StorageTx) Get(key []byte) (*merkletree.Node, error) {
  70. if v, ok := tx.kv.Get(merkletree.Concat(tx.s.prefix, key)); ok {
  71. return &v, nil
  72. }
  73. if v, ok := tx.s.kv.Get(merkletree.Concat(tx.s.prefix, key)); ok {
  74. return &v, nil
  75. }
  76. return nil, merkletree.ErrNotFound
  77. }
  78. // Put implements the method Put of the interface db.Tx
  79. func (tx *StorageTx) Put(k []byte, v *merkletree.Node) error {
  80. tx.kv.Put(merkletree.Concat(tx.s.prefix, k), *v)
  81. return nil
  82. }
  83. func (tx *StorageTx) GetRoot() (*merkletree.Hash, error) {
  84. if tx.currentRoot != nil {
  85. hash := merkletree.Hash{}
  86. copy(tx.currentRoot[:], hash[:])
  87. return &hash, nil
  88. }
  89. return nil, merkletree.ErrNotFound
  90. }
  91. // SetRoot sets a hash of merkle tree root in the interface db.Tx
  92. func (tx *StorageTx) SetRoot(hash *merkletree.Hash) error {
  93. root := &merkletree.Hash{}
  94. copy(root[:], hash[:])
  95. tx.currentRoot = root
  96. return nil
  97. }
  98. // Commit implements the method Commit of the interface db.Tx
  99. func (tx *StorageTx) Commit() error {
  100. for _, v := range tx.kv {
  101. tx.s.kv.Put(v.K, v.V)
  102. }
  103. tx.kv = nil
  104. return nil
  105. }
  106. // Add implements the method Add of the interface db.Tx
  107. func (tx *StorageTx) Add(atx merkletree.Tx) error {
  108. mstx := atx.(*StorageTx)
  109. for _, v := range mstx.kv {
  110. tx.kv.Put(v.K, v.V)
  111. }
  112. return nil
  113. }
  114. // Close implements the method Close of the interface db.Tx
  115. func (tx *StorageTx) Close() {
  116. tx.kv = nil
  117. }
  118. // Close implements the method Close of the interface db.Storage
  119. func (m *Storage) Close() {
  120. }
  121. // List implements the method List of the interface db.Storage
  122. func (m *Storage) List(limit int) ([]merkletree.KV, error) {
  123. ret := []merkletree.KV{}
  124. err := m.Iterate(func(key []byte, value *merkletree.Node) (bool, error) {
  125. ret = append(ret, merkletree.KV{K: merkletree.Clone(key), V: *value})
  126. if len(ret) == limit {
  127. return false, nil
  128. }
  129. return true, nil
  130. })
  131. return ret, err
  132. }