8#include <unordered_map>
10#include <dune/common/hash.hh>
15 template <
class Container>
16 struct ConsecutivePolicy;
19 template <
class Container>
20 struct ThreadLocalPolicy;
23 template <
class Container>
24 struct StaticLockedPolicy;
51 template <
class>
class Policy = ThreadLocalPolicy,
52 class Container = std::unordered_map<Key, Data>>
53 class ConcurrentCache;
66 template <
class Container>
67 class ConcurrentCachePolicy;
71 template <
class Container>
74 using key_type =
typename Container::key_type;
75 using data_type =
typename Container::mapped_type;
76 using container_type = Container;
78 template <
class F,
class... Args>
79 data_type
const& get_or_init(key_type
const& key, F&& f, Args&&... args)
const
81 return impl(std::is_default_constructible<data_type>{}, key, FWD(f), FWD(args)...);
86 template <
class F,
class... Args>
87 data_type
const& impl(std::true_type, key_type
const& key, F&& f, Args&&... args)
const
90 auto it = cachedData_.emplace(key, std::move(empty));
92 data_type data = f(key, FWD(args)...);
93 it.first->second = std::move(data);
95 return it.first->second;
99 template <
class F,
class... Args>
100 data_type
const& impl(std::false_type, key_type
const& key, F&& f, Args&&... args)
const
102 auto it = cachedData_.find(key);
103 if (it != cachedData_.end())
106 data_type data = f(key, FWD(args)...);
107 auto it = cachedData_.emplace(key, std::move(data));
108 return it.first->second;
112 mutable container_type cachedData_;
117 template <
class Container>
120 using key_type =
typename Container::key_type;
121 using data_type =
typename Container::mapped_type;
122 using container_type = Container;
124 template <
class F,
class... Args>
125 static data_type
const& get_or_init(key_type
const& key, F&& f, Args&&... args)
127 return impl(std::is_default_constructible<data_type>{}, key, FWD(f), FWD(args)...);
132 template <
class F,
class... Args>
133 static data_type
const& impl(std::true_type, key_type
const& key, F&& f, Args&&... args)
136 thread_local container_type cached_data;
139 auto it = cached_data.emplace(key, std::move(empty));
141 data_type data = f(key, FWD(args)...);
142 it.first->second = std::move(data);
144 return it.first->second;
148 template <
class F,
class... Args>
149 static data_type
const& impl(std::false_type, key_type
const& key, F&& f, Args&&... args)
152 thread_local container_type cached_data;
154 auto it = cached_data.find(key);
155 if (it != cached_data.end())
158 data_type data = f(key, FWD(args)...);
159 auto it = cached_data.emplace(key, std::move(data));
160 return it.first->second;
167 template <
class Container>
170 using key_type =
typename Container::key_type;
171 using data_type =
typename Container::mapped_type;
172 using container_type = Container;
174 template <
class F,
class... Args>
175 static data_type
const& get_or_init(key_type
const& key, F&& f, Args&&... args)
178 static container_type cached_data;
182 using mutex_type = std::shared_timed_mutex;
183 static mutex_type access_mutex;
187 std::shared_lock<mutex_type> read_lock(access_mutex);
188 auto it = cached_data.find(key);
189 if (it != cached_data.end())
193 data_type data = f(key, FWD(args)...);
194 std::unique_lock<mutex_type> write_lock(access_mutex);
195 auto new_it = cached_data.emplace(key, std::move(data));
196 return new_it.first->second;
202 template <
class Key,
class Data,
template <
class>
class Policy,
class Container>
204 :
protected Policy<Container>
206 using key_type = Key;
207 using data_type = Data;
219 template <
class F,
class... Args>
220 data_type
const&
get(key_type
const& key, F&& f, Args&&... args)
const
222 static_assert(std::is_invocable_r_v<data_type, F, key_type, Args...>,
223 "Functor F must have the signature data_type(key_type, Args...)");
225 return ConcurrentCache::get_or_init(key, FWD(f), FWD(args)...);
The class template ConcurrentCache describes an associative static container that allows the concurre...
Definition: ConcurrentCache.hpp:205
data_type const & get(key_type const &key, F &&f, Args &&... args) const
Return the data associated to the key.
Definition: ConcurrentCache.hpp:220
Store cache in instance.
Definition: ConcurrentCache.hpp:73
Stores cache global static, requires locking on write access.
Definition: ConcurrentCache.hpp:169
Store cache thread local, requires no locking.
Definition: ConcurrentCache.hpp:119