blob: f5b8f986f5878bf9c98b565f729eca8d8735c515 [file] [log] [blame]
Jason Macnakcd947252022-09-06 13:53:06 -07001// Copyright 2022 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <list>
18#include <unordered_map>
19
20template <typename Key, typename Value>
21class LruCache {
Kaiyi Li15765fe2024-01-24 09:16:05 -080022 public:
23 LruCache(std::size_t maxSize) : m_maxSize(maxSize) { m_table.reserve(maxSize); }
Jason Macnakcd947252022-09-06 13:53:06 -070024
25 Value* get(const Key& key) {
26 auto tableIt = m_table.find(key);
27 if (tableIt == m_table.end()) {
28 return nullptr;
29 }
30
31 // Move to front.
32 auto elementsIt = tableIt->second;
33 m_elements.splice(elementsIt, m_elements, m_elements.begin());
34 return &elementsIt->value;
35 }
36
37 void set(const Key& key, Value&& value) {
38 auto tableIt = m_table.find(key);
39 if (tableIt == m_table.end()) {
40 if (m_table.size() >= m_maxSize) {
41 auto& kv = m_elements.back();
42 m_table.erase(kv.key);
43 m_elements.pop_back();
44 }
45 } else {
46 auto elementsIt = tableIt->second;
47 m_elements.erase(elementsIt);
48 }
49 m_elements.emplace_front(KeyValue{
50 key,
51 std::forward<Value>(value),
52 });
53 m_table[key] = m_elements.begin();
54 }
55
56 void remove(const Key& key) {
57 auto tableIt = m_table.find(key);
58 if (tableIt == m_table.end()) {
59 return;
60 }
61 auto elementsIt = tableIt->second;
62 m_elements.erase(elementsIt);
63 m_table.erase(tableIt);
64 }
65
66 void clear() {
67 m_elements.clear();
68 m_table.clear();
69 }
70
Kaiyi Li15765fe2024-01-24 09:16:05 -080071 private:
Jason Macnakcd947252022-09-06 13:53:06 -070072 struct KeyValue {
73 Key key;
74 Value value;
75 };
76
77 const std::size_t m_maxSize;
78 // Front is the most recently used and back is the least recently used.
79 std::list<KeyValue> m_elements;
80 std::unordered_map<Key, typename std::list<KeyValue>::iterator> m_table;
81};