34 explicit LRUCache(
const std::size_t maxSize = 100) : m_maxSize{maxSize} {}
37 using mapped_type = Value;
38 using allocator_type = Allocator;
39 using value_type = std::pair<key_type, mapped_type>;
40 using container_type = std::list<value_type, allocator_type>;
41 using size_type =
typename container_type::size_type;
42 using difference_type =
typename container_type::difference_type;
43 using iterator =
typename container_type::iterator;
44 using const_iterator =
typename container_type::const_iterator;
45 using reverse_iterator = std::reverse_iterator<iterator>;
46 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
48 using reference = value_type &;
49 using const_reference =
const value_type &;
50 using pointer =
typename std::allocator_traits<allocator_type>::pointer;
53 typename std::allocator_traits<allocator_type>::const_pointer;
55 [[nodiscard]] iterator begin()
noexcept
57 return m_container.begin();
60 [[nodiscard]] const_iterator begin()
const noexcept
62 return m_container.begin();
65 [[nodiscard]] reverse_iterator rbegin()
noexcept
67 return m_container.rbegin();
70 [[nodiscard]] const_reverse_iterator rbegin()
const noexcept
72 return m_container.rbegin();
75 [[nodiscard]] iterator end()
noexcept
77 return m_container.end();
80 [[nodiscard]] const_iterator end()
const noexcept
82 return m_container.end();
85 [[nodiscard]] reverse_iterator rend()
noexcept
87 return m_container.rend();
90 [[nodiscard]] const_reverse_iterator rend()
const noexcept
92 return m_container.rend();
95 [[nodiscard]]
bool empty()
const noexcept
97 return m_container.empty();
100 [[nodiscard]] std::size_t size()
const noexcept
102 return m_currentSize;
105 [[nodiscard]] std::size_t max_size()
const noexcept
117 void put(
const key_type & key,
const mapped_type & value)
119 Q_UNUSED(remove(key))
121 m_container.push_front(value_type(key, value));
122 m_mapper[key] = m_container.begin();
128 [[nodiscard]]
const mapped_type * get(
const key_type & key)
const noexcept
130 auto mapperIt = m_mapper.find(key);
131 if (mapperIt == m_mapper.end()) {
135 auto it = mapperIt.value();
136 if (it == m_container.end()) {
140 m_container.splice(m_container.begin(), m_container, it);
141 mapperIt.value() = m_container.begin();
142 return &(mapperIt.value()->second);
145 [[nodiscard]]
bool exists(
const key_type & key)
const noexcept
147 const auto mapperIt = m_mapper.find(key);
148 if (mapperIt == m_mapper.end()) {
152 const auto it = mapperIt.value();
153 return (it != m_container.end());
156 bool remove(
const key_type & key)
noexcept
158 const auto mapperIt = m_mapper.find(key);
159 if (mapperIt == m_mapper.end()) {
163 const auto it = mapperIt.value();
164 Q_UNUSED(m_container.erase(it))
165 Q_UNUSED(m_mapper.erase(mapperIt))
167 if (m_currentSize != 0) {
174 void setMaxSize(
const std::size_t maxSize)
176 if (maxSize >= m_maxSize) {
181 std::size_t diff = m_maxSize - maxSize;
182 for (std::size_t i = 0; (i < diff) && !m_container.empty(); ++i) {
183 auto lastIt = m_container.end();
186 const key_type & lastElementKey = lastIt->first;
187 Q_UNUSED(m_mapper.remove(lastElementKey))
188 Q_UNUSED(m_container.erase(lastIt))
190 if (m_currentSize != 0) {
199 if (m_currentSize <= m_maxSize) {
203 if (Q_UNLIKELY(m_container.empty())) {
207 auto lastIt = m_container.end();
210 const key_type & lastElementKey = lastIt->first;
212 Q_UNUSED(m_mapper.remove(lastElementKey))
213 Q_UNUSED(m_container.erase(lastIt))
215 if (m_currentSize != 0) {
221 mutable container_type m_container;
222 std::size_t m_currentSize = 0;
223 std::size_t m_maxSize;
225 mutable QHash<Key, iterator> m_mapper;