Cachemere
Modular Caching Library for C++
eviction_gdsf.hpp
1 namespace cachemere::policy {
2 
3 template<class Key, class KeyHash, class Value, class Cost>
4 EvictionGDSF<Key, KeyHash, Value, Cost>::PriorityEntry::PriorityEntry(KeyRef key, double coefficient) : m_key(key),
5  m_h_coefficient(coefficient)
6 {
7 }
8 
9 template<class Key, class KeyHash, class Value, class Cost>
10 bool EvictionGDSF<Key, KeyHash, Value, Cost>::PriorityEntry::operator<(const PriorityEntry& other) const
11 {
12  return m_h_coefficient < other.m_h_coefficient;
13 }
14 
15 template<class Key, class KeyHash, class Value, class Cost>
16 EvictionGDSF<Key, KeyHash, Value, Cost>::VictimIterator::VictimIterator(PrioritySetIt iterator) : m_iterator(std::move(iterator))
17 {
18 }
19 
20 template<class Key, class KeyHash, class Value, class Cost> const Key& EvictionGDSF<Key, KeyHash, Value, Cost>::VictimIterator::operator*() const
21 {
22  return m_iterator->m_key;
23 }
24 
25 template<class Key, class KeyHash, class Value, class Cost> auto EvictionGDSF<Key, KeyHash, Value, Cost>::VictimIterator::operator++() -> VictimIterator&
26 {
27  ++m_iterator;
28  return *this;
29 }
30 
31 template<class Key, class KeyHash, class Value, class Cost> auto EvictionGDSF<Key, KeyHash, Value, Cost>::VictimIterator::operator++(int) -> VictimIterator
32 {
33  return (*this)++;
34 }
35 
36 template<class Key, class KeyHash, class Value, class Cost>
37 bool EvictionGDSF<Key, KeyHash, Value, Cost>::VictimIterator::operator==(const VictimIterator& other) const
38 {
39  return m_iterator == other.m_iterator;
40 }
41 
42 template<class Key, class KeyHash, class Value, class Cost>
43 bool EvictionGDSF<Key, KeyHash, Value, Cost>::VictimIterator::operator!=(const VictimIterator& other) const
44 {
45  return m_iterator != other.m_iterator;
46 }
47 
48 template<class Key, class KeyHash, class Value, class Cost> void EvictionGDSF<Key, KeyHash, Value, Cost>::clear()
49 {
50  m_priority_set.clear();
51  m_iterator_map.clear();
52  m_frequency_sketch.clear();
53 }
54 
55 template<class Key, class KeyHash, class Value, class Cost> void EvictionGDSF<Key, KeyHash, Value, Cost>::set_cardinality(uint32_t cardinality)
56 {
57  m_frequency_sketch = detail::CountingBloomFilter<Key>{cardinality};
58 }
59 
60 template<class Key, class KeyHash, class Value, class Cost> void EvictionGDSF<Key, KeyHash, Value, Cost>::on_insert(const Key& key, const CacheItem& item)
61 {
62  m_frequency_sketch.add(key);
63 
64  PrioritySetIt it = m_priority_set.emplace(std::ref(key), get_h_coefficient(key, item));
65  m_iterator_map[std::ref(key)] = std::move(it);
66 }
67 
68 template<class Key, class KeyHash, class Value, class Cost>
69 void EvictionGDSF<Key, KeyHash, Value, Cost>::on_update(const Key& key, const CacheItem& /* old_item */, const CacheItem& new_item)
70 {
71  on_cache_hit(key, new_item);
72 }
73 
74 template<class Key, class KeyHash, class Value, class Cost> void EvictionGDSF<Key, KeyHash, Value, Cost>::on_cache_hit(const Key& key, const CacheItem& item)
75 {
76  auto keyref_and_it = m_iterator_map.find(std::ref(key));
77  assert(keyref_and_it != m_iterator_map.end());
78 
79  PrioritySetIt it = keyref_and_it->second;
80 
81  m_priority_set.erase(it);
82 
83  on_insert(key, item);
84 }
85 
86 template<class Key, class KeyHash, class Value, class Cost> void EvictionGDSF<Key, KeyHash, Value, Cost>::on_evict(const Key& key, const CacheItem& /* item */)
87 {
88  auto keyref_and_it = m_iterator_map.find(std::ref(key));
89  assert(keyref_and_it != m_iterator_map.end());
90 
91  PrioritySetIt it = keyref_and_it->second;
92  m_clock = std::max(m_clock, static_cast<uint64_t>(it->m_h_coefficient));
93 
94  m_priority_set.erase(it);
95  m_iterator_map.erase(keyref_and_it);
96 
97  assert(m_iterator_map.find(key) == m_iterator_map.end());
98 }
99 
100 template<class Key, class KeyHash, class Value, class Cost> auto EvictionGDSF<Key, KeyHash, Value, Cost>::victim_begin() const -> VictimIterator
101 {
102  return VictimIterator{std::move(m_priority_set.begin())};
103 }
104 
105 template<class Key, class KeyHash, class Value, class Cost> auto EvictionGDSF<Key, KeyHash, Value, Cost>::victim_end() const -> VictimIterator
106 {
107  return VictimIterator{std::move(m_priority_set.end())};
108 }
109 
110 template<class Key, class KeyHash, class Value, class Cost>
111 double EvictionGDSF<Key, KeyHash, Value, Cost>::get_h_coefficient(const Key& key, const CacheItem& item) const noexcept
112 {
113  return static_cast<double>(m_clock) +
114  static_cast<double>(m_frequency_sketch.estimate(key)) * (static_cast<double>(m_measure_cost(key, item)) / static_cast<double>(item.m_total_size));
115 }
116 
117 } // namespace cachemere::policy
cachemere::policy::EvictionGDSF::on_cache_hit
void on_cache_hit(const Key &key, const CacheItem &item)
Cache hit event handler.
Definition: eviction_gdsf.hpp:74
cachemere::policy::EvictionGDSF::on_evict
void on_evict(const Key &key, const CacheItem &item)
Eviction event handler.
Definition: eviction_gdsf.hpp:86
cachemere::policy::EvictionGDSF::set_cardinality
void set_cardinality(uint32_t cardinality)
Set the cardinality of the policy.
Definition: eviction_gdsf.hpp:55
cachemere::policy::detail::CountingBloomFilter::add
void add(const ItemKey &item)
Increment the count for a given item by one.
Definition: counting_bloom_filter.hpp:17
cachemere::policy::detail::CountingBloomFilter
Space-efficient probabilistic data structure to estimate the number of times an item was inserted in ...
Definition: counting_bloom_filter.h:18
cachemere::policy::EvictionGDSF::on_insert
void on_insert(const Key &key, const CacheItem &item)
Insertion event handler.
Definition: eviction_gdsf.hpp:60
cachemere::Item
A wrapper for items stored in the cache.
Definition: item.h:10
cachemere::policy::detail::CountingBloomFilter::clear
void clear()
Clear the filter while keeping the allocated memory.
Definition: counting_bloom_filter.hpp:48
cachemere::policy::EvictionGDSF::victim_end
VictimIterator victim_end() const
Get an end iterator.
Definition: eviction_gdsf.hpp:105
cachemere::policy::EvictionGDSF
Greedy-Dual-Size-Frequency (GDSF) eviction policy.
Definition: eviction_gdsf.h:24
cachemere::policy::EvictionGDSF::clear
void clear()
Clears the policy.
Definition: eviction_gdsf.hpp:48
cachemere::policy::EvictionGDSF::victim_begin
VictimIterator victim_begin() const
Get an iterator to the first item that should be evicted.
Definition: eviction_gdsf.hpp:100
cachemere::policy::EvictionGDSF::VictimIterator
Iterator for iterating over cache items in the order they should be evicted.
Definition: eviction_gdsf.h:46
cachemere::policy::EvictionGDSF::on_update
void on_update(const Key &key, const CacheItem &old_item, const CacheItem &new_item)
Update event handler.
Definition: eviction_gdsf.hpp:69
cachemere::policy::detail::CountingBloomFilter::estimate
uint32_t estimate(const ItemKey &item) const
Get the counter estimate for a given item.
Definition: counting_bloom_filter.hpp:64