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.

132 lines
3.0 KiB

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