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.

127 lines
2.9 KiB

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