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  }