OpenTTD Source 20250312-master-gcdcc6b491d
lrucache.hpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#ifndef LRUCACHE_HPP
11#define LRUCACHE_HPP
12
13#include <utility>
14#include <unordered_map>
15
21template <class Tkey, class Tdata>
22class LRUCache {
23private:
24 typedef std::pair<Tkey, std::unique_ptr<Tdata>> Tpair;
25 typedef typename std::list<Tpair>::iterator Titer;
26
27 std::list<Tpair> data;
28 std::unordered_map<Tkey, Titer> lookup;
29
30 const size_t capacity;
31
32public:
37 LRUCache(size_t max_items) : capacity(max_items) {}
38
44 inline bool Contains(const Tkey key)
45 {
46 return this->lookup.find(key) != this->lookup.end();
47 }
48
54 void Insert(const Tkey key, std::unique_ptr<Tdata> &&item)
55 {
56 if (this->Contains(key)) {
57 /* Replace old value. */
58 this->lookup[key]->second = std::move(item);
59 return;
60 }
61
62 /* Delete least used item if maximum items cached. */
63 if (this->data.size() >= this->capacity) {
64 this->lookup.erase(data.back().first);
65 this->data.pop_back();
66 }
67
68 /* Insert new item. */
69 this->data.emplace_front(key, std::move(item));
70 this->lookup.emplace(key, this->data.begin());
71 }
72
76 void Clear()
77 {
78 this->lookup.clear();
79 this->data.clear();
80 }
81
88 inline Tdata *Get(const Tkey key)
89 {
90 if (this->lookup.find(key) == this->lookup.end()) throw std::out_of_range("item not found");
91 /* Move to front if needed. */
92 this->data.splice(this->data.begin(), this->data, this->lookup[key]);
93
94 return this->data.front().second.get();
95 }
96};
97
98#endif /* LRUCACHE_HPP */
Size limited cache with a least recently used eviction strategy.
Definition lrucache.hpp:22
Tdata * Get(const Tkey key)
Get an item from the cache.
Definition lrucache.hpp:88
LRUCache(size_t max_items)
Construct new LRU cache map.
Definition lrucache.hpp:37
bool Contains(const Tkey key)
Test if a key is already contained in the cache.
Definition lrucache.hpp:44
void Insert(const Tkey key, std::unique_ptr< Tdata > &&item)
Insert a new data item with a specified key.
Definition lrucache.hpp:54
std::list< Tpair > data
Ordered list of all items.
Definition lrucache.hpp:27
void Clear()
Clear the cache.
Definition lrucache.hpp:76
const size_t capacity
Number of items to cache.
Definition lrucache.hpp:30
std::unordered_map< Tkey, Titer > lookup
Map of keys to items.
Definition lrucache.hpp:28