1 namespace cachemere::policy {
3 template<
class Key,
class KeyHash,
class Value>
4 EvictionSegmentedLRU<Key, KeyHash, Value>::VictimIterator::VictimIterator(
const KeyRefReverseIt& probation_iterator,
5 const KeyRefReverseIt& probation_end_iterator,
6 const KeyRefReverseIt& protected_iterator)
7 : m_probation_iterator{probation_iterator},
8 m_probation_end_iterator{probation_end_iterator},
9 m_protected_iterator{protected_iterator},
10 m_done_with_probation{probation_iterator == probation_end_iterator}
14 template<
class Key,
class KeyHash,
class Value>
const Key& EvictionSegmentedLRU<Key, KeyHash, Value>::VictimIterator::operator*()
const
16 const auto it = m_done_with_probation ? m_protected_iterator : m_probation_iterator;
20 template<
class Key,
class KeyHash,
class Value>
auto EvictionSegmentedLRU<Key, KeyHash, Value>::VictimIterator::operator++() -> VictimIterator&
22 if (m_done_with_probation) {
23 ++m_protected_iterator;
25 ++m_probation_iterator;
26 m_done_with_probation |= m_probation_iterator == m_probation_end_iterator;
31 template<
class Key,
class KeyHash,
class Value>
auto EvictionSegmentedLRU<Key, KeyHash, Value>::VictimIterator::operator++(
int) -> VictimIterator
38 template<
class Key,
class KeyHash,
class Value>
bool EvictionSegmentedLRU<Key, KeyHash, Value>::VictimIterator::operator==(
const VictimIterator& other)
const
40 return m_protected_iterator == other.m_protected_iterator && m_probation_iterator == other.m_probation_iterator &&
41 m_done_with_probation == other.m_done_with_probation;
44 template<
class Key,
class KeyHash,
class Value>
bool EvictionSegmentedLRU<Key, KeyHash, Value>::VictimIterator::operator!=(
const VictimIterator& other)
const
46 return !(*
this == other);
51 m_probation_list.clear();
52 m_probation_nodes.clear();
54 m_protected_list.clear();
55 m_protected_nodes.clear();
60 m_protected_segment_size = size;
65 assert(m_probation_nodes.find(key) == m_probation_nodes.end());
67 m_probation_list.emplace_front(std::ref(key));
68 m_probation_nodes.emplace(std::ref(key), m_probation_list.begin());
71 template<
class Key,
class KeyHash,
class Value>
79 assert(m_probation_nodes.size() == m_probation_list.size());
80 assert(m_protected_nodes.size() == m_protected_list.size());
82 auto protected_node_it = m_protected_nodes.find(key);
83 if (protected_node_it != m_protected_nodes.end()) {
84 if (protected_node_it->second != m_protected_list.begin()) {
86 m_protected_list.splice(m_protected_list.begin(), m_protected_list, protected_node_it->second);
90 [[maybe_unused]]
const bool promotion_ok = move_to_protected(key);
94 while (m_protected_list.size() > m_protected_segment_size) {
95 [[maybe_unused]]
const bool demotion_ok = pop_to_probation();
97 assert(m_protected_list.size() == m_protected_segment_size);
100 assert(m_probation_nodes.size() == m_probation_list.size());
101 assert(m_protected_nodes.size() == m_protected_list.size());
106 assert((!m_protected_list.empty()) || !m_probation_list.empty());
108 auto key_and_it = m_probation_nodes.find(key);
109 if (key_and_it != m_probation_nodes.end()) {
110 m_probation_list.erase(key_and_it->second);
111 m_probation_nodes.erase(key_and_it);
113 key_and_it = m_protected_nodes.find(key);
114 assert(key_and_it != m_protected_nodes.end());
115 m_protected_list.erase(key_and_it->second);
116 m_protected_nodes.erase(key_and_it);
122 return VictimIterator{m_probation_list.rbegin(), m_probation_list.rend(), m_protected_list.rbegin()};
127 return VictimIterator{m_probation_list.rend(), m_probation_list.rend(), m_protected_list.rend()};
132 auto probation_node_it = m_probation_nodes.find(key);
133 if (probation_node_it == m_probation_nodes.end()) {
137 m_protected_list.splice(m_protected_list.begin(), m_probation_list, probation_node_it->second);
138 m_probation_nodes.erase(key);
139 m_protected_nodes.emplace(key, m_protected_list.begin());
143 template<
class Key,
class KeyHash,
class Value>
bool EvictionSegmentedLRU<Key, KeyHash, Value>::pop_to_probation()
145 if (m_protected_list.empty()) {
149 m_probation_list.splice(m_probation_list.begin(), m_protected_list, --m_protected_list.end());
150 m_protected_nodes.erase(*m_probation_list.begin());
151 m_probation_nodes.emplace(*m_probation_list.begin(), m_probation_list.begin());