Iguana 1.2.0
Implementation Guardian of Analysis Algorithms
Loading...
Searching...
No Matches
ConcurrentParam.h
Go to the documentation of this file.
1
2#pragma once
3
4#include "GlobalParam.h"
5#include <shared_mutex>
6
7namespace iguana {
8
10 using concurrent_key_t = std::size_t;
11
12 // ==================================================================================
13 // ConcurrentParam
14 // ==================================================================================
15
18 template <typename T>
20 {
21
22 public:
23
27 ConcurrentParam(std::string const& model, std::string const& name);
28 virtual ~ConcurrentParam() = default;
29
33 virtual T const Load(concurrent_key_t const key) const = 0;
34
38 virtual void Save(T const& value, concurrent_key_t const key) = 0;
39
42 virtual bool HasKey(concurrent_key_t const key) const = 0;
43
48 virtual bool NeedsUpdate(T const& value, concurrent_key_t const key) const = 0;
49
50 protected:
51
53 mutable std::shared_mutex m_mutex;
54
56 std::string const m_name;
57 };
58
59 // ==================================================================================
60 // SingleThreadParam
61 // ==================================================================================
62
65 template <typename T>
67 {
68
69 public:
71 SingleThreadParam(std::string const& name);
72 ~SingleThreadParam() override = default;
73 T const Load(concurrent_key_t const key) const override;
74 void Save(T const& value, concurrent_key_t const key) override;
75 bool HasKey(concurrent_key_t const key) const override;
76 bool NeedsUpdate(T const& value, concurrent_key_t const key) const override;
77
78 private:
79
82 T m_value;
83
85 bool m_empty{true};
86 };
87
88 // ==================================================================================
89 // MemoizedParam
90 // ==================================================================================
91
94 template <typename T>
96 {
97
98 public:
100 MemoizedParam(std::string const& name);
101 ~MemoizedParam() override = default;
102 T const Load(concurrent_key_t const key) const override;
103 void Save(T const& value, concurrent_key_t const key) override;
104 bool HasKey(concurrent_key_t const key) const override;
105 bool NeedsUpdate(T const& value, concurrent_key_t const key) const override;
106
107 private:
108
110 std::unordered_map<concurrent_key_t, T> m_container;
111 };
112
113
114 // ==================================================================================
115 // ConcurrentParamFactory
116 // ==================================================================================
117
119 class ConcurrentParamFactory
120 {
121
122 public:
123 ConcurrentParamFactory() = delete;
124
127 {
128 if(GlobalConcurrencyModel() == "none")
129 GlobalConcurrencyModel = "memoize"; // the safest default, but not the fastest for single-threaded users
130 if(GlobalConcurrencyModel() != "single" && GlobalConcurrencyModel() != "memoize")
131 throw std::runtime_error("unknown GlobalConcurrencyModel '" + GlobalConcurrencyModel() + "'; valid options are 'single' or 'memoize'");
132 }
133
139 template <typename T>
140 static std::unique_ptr<ConcurrentParam<T>> Create(std::string const& name)
141 {
143 if(GlobalConcurrencyModel() == "single")
144 return std::make_unique<SingleThreadParam<T>>(name);
145 else
146 return std::make_unique<MemoizedParam<T>>(name);
147 }
148 };
149
150
151 // ==================================================================================
152 // Keysmith
153 // ==================================================================================
154
156 template <typename... Ts>
158 {
159
160 public:
161
177 {
179 if(GlobalConcurrencyModel() == "single") {
180 m_make_key = [](Ts const&... args) -> concurrent_key_t { return 0; };
181 }
182 else {
183 m_make_key = [](Ts const&... args) -> concurrent_key_t {
184 std::size_t seed = 0;
185 (hash_combine(seed, args), ...);
186 return seed;
187 };
188 }
189 }
190
194 concurrent_key_t MakeKey(Ts const&... args)
195 {
196 return m_make_key(args...);
197 }
198
199 private:
200
204 template <typename T>
205 static void hash_combine(std::size_t& seed, T const& value)
206 {
207 seed ^= std::hash<T>{}(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
208 }
209
211 std::function<concurrent_key_t(Ts...)> m_make_key;
212 };
213
214}
std::size_t concurrent_key_t
concurrent key type for ConcurrentParam objects
static std::unique_ptr< ConcurrentParam< T > > Create(std::string const &name)
create a new ConcurrentParam-derived class instance
static void CheckConcurrencyModel()
check the concurrency model; if not set, it will set a default
virtual void Save(T const &value, concurrent_key_t const key)=0
modify a value
ConcurrentParam(std::string const &model, std::string const &name)
std::shared_mutex m_mutex
mutex for this ConcurrentParam
virtual bool NeedsUpdate(T const &value, concurrent_key_t const key) const =0
if either key is not found or value does not match the value at key, the caller likely needs to call ...
virtual bool HasKey(concurrent_key_t const key) const =0
std::string const m_name
a name for this parameter
virtual T const Load(concurrent_key_t const key) const =0
access a stored value
Keysmith()
constructor
concurrent_key_t MakeKey(Ts const &... args)
make a new key
MemoizedParam(std::string const &name)
T const Load(concurrent_key_t const key) const override
access a stored value
bool NeedsUpdate(T const &value, concurrent_key_t const key) const override
if either key is not found or value does not match the value at key, the caller likely needs to call ...
bool HasKey(concurrent_key_t const key) const override
void Save(T const &value, concurrent_key_t const key) override
modify a value
void Save(T const &value, concurrent_key_t const key) override
modify a value
T const Load(concurrent_key_t const key) const override
access a stored value
bool NeedsUpdate(T const &value, concurrent_key_t const key) const override
if either key is not found or value does not match the value at key, the caller likely needs to call ...
bool HasKey(concurrent_key_t const key) const override
SingleThreadParam(std::string const &name)