hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
cache.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_CACHE_HPP
7 #define IROHA_CACHE_HPP
8 
10 
11 #include <unordered_map>
12 
13 #include "common/ring_buffer.hpp"
14 
15 namespace iroha {
16  namespace cache {
17 
24  template <typename KeyType,
25  typename ValueType,
26  typename KeyHash = std::hash<KeyType>,
27  size_t Count = 20000ull>
28  class Cache final
29  : public AbstractCache<KeyType,
30  ValueType,
31  Cache<KeyType, ValueType, KeyHash, Count>> {
32  using HashType =
33  decltype(std::declval<KeyHash>()(std::declval<KeyType>()));
34 
35  struct KeyAndValue {
36  HashType hash;
37  ValueType value;
38 
39  KeyAndValue() = delete;
40  KeyAndValue(KeyAndValue const &) = delete;
41  KeyAndValue(HashType h, ValueType const &v) : hash(h), value(v) {}
42 
43  KeyAndValue &operator=(KeyAndValue const &) = delete;
44  };
45 
47  using ValueHandle = typename ValuesBuffer::Handle;
48  using KeyValuesBuffer = std::unordered_map<HashType, ValueHandle>;
49 
50  inline HashType toHash(KeyType const &key) const {
51  return KeyHash()(key);
52  }
53 
54  public:
55  Cache() {}
56 
57  uint32_t getIndexSizeHighImpl() const {
58  return Count;
59  }
60 
61  uint32_t getCacheItemCountImpl() const {
62  return static_cast<uint32_t>(keys_.size());
63  }
64 
65  void addItemImpl(const KeyType &key, const ValueType &value) {
66  auto const hash = toHash(key);
67  auto it = keys_.find(hash);
68  if (keys_.end() == it) {
69  values_.push(
70  [&](ValueHandle h, KeyAndValue const & /*value*/) {
71  this->keys_[hash] = h;
72  },
73  [&](ValueHandle h, KeyAndValue const &stored_value) {
74  BOOST_ASSERT_MSG(
75  this->keys_.end() != this->keys_.find(stored_value.hash),
76  "keys_ must contain item, which we want to remove!");
77  this->keys_.erase(stored_value.hash);
78  },
79  hash,
80  value);
81  } else {
82  auto &stored_value = values_.getItem(it->second);
83  stored_value.value = value;
84  }
85  }
86 
87  boost::optional<ValueType> findItemImpl(const KeyType &key) const {
88  auto const hash = toHash(key);
89  auto it = keys_.find(hash);
90 
91  if (keys_.end() == it) {
92  return boost::none;
93  } else {
94  return values_.getItem(it->second).value;
95  }
96  }
97 
98  private:
99  KeyValuesBuffer keys_;
100  ValuesBuffer values_;
101  };
102  } // namespace cache
103 } // namespace iroha
104 
105 #endif // IROHA_CACHE_HPP
Cache()
Definition: cache.hpp:55
boost::optional< ValueType > findItemImpl(const KeyType &key) const
Definition: cache.hpp:87
uint32_t getCacheItemCountImpl() const
Definition: cache.hpp:61
Definition: block_query.hpp:15
uint32_t getIndexSizeHighImpl() const
Definition: cache.hpp:57
hash256_t hash(const T &pb)
Definition: pb_common.hpp:43
Definition: abstract_cache.hpp:26
void addItemImpl(const KeyType &key, const ValueType &value)
Definition: cache.hpp:65
Definition: cache.hpp:28
size_t Handle
Definition: ring_buffer.hpp:21