41 #include <unordered_map> 51 bool try_lock() {
return true; }
57 class KeyNotFound :
public std::invalid_argument {
59 KeyNotFound() : std::invalid_argument(
"key_not_found") {}
62 template <
typename K,
typename V>
68 KeyValuePair(
const K& k,
const V& v) : key(k), value(v) {}
83 template <
class Key,
class Value,
class Lock = NullLock,
84 class Map = std::unordered_map<
85 Key,
typename std::list<KeyValuePair<Key, Value>>::iterator>>
88 typedef KeyValuePair<Key, Value> node_type;
89 typedef std::list<KeyValuePair<Key, Value>> list_type;
91 typedef Lock lock_type;
92 using Guard = std::lock_guard<lock_type>;
102 explicit Cache(
size_t maxSize = 64,
size_t elasticity = 10)
103 : maxSize_(maxSize), elasticity_(elasticity) {}
104 virtual ~Cache() =
default;
105 size_t size()
const {
107 return cache_.size();
111 return cache_.empty();
118 void insert(
const Key& k,
const Value& v) {
120 const auto iter = cache_.find(k);
121 if (iter != cache_.end()) {
122 iter->second->value = v;
123 keys_.splice(keys_.begin(), keys_, iter->second);
127 keys_.emplace_front(k, v);
128 cache_[k] = keys_.begin();
131 bool tryGet(
const Key& kIn, Value& vOut) {
133 const auto iter = cache_.find(kIn);
134 if (iter == cache_.end()) {
137 keys_.splice(keys_.begin(), keys_, iter->second);
138 vOut = iter->second->value;
145 const Value&
get(
const Key& k) {
147 const auto iter = cache_.find(k);
148 if (iter == cache_.end()) {
151 keys_.splice(keys_.begin(), keys_, iter->second);
152 return iter->second->value;
157 Value getCopy(
const Key& k) {
160 bool remove(
const Key& k) {
162 auto iter = cache_.find(k);
163 if (iter == cache_.end()) {
166 keys_.erase(iter->second);
170 bool contains(
const Key& k) {
172 return cache_.find(k) != cache_.end();
175 bool getOldestEntry(Key& kOut, Value& vOut) {
177 if( keys_.empty() ) {
180 kOut = keys_.back().key;
181 vOut = keys_.back().value;
185 size_t getMaxSize()
const {
return maxSize_; }
186 size_t getElasticity()
const {
return elasticity_; }
187 size_t getMaxAllowedSize()
const {
return maxSize_ + elasticity_; }
188 template <
typename F>
189 void cwalk(F& f)
const {
191 std::for_each(keys_.begin(), keys_.end(), f);
196 size_t maxAllowed = maxSize_ + elasticity_;
197 if (maxSize_ == 0 || cache_.size() <= maxAllowed) {
201 while (cache_.size() > maxSize_) {
202 cache_.erase(keys_.back().key);
211 Cache(
const Cache&) =
delete;
212 Cache& operator=(
const Cache&) =
delete;
214 mutable Lock lock_{};