github.com/iotexproject/iotex-core@v1.14.1-rc1/db/trie/kvstoreimpl.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package trie 7 8 import ( 9 "context" 10 11 "github.com/pkg/errors" 12 "github.com/prometheus/client_golang/prometheus" 13 14 "github.com/iotexproject/iotex-core/db" 15 "github.com/iotexproject/iotex-core/pkg/lifecycle" 16 ) 17 18 var ( 19 _trieKeystoreMtc = prometheus.NewCounterVec( 20 prometheus.CounterOpts{ 21 Name: "iotex_trie_keystore", 22 Help: "IoTeX Trie Keystore", 23 }, 24 []string{"type"}, 25 ) 26 ) 27 28 func init() { 29 prometheus.MustRegister(_trieKeystoreMtc) 30 } 31 32 type ( 33 // kvStoreImpl defines a kvStore with fixed bucket and cache layer for trie. 34 // It may be used in other cases as well 35 kvStoreImpl struct { 36 lc lifecycle.Lifecycle 37 bucket string 38 dao db.KVStoreBasic 39 } 40 41 mKeyType [32]byte 42 43 inMemKVStore struct { 44 kvpairs map[mKeyType][]byte 45 } 46 ) 47 48 func castKeyType(k []byte) mKeyType { 49 var c mKeyType 50 copy(c[:], k) 51 52 return c 53 } 54 55 // NewMemKVStore defines a kv store in memory 56 func NewMemKVStore() KVStore { 57 return &inMemKVStore{kvpairs: map[mKeyType][]byte{}} 58 } 59 60 func (s *inMemKVStore) Start(ctx context.Context) error { 61 return nil 62 } 63 64 func (s *inMemKVStore) Stop(ctx context.Context) error { 65 return nil 66 } 67 68 func (s *inMemKVStore) Put(k []byte, v []byte) error { 69 dbKey := castKeyType(k) 70 s.kvpairs[dbKey] = v 71 72 return nil 73 } 74 75 func (s *inMemKVStore) Get(k []byte) ([]byte, error) { 76 dbKey := castKeyType(k) 77 v, ok := s.kvpairs[dbKey] 78 if !ok { 79 return nil, ErrNotExist 80 } 81 return v, nil 82 } 83 84 func (s *inMemKVStore) Delete(k []byte) error { 85 dbKey := castKeyType(k) 86 delete(s.kvpairs, dbKey) 87 88 return nil 89 } 90 91 func (s *inMemKVStore) Purge(tag, k []byte) error { 92 return nil 93 } 94 95 // NewKVStore creates a new KVStore 96 func NewKVStore(bucket string, dao db.KVStoreBasic) (KVStore, error) { 97 s := &kvStoreImpl{ 98 bucket: bucket, 99 dao: dao, 100 } 101 s.lc.Add(s.dao) 102 103 return s, nil 104 } 105 106 // Start starts the kv store 107 func (s *kvStoreImpl) Start(ctx context.Context) error { 108 return s.lc.OnStart(ctx) 109 } 110 111 // Stop stops the kv store 112 func (s *kvStoreImpl) Stop(ctx context.Context) error { 113 return s.lc.OnStop(ctx) 114 } 115 116 // Delete deletes key 117 func (s *kvStoreImpl) Delete(key []byte) error { 118 _trieKeystoreMtc.WithLabelValues("delete").Inc() 119 120 err := s.dao.Delete(s.bucket, key) 121 if errors.Cause(err) == db.ErrNotExist { 122 return errors.Wrap(ErrNotExist, err.Error()) 123 } 124 125 return err 126 } 127 128 // Put puts value for key 129 func (s *kvStoreImpl) Put(key, value []byte) error { 130 _trieKeystoreMtc.WithLabelValues("put").Inc() 131 return s.dao.Put(s.bucket, key, value) 132 } 133 134 // Get gets value of key 135 func (s *kvStoreImpl) Get(key []byte) ([]byte, error) { 136 _trieKeystoreMtc.WithLabelValues("get").Inc() 137 value, err := s.dao.Get(s.bucket, key) 138 if errors.Cause(err) == db.ErrNotExist { 139 return nil, errors.Wrapf(ErrNotExist, err.Error()) 140 } 141 142 return value, err 143 }