Chatterino
lrucache.hpp
Go to the documentation of this file.
1 /*
2  * File: lrucache.hpp
3  * Original Author: Alexander Ponomarev
4  *
5  * Created on June 20, 2013, 5:09 PM
6  */
7 
8 #ifndef _LRUCACHE_HPP_INCLUDED_
9 #define _LRUCACHE_HPP_INCLUDED_
10 
11 #include <cstddef>
12 #include <list>
13 #include <stdexcept>
14 #include <unordered_map>
15 
16 namespace cache {
17 
18 template <typename key_t, typename value_t>
19 class lru_cache
20 {
21 public:
22  typedef typename std::pair<key_t, value_t> key_value_pair_t;
23  typedef typename std::list<key_value_pair_t>::iterator list_iterator_t;
24 
25  lru_cache(size_t max_size)
26  : _max_size(max_size)
27  {
28  }
29 
30  // copy doesn't make sense since we reference the linked list elements directly
33 
34  // move
36  : _cache_items_list(std::move(other._cache_items_list))
37  , _cache_items_map(std::move(other._cache_items_map))
38  , _max_size(other._max_size)
39  {
40  other._cache_items_list.clear();
41  other._cache_items_map.clear();
42  }
43 
45  {
46  _cache_items_list = std::move(other._cache_items_list);
47  _cache_items_map = std::move(other._cache_items_map);
48  _max_size = other._max_size;
49  other._cache_items_list.clear();
50  other._cache_items_map.clear();
51  return *this;
52  }
53 
54  void put(const key_t &key, const value_t &value)
55  {
56  auto it = _cache_items_map.find(key);
57  _cache_items_list.push_front(key_value_pair_t(key, value));
58  if (it != _cache_items_map.end())
59  {
60  _cache_items_list.erase(it->second);
61  _cache_items_map.erase(it);
62  }
63  _cache_items_map[key] = _cache_items_list.begin();
64 
65  if (_cache_items_map.size() > _max_size)
66  {
67  auto last = _cache_items_list.end();
68  last--;
69  _cache_items_map.erase(last->first);
70  _cache_items_list.pop_back();
71  }
72  }
73 
74  const value_t &get(const key_t &key)
75  {
76  auto it = _cache_items_map.find(key);
77  if (it == _cache_items_map.end())
78  {
79  throw std::range_error("There is no such key in cache");
80  }
81  else
82  {
83  _cache_items_list.splice(_cache_items_list.begin(),
84  _cache_items_list, it->second);
85  return it->second->second;
86  }
87  }
88 
89  bool exists(const key_t &key) const
90  {
91  return _cache_items_map.find(key) != _cache_items_map.end();
92  }
93 
94  size_t size() const
95  {
96  return _cache_items_map.size();
97  }
98 
99  auto begin() const
100  {
101  return _cache_items_list.begin();
102  }
103 
104  auto end() const
105  {
106  return _cache_items_list.end();
107  }
108 
109 private:
110  std::list<key_value_pair_t> _cache_items_list;
111  std::unordered_map<key_t, list_iterator_t> _cache_items_map;
112  size_t _max_size;
113 };
114 
115 } // namespace cache
116 
117 #endif /* _LRUCACHE_HPP_INCLUDED_ */
std::list< key_value_pair_t >::iterator list_iterator_t
Definition: lrucache.hpp:23
Definition: SeventvEventAPISubscription.hpp:67
Definition: lrucache.hpp:19
auto end() const
Definition: lrucache.hpp:104
bool exists(const key_t &key) const
Definition: lrucache.hpp:89
std::pair< key_t, value_t > key_value_pair_t
Definition: lrucache.hpp:22
size_t size() const
Definition: lrucache.hpp:94
lru_cache(size_t max_size)
Definition: lrucache.hpp:25
lru_cache< key_t, value_t > & operator=(lru_cache< key_t, value_t > &)=delete
lru_cache(lru_cache< key_t, value_t > &&other)
Definition: lrucache.hpp:35
auto begin() const
Definition: lrucache.hpp:99
lru_cache< key_t, value_t > & operator=(lru_cache< key_t, value_t > &&other)
Definition: lrucache.hpp:44
void put(const key_t &key, const value_t &value)
Definition: lrucache.hpp:54
Definition: lrucache.hpp:16