OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LruCache.h
Go to the documentation of this file.
1 /*
2  * File: lrucache.hpp
3  * Author: Alexander Ponomarev
4  *
5  * Created on June 20, 2013, 5:09 PM
6  */
7 
8 #pragma once
9 
10 #include <cstddef>
11 #include <list>
12 #include <memory>
13 #include <type_traits>
14 #include <unordered_map>
15 
16 template <class T>
17 struct is_shared_ptr : std::false_type {};
18 
19 template <class T>
20 struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
21 
23 
24 template <typename key_t, typename value_t, class hash_t = std::hash<key_t>>
25 class LruCache {
26  private:
27  using key_value_pair_t = typename std::pair<key_t, value_t>;
28  using cache_list_t = typename std::list<key_value_pair_t>;
29  using list_iterator_t = typename cache_list_t::iterator;
30  using map_t = typename std::unordered_map<key_t, list_iterator_t, hash_t>;
31  using map_t_iterator = typename map_t::iterator;
32 
33  public:
34  LruCache(EvictionMetricType eviction_metric_type, const size_t max_size)
35  : eviction_metric_type_(eviction_metric_type)
36  , max_size_(max_size)
37  , total_byte_size_(0) {}
38 
39  size_t put(const key_t& key, value_t&& value) {
41  auto it = cache_items_map_.find(key);
42  cache_items_list_.emplace_front(key, std::forward<value_t&&>(value));
43  return putCommon(it, key);
44  }
45 
46  size_t put(const key_t& key, const value_t& value) {
48  auto it = cache_items_map_.find(key);
49  cache_items_list_.emplace_front(key, std::forward<const value_t&&>(value));
50  return putCommon(it, key);
51  }
52 
53  void erase(const key_t& key) {
54  auto it = cache_items_map_.find(key);
55  if (it != cache_items_map_.end()) {
56  total_byte_size_ -= getValueSize(it->second);
57  cache_items_list_.erase(it->second);
58  cache_items_map_.erase(it);
59  }
60  }
61 
62  value_t* get(const key_t& key) {
63  auto it = cache_items_map_.find(key);
64  if (it == cache_items_map_.end()) {
65  return nullptr;
66  }
67  cache_items_list_.splice(cache_items_list_.begin(), cache_items_list_, it->second);
68  return &it->second->second;
69  }
70  using const_list_iterator_t = typename cache_list_t::const_iterator;
71 
72  const_list_iterator_t find(const key_t& key) const {
73  auto it = cache_items_map_.find(key);
74  if (it == cache_items_map_.end()) {
75  return cend();
76  } else {
77  return it->second;
78  }
79  }
80 
81  const_list_iterator_t cbegin() const { return (cache_items_list_.cbegin()); }
82 
83  const_list_iterator_t cend() const { return (cache_items_list_.cend()); }
84 
85  void clear() {
86  cache_items_list_.clear();
87  cache_items_map_.clear();
88  total_byte_size_ = 0;
89  }
90 
91  size_t computeNumEntriesToEvict(const float fraction) {
92  return std::min(
93  std::min(std::max(static_cast<size_t>(cache_items_map_.size() * fraction),
94  static_cast<size_t>(1)),
95  cache_items_map_.size()),
96  cache_items_map_.size());
97  }
98 
99  size_t evictNEntries(const size_t n) { return evictCommon(n); }
100 
101  size_t size() const {
103  ? cache_items_list_.size()
105  }
106 
107  private:
108  size_t putCommon(map_t_iterator& it, key_t const& key) {
109  size_t entries_erased = 0;
110  if (it != cache_items_map_.end()) {
111  total_byte_size_ -= getValueSize(it->second);
112  cache_items_list_.erase(it->second);
113  cache_items_map_.erase(it);
114  entries_erased++;
115  }
116  cache_items_map_[key] = cache_items_list_.begin();
117 
119  cache_items_map_.size() > max_size_) ||
122  auto last = cache_items_list_.end();
123  last--;
124  auto target_it = cache_items_map_.find(last->first);
125  total_byte_size_ -= getValueSize(target_it->second);
126  cache_items_map_.erase(target_it);
127  cache_items_list_.pop_back();
128  entries_erased++;
129  }
130  return entries_erased;
131  }
132 
133  size_t evictCommon(const size_t entries_to_evict) {
134  auto last = cache_items_list_.end();
135  size_t entries_erased = 0;
136  while (entries_erased < entries_to_evict && last != cache_items_list_.begin()) {
137  last--;
138  total_byte_size_ -= getValueSize(last->second);
139  cache_items_map_.erase(last->first);
140  last = cache_items_list_.erase(last);
141  entries_erased++;
142  }
143  return entries_erased;
144  }
145 
146  size_t getValueSize(const value_t& value) {
147  if constexpr (std::is_pointer_v<value_t> || is_shared_ptr<value_t>::value) {
148  // 'value == nullptr' represents a call from the `get_or_wait` function
149  return value ? value->size() : 0;
150  } else {
151  return value.size();
152  }
153  }
154 
155  size_t getValueSize(const list_iterator_t& it) { return getValueSize(it->second); }
156 
160  size_t max_size_;
162 };
typename std::unordered_map< CompilationContext, list_iterator_t, std::hash< CompilationContext > > map_t
Definition: LruCache.h:30
void clear()
Definition: LruCache.h:85
size_t getValueSize(const list_iterator_t &it)
Definition: LruCache.h:155
typename cache_list_t::iterator list_iterator_t
Definition: LruCache.h:29
size_t computeNumEntriesToEvict(const float fraction)
Definition: LruCache.h:91
LruCache(EvictionMetricType eviction_metric_type, const size_t max_size)
Definition: LruCache.h:34
void erase(const key_t &key)
Definition: LruCache.h:53
size_t putCommon(map_t_iterator &it, key_t const &key)
Definition: LruCache.h:108
size_t put(const key_t &key, const value_t &value)
Definition: LruCache.h:46
typename std::pair< CompilationContext, value_t > key_value_pair_t
Definition: LruCache.h:27
size_t put(const key_t &key, value_t &&value)
Definition: LruCache.h:39
size_t evictCommon(const size_t entries_to_evict)
Definition: LruCache.h:133
size_t evictNEntries(const size_t n)
Definition: LruCache.h:99
const_list_iterator_t cend() const
Definition: LruCache.h:83
map_t cache_items_map_
Definition: LruCache.h:158
const_list_iterator_t cbegin() const
Definition: LruCache.h:81
cache_list_t cache_items_list_
Definition: LruCache.h:157
EvictionMetricType eviction_metric_type_
Definition: LruCache.h:159
size_t max_size_
Definition: LruCache.h:160
size_t total_byte_size_
Definition: LruCache.h:161
typename map_t::iterator map_t_iterator
Definition: LruCache.h:31
typename std::list< key_value_pair_t > cache_list_t
Definition: LruCache.h:28
EvictionMetricType
Definition: LruCache.h:22
size_t getValueSize(const value_t &value)
Definition: LruCache.h:146
constexpr double n
Definition: Utm.h:38
size_t size() const
Definition: LruCache.h:101
const_list_iterator_t find(const key_t &key) const
Definition: LruCache.h:72
typename cache_list_t::const_iterator const_list_iterator_t
Definition: LruCache.h:70