mod_servlet
C++Servlets
 All Classes Files Functions Variables Typedefs Macros Pages
lru_map.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2016 Alexei Novakov
3 https://github.com/novalexei
4 
5 Distributed under the Boost Software License, Version 1.0.
6 http://boost.org/LICENSE_1_0.txt
7 */
8 #ifndef MOD_SERVLET_TIMED_MAP_H
9 #define MOD_SERVLET_TIMED_MAP_H
10 
11 #include <map>
12 #include <unordered_map>
13 
14 #include <servlet/lib/linked_map.h>
15 
22 namespace servlet
23 {
24 
28 template<typename T>
29 class timed_entry
30 {
31 public:
32  typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::system_clock::duration> tp_type;
33 
34  timed_entry(const T& value) : _value{value}, _last_modified{std::chrono::system_clock::now()} {}
35  timed_entry(T&& value) : _value{std::move(value)}, _last_modified{std::chrono::system_clock::now()} {}
36  timed_entry(const timed_entry& other) : _value{other._value}, _last_modified{std::chrono::system_clock::now()} {}
37  timed_entry(timed_entry&& other) : _value{std::move(other._value)}, _last_modified{std::chrono::system_clock::now()} {}
38 
39  ~timed_entry() = default;
40 
41  timed_entry& operator=(const timed_entry& other)
42  {
43  _value = other._value; _last_modified = other._last_modified;
44  return *this;
45  }
46  timed_entry& operator=(timed_entry&& other)
47  {
48  _value = std::move(other._value); _last_modified = other._last_modified;
49  return *this;
50  }
51  timed_entry& operator=(const T& value) { _value = value; update_last_modified(); return *this; }
52  timed_entry& operator=(T&& value) { _value = std::move(value); update_last_modified(); return *this; }
53 
54  operator T&() & { return _value; }
55  operator T&&() && { return std::move(_value); }
56 
57  T& operator*() { return _value; }
58  const T& operator*() const { return _value; }
59 
60  tp_type last_modified() { return _last_modified; }
61  void update_last_modified() { _last_modified = std::chrono::system_clock::now(); }
62 
63 private:
64  T _value;
65  tp_type _last_modified;
66 };
85 template<typename _Key, typename _Tp, typename _MT>
86 class lru_map : public linked_map<_Key, _Tp, _MT>
87 {
88 public:
93 
97  typedef typename base_type::key_type key_type;
106 
114  typedef typename base_type::reference reference;
122  typedef typename base_type::pointer pointer;
130  typedef typename base_type::size_type size_type;
135 
139  typedef typename base_type::iterator iterator;
152 
160  lru_map(std::size_t timeout_sec) : base_type{}, _timeout_sec{timeout_sec} {}
167  lru_map(const lru_map& other) : base_type{other}, _timeout_sec{other._timeout_sec} {}
174  lru_map(lru_map&& other) : base_type{std::move(other)}, _timeout_sec{other._timeout_sec} {}
175 
176  ~lru_map() = default;
177 
186  lru_map& operator=(const lru_map& other)
187  {
188  _timeout_sec = other._timeout_sec; base_type::operator=(other);
189  return *this;
190  }
200  {
201  _timeout_sec = other._timeout_sec; base_type::operator=(std::move(other));
202  return *this;
203  }
204 
211  void set_timeout(std::size_t timeout_sec) { _timeout_sec = timeout_sec; }
212 
221  template<typename KeyType>
222  bool contains_key(const KeyType &key) const
223  {
224  std::lock_guard<std::mutex> guard{_mutex};
225  return base_type::contains_key(key);
226  }
227 
234  void clear()
235  {
236  std::lock_guard<std::mutex> guard{_mutex};
238  }
239 
254  template<typename KeyType>
255  optional_ref<const mapped_type> get(const KeyType& key) const
256  {
257  std::lock_guard<std::mutex> guard{_mutex};
258  return base_type::get(key);
259  }
274  template<typename KeyType>
275  optional_ref<mapped_type> get(const KeyType& key)
276  {
277  std::lock_guard<std::mutex> guard{_mutex};
278  return base_type::get(key);
279  }
280 
292  template<class... Args>
293  bool put(key_type&& key, Args &&... args)
294  {
295  std::lock_guard<std::mutex> guard{_mutex};
296  return base_type::put(std::move(key), std::forward<Args>(args)...);
297  }
309  template<class... Args>
310  bool put(const key_type& key, Args &&... args)
311  {
312  std::lock_guard<std::mutex> guard{_mutex};
313  return base_type::put(key, std::forward<Args>(args)...);
314  }
315 
327  template<class... Args>
328  bool try_put(key_type&& key, Args &&... args)
329  {
330  std::lock_guard<std::mutex> guard{_mutex};
331  return base_type::try_put(std::move(key), std::forward<Args>(args)...);
332  }
333 
345  template<class... Args>
346  bool try_put(const key_type& key, Args &&... args)
347  {
348  std::lock_guard<std::mutex> guard{_mutex};
349  return base_type::try_put(key, std::forward<Args>(args)...);
350  }
351 
364  template<typename KeyType>
365  bool erase(const KeyType &key)
366  {
367  std::lock_guard<std::mutex> guard{_mutex};
368  return base_type::erase(key);
369  }
370 protected:
375  void update(value_type& val) const override { val.second.update_last_modified(); }
376 
381  void purge() override
382  {
383  auto now = std::chrono::system_clock::now();
384  auto b = this->begin();
385  auto e = this->end();
386  while (b != e &&
387  std::chrono::duration_cast<std::chrono::seconds>(now-b->second.last_modified()).count() > _timeout_sec)
388  {
389  const key_type& key_ref = b->first;
390  ++b;
391  this->erase(key_ref);
392  }
393  }
394 private:
395  std::size_t _timeout_sec;
396  mutable std::mutex _mutex;
397 };
398 
402 template<typename _Key, typename _Value, typename _Compare = std::less<>,
403  typename _Alloc = std::allocator<std::pair<const _Key,
404  typename std::list<std::pair<const _Key &, _Value>>::iterator>>>
405 using lru_tree_map = lru_map<_Key, timed_entry<_Value>,
406  std::map<_Key, typename std::list<std::pair<const _Key &, timed_entry<_Value>>>::iterator,
407  _Compare, _Alloc>>;
408 
412 template<typename _Key, typename _Value, typename _Hash = std::hash<_Key>,
413  typename _Pred = std::equal_to<_Key>,
414  typename _Alloc = std::allocator<std::pair<const _Key,
415  typename std::list<std::pair<const _Key &, _Value>>::iterator>>>
416 using lru_hash_map = lru_map<_Key, timed_entry<_Value>,
417  std::unordered_map<_Key, typename std::list<std::pair<const _Key &, timed_entry<_Value>>>::iterator,
418  _Hash, _Pred, _Alloc>>;
419 
420 } // end of servlet namespace
421 
422 #endif // MOD_SERVLET_TIMED_MAP_H
bool contains_key(const KeyType &key) const
Tests whether value with a given key exists in this container.
Definition: lru_map.h:222
lru_map & operator=(lru_map &&other)
The move assignment.
Definition: lru_map.h:199
map_type::difference_type difference_type
A signed integral type to represent distance between iterators.
Definition: linked_map.h:113
linked_map & operator=(const linked_map &m)=default
The copy assignment.
lru_map & operator=(const lru_map &other)
The copy assignment.
Definition: lru_map.h:186
map_type::size_type size_type
An unsigned integral type to represent the size of this container.
Definition: linked_map.h:109
list_type::iterator iterator
Bidirectional iterator type.
Definition: linked_map.h:118
base_type::const_pointer const_pointer
Constant pointer to value_type type.
Definition: lru_map.h:126
bool erase(const KeyType &key)
Erase element.
Definition: lru_map.h:365
base_type::difference_type difference_type
A signed integral type to represent distance between iterators.
Definition: lru_map.h:134
Optional reference implementation.
Definition: optional.h:221
base_type::pointer pointer
Pointer to value_type type.
Definition: lru_map.h:122
base_type::mapped_type mapped_type
Container's mapped type.
Definition: lru_map.h:101
bool put(key_type &&key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: lru_map.h:293
void purge() override
Removes all the elements from the cache which has not been accessed for longer than this cache timeou...
Definition: lru_map.h:381
void update(value_type &val) const override
Updates access timestamp of the element.
Definition: lru_map.h:375
base_type::iterator iterator
Bidirectional iterator type.
Definition: lru_map.h:139
void clear()
Clear content.
Definition: lru_map.h:234
base_type::const_reference const_reference
const value_type&
Definition: lru_map.h:118
bool contains_key(const KeyType &key) const
Tests whether value with a given key exists in this container.
Definition: linked_map.h:193
lru_map(const lru_map &other)
Copy constructor.
Definition: lru_map.h:167
linked_map< _Key, _Tp, _MT > base_type
Type of base linked_map
Definition: lru_map.h:92
bool erase(const KeyType &key)
Erase element.
Definition: linked_map.h:381
base_type::value_type value_type
Container's value type: std::pair<const key_type&, mapped_type>
Definition: lru_map.h:105
const value_type * const_pointer
Constant pointer to value_type type.
Definition: linked_map.h:105
base_type::key_type key_type
Container's key type.
Definition: lru_map.h:97
Implementation of linked associative container.
Definition: linked_map.h:57
value_type & reference
value_type&
Definition: linked_map.h:93
list_type::reverse_iterator reverse_iterator
Reverse iterator type.
Definition: linked_map.h:126
lru_map(lru_map &&other)
Move constructor.
Definition: lru_map.h:174
bool try_put(key_type &&key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: lru_map.h:328
iterator end() noexcept
Return iterator to end of the container.
Definition: linked_map.h:405
void set_timeout(std::size_t timeout_sec)
Sets the timeout after which inactive elements will be purged from the cache.
Definition: lru_map.h:211
base_type::reverse_iterator reverse_iterator
Reverse iterator type.
Definition: lru_map.h:147
base_type::reference reference
value_type&
Definition: lru_map.h:114
base_type::const_iterator const_iterator
Bidirectional constant iterator type.
Definition: lru_map.h:143
bool try_put(const key_type &key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: lru_map.h:346
base_type::allocator_type allocator_type
Container's allocator type.
Definition: lru_map.h:110
std::pair< const _Key &, _Tp > value_type
Container's value type: std::pair<const key_type&, mapped_type>
Definition: linked_map.h:71
map_type::allocator_type allocator_type
Container's allocator type.
Definition: linked_map.h:89
bool try_put(key_type &&key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: linked_map.h:331
value_type * pointer
Pointer to value_type type.
Definition: linked_map.h:101
lru_map(std::size_t timeout_sec)
Constructs an empty container, with no elements.
Definition: lru_map.h:160
bool put(const key_type &key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: lru_map.h:310
const value_type & const_reference
const value_type&
Definition: linked_map.h:97
base_type::const_reverse_iterator const_reverse_iterator
Constant reverse iterator type.
Definition: lru_map.h:151
list_type::const_reverse_iterator const_reverse_iterator
Constant reverse iterator type.
Definition: linked_map.h:130
Implementation of LRU (least recently used) timed cache.
Definition: lru_map.h:86
list_type::const_iterator const_iterator
Bidirectional constant iterator type.
Definition: linked_map.h:122
_Key key_type
Container's key type.
Definition: linked_map.h:63
_Tp mapped_type
Container's mapped type.
Definition: linked_map.h:67
bool put(key_type &&key, Args &&...args)
Associates a value of specified type created with a given arguments with the specified key in this ma...
Definition: linked_map.h:266
optional_ref< const mapped_type > get(const KeyType &key) const
Returns optional_ref object to a value with a specified type, if that value exists and can be casted ...
Definition: linked_map.h:222
void clear()
Clear content.
Definition: linked_map.h:201
iterator begin() noexcept
Returns iterator to beginning of the container.
Definition: linked_map.h:398
Containes the implementation of linked_map class and related type definitions.
base_type::size_type size_type
An unsigned integral type to represent the size of this container.
Definition: lru_map.h:130