28 #include <olp/core/porting/try_emplace.h>
65 template <
typename Key,
typename Value,
66 typename CacheCostFunc = CacheCost<Value>,
67 typename Compare = std::less<Key>,
68 template <
typename>
class Alloc = std::allocator>
72 std::map<Key, Bucket, Compare, Alloc<std::pair<const Key, Bucket> > >;
96 inline const Key&
key()
const;
103 inline const Value&
value()
const;
107 typename MapType::const_iterator
m_it;
197 template <
typename,
typename,
typename,
typename,
template <
typename>
class>
200 explicit const_iterator(
const typename MapType::const_iterator& it) {
233 LruCache(std::size_t maxSize, CacheCostFunc cacheCostFunc = CacheCostFunc(),
236 : cache_cost_func_(std::move(cacheCostFunc)),
237 map_(compare, alloc),
248 : eviction_callback_(std::move(other.eviction_callback_)),
249 cache_cost_func_(std::move(other.cache_cost_func_)),
250 map_(std::move(other.map_)),
251 first_(other.first_ != map_.end() ? map_.find(other.first_->first)
253 last_(other.last_ != map_.end() ? map_.find(other.last_->first)
255 max_size_(other.max_size_),
256 size_(other.size_) {}
263 eviction_callback_ = std::move(other.eviction_callback_);
264 cache_cost_func_ = std::move(other.cache_cost_func_);
265 map_ = std::move(other.map_);
266 first_ = other.first_ != map_.end() ? map_.find(other.first_->first)
269 other.last_ != map_.end() ? map_.find(other.last_->first) : map_.end();
270 std::swap(max_size_, other.max_size_);
271 std::swap(size_, other.size_);
298 template <
typename _Key,
typename _Value>
299 std::pair<const_iterator, bool>
Insert(_Key&& key, _Value&& value);
316 template <
typename _Value>
328 auto it = map_.find(key);
329 if (it == map_.end())
356 std::size_t
Size()
const {
return size_; }
389 auto it = map_.find(key);
390 if (it != map_.end())
406 auto it = map_.find(key);
420 const Value&
Find(
const Key& key,
const Value& nullValue) {
422 return it ==
end() ? nullValue : it.
value();
445 first_ = last_ = map_.end();
462 eviction_callback_ = std::move(func);
466 friend struct CacheLruChecker;
469 CacheCostFunc cache_cost_func_;
471 typename MapType::iterator first_;
472 typename MapType::iterator last_;
473 std::size_t max_size_;
478 inline bool IsEqual(
const Key& key1,
const Key& key2) {
479 auto comp = map_.key_comp();
480 return !comp(key1, key2) && !comp(key2, key1);
486 using Iterator =
typename MapType::iterator;
490 #if defined(_MSC_VER) && _MSC_VER < 1900
491 inline Bucket(Iterator next, Iterator previous, Value&& value)
492 : next_(std::move(next)),
493 previous_(std::move(previous)),
494 value_(std::move(value)) {}
495 inline Bucket(Iterator next, Iterator previous,
const Value& value)
496 : next_(std::move(next)),
497 previous_(std::move(previous)),
499 inline Bucket(
const Bucket&) =
delete;
500 inline Bucket(Bucket&& other)
501 : next_(std::move(other.next_)),
502 previous_(std::move(other.previous_)),
503 value_(std::move(other.value_)) {}
510 inline void setNext(Iterator it) { next_ = std::move(it); }
512 inline void setPrevious(Iterator it) { previous_ = std::move(it); }
515 void Erase(
typename MapType::iterator it,
bool);
516 void AddInternal(
const typename MapType::iterator& it, std::size_t cost,
517 std::size_t* oldCost =
nullptr);
518 void Promote(
const typename MapType::iterator& it);
521 while (size_ > max_size_)
526 template <
typename Key,
typename Value,
typename CacheCostFunc,
527 typename Compare,
template <
typename>
class Alloc>
528 template <
typename _Key,
typename _Value>
554 -> std::pair<const_iterator, bool> {
555 Bucket bucket{map_.end(), map_.end(), std::forward<_Value>(value)};
558 std::size_t valueCost = cache_cost_func_(bucket.value_);
559 if (valueCost > max_size_)
563 porting::try_emplace(map_, std::forward<_Key>(key), std::move(bucket));
566 AddInternal(it.first, valueCost);
573 template <
typename Key,
typename Value,
typename CacheCostFunc,
574 typename Compare,
template <
typename>
class Alloc>
575 template <
typename _Value>
593 Key key, _Value&& value) -> std::pair<const_iterator, bool> {
596 auto it = map_.lower_bound(key);
597 if (it != map_.end() && IsEqual(key, it->first)) {
599 std::size_t oldCost = cache_cost_func_(it->second.value_);
600 it->second.value_ = std::forward<_Value>(value);
601 std::size_t newCost = cache_cost_func_(it->second.value_);
602 AddInternal(it, newCost, &oldCost);
606 Bucket bucket{map_.end(), map_.end(), std::forward<_Value>(value)};
607 std::size_t newCost = cache_cost_func_(bucket.value_);
608 if (newCost > max_size_)
612 map_.insert(it, std::make_pair(std::move(key), std::move(bucket)));
613 AddInternal(new_it, newCost);
618 template <
typename Key,
typename Value,
typename CacheCostFunc,
619 typename Compare,
template <
typename>
class Alloc>
621 const typename MapType::iterator& it) {
626 it->second.previous_->second.setNext(it->second.next_);
627 if (it->second.next_ != map_.end())
628 it->second.next_->second.setPrevious(it->second.previous_);
630 last_ = it->second.previous_;
633 it->second.setPrevious(map_.end());
634 it->second.setNext(first_);
637 first_->second.setPrevious(it);
641 template <
typename Key,
typename Value,
typename CacheCostFunc,
642 typename Compare,
template <
typename>
class Alloc>
643 void LruCache<Key, Value, CacheCostFunc, Compare, Alloc>::AddInternal(
644 const typename MapType::iterator& it, std::size_t cost,
645 std::size_t* oldCost) {
648 if (map_.size() == 1) {
650 assert(last_ == map_.end() && first_ == map_.end());
654 it->second.setNext(first_);
655 first_->second.setPrevious(it);
661 size_ += cost - *oldCost;
668 template <
typename Key,
typename Value,
typename CacheCostFunc,
669 typename Compare,
template <
typename>
class Alloc>
671 typename MapType::iterator it,
bool doEvictionCallback) {
672 std::size_t cost = cache_cost_func_(it->second.value_);
674 if (it->second.next_ == map_.end())
675 last_ = it->second.previous_;
677 it->second.next_->second.setPrevious(it->second.previous_);
679 if (it->second.previous_ == map_.end())
680 first_ = it->second.next_;
682 it->second.previous_->second.setNext(it->second.next_);
684 if (doEvictionCallback && eviction_callback_)
685 eviction_callback_(it->first, std::move(it->second.value_));
691 template <
typename Key,
typename Value,
typename CacheCostFunc,
692 typename Compare,
template <
typename>
class Alloc>
693 void LruCache<Key, Value, CacheCostFunc, Compare, Alloc>::PopLast() {
695 assert(last_ != map_.end());
697 assert(last_->second.next_ == map_.end());
702 template <
typename Key,
typename Value,
typename CacheCostFunc,
703 typename Compare,
template <
typename>
class Alloc>
709 template <
typename Key,
typename Value,
typename CacheCostFunc,
710 typename Compare,
template <
typename>
class Alloc>
713 return m_it->second.value_;
716 template <
typename Key,
typename Value,
typename CacheCostFunc,
717 typename Compare,
template <
typename>
class Alloc>
721 return this->m_it == other.
m_it;
724 template <
typename Key,
typename Value,
typename CacheCostFunc,
725 typename Compare,
template <
typename>
class Alloc>
726 inline typename LruCache<Key, Value, CacheCostFunc, Compare,
730 this->m_it = this->m_it->second.next_;
734 template <
typename Key,
typename Value,
typename CacheCostFunc,
735 typename Compare,
template <
typename>
class Alloc>
740 typename MapType::const_iterator old_value = this->m_it;
741 this->m_it = this->m_it->second.next_;
745 template <
typename Key,
typename Value,
typename CacheCostFunc,
746 typename Compare,
template <
typename>
class Alloc>
747 inline typename LruCache<Key, Value, CacheCostFunc, Compare,
751 this->m_it = this->m_it->second.m_previous;
755 template <
typename Key,
typename Value,
typename CacheCostFunc,
756 typename Compare,
template <
typename>
class Alloc>
761 typename MapType::const_iterator old_value = this->m_it;
762 this->m_it = this->m_it->second.m_previous;
A type of objects to be stored.
Definition: LruCache.h:89
const Key & key() const
Gets the key of the ValueType object.
Definition: LruCache.h:705
MapType::const_iterator m_it
A typename of the map constant iterator.
Definition: LruCache.h:107
const Value & value() const
Gets the value of the ValueType object.
Definition: LruCache.h:712
A constant iterator of the LruCache object.
Definition: LruCache.h:111
bool operator!=(const const_iterator &other) const
Checks whether the values of the const_iterator parameter are not the same as the values of the other...
Definition: LruCache.h:152
std::ptrdiff_t difference_type
A typedef for the difference type.
Definition: LruCache.h:116
const value_type & reference
A typedef for the ValueType constant reference.
Definition: LruCache.h:120
const_iterator()=default
Creates a constant iterator object.
std::bidirectional_iterator_tag iterator_category
A typedef for the iterator category.
Definition: LruCache.h:114
const_iterator(const const_iterator &)=default
Creates a constant iterator object.
pointer operator->() const
Gets a pointer to this object.
Definition: LruCache.h:194
reference operator*() const
Gets a reference to this object.
Definition: LruCache.h:187
bool operator==(const const_iterator &other) const
Checks whether the values of the const_iterator parameter are the same as the values of the other par...
Definition: LruCache.h:719
const_iterator & operator++()
Iterates to the next LruCache object.
Definition: LruCache.h:729
ValueType value_type
A typedef for the ValueType type.
Definition: LruCache.h:118
const value_type * pointer
A typedef for the ValueType constant pointer.
Definition: LruCache.h:122
const_iterator & operator--()
Iterates to the previous LruCache object.
Definition: LruCache.h:750
const_iterator & operator=(const const_iterator &)=default
Copies this and the specified iterator to this.
A generic key-value LRU cache.
Definition: LruCache.h:69
std::size_t Size() const
Gets the current size of the cache.
Definition: LruCache.h:356
const_iterator Erase(const_iterator &it)
Removes a key from the cache.
Definition: LruCache.h:343
const_iterator FindNoPromote(const Key &key) const
Finds a value in the cache.
Definition: LruCache.h:405
void Resize(size_t maxSize)
Sets the new maximum size of the cache.
Definition: LruCache.h:373
typename MapType::key_compare CompareType
An alias for the key comparison function.
Definition: LruCache.h:79
LruCache(const AllocType &alloc=AllocType())
Creates an LruCache instance.
Definition: LruCache.h:217
void SetEvictionCallback(EvictionFunction func)
Sets a function that is invoked when a value is evicted from the cache.
Definition: LruCache.h:461
std::pair< const_iterator, bool > Insert(_Key &&key, _Value &&value)
Inserts a key-value pair in the cache.
bool Erase(const Key &key)
Removes a key from the cache.
Definition: LruCache.h:327
std::function< void(const Key &, Value &&)> EvictionFunction
An alias for the eviction function.
Definition: LruCache.h:76
typename MapType::allocator_type AllocType
An alias for the cache allocator type.
Definition: LruCache.h:82
LruCache(std::size_t maxSize, CacheCostFunc cacheCostFunc=CacheCostFunc(), const CompareType &compare=CompareType(), const AllocType &alloc=AllocType())
Creates an LruCache instance.
Definition: LruCache.h:233
const_iterator rend() const
Returns a reverse constant iterator to the end.
Definition: LruCache.h:435
const_iterator rbegin() const
Returns a reverse constant iterator to the beginning.
Definition: LruCache.h:432
const_iterator Find(const Key &key)
Finds a value in the cache.
Definition: LruCache.h:388
LruCache & operator=(LruCache &&other) noexcept
The default move assignment operator.
Definition: LruCache.h:262
const Value & Find(const Key &key, const Value &nullValue)
Finds a value in the cache.
Definition: LruCache.h:420
void Clear()
Removes all items from the cache.
Definition: LruCache.h:443
LruCache(const LruCache &)=delete
The deleted copy constructor.
std::size_t GetMaxSize() const
Gets the maximum size of the cache.
Definition: LruCache.h:363
std::pair< const_iterator, bool > InsertOrAssign(Key key, _Value &&value)
Inserts a key-value pair in the cache or updates an existing key-value pair.
LruCache & operator=(const LruCache &)=delete
The deleted assignment operator.
LruCache(LruCache &&other) noexcept
The default move constructor.
Definition: LruCache.h:247
const_iterator begin() const
Returns a constant iterator to the beginning.
Definition: LruCache.h:426
const_iterator end() const
Returns a constant iterator to the end.
Definition: LruCache.h:429
Rules all the other namespaces.
Definition: AppleSignInProperties.h:24
The default cost operator for LruCache.
Definition: LruCache.h:41
std::size_t operator()(const T &) const
Gets the size of the specified object.
Definition: LruCache.h:43