KTextAddons

lrucache.h
1/*
2 SPDX-FileCopyrightText: 2020 Milian Wolff <mail@milianw.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#pragma once
8
9#include <algorithm>
10#include <vector>
11
12template<typename Key, typename Value>
13class LRUCache
14{
15public:
16 struct Entry {
17 Key key;
18 Value value;
19 bool operator==(const Key &rhs) const
20 {
21 return key == rhs;
22 }
23 };
24 using Entries = std::vector<Entry>;
25 using value_type = typename Entries::value_type;
26 using size_type = typename Entries::size_type;
27 using difference_type = typename Entries::difference_type;
28 // only const access
29 using reference = typename Entries::const_reference;
30 using const_reference = typename Entries::const_reference;
31 using pointer = typename Entries::const_pointer;
32 using iterator = typename Entries::const_iterator;
33 using const_iterator = typename Entries::const_iterator;
34
35 void setMaxEntries(int maxEntries)
36 {
37 mMaxEntries = maxEntries;
38 }
39
40 std::size_t size() const
41 {
42 return mEntries.size();
43 }
44
45 const_iterator begin() const
46 {
47 return mEntries.begin();
48 }
49
50 const_iterator end() const
51 {
52 return std::next(mEntries.begin(), size());
53 }
54
55 const_iterator find(const Key &key)
56 {
57 // using non-const iterators here since we will re-insert when we find
58 const auto begin = mEntries.begin();
59 const auto end = std::next(mEntries.begin(), size());
60 auto it = std::find(begin, end, key);
61 if (it == begin || it == end) { // not found or already the last recently used one
62 return it;
63 }
64
65 // rotate to mark entry as last recently used one
66 std::rotate(begin, it, it + 1);
67 return mEntries.cbegin();
68 }
69
70 void insert(Key key, Value value)
71 {
72 auto entriesSize = size();
73 if (mMaxEntries == -1 || (entriesSize < static_cast<size_t>(mMaxEntries))) {
74 // open up a new slot
75 ++entriesSize;
76 mEntries.resize(entriesSize);
77 }
78
79 // right shift to make space at the front
80 std::rotate(mEntries.begin(), std::next(mEntries.begin(), entriesSize - 1), std::next(mEntries.begin(), entriesSize));
81
82 // insert up front
83 mEntries.front() = {std::move(key), std::move(value)};
84 }
85
86 bool remove(const Key &key)
87 {
88 const auto begin = mEntries.begin();
89 const auto end = std::next(mEntries.begin(), size());
90 auto it = std::find(begin, end, key);
91 if (it == end) { // not found or already the last recently used one
92 return false;
93 }
94
95 std::move(std::next(it), end, it);
96 mEntries.resize(size() - 1);
97 return true;
98 }
99
100 void clear()
101 {
102 mEntries.clear();
103 }
104
105private:
106 Entries mEntries;
107 int mMaxEntries = -1;
108};
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 12:06:13 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.