Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description:
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 #ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
37 #define NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
38 
39 #include <map>
40 
41 #include <boost/function.hpp>
42 #include <boost/call_traits.hpp>
43 #include <boost/concept_check.hpp>
44 #include <boost/thread/shared_mutex.hpp>
45 #include <boost/thread/locks.hpp>
46 
47 #include <boost/shared_ptr.hpp>
49 
50 namespace Nektar
51 {
52  namespace LibUtilities
53  {
54  using namespace std;
55 
56  typedef boost::unique_lock<boost::shared_mutex> WriteLock;
57  typedef boost::shared_lock<boost::shared_mutex> ReadLock;
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  BOOST_CLASS_REQUIRE(KeyType, boost, LessThanComparableConcept);
73 
74  typedef boost::shared_ptr<ValueT> ValueType;
75  typedef boost::function<ValueType (const KeyType& key)> CreateFuncType;
76  typedef std::map<KeyType, ValueType> ValueContainer;
77  typedef boost::shared_ptr<ValueContainer> ValueContainerShPtr;
78  typedef std::map<KeyType, CreateFuncType, opLessCreator> CreateFuncContainer;
79  typedef std::map<std::string, boost::shared_ptr<ValueContainer> > ValueContainerPool;
80  typedef boost::shared_ptr<bool> BoolSharedPtr;
81  typedef std::map<std::string, BoolSharedPtr> FlagContainerPool;
82 
83  NekManager(std::string whichPool="") :
84  m_values(),
85  m_globalCreateFunc(),
86  m_keySpecificCreateFuncs()
87 
88  {
89  if (!whichPool.empty())
90  {
91  typename ValueContainerPool::iterator iter = m_ValueContainerPool.find(whichPool);
92  if (iter != m_ValueContainerPool.end())
93  {
94  m_values = iter->second;
95  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
96  }
97  else
98  {
99  m_values = ValueContainerShPtr(new ValueContainer);
100  m_ValueContainerPool[whichPool] = m_values;
101  if (m_managementEnabledContainerPool.find(whichPool) == m_managementEnabledContainerPool.end())
102  {
103  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
104  }
105  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
106  }
107  }
108  else
109  {
110  m_values = ValueContainerShPtr(new ValueContainer);
111  m_managementEnabled = BoolSharedPtr(new bool(true));
112  }
113  };
114 
115 
116  explicit NekManager(CreateFuncType f, std::string whichPool="") :
117  m_values(),
118  m_globalCreateFunc(f),
119  m_keySpecificCreateFuncs()
120  {
121  if (!whichPool.empty())
122  {
123  ReadLock v_rlock(m_mutex); // reading static members
124  typename ValueContainerPool::iterator iter = m_ValueContainerPool.find(whichPool);
125  if (iter != m_ValueContainerPool.end())
126  {
127  m_values = iter->second;
128  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
129  }
130  else
131  {
132  v_rlock.unlock();
133  // now writing static members. Apparently upgrade_lock has less desirable properties
134  // than just dropping read lock, grabbing write lock.
135  // write will block until all reads are done, but reads cannot be acquired if write
136  // lock is blocking. In this context writes are supposed to be rare.
137  WriteLock v_wlock(m_mutex);
138  m_values = ValueContainerShPtr(new ValueContainer);
139  m_ValueContainerPool[whichPool] = m_values;
140  if (m_managementEnabledContainerPool.find(whichPool) == m_managementEnabledContainerPool.end())
141  {
142  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
143  }
144  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
145  }
146 
147  }
148  else
149  {
150  m_values = ValueContainerShPtr(new ValueContainer);
151  m_managementEnabled = BoolSharedPtr(new bool(true));
152  }
153  }
154 
156  {
157  }
158 
159  /// Register the given function and associate it with the key.
160  /// The return value is just to facilitate calling statically.
161  bool RegisterCreator(typename boost::call_traits<KeyType>::const_reference key,
162  const CreateFuncType& createFunc)
163  {
164  m_keySpecificCreateFuncs[key] = createFunc;
165 
166  return true;
167  }
168 
169  /// Register the Global Create Function.
170  /// The return value is just to facilitate calling statically.
171  bool RegisterGlobalCreator(const CreateFuncType& createFunc)
172  {
173  m_globalCreateFunc = createFunc;
174 
175  return true;
176  }
177 
178  bool AlreadyCreated(typename boost::call_traits<KeyType>::const_reference key)
179  {
180  bool value = false;
181  typename ValueContainer::iterator found = m_values->find(key);
182  if( found != m_values->end() )
183  {
184  value = true;
185  }
186 
187  return value;
188  }
189 
190  ValueType operator[](typename boost::call_traits<KeyType>::const_reference key)
191  {
192  typename ValueContainer::iterator found = m_values->find(key);
193 
194  if( found != m_values->end() )
195  {
196  return (*found).second;
197  }
198  else
199  {
200  // No object, create a new one.
201  CreateFuncType f = m_globalCreateFunc;
202  typename CreateFuncContainer::iterator keyFound = m_keySpecificCreateFuncs.find(key);
203  if( keyFound != m_keySpecificCreateFuncs.end() )
204  {
205  f = (*keyFound).second;
206  }
207 
208  if( f )
209  {
210  ValueType v = f(key);
211  if (*m_managementEnabled)
212  {
213  (*m_values)[key] = v;
214  }
215  return v;
216  }
217  else
218  {
219  std::string keyAsString = boost::lexical_cast<std::string>(key);
220  std::string message = std::string("No create func found for key ") + keyAsString;
221  NEKERROR(ErrorUtil::efatal, message.c_str());
222  static ValueType result;
223  return result;
224  }
225  }
226  }
227 
228  void DeleteObject(typename boost::call_traits<KeyType>::const_reference key)
229  {
230  typename ValueContainer::iterator found = m_values->find(key);
231 
232  if( found != m_values->end() )
233  {
234  m_values->erase(found);
235  }
236  }
237 
238  static void ClearManager(std::string whichPool = "")
239  {
240  typename ValueContainerPool::iterator x;
241  if (!whichPool.empty())
242  {
243  WriteLock v_wlock(m_mutex);
244 
245  x = m_ValueContainerPool.find(whichPool);
246  ASSERTL1(x != m_ValueContainerPool.end(),
247  "Could not find pool " + whichPool);
248  x->second->clear();
249  }
250  else
251  {
252  WriteLock v_wlock(m_mutex);
253 
254  for (x = m_ValueContainerPool.begin(); x != m_ValueContainerPool.end(); ++x)
255  {
256  x->second->clear();
257  }
258  }
259  }
260 
261  static bool PoolCreated(std::string whichPool)
262  {
263  bool value = false;
264  typename ValueContainerPool::iterator x;
265 
266  x = m_ValueContainerPool.find(whichPool);
267  if (x != m_ValueContainerPool.end())
268  {
269  value = true;
270  }
271  return value;
272  }
273 
274  static void EnableManagement(std::string whichPool = "")
275  {
276  typename FlagContainerPool::iterator x;
277  if (!whichPool.empty())
278  {
279  WriteLock v_wlock(m_mutex);
280 
281  x = m_managementEnabledContainerPool.find(whichPool);
282  if (x != m_managementEnabledContainerPool.end())
283  {
284  (*x->second) = true;
285  }
286  else
287  {
288  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
289  }
290  }
291  }
292 
293  static void DisableManagement(std::string whichPool = "")
294  {
295  typename FlagContainerPool::iterator x;
296  if (!whichPool.empty())
297  {
298  WriteLock v_wlock(m_mutex);
299 
300  x = m_managementEnabledContainerPool.find(whichPool);
301  if (x != m_managementEnabledContainerPool.end())
302  {
303  (*x->second) = false;
304  }
305  else
306  {
307  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(false));
308  }
309  }
310  }
311 
312  private:
315 
316  ValueContainerShPtr m_values;
317  BoolSharedPtr m_managementEnabled;
318  static ValueContainerPool m_ValueContainerPool;
319  static FlagContainerPool m_managementEnabledContainerPool;
320  CreateFuncType m_globalCreateFunc;
321  CreateFuncContainer m_keySpecificCreateFuncs;
322  static boost::shared_mutex m_mutex;
323  };
324  template <typename KeyType, typename ValueT, typename opLessCreator> typename NekManager<KeyType, ValueT, opLessCreator>::ValueContainerPool NekManager<KeyType, ValueT, opLessCreator>::m_ValueContainerPool;
326  template <typename KeyType, typename ValueT, typename opLessCreator>
327  typename boost::shared_mutex NekManager<KeyType, ValueT, opLessCreator>::m_mutex;
328  }
329 }
330 
331 
332 #endif //NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
boost::unique_lock< boost::shared_mutex > WriteLock
Definition: NekFactory.hpp:70
static void DisableManagement(std::string whichPool="")
Definition: NekManager.hpp:293
boost::shared_ptr< ValueContainer > ValueContainerShPtr
Definition: NekManager.hpp:77
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:191
NekManager(CreateFuncType f, std::string whichPool="")
Definition: NekManager.hpp:116
static FlagContainerPool m_managementEnabledContainerPool
Definition: NekManager.hpp:319
NekManager(std::string whichPool="")
Definition: NekManager.hpp:83
static ValueContainerPool m_ValueContainerPool
Definition: NekManager.hpp:318
STL namespace.
boost::shared_ptr< bool > BoolSharedPtr
Definition: NekManager.hpp:80
StandardMatrixTag & lhs
static void EnableManagement(std::string whichPool="")
Definition: NekManager.hpp:274
std::map< KeyType, ValueType > ValueContainer
Definition: NekManager.hpp:76
bool RegisterCreator(typename boost::call_traits< KeyType >::const_reference 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:161
boost::function< ValueType(const KeyType &key)> CreateFuncType
Definition: NekManager.hpp:75
bool operator()(const KeyType &lhs, const KeyType &rhs) const
Definition: NekManager.hpp:62
std::map< std::string, boost::shared_ptr< ValueContainer > > ValueContainerPool
Definition: NekManager.hpp:79
void DeleteObject(typename boost::call_traits< KeyType >::const_reference key)
Definition: NekManager.hpp:228
boost::shared_lock< boost::shared_mutex > ReadLock
Definition: NekFactory.hpp:71
bool AlreadyCreated(typename boost::call_traits< KeyType >::const_reference key)
Definition: NekManager.hpp:178
std::map< KeyType, CreateFuncType, opLessCreator > CreateFuncContainer
Definition: NekManager.hpp:78
CreateFuncContainer m_keySpecificCreateFuncs
Definition: NekManager.hpp:321
static void ClearManager(std::string whichPool="")
Definition: NekManager.hpp:238
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
static bool PoolCreated(std::string whichPool)
Definition: NekManager.hpp:261
boost::shared_ptr< ValueT > ValueType
Definition: NekManager.hpp:74
static boost::shared_mutex m_mutex
Definition: NekManager.hpp:322
bool RegisterGlobalCreator(const CreateFuncType &createFunc)
Register the Global Create Function. The return value is just to facilitate calling statically...
Definition: NekManager.hpp:171
ValueContainerShPtr m_values
Definition: NekManager.hpp:316
std::map< std::string, BoolSharedPtr > FlagContainerPool
Definition: NekManager.hpp:81
ValueType operator[](typename boost::call_traits< KeyType >::const_reference key)
Definition: NekManager.hpp:190
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:228