Cachemere
Modular Caching Library for C++
cache.h
1 #ifndef CACHEMERE_CACHE_H
2 #define CACHEMERE_CACHE_H
3 
4 #include <cstdint>
5 #include <functional>
6 #include <memory>
7 #include <mutex>
8 #include <optional>
9 #include <vector>
10 
11 #include <absl/container/node_hash_map.h>
12 #include <absl/hash/hash.h>
13 
14 #ifdef _WIN32
15 # pragma warning(push)
16 # pragma warning(disable : 4244)
17 # pragma warning(disable : 4018)
18 #endif
19 
20 #include <boost/accumulators/accumulators.hpp>
21 #include <boost/accumulators/statistics/rolling_mean.hpp>
22 #include <boost/accumulators/statistics/stats.hpp>
23 #include <boost/hana.hpp>
24 
25 #ifdef _WIN32
26 # pragma warning(pop)
27 #endif
28 
29 #include "item.h"
30 #include "measurement.h"
31 #include "detail/transparent_eq.h"
32 #include "detail/traits.h"
33 
35 namespace cachemere {
36 
51 template<typename Key,
52  typename Value,
53  template<class, class, class>
54  class InsertionPolicy,
55  template<class, class, class>
56  class EvictionPolicy,
57  template<class, class, class>
58  class ConstraintPolicy,
59  typename MeasureValue = measurement::Size<Value>,
60  typename MeasureKey = measurement::Size<Key>,
61  typename KeyHash = absl::Hash<Key>,
62  bool ThreadSafe = true>
63 class Cache
64 {
65 public:
66  using MyInsertionPolicy = InsertionPolicy<Key, KeyHash, Value>;
67  using MyEvictionPolicy = EvictionPolicy<Key, KeyHash, Value>;
68  using MyConstraintPolicy = ConstraintPolicy<Key, KeyHash, Value>;
70  using LockGuard = std::unique_lock<std::recursive_mutex>;
71 
74  template<typename... Args> Cache(Args... args);
75 
82  template<typename C, typename... Args> Cache(C& collection, std::tuple<Args...> args);
83 
88  template<typename KeyView> bool contains(const KeyView& key) const;
89 
94  template<typename KeyView> std::optional<Value> find(const KeyView& key) const;
95 
103  template<typename C> void collect_into(C& container) const;
104 
111  bool insert(Key key, Value value);
112 
117  bool remove(const Key& key);
118 
120  void clear();
121 
127  template<typename P> void retain(P predicate_fn);
128 
132  template<typename F> void for_each(F unary_function);
133 
137  void swap(CacheType& other) noexcept;
138 
143  [[nodiscard]] size_t number_of_items() const;
144 
149  template<typename... Args> void update_constraint(Args... args);
150 
152  [[nodiscard]] MyInsertionPolicy& insertion_policy();
153 
155  [[nodiscard]] const MyInsertionPolicy& insertion_policy() const;
156 
158  [[nodiscard]] MyEvictionPolicy& eviction_policy();
159 
161  [[nodiscard]] const MyEvictionPolicy& eviction_policy() const;
162 
164  [[nodiscard]] MyConstraintPolicy& constraint_policy();
165 
167  [[nodiscard]] const MyConstraintPolicy& constraint_policy() const;
168 
173  [[nodiscard]] double hit_rate() const;
174 
180  [[nodiscard]] double byte_hit_rate() const;
181 
184  [[nodiscard]] uint32_t statistics_window_size() const;
185 
190  void statistics_window_size(uint32_t window_size);
191 
192 protected:
193  LockGuard lock() const;
194  LockGuard lock(std::defer_lock_t defer_lock_tag) const;
195  std::pair<LockGuard, LockGuard> lock_pair(CacheType& other) const;
196 
197  template<typename C> void import(C& collection);
198 
199 private:
200  using CacheItem = Item<Value>;
201 
202  using DataMap = absl::node_hash_map<Key, CacheItem, KeyHash, detail::TransparentEq<Key>>;
203 
204  using DataMapIt = typename DataMap::iterator;
205 
206  using MyInsertionPolicySP = std::unique_ptr<MyInsertionPolicy>;
207  using MyEvictionPolicySP = std::unique_ptr<MyEvictionPolicy>;
208  using MyConstraintPolicySP = std::unique_ptr<MyConstraintPolicy>;
209 
210  using RollingMeanTag = boost::accumulators::tag::rolling_mean;
211  using RollingMeanStatistics = boost::accumulators::stats<RollingMeanTag>;
212  using MeanAccumulator = boost::accumulators::accumulator_set<uint32_t, RollingMeanStatistics>;
213 
214  uint32_t m_statistics_window_size = 1000;
215 
216  MyInsertionPolicySP m_insertion_policy;
217  MyEvictionPolicySP m_eviction_policy;
218  MyConstraintPolicySP m_constraint_policy;
219 
220  MeasureKey m_measure_key;
221  MeasureValue m_measure_value;
222 
223  mutable std::recursive_mutex m_mutex;
224  DataMap m_data;
225 
226  mutable MeanAccumulator m_hit_rate_acc;
227  mutable MeanAccumulator m_byte_hit_rate_acc;
228 
229  bool check_insert(const Key& candidate_key, const CacheItem& item);
230  bool check_replace(const Key& candidate_key, const CacheItem& old_item, const CacheItem& new_item);
231 
232  void insert_or_update(Key&& key, CacheItem&& value);
233  void remove(DataMapIt it);
234 
235  void on_insert(const Key& key, const CacheItem& item) const;
236  void on_update(const Key& key, const CacheItem& old_item, const CacheItem& new_item) const;
237  void on_cache_hit(const Key& key, const CacheItem& item) const;
238  template<typename KeyView> void on_cache_miss(const KeyView& key) const;
239  void on_evict(const Key& key, const CacheItem& item) const;
240 };
241 
242 template<class K,
243  class V,
244  template<class, class, class>
245  class I,
246  template<class, class, class>
247  class E,
248  template<class, class, class>
249  class C,
250  class SV,
251  class SK,
252  class KH,
253  bool TS>
255 
256 } // namespace cachemere
257 
258 #include "cache.hpp"
259 
260 #endif
cachemere::Cache::insertion_policy
MyInsertionPolicy & insertion_policy()
Get a reference to the insertion policy used by the cache.
Definition: cache.hpp:389
cachemere::Cache::eviction_policy
MyEvictionPolicy & eviction_policy()
Get a reference to the eviction policy used by the cache.
Definition: cache.hpp:423
cachemere::Cache::remove
bool remove(const Key &key)
Remove a key and its value from the cache.
cachemere::Cache::swap
void swap(CacheType &other) noexcept
Swaps the current cache with another cache of the same type.
Definition: cache.hpp:288
cachemere::Cache::for_each
void for_each(F unary_function)
Apply a function to all objects in cache.
Definition: cache.hpp:268
cachemere::Cache::retain
void retain(P predicate_fn)
Retain all objects matching a predicate.
Definition: cache.hpp:240
cachemere::measurement::Size< Value >
cachemere::Cache::clear
void clear()
Clears the cache contents.
Definition: cache.hpp:213
cachemere::Cache::byte_hit_rate
double byte_hit_rate() const
Compute and return the running byte hit rate of the cache, in bytes.
Definition: cache.hpp:508
cachemere::Item
A wrapper for items stored in the cache.
Definition: item.h:10
cachemere::Cache::number_of_items
size_t number_of_items() const
Get the number of items currently stored in the cache.
Definition: cache.hpp:336
cachemere::Cache::contains
bool contains(const KeyView &key) const
Check whether a given key is stored in the cache.
Definition: cache.hpp:66
cachemere::Cache::insert
bool insert(Key key, Value value)
Insert a key/value pair in the cache.
Definition: cache.hpp:148
cachemere::Cache::find
std::optional< Value > find(const KeyView &key) const
Find a given key in cache returning the associated value when it exists.
cachemere::Cache::hit_rate
double hit_rate() const
Compute and return the running hit rate of the cache.
Definition: cache.hpp:491
cachemere::Cache::update_constraint
void update_constraint(Args... args)
Update the cache constraint.
Definition: cache.hpp:355
cachemere::Cache
Thread-safe memory-restricted cache.
Definition: cache.h:63
cachemere
Root namespace.
Definition: cache.h:35
cachemere::Cache::constraint_policy
MyConstraintPolicy & constraint_policy()
Get a reference to the constraint policy used by the cache.
Definition: cache.hpp:457
cachemere::Cache::Cache
Cache(Args... args)
Simple constructor.
Definition: cache.hpp:16
cachemere::Cache::collect_into
void collect_into(C &container) const
Copy the cache contents in the provided container.
cachemere::Cache::statistics_window_size
uint32_t statistics_window_size() const
Get the size of the sliding window used for computing statistics.
Definition: cache.hpp:525