40#include <unordered_map>
65#pragma clang diagnostic push
66#pragma clang diagnostic ignored "-Wweak-vtables"
72class KeyNotFound :
public std::invalid_argument
75 KeyNotFound() : std::invalid_argument(
"key_not_found")
81#pragma clang diagnostic pop
84template <
typename K,
typename V>
struct KeyValuePair
90 KeyValuePair(
const K &k,
const V &v) : key(k), value(v)
94 KeyValuePair(
const K &k, V &&v) : key(k), value(std::move(v))
99 KeyValuePair(
const KeyValuePair &) =
delete;
100 KeyValuePair &operator=(
const KeyValuePair &) =
delete;
115template <
class Key,
class Value,
class Lock = NullLock,
116 class Map = std::unordered_map<
117 Key,
typename std::list<KeyValuePair<Key, Value>>::iterator>>
121 typedef KeyValuePair<Key, Value> node_type;
122 typedef std::list<KeyValuePair<Key, Value>> list_type;
123 typedef Map map_type;
124 typedef Lock lock_type;
125 using Guard = std::lock_guard<lock_type>;
135 explicit Cache(
size_t maxSize = 64,
size_t elasticity = 10)
136 : maxSize_(maxSize), elasticity_(elasticity)
145 return cache_.size();
151 return cache_.empty();
161 void insert(
const Key &k,
const Value &v)
164 const auto iter = cache_.find(k);
165 if (iter != cache_.end())
167 iter->second->value = v;
168 keys_.splice(keys_.begin(), keys_, iter->second);
172 keys_.emplace_front(k, v);
173 cache_[k] = keys_.begin();
177 Value &insert(
const Key &k, Value &&v)
180 const auto iter = cache_.find(k);
181 if (iter != cache_.end())
183 iter->second->value = std::move(v);
184 keys_.splice(keys_.begin(), keys_, iter->second);
185 return keys_.front().value;
188 keys_.emplace_front(k, std::move(v));
189 cache_[k] = keys_.begin();
191 return keys_.front().value;
194 bool tryGet(
const Key &kIn, Value &vOut)
197 const auto iter = cache_.find(kIn);
198 if (iter == cache_.end())
202 keys_.splice(keys_.begin(), keys_, iter->second);
203 vOut = iter->second->value;
211 const Value &get(
const Key &k)
214 const auto iter = cache_.find(k);
215 if (iter == cache_.end())
219 keys_.splice(keys_.begin(), keys_, iter->second);
220 return iter->second->value;
223 Value *getPtr(
const Key &k)
226 const auto iter = cache_.find(k);
227 if (iter == cache_.end())
231 keys_.splice(keys_.begin(), keys_, iter->second);
232 return &(iter->second->value);
238 Value getCopy(
const Key &k)
243 bool remove(
const Key &k)
246 auto iter = cache_.find(k);
247 if (iter == cache_.end())
251 keys_.erase(iter->second);
256 bool contains(
const Key &k)
259 return cache_.find(k) != cache_.end();
262 bool getOldestEntry(Key &kOut, Value &vOut)
269 kOut = keys_.back().key;
270 vOut = keys_.back().value;
274 bool removeAndRecycleOldestEntry(Value &vOut)
281 vOut = std::move(keys_.back().value);
282 cache_.erase(keys_.back().key);
287 size_t getMaxSize()
const
292 size_t getElasticity()
const
297 size_t getMaxAllowedSize()
const
299 return maxSize_ + elasticity_;
302 template <
typename F>
void cwalk(
F &f)
const
305 std::for_each(keys_.begin(), keys_.end(), f);
309 : cache_(std::move(other.cache_)), keys_(std::move(other.keys_)),
310 maxSize_(other.maxSize_), elasticity_(other.elasticity_)
317 size_t maxAllowed = maxSize_ + elasticity_;
318 if (maxSize_ == 0 || cache_.size() <= maxAllowed)
323 while (cache_.size() > maxSize_)
325 cache_.erase(keys_.back().key);
334 Cache(
const Cache &) =
delete;
335 Cache &operator=(
const Cache &) =
delete;
337 mutable Lock lock_{};
@ F
F-type formatting.
Definition ogr_geometry.h:39