Electroneum
cache.hpp
Go to the documentation of this file.
1 #ifndef CACHE_HPP
2 #define CACHE_HPP
3 
4 #include <cstddef>
5 #include <limits>
6 #include <memory>
7 #include <mutex>
8 #include <unordered_map>
9 #include "cache_policy.hpp"
10 
11 namespace caches
12 {
13 
14 // Base class for caching algorithms
15 template <typename Key, typename Value, typename Policy = NoCachePolicy<Key>>
17 {
18  public:
19 
20  using iterator = typename std::unordered_map<Key, Value>::iterator;
21 
22  using const_iterator =
23  typename std::unordered_map<Key, Value>::const_iterator;
24 
25  using operation_guard = typename std::lock_guard<std::mutex>;
26 
28  size_t max_size,
29  const Policy& policy = Policy())
30  : max_cache_size{max_size},
31  cache_policy(policy)
32  {
33  if (max_cache_size == 0)
34  {
35  max_cache_size = std::numeric_limits<size_t>::max();
36  }
37  }
38 
39  void Put(const Key& key, const Value& value)
40  {
42  auto elem_it = FindElem(key);
43 
44  if (elem_it == cache_items_map.end())
45  {
46  // add new element to the cache
47  if (Size() + 1 > max_cache_size)
48  {
49  auto disp_candidate_key = cache_policy.ReplCandidate();
50 
51  Erase(disp_candidate_key);
52  }
53 
54  Insert(key, value);
55  }
56  else
57  {
58  // update previous value
59  Update(key, value);
60  }
61  }
62 
63  bool Contains(const Key& key)
64  {
66  auto elem_it = FindElem(key);
67  return elem_it != cache_items_map.end();
68  }
69 
70  const Value& Get(const Key& key) const
71  {
73  auto elem_it = FindElem(key);
74 
75  if (elem_it == cache_items_map.end())
76  {
77  throw std::range_error{"No such element in the cache"};
78  }
79  cache_policy.Touch(key);
80 
81  return elem_it->second;
82  }
83 
84  const size_t Size() const
85  {
87 
88  return cache_items_map.size();
89  }
90 
91  // return a key of a displacement candidate
92  void Clear()
93  {
95 
96  cache_policy.Clear();
97  cache_items_map.clear();
98  }
99 
100  protected:
101 
102  void Insert(const Key& key, const Value& value)
103  {
104  cache_policy.Insert(key);
105  cache_items_map.emplace(std::make_pair(key, value));
106  }
107 
108  void Erase(const Key& key)
109  {
110  cache_policy.Erase(key);
111  cache_items_map.erase(key);
112  }
113 
114  void Update(const Key& key, const Value& value)
115  {
116  cache_policy.Touch(key);
117  cache_items_map[key] = value;
118  }
119 
120  const_iterator FindElem(const Key& key) const
121  {
122  return cache_items_map.find(key);
123  }
124 
125 
126 private:
127 
128  std::unordered_map<Key, Value> cache_items_map;
129 
130  mutable Policy cache_policy;
131  mutable std::mutex safe_op;
132 
134 
135 };
136 }
137 
138 #endif // CACHE_HPP
void Put(const Key &key, const Value &value)
Definition: cache.hpp:39
bool Contains(const Key &key)
Definition: cache.hpp:63
typename std::unordered_map< Key, Value >::const_iterator const_iterator
Definition: cache.hpp:23
const_iterator FindElem(const Key &key) const
Definition: cache.hpp:120
std::unordered_map< Key, Value > cache_items_map
Definition: cache.hpp:128
Definition: cache.hpp:16
void Erase(const Key &key)
Definition: cache.hpp:108
fixed_sized_cache(size_t max_size, const Policy &policy=Policy())
Definition: cache.hpp:27
typename std::unordered_map< Key, Value >::iterator iterator
Definition: cache.hpp:20
const size_t Size() const
Definition: cache.hpp:84
std::mutex safe_op
Definition: cache.hpp:131
Policy cache_policy
Definition: cache.hpp:130
void Clear()
Definition: cache.hpp:92
size_t max_cache_size
Definition: cache.hpp:133
Definition: cache.hpp:11
void Update(const Key &key, const Value &value)
Definition: cache.hpp:114
void Insert(const Key &key, const Value &value)
Definition: cache.hpp:102
typename std::lock_guard< std::mutex > operation_guard
Definition: cache.hpp:25
const Value & Get(const Key &key) const
Definition: cache.hpp:70