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 <map>
39 #include <sstream>
40 #include <memory>
41 #include <functional>
42 
43 #ifdef NEKTAR_USE_THREAD_SAFETY
44 #include <boost/thread/shared_mutex.hpp>
45 #include <boost/thread/locks.hpp>
46 #endif
47 
49 
50 namespace Nektar
51 {
52  namespace LibUtilities
53  {
54 #ifdef NEKTAR_USE_THREAD_SAFETY
55  typedef boost::unique_lock<boost::shared_mutex> WriteLock;
56  typedef boost::shared_lock<boost::shared_mutex> ReadLock;
57 #endif
58 
59  template <typename KeyType>
61  {
62  bool operator()(const KeyType &lhs, const KeyType &rhs) const
63  {
64  return lhs < rhs;
65  }
66  };
67 
68  template <typename KeyType, typename ValueT, typename opLessCreator = defOpLessCreator<KeyType> >
69  class NekManager
70  {
71  public:
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> CreateFuncContainer;
77  typedef std::map<std::string, std::shared_ptr<ValueContainer> > ValueContainerPool;
78  typedef std::shared_ptr<bool> BoolSharedPtr;
79  typedef std::map<std::string, BoolSharedPtr> FlagContainerPool;
80 
81  NekManager(std::string whichPool="") :
82  m_values(),
85 
86  {
87  if (!whichPool.empty())
88  {
89  auto iter = m_ValueContainerPool.find(whichPool);
90  if (iter != m_ValueContainerPool.end())
91  {
92  m_values = iter->second;
94  }
95  else
96  {
98  m_ValueContainerPool[whichPool] = m_values;
100  {
101  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
102  }
104  }
105  }
106  else
107  {
109  m_managementEnabled = BoolSharedPtr(new bool(true));
110  }
111  };
112 
113 
114  explicit NekManager(CreateFuncType f, std::string whichPool="") :
115  m_values(),
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;
129  }
130  else
131  {
132 #ifdef NEKTAR_USE_THREAD_SAFETY
133  v_rlock.unlock();
134  // now writing static members. Apparently
135  // upgrade_lock has less desirable properties than
136  // just dropping read lock, grabbing write lock.
137  // write will block until all reads are done, but
138  // reads cannot be acquired if write lock is
139  // blocking. In this context writes are supposed to
140  // be rare.
141  WriteLock v_wlock(m_mutex);
142 #endif
144  m_ValueContainerPool[whichPool] = m_values;
146  {
147  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
148  }
150  }
151 
152  }
153  else
154  {
156  m_managementEnabled = BoolSharedPtr(new bool(true));
157  }
158  }
159 
161  {
162  }
163 
164  /// Register the given function and associate it with the key.
165  /// The return value is just to facilitate calling statically.
166  bool RegisterCreator(const KeyType& key,
167  const CreateFuncType& createFunc)
168  {
169  m_keySpecificCreateFuncs[key] = createFunc;
170 
171  return true;
172  }
173 
174  /// Register the Global Create Function.
175  /// The return value is just to facilitate calling statically.
176  bool RegisterGlobalCreator(const CreateFuncType& createFunc)
177  {
178  m_globalCreateFunc = createFunc;
179 
180  return true;
181  }
182 
183  bool AlreadyCreated(const KeyType &key)
184  {
185  bool value = false;
186  auto found = m_values->find(key);
187  if( found != m_values->end() )
188  {
189  value = true;
190  }
191 
192  return value;
193  }
194 
195  ValueType operator[](const KeyType &key)
196  {
197  auto found = m_values->find(key);
198 
199  if( found != m_values->end() )
200  {
201  return (*found).second;
202  }
203  else
204  {
205  // No object, create a new one.
207  auto keyFound = m_keySpecificCreateFuncs.find(key);
208  if( keyFound != m_keySpecificCreateFuncs.end() )
209  {
210  f = (*keyFound).second;
211  }
212 
213  if( f )
214  {
215  ValueType v = f(key);
216  if (*m_managementEnabled)
217  {
218  (*m_values)[key] = v;
219  }
220  return v;
221  }
222  else
223  {
224  std::stringstream ss;
225  ss << key;
226  std::string message = "No create func found for key " + ss.str();
227  NEKERROR(ErrorUtil::efatal, message.c_str());
228  static ValueType result;
229  return result;
230  }
231  }
232  }
233 
234  void DeleteObject(const KeyType &key)
235  {
236  auto found = m_values->find(key);
237 
238  if( found != m_values->end() )
239  {
240  m_values->erase(found);
241  }
242  }
243 
244  static void ClearManager(std::string whichPool = "")
245  {
246  if (!whichPool.empty())
247  {
248 #ifdef NEKTAR_USE_THREAD_SAFETY
249  WriteLock v_wlock(m_mutex);
250 #endif
251  auto x = m_ValueContainerPool.find(whichPool);
252  ASSERTL1(x != m_ValueContainerPool.end(),
253  "Could not find pool " + whichPool);
254  x->second->clear();
255  }
256  else
257  {
258 #ifdef NEKTAR_USE_THREAD_SAFETY
259  WriteLock v_wlock(m_mutex);
260 #endif
261 
262  for (auto &x : m_ValueContainerPool)
263  {
264  x.second->clear();
265  }
266  }
267  }
268 
269  static bool PoolCreated(std::string whichPool)
270  {
271  bool value = false;
272  auto x = m_ValueContainerPool.find(whichPool);
273  if (x != m_ValueContainerPool.end())
274  {
275  value = true;
276  }
277  return value;
278  }
279 
280  static void EnableManagement(std::string whichPool = "")
281  {
282  if (!whichPool.empty())
283  {
284 #ifdef NEKTAR_USE_THREAD_SAFETY
285  WriteLock v_wlock(m_mutex);
286 #endif
287 
288  auto x = m_managementEnabledContainerPool.find(whichPool);
289  if (x != m_managementEnabledContainerPool.end())
290  {
291  (*x->second) = true;
292  }
293  else
294  {
295  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
296  }
297  }
298  }
299 
300  static void DisableManagement(std::string whichPool = "")
301  {
302  if (!whichPool.empty())
303  {
304 #ifdef NEKTAR_USE_THREAD_SAFETY
305  WriteLock v_wlock(m_mutex);
306 #endif
307  auto x = m_managementEnabledContainerPool.find(whichPool);
308  if (x != m_managementEnabledContainerPool.end())
309  {
310  (*x->second) = false;
311  }
312  else
313  {
314  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(false));
315  }
316  }
317  }
318 
319  private:
322 
329 #ifdef NEKTAR_USE_THREAD_SAFETY
330  static boost::shared_mutex m_mutex;
331 #endif
332  };
333  template <typename KeyType, typename ValueT, typename opLessCreator> typename NekManager<KeyType, ValueT, opLessCreator>::ValueContainerPool NekManager<KeyType, ValueT, opLessCreator>::m_ValueContainerPool;
335 #ifdef NEKTAR_USE_THREAD_SAFETY
336  template <typename KeyType, typename ValueT, typename opLessCreator>
337  typename boost::shared_mutex NekManager<KeyType, ValueT, opLessCreator>::m_mutex;
338 #endif
339  }
340 }
341 
342 
343 #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:250
static void DisableManagement(std::string whichPool="")
Definition: NekManager.hpp:300
bool AlreadyCreated(const KeyType &key)
Definition: NekManager.hpp:183
std::shared_ptr< bool > BoolSharedPtr
Definition: NekManager.hpp:78
ValueType operator[](const KeyType &key)
Definition: NekManager.hpp:195
std::map< std::string, BoolSharedPtr > FlagContainerPool
Definition: NekManager.hpp:79
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:166
NekManager(std::string whichPool="")
Definition: NekManager.hpp:81
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:323
std::map< std::string, std::shared_ptr< ValueContainer > > ValueContainerPool
Definition: NekManager.hpp:77
NekManager(CreateFuncType f, std::string whichPool="")
Definition: NekManager.hpp:114
static ValueContainerPool m_ValueContainerPool
Definition: NekManager.hpp:325
std::function< ValueType(const KeyType &key)> CreateFuncType
Definition: NekManager.hpp:73
std::shared_ptr< ValueContainer > ValueContainerShPtr
Definition: NekManager.hpp:75
static bool PoolCreated(std::string whichPool)
Definition: NekManager.hpp:269
static FlagContainerPool m_managementEnabledContainerPool
Definition: NekManager.hpp:326
bool RegisterGlobalCreator(const CreateFuncType &createFunc)
Register the Global Create Function. The return value is just to facilitate calling statically.
Definition: NekManager.hpp:176
CreateFuncContainer m_keySpecificCreateFuncs
Definition: NekManager.hpp:328
static void EnableManagement(std::string whichPool="")
Definition: NekManager.hpp:280
void DeleteObject(const KeyType &key)
Definition: NekManager.hpp:234
std::map< KeyType, CreateFuncType, opLessCreator > CreateFuncContainer
Definition: NekManager.hpp:76
static void ClearManager(std::string whichPool="")
Definition: NekManager.hpp:244
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:323
boost::unique_lock< boost::shared_mutex > WriteLock
Definition: Thread.h:322
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
bool operator()(const KeyType &lhs, const KeyType &rhs) const
Definition: NekManager.hpp:62