Nektar++
NekManager.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: NekManager.hpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
36#define NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
37
38#include <functional>
39#include <map>
40#include <memory>
41#include <sstream>
42
43#ifdef NEKTAR_USE_THREAD_SAFETY
44#include <boost/thread/locks.hpp>
45#include <boost/thread/shared_mutex.hpp>
46#endif
47
49
50namespace Nektar
51{
52namespace LibUtilities
53{
54#ifdef NEKTAR_USE_THREAD_SAFETY
55typedef boost::unique_lock<boost::shared_mutex> WriteLock;
56typedef boost::shared_lock<boost::shared_mutex> ReadLock;
57#endif
58
59template <typename KeyType> struct defOpLessCreator
60{
61 bool operator()(const KeyType &lhs, const KeyType &rhs) const
62 {
63 return lhs < rhs;
64 }
65};
66
67template <typename KeyType, typename ValueT,
68 typename opLessCreator = defOpLessCreator<KeyType>>
70{
71public:
72 typedef std::shared_ptr<ValueT> ValueType;
73 typedef std::function<ValueType(const KeyType &key)> CreateFuncType;
74 typedef std::map<KeyType, ValueType> ValueContainer;
75 typedef std::shared_ptr<ValueContainer> ValueContainerShPtr;
76 typedef std::map<KeyType, CreateFuncType, opLessCreator>
78 typedef std::map<std::string, std::shared_ptr<ValueContainer>>
80 typedef std::shared_ptr<bool> BoolSharedPtr;
81 typedef std::map<std::string, BoolSharedPtr> FlagContainerPool;
82
83 NekManager(std::string whichPool = "")
85 {
86 if (!whichPool.empty())
87 {
88 auto iter = m_ValueContainerPool.find(whichPool);
89 if (iter != m_ValueContainerPool.end())
90 {
91 m_values = iter->second;
94 }
95 else
96 {
98 m_ValueContainerPool[whichPool] = m_values;
99 if (m_managementEnabledContainerPool.find(whichPool) ==
101 {
103 BoolSharedPtr(new bool(true));
104 }
107 }
108 }
109 else
110 {
112 m_managementEnabled = BoolSharedPtr(new bool(true));
113 }
114 };
115
116 explicit NekManager(CreateFuncType f, std::string whichPool = "")
118 {
119 if (!whichPool.empty())
120 {
121#ifdef NEKTAR_USE_THREAD_SAFETY
122 ReadLock v_rlock(m_mutex); // reading static members
123#endif
124 auto iter = m_ValueContainerPool.find(whichPool);
125 if (iter != m_ValueContainerPool.end())
126 {
127 m_values = iter->second;
130 }
131 else
132 {
133#ifdef NEKTAR_USE_THREAD_SAFETY
134 v_rlock.unlock();
135 // Now writing static members. Apparently
136 // upgrade_lock has less desirable properties than
137 // just dropping read lock, grabbing write lock.
138 // write will block until all reads are done, but
139 // reads cannot be acquired if write lock is
140 // blocking. In this context writes are supposed to
141 // be rare.
142 WriteLock v_wlock(m_mutex);
143#endif
145 m_ValueContainerPool[whichPool] = m_values;
146 if (m_managementEnabledContainerPool.find(whichPool) ==
148 {
150 BoolSharedPtr(new bool(true));
151 }
154 }
155 }
156 else
157 {
159 m_managementEnabled = BoolSharedPtr(new bool(true));
160 }
161 }
162
164 {
165 }
166
167 /// Register the given function and associate it with the key.
168 /// The return value is just to facilitate calling statically.
169 bool RegisterCreator(const KeyType &key, const CreateFuncType &createFunc)
170 {
171 m_keySpecificCreateFuncs[key] = createFunc;
172
173 return true;
174 }
175
176 /// Register the Global Create Function.
177 /// The return value is just to facilitate calling statically.
178 bool RegisterGlobalCreator(const CreateFuncType &createFunc)
179 {
180 m_globalCreateFunc = createFunc;
181
182 return true;
183 }
184
185 ValueType operator[](const KeyType &key)
186 {
187 auto found = m_values->find(key);
188
189 if (found != m_values->end())
190 {
191 return (*found).second;
192 }
193 else
194 {
195 // No object, create a new one.
196 auto keyFound = m_keySpecificCreateFuncs.find(key);
197 bool isfound = keyFound != m_keySpecificCreateFuncs.end();
199 isfound ? (*keyFound).second : m_globalCreateFunc;
200
201 if (f)
202 {
203 ValueType v = f(key);
205 {
206 (*m_values)[key] = v;
207 }
208 return v;
209 }
210 else
211 {
212 std::stringstream ss;
213 ss << key;
214 std::string message =
215 "No create func found for key " + ss.str();
216 NEKERROR(ErrorUtil::efatal, message.c_str());
217 static ValueType result;
218 return result;
219 }
220 }
221 }
222
223 void DeleteObject(const KeyType &key)
224 {
225 auto found = m_values->find(key);
226
227 if (found != m_values->end())
228 {
229 m_values->erase(found);
230 }
231 }
232
233 static void ClearManager(std::string whichPool = "")
234 {
235#ifdef NEKTAR_USE_THREAD_SAFETY
236 WriteLock v_wlock(m_mutex);
237#endif
238
239 if (!whichPool.empty())
240 {
241 auto x = m_ValueContainerPool.find(whichPool);
243 "Could not find pool " + whichPool);
244 x->second->clear();
245 }
246 else
247 {
248 for (auto &x : m_ValueContainerPool)
249 {
250 x.second->clear();
251 }
252 }
253 }
254
255 static bool PoolCreated(std::string whichPool)
256 {
257 return m_ValueContainerPool.find(whichPool) !=
259 }
260
261 size_t PoolCount(std::string whichPool)
262 {
263 auto x = m_ValueContainerPool.find(whichPool);
265 "Could not find pool " + whichPool);
266 return x->second->size();
267 }
268
269 static void EnableManagement(std::string whichPool = "")
270 {
271 if (!whichPool.empty())
272 {
273#ifdef NEKTAR_USE_THREAD_SAFETY
274 WriteLock v_wlock(m_mutex);
275#endif
276
277 auto x = m_managementEnabledContainerPool.find(whichPool);
279 {
280 (*x->second) = true;
281 }
282 else
283 {
285 BoolSharedPtr(new bool(true));
286 }
287 }
288 }
289
290 static void DisableManagement(std::string whichPool = "")
291 {
292 if (!whichPool.empty())
293 {
294#ifdef NEKTAR_USE_THREAD_SAFETY
295 WriteLock v_wlock(m_mutex);
296#endif
297 auto x = m_managementEnabledContainerPool.find(whichPool);
299 {
300 (*x->second) = false;
301 }
302 else
303 {
305 BoolSharedPtr(new bool(false));
306 }
307 }
308 }
309
310private:
314
321#ifdef NEKTAR_USE_THREAD_SAFETY
322 static boost::shared_mutex m_mutex;
323#endif
324};
325
326template <typename KeyType, typename ValueT, typename opLessCreator>
329template <typename KeyType, typename ValueT, typename opLessCreator>
331 NekManager<KeyType, ValueT,
332 opLessCreator>::m_managementEnabledContainerPool;
333#ifdef NEKTAR_USE_THREAD_SAFETY
334template <typename KeyType, typename ValueT, typename opLessCreator>
335typename boost::shared_mutex
337#endif
338} // namespace LibUtilities
339} // namespace Nektar
340
341#endif // NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
static void DisableManagement(std::string whichPool="")
Definition: NekManager.hpp:290
std::shared_ptr< bool > BoolSharedPtr
Definition: NekManager.hpp:80
ValueType operator[](const KeyType &key)
Definition: NekManager.hpp:185
std::map< std::string, BoolSharedPtr > FlagContainerPool
Definition: NekManager.hpp:81
size_t PoolCount(std::string whichPool)
Definition: NekManager.hpp:261
bool RegisterCreator(const KeyType &key, const CreateFuncType &createFunc)
Register the given function and associate it with the key. The return value is just to facilitate cal...
Definition: NekManager.hpp:169
NekManager(std::string whichPool="")
Definition: NekManager.hpp:83
std::function< ValueType(const KeyType &key)> CreateFuncType
Definition: NekManager.hpp:73
NekManager< KeyType, ValueType, opLessCreator > & operator=(const NekManager< KeyType, ValueType, opLessCreator > &rhs)
std::shared_ptr< ValueT > ValueType
Definition: NekManager.hpp:72
ValueContainerShPtr m_values
Definition: NekManager.hpp:315
std::map< std::string, std::shared_ptr< ValueContainer > > ValueContainerPool
Definition: NekManager.hpp:79
NekManager(CreateFuncType f, std::string whichPool="")
Definition: NekManager.hpp:116
static ValueContainerPool m_ValueContainerPool
Definition: NekManager.hpp:317
std::shared_ptr< ValueContainer > ValueContainerShPtr
Definition: NekManager.hpp:75
static bool PoolCreated(std::string whichPool)
Definition: NekManager.hpp:255
static FlagContainerPool m_managementEnabledContainerPool
Definition: NekManager.hpp:318
bool RegisterGlobalCreator(const CreateFuncType &createFunc)
Register the Global Create Function. The return value is just to facilitate calling statically.
Definition: NekManager.hpp:178
CreateFuncContainer m_keySpecificCreateFuncs
Definition: NekManager.hpp:320
static void EnableManagement(std::string whichPool="")
Definition: NekManager.hpp:269
void DeleteObject(const KeyType &key)
Definition: NekManager.hpp:223
std::map< KeyType, CreateFuncType, opLessCreator > CreateFuncContainer
Definition: NekManager.hpp:77
static void ClearManager(std::string whichPool="")
Definition: NekManager.hpp:233
NekManager(const NekManager< KeyType, ValueType, opLessCreator > &rhs)
std::map< KeyType, ValueType > ValueContainer
Definition: NekManager.hpp:74
boost::shared_lock< boost::shared_mutex > ReadLock
Definition: Thread.h:380
boost::unique_lock< boost::shared_mutex > WriteLock
Definition: Thread.h:379
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
bool operator()(const KeyType &lhs, const KeyType &rhs) const
Definition: NekManager.hpp:61