6#include <userver/cache/impl/lru.hpp>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
29USERVER_NAMESPACE_BEGIN
31namespace cache::
impl {
33template <
typename T,
typename U,
typename Hash = std::hash<T>,
34 typename Equal = std::equal_to<T>>
37 using NodeType = std::unique_ptr<LruNode<T, U>>;
39 explicit SlruBase(std::size_t probation_size, std::size_t protected_size,
40 const Hash& hash = Hash(),
const Equal& equal = Equal());
41 ~SlruBase() =
default;
43 SlruBase(SlruBase&& other)
noexcept =
default;
45 SlruBase& operator=(SlruBase&& other)
noexcept =
default;
47 SlruBase(
const SlruBase& slru) =
delete;
48 SlruBase& operator=(
const SlruBase& slru) =
delete;
50 bool Put(
const T& key, U value);
52 template <
typename... Args>
53 U* Emplace(
const T& key, Args&&... args);
55 void Erase(
const T& key);
59 const T* GetLeastUsedKey()
const;
61 U* GetLeastUsedValue();
63 NodeType ExtractLeastUsedNode();
65 void SetMaxSize(std::size_t new_probation_size,
66 std::size_t new_protected_size);
68 void Clear()
noexcept;
70 template <
typename Function>
71 void VisitAll(Function&& func)
const;
73 template <
typename Function>
74 void VisitAll(Function&& func);
76 std::size_t GetSize()
const;
78 std::size_t GetCapacity()
const;
80 U& InsertNode(NodeType&& node)
noexcept;
81 NodeType ExtractNode(
const T& key)
noexcept;
84 cache::
impl::LruBase<T, U, Hash, Equal> probation_part_;
85 cache::
impl::LruBase<T, U, Hash, Equal> protected_part_;
88template <
typename T,
typename U,
typename Hash,
typename Equal>
89SlruBase<T, U, Hash, Equal>::SlruBase(std::size_t probation_size,
90 std::size_t protected_size,
91 const Hash& hash,
const Equal& equal)
92 : probation_part_(probation_size, hash, equal),
93 protected_part_(protected_size, hash, equal) {}
95template <
typename T,
typename U,
typename Hash,
typename Equal>
96bool SlruBase<T, U, Hash, Equal>::Put(
const T& key, U value) {
97 auto*
const value_ptr = protected_part_.Get(key);
99 *value_ptr = std::move(value);
103 auto node_to_protected = probation_part_.ExtractNode(key);
104 if (node_to_protected) {
105 node_to_protected->SetValue(std::move(value));
106 if (protected_part_.GetSize() == protected_part_.GetCapacity()) {
107 auto node_to_probation = protected_part_.ExtractLeastUsedNode();
108 probation_part_.InsertNode(std::move(node_to_probation));
110 protected_part_.InsertNode(std::move(node_to_protected));
114 return probation_part_.Put(key, std::move(value));
117template <
typename T,
typename U,
typename Hash,
typename Equal>
118template <
typename... Args>
119U* SlruBase<T, U, Hash, Equal>::Emplace(
const T& key, Args&&... args) {
120 auto value_ptr = protected_part_.Get(key);
125 auto node_to_protected = probation_part_.ExtractNode(key);
126 if (node_to_protected) {
127 return protected_part_.Emplace(key, std::forward<Args>(args)...);
130 return probation_part_.Emplace(key, std::forward<Args>(args)...);
133template <
typename T,
typename U,
typename Hash,
typename Equal>
134void SlruBase<T, U, Hash, Equal>::Erase(
const T& key) {
135 probation_part_.Erase(key);
136 protected_part_.Erase(key);
139template <
typename T,
typename U,
typename Hash,
typename Equal>
140U* SlruBase<T, U, Hash, Equal>::Get(
const T& key) {
141 auto value_ptr = protected_part_.Get(key);
146 auto node_to_protected = probation_part_.ExtractNode(key);
147 if (node_to_protected) {
148 if (protected_part_.GetSize() == protected_part_.GetCapacity()) {
149 auto node_to_probation = protected_part_.ExtractLeastUsedNode();
150 probation_part_.InsertNode(std::move(node_to_probation));
152 return &protected_part_.InsertNode(std::move(node_to_protected));
157template <
typename T,
typename U,
typename Hash,
typename Equal>
158const T* SlruBase<T, U, Hash, Equal>::GetLeastUsedKey()
const {
159 return probation_part_.GetLeastUsedKey();
162template <
typename T,
typename U,
typename Hash,
typename Equal>
163U* SlruBase<T, U, Hash, Equal>::GetLeastUsedValue() {
164 return probation_part_.GetLeastUsedValue();
167template <
typename T,
typename U,
typename Hash,
typename Equal>
168typename SlruBase<T, U, Hash, Equal>::NodeType
169SlruBase<T, U, Hash, Equal>::ExtractLeastUsedNode() {
170 return probation_part_.ExtractLeastUsedNode();
173template <
typename T,
typename U,
typename Hash,
typename Equal>
174void SlruBase<T, U, Hash, Equal>::SetMaxSize(std::size_t new_probation_size,
175 std::size_t new_protected_size) {
176 probation_part_.SetMaxSize(new_probation_size);
177 protected_part_.SetMaxSize(new_protected_size);
180template <
typename T,
typename U,
typename Hash,
typename Equal>
181void SlruBase<T, U, Hash, Equal>::Clear()
noexcept {
182 probation_part_.Clear();
183 protected_part_.Clear();
186template <
typename T,
typename U,
typename Hash,
typename Equal>
187template <
typename Function>
188void SlruBase<T, U, Hash, Equal>::VisitAll(Function&& func)
const {
189 probation_part_.VisitAll(std::forward<Function>(func));
190 protected_part_.VisitAll(std::forward<Function>(func));
193template <
typename T,
typename U,
typename Hash,
typename Equal>
194template <
typename Function>
195void SlruBase<T, U, Hash, Equal>::VisitAll(Function&& func) {
196 probation_part_.VisitAll(std::forward<Function>(func));
197 protected_part_.VisitAll(std::forward<Function>(func));
200template <
typename T,
typename U,
typename Hash,
typename Equal>
201std::size_t SlruBase<T, U, Hash, Equal>::GetSize()
const {
202 return probation_part_.GetSize() + protected_part_.GetSize();
205template <
typename T,
typename U,
typename Hash,
typename Equal>
206std::size_t SlruBase<T, U, Hash, Equal>::GetCapacity()
const {
207 return probation_part_.GetCapacity() + protected_part_.GetCapacity();
210template <
typename T,
typename U,
typename Hash,
typename Equal>
211U& SlruBase<T, U, Hash, Equal>::InsertNode(NodeType&& node)
noexcept {
212 return probation_part_.InsertNode(std::move(node));
215template <
typename T,
typename U,
typename Hash,
typename Equal>
216typename SlruBase<T, U, Hash, Equal>::NodeType
217SlruBase<T, U, Hash, Equal>::ExtractNode(
const T& key)
noexcept {
218 auto protected_node = protected_part_.ExtractNode(key);
219 if (protected_node) {
220 return protected_node;
223 return probation_part_.ExtractNode(key);