CCF
Loading...
Searching...
No Matches
lru.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
5#include <list>
6#include <map>
7
17template <typename K, typename V>
18class LRU
19{
20public:
21 using Entry = std::pair<const K, V>;
22 using List = std::list<Entry>;
23 using Map = std::map<K, typename List::iterator>;
24 using Iterator = typename List::iterator;
25 using ConstIterator = typename List::const_iterator;
26
27private:
28 // Entries are ordered by when they were most recently accessed, with most
29 // recent at the front
30 List entries_list;
31
32 // Maps from keys to iterators from entries_list, which must remain valid even
33 // when entries_list is modified
34 Map iter_map;
35
36 size_t max_size;
37
38 void cull()
39 {
40 while (entries_list.size() > max_size)
41 {
42 const auto& least_recent_entry = entries_list.back();
43 iter_map.erase(least_recent_entry.first);
44 entries_list.pop_back();
45 }
46 }
47
48public:
49 LRU(size_t max_size) : max_size(max_size) {}
50
51 size_t size() const
52 {
53 return iter_map.size();
54 }
55
56 void set_max_size(size_t ms)
57 {
58 max_size = ms;
59 cull();
60 }
61
62 size_t get_max_size() const
63 {
64 return max_size;
65 }
66
68 {
69 return entries_list.begin();
70 }
71
73 {
74 return entries_list.end();
75 }
76
78 {
79 return entries_list.begin();
80 }
81
83 {
84 return entries_list.end();
85 }
86
87 Iterator find(const K& k)
88 {
89 const auto it = iter_map.find(k);
90 if (it != iter_map.end())
91 {
92 return it->second;
93 }
94
95 return entries_list.end();
96 }
97
98 bool contains(const K& k) const
99 {
100 const auto it = iter_map.find(k);
101 return it != iter_map.end();
102 }
103
104 // Move an iterator (returned from find) to the most recently used
105 void promote(const Iterator& list_it)
106 {
107 entries_list.splice(entries_list.begin(), entries_list, list_it);
108 }
109
110 Iterator insert(const K& k, V&& v)
111 {
112 auto it = iter_map.find(k);
113 if (it != iter_map.end())
114 {
115 // If it already exists, move to the front
116 promote(it->second);
117 }
118 else
119 {
120 // Else add a new entry to both containers, and cull if necessary
121 entries_list.push_front(std::make_pair(k, std::forward<V>(v)));
122 const auto list_it = entries_list.begin();
123 iter_map.emplace_hint(it, k, list_it);
124 cull();
125 }
126
127 return entries_list.begin();
128 }
129
130 V& operator[](const K& k)
131 {
132 auto it = insert(k, V{});
133 return it->second;
134 }
135
136 void clear()
137 {
138 entries_list.clear();
139 iter_map.clear();
140 }
141};
Definition lru.h:19
Iterator begin()
Definition lru.h:67
LRU(size_t max_size)
Definition lru.h:49
Iterator end()
Definition lru.h:72
std::pair< const K, V > Entry
Definition lru.h:21
typename List::iterator Iterator
Definition lru.h:24
typename List::const_iterator ConstIterator
Definition lru.h:25
ConstIterator begin() const
Definition lru.h:77
size_t size() const
Definition lru.h:51
bool contains(const K &k) const
Definition lru.h:98
std::map< K, typename List::iterator > Map
Definition lru.h:23
void set_max_size(size_t ms)
Definition lru.h:56
V & operator[](const K &k)
Definition lru.h:130
ConstIterator end() const
Definition lru.h:82
Iterator insert(const K &k, V &&v)
Definition lru.h:110
void clear()
Definition lru.h:136
std::list< Entry > List
Definition lru.h:22
void promote(const Iterator &list_it)
Definition lru.h:105
size_t get_max_size() const
Definition lru.h:62
Iterator find(const K &k)
Definition lru.h:87