Tatooine
cache.h
Go to the documentation of this file.
1#ifndef TATOOINE_CACHE_H
2#define TATOOINE_CACHE_H
3//==============================================================================
4#include <map>
5#include <list>
6#include <optional>
7#include <algorithm>
8//#include <tatooine/memory_usage.h>
9//==============================================================================
10namespace tatooine {
11//==============================================================================
12template <typename Key, typename Value>
13class cache {
14 //----------------------------------------------------------------------------
15 // typedefs
16 //----------------------------------------------------------------------------
17 public:
18 using container_type = std::map<Key, Value>;
19 using const_iterator = typename container_type::const_iterator;
20 using usage_type = std::list<const_iterator>;
21
22 //----------------------------------------------------------------------------
23 // members
24 //----------------------------------------------------------------------------
25 private:
30
31 //----------------------------------------------------------------------------
32 // ctors
33 //----------------------------------------------------------------------------
34 public:
35 cache(uint64_t max_elements = std::numeric_limits<uint64_t>::max(),
36 uint64_t max_memory_usage = std::numeric_limits<uint64_t>::max())
37 : m_max_elements{max_elements}, m_max_memory_usage{max_memory_usage} {}
38 cache(const cache& other)
39 : m_data{other.m_data},
42 for (auto it : other.m_usage) {
43 m_usage.push_back(next(begin(m_data), distance(begin(other.m_data), it)));
44 }
45 }
46 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47 cache(cache&& other) = default;
48 auto& operator=(const cache& other) {
49 m_data = other.m_data;
52 for (auto it : other.m_usage) {
53 m_usage.push_back(next(begin(m_data), distance(begin(other.m_data), it)));
54 }
55 return *this;
56 }
57 cache& operator=(cache&& other) = default;
58
59 //----------------------------------------------------------------------------
60 // methods
61 //----------------------------------------------------------------------------
62 private:
64 while (m_data.size() > m_max_elements
65 //|| (memory_usage().first / 1024.0 > m_max_memory_usage &&
66 // !m_data.empty())
67 ) {
68 m_data.erase(m_usage.back());
69 m_usage.pop_back();
70 }
71 }
72 //----------------------------------------------------------------------------
73 void enqueue(const_iterator it, bool ins) {
74 if (ins) {
75 m_usage.push_front(it);
77 }
78 }
79 //----------------------------------------------------------------------------
81 m_usage.erase(std::find(begin(m_usage), end(m_usage), it));
82 m_usage.push_front(it);
83 }
84
85 public:
86 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
87 auto insert(const Key& key, const Value& value) {
88 auto insertion = m_data.insert(std::pair{key, value});
89 enqueue(insertion.first, insertion.second);
90 return insertion;
91 }
92 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
93 auto insert(Key&& key, const Value& value) {
94 auto insertion = m_data.insert(std::pair{std::move(key), value});
95 enqueue(insertion.first, insertion.second);
96 return insertion;
97 }
98 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99 auto insert(const Key& key, Value&& value) {
100 auto insertion = m_data.insert(std::pair{key, std::move(value)});
101 enqueue(insertion.first, insertion.second);
102 return insertion;
103 }
104 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
105 auto insert(Key&& key, Value&& value) {
106 auto insertion = m_data.insert(std::pair{std::move(key), std::move(value)});
107 enqueue(insertion.first, insertion.second);
108 return insertion;
109 }
110 //----------------------------------------------------------------------------
111 template <typename... Args>
112 auto emplace(const Key& key, Args&&... args) {
113 return insert(key, Value{std::forward<Args>(args)...});
114 }
115 //----------------------------------------------------------------------------
116 const auto& operator[](const Key& key) const { return at(key); }
117 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
118 auto& operator[](const Key& key) { return at(key); }
119 //----------------------------------------------------------------------------
120 const auto& at(const Key& key) const {
121 auto it = m_data.find(key);
122 refresh_usage(it);
123 return *it;
124 }
125 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
126 auto& at(const Key& key) {
127 auto it = m_data.find(key);
128 refresh_usage(it);
129 return *it;
130 }
131 //----------------------------------------------------------------------------
132 std::optional<const_iterator> contains(const Key& key) const {
133 if (auto it = m_data.find(key); it != end(m_data)) {
134 return it;
135 }
136 return {};
137 }
138 //----------------------------------------------------------------------------
139 bool is_cached(const Key& key) const {
140 return m_data.find(key) != end(m_data);
141 }
142 //----------------------------------------------------------------------------
143 auto size() const { return m_data.size(); }
144 //----------------------------------------------------------------------------
145 void clear() {
146 m_data.clear();
147 m_usage.clear();
148 }
149};
150
151//==============================================================================
152} // namespace tatooine
153//==============================================================================
154
155#endif
Definition: cache.h:13
auto & operator[](const Key &key)
Definition: cache.h:118
cache(const cache &other)
Definition: cache.h:38
cache(cache &&other)=default
void capacity_check()
Definition: cache.h:63
void clear()
Definition: cache.h:145
auto insert(const Key &key, Value &&value)
Definition: cache.h:99
auto size() const
Definition: cache.h:143
cache(uint64_t max_elements=std::numeric_limits< uint64_t >::max(), uint64_t max_memory_usage=std::numeric_limits< uint64_t >::max())
Definition: cache.h:35
std::map< Key, Value > container_type
Definition: cache.h:18
const auto & operator[](const Key &key) const
Definition: cache.h:116
const auto & at(const Key &key) const
Definition: cache.h:120
auto emplace(const Key &key, Args &&... args)
Definition: cache.h:112
auto insert(Key &&key, Value &&value)
Definition: cache.h:105
bool is_cached(const Key &key) const
Definition: cache.h:139
void enqueue(const_iterator it, bool ins)
Definition: cache.h:73
cache & operator=(cache &&other)=default
auto & operator=(const cache &other)
Definition: cache.h:48
typename container_type::const_iterator const_iterator
Definition: cache.h:19
void refresh_usage(const_iterator it)
Definition: cache.h:80
auto & at(const Key &key)
Definition: cache.h:126
uint64_t m_max_memory_usage
Definition: cache.h:29
std::list< const_iterator > usage_type
Definition: cache.h:20
auto insert(const Key &key, const Value &value)
Definition: cache.h:87
auto insert(Key &&key, const Value &value)
Definition: cache.h:93
container_type m_data
Definition: cache.h:26
std::optional< const_iterator > contains(const Key &key) const
Definition: cache.h:132
usage_type m_usage
Definition: cache.h:27
uint64_t m_max_elements
Definition: cache.h:28
Definition: algorithm.h:6
constexpr auto distance(Iter const &it0, Iter const &it1)
Definition: iterator_facade.h:372
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
auto next(Iter iter)
Definition: iterator_facade.h:325