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