DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
Configuration.hxx
Go to the documentation of this file.
1#ifndef __DUNEDAQ_CONFFWK_CONFIGURATION_HXX__
2#define __DUNEDAQ_CONFFWK_CONFIGURATION_HXX__
3
5
6namespace dunedaq {
7namespace conffwk {
8
9
10template<class T>
11 const T *
12 Configuration::create(const std::string& at, const std::string& id, bool init_object)
13 {
14 ConfigObject obj;
15
16 std::lock_guard<std::mutex> scoped_lock(m_tmpl_mutex);
17 create(at, T::s_class_name, id, obj);
18 return m_registry.get<T>(obj, false, init_object);
19 }
20
21
22template<class T>
23 void
25 {
26 destroy_obj(const_cast<ConfigObject&>(obj.config_object()));
27 }
28
29// Get object of given class and instantiate the template parameter with it.
30template<class T>
31 const T *
32 Configuration::_get(const std::string& name, bool init_children, bool init_object, unsigned long rlevel, const std::vector<std::string> * rclasses)
33 {
34 return m_registry.get<T>(name, init_children, init_object, rlevel, rclasses);
35 }
36
37// Instantiate the template parameter using existing conffwk object.
38template<class T>
39 const T *
40 Configuration::_get(ConfigObject& obj, bool init_children, bool init_object)
41 {
42 return m_registry.get<T>(obj, init_children, init_object);
43 }
44
45// FIXME : not supported, delete
46// template<class T>
47// const T *
48// Configuration::_get(ConfigObject& obj, const std::string& id)
49// {
50// return m_registry.get<T>(obj, id);
51// }
52
53template<class T>
54 const T *
55 Configuration::_find(const std::string& id)
56 {
57 // auto it = m_cache_map.find(&T::s_class_name);
58 // return (it != m_cache_map.end() ? static_cast<Cache<T>*>(it->second)->find(id) : nullptr);
59 return m_registry.find<T>(id);
60 }
61
62// Get all objects the given class and instantiate a vector of the template parameters object with it.
63template<class T>
64 void
65 Configuration::_get(std::vector<const T*>& result, bool init_children, bool init_object, const std::string& query, unsigned long rlevel, const std::vector<std::string> * rclasses)
66 {
67 std::vector<ConfigObject> objs;
68
69 try
70 {
71 get(T::s_class_name, objs, query, rlevel, rclasses);
72 }
74 {
75 std::ostringstream text;
76 text << "wrong database schema, cannot find class \'" << ex.get_data() << '\'';
77 throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());
78 }
79
80 if (!objs.empty())
81 {
82 for (auto& i : objs)
83 {
84 result.push_back(this->_get<T>(i, init_children, init_object));
85 }
86 }
87 }
88
89
90// Get relation from object and instantiate result with it.
91template<class T>
92 const T *
93 Configuration::_ref(ConfigObject& obj, const std::string& name, bool read_children)
94 {
95 return m_registry._ref<T>(obj, name, read_children);
96 // ConfigObject res;
97
98 // try
99 // {
100 // obj.get(name, res);
101 // }
102 // catch (dunedaq::conffwk::Generic & ex)
103 // {
104 // throw(dunedaq::conffwk::Generic( ERS_HERE, mk_ref_ex_text("an object", T::s_class_name, name, obj).c_str(), ex ) );
105 // }
106
107 // return ((!res.is_null()) ? get_cache<T>(res.class_name())->get(*this, res, read_children, read_children) : nullptr);
108 }
109
110
111// Get multiple relations from object and instantiate result with it.
112template<class T>
113 void
114 Configuration::_ref(ConfigObject& obj, const std::string& name, std::vector<const T*>& results, bool read_children)
115 {
116
117 return m_registry._ref<T>(obj, name, results, read_children);
118 // std::vector<ConfigObject> objs;
119
120 // results.clear();
121
122 // try
123 // {
124 // obj.get(name, objs);
125 // results.reserve(objs.size());
126
127 // for (auto& i : objs)
128 // {
129 // results.push_back(get_cache<T>(i.class_name())->get(*this, i, read_children, read_children));
130 // }
131 // }
132 // catch (dunedaq::conffwk::Generic & ex)
133 // {
134 // throw(dunedaq::conffwk::Generic( ERS_HERE, mk_ref_ex_text("objects", T::s_class_name, name, obj).c_str(), ex ) );
135 // }
136 }
137
138template<class T, class V>
139 void
140 Configuration::referenced_by(const T& obj, std::vector<const V*>& results, const std::string& relationship_name, bool check_composite_only, bool init, unsigned long rlevel, const std::vector<std::string> * rclasses)
141 {
142 std::vector<ConfigObject> objs;
143
144 results.clear();
145
146 std::lock_guard<std::mutex> scoped_lock(m_tmpl_mutex);
147
148 try
149 {
150 obj.p_obj.referenced_by(objs, relationship_name, check_composite_only, rlevel, rclasses);
151
152 for (auto& i : objs)
153 {
154 if (try_cast(V::s_class_name, i.class_name()) == true)
155 {
156 // if (const V * o = get_cache<V>()->get(*this, i, init, init))
157 if (const V * o = m_registry.get<V>(i, init, init))
158 {
159 results.push_back(o);
160 }
161 }
162 }
163 }
164 catch (dunedaq::conffwk::Generic & ex)
165 {
166 throw(dunedaq::conffwk::Generic( ERS_HERE, mk_ref_by_ex_text(V::s_class_name, relationship_name, obj.p_obj).c_str(), ex ) );
167 }
168 }
169
170
171// template<class T>
172// Configuration::Cache<T>::~Cache() noexcept
173// {
174// // delete each object in cache
175// for (const auto& i : m_cache)
176// {
177// delete i.second;
178// }
179// }
180
181
182// template<class T>
183// T *
184// Configuration::Cache<T>::get(Configuration& conffwk,
185// ConfigObject& obj, bool init_children, bool init_object)
186// {
187// DalObject*& dalptr = m_cache[obj.m_impl->m_id];
188// T* result = dynamic_cast<T*>(dalptr);
189// if (dalptr == nullptr)
190// {
191// result = dynamic_cast<T*>(m_functions.m_instantiator_fn(conffwk, obj));
192// if (init_object)
193// {
194// std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
195// result->init(init_children);
196// }
197// dalptr = result;
198// }
199// else if(obj.m_impl != result->p_obj.m_impl)
200// {
201// std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
202// result->set(obj); // update implementation object; to be used in case if the object is re-created
203// }
204// increment_gets(conffwk);
205// return result;
206// }
207
208// template<class T>
209// T *
210// Configuration::Cache<T>::find(const std::string& id)
211// {
212// auto it = m_cache.find(id);
213// return (it != m_cache.end() ? dynamic_cast<T*>(it->second) : nullptr);
214// }
215
216// template<class T>
217// T *
218// Configuration::Cache<T>::get(Configuration& db, ConfigObject& obj, const std::string& id)
219// {
220
221// DalObject*& dalptr = m_cache[id];
222// T* result = dynamic_cast<T*>(dalptr);
223// if (dalptr == nullptr)
224// {
225// result = dynamic_cast<T*>(m_functions.m_instantiator_fn(db, obj));
226// if (id != obj.UID())
227// {
228// result->p_UID = id;
229// m_t_cache.emplace(obj.UID(), result);
230// }
231// dalptr = result;
232// }
233// else if(obj.m_impl != result->p_obj.m_impl)
234// {
235// std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
236// result->set(obj); // update implementation object; to be used in case if the object is re-created
237// }
238// increment_gets(db);
239// return result;
240// }
241
242
243// // Get object from cache or create it.
244
245// template<class T> T *
246// Configuration::Cache<T>::get(Configuration& conffwk, const std::string& name, bool init_children, bool init_object, unsigned long rlevel, const std::vector<std::string> * rclasses)
247// {
248
249// typename conffwk::map<DalObject*>::iterator i = m_cache.find(name);
250// if(i == m_cache.end()) {
251// try {
252// ConfigObject obj;
253// // class name should be the true cache class name
254// conffwk._get(m_class_name, name, obj, rlevel, rclasses);
255// return get(conffwk, obj, init_children, init_object);
256// }
257// catch(dunedaq::conffwk::NotFound & ex) {
258// if(!strcmp(ex.get_type(), "class")) {
259// std::ostringstream text;
260// text << "wrong database schema, cannot find class \"" << ex.get_data() << '\"';
261// throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());
262// }
263// else {
264// return 0;
265// }
266// }
267// }
268// increment_gets(conffwk);
269// return dynamic_cast<T*>(i->second);
270// }
271
272
273template<class T>
274 bool
275 Configuration::is_valid(const T * object) noexcept
276 {
277 // std::lock_guard<std::mutex> scoped_lock(m_tmpl_mutex);
278
279 // auto j = m_cache_map.find(&T::s_class_name);
280
281 // if (j != m_cache_map.end())
282 // {
283 // Cache<T> *c = static_cast<Cache<T>*>(j->second);
284
285 // for (const auto& i : c->m_cache)
286 // {
287 // if (i->second == object)
288 // return true;
289 // }
290 // }
291
292 // return false;
293
294 return m_registry.is_valid(object);
295 }
296
297
298template<class T> void
299Configuration::update(const std::vector<std::string>& modified,
300 const std::vector<std::string>& removed,
301 const std::vector<std::string>& created) noexcept
302 {
303 // auto j = m_cache_map.find(&T::s_class_name);
304
305 // TLOG_DEBUG(4) << "call for class \'" << T::s_class_name << '\'';
306
307 // if (j != m_cache_map.end())
308 // {
309 // Cache<T> *c = static_cast<Cache<T>*>(j->second);
310 // set_cache_unread(removed, *c);
311 // set_cache_unread(created, *c);
312 // set_cache_unread(modified, *c);
313 // }
314 m_registry.update<T>(modified, removed, created);
315 }
316
317template<class T> void
319 {
320 // auto j = m_cache_map.find(&T::s_class_name);
321
322 // if (j != m_cache_map.end())
323 // {
324 // _unread_objects(static_cast<Cache<T>*>(j->second));
325 // }
327 }
328
329// // FIXME: Delete ME
330// template<class T>
331// void
332// Configuration::_unread_objects(CacheBase* x) noexcept
333// {
334// Cache<T> *c = static_cast<Cache<T>*>(x);
335
336// for (auto& i : c->m_cache)
337// {
338// i.second->p_was_read = false;
339// }
340// }
341
342// // FIXME: Delete ME
343// template<class T> void
344// Configuration::_rename_object(CacheBase* x, const std::string& old_id, const std::string& new_id) noexcept
345// {
346// Cache<T> *c = static_cast<Cache<T>*>(x);
347
348// // rename template object
349// auto it = c->m_cache.find(old_id);
350// if (it != c->m_cache.end())
351// {
352// TLOG_DEBUG(3) << " * rename \'" << old_id << "\' to \'" << new_id << "\' in class \'" << T::s_class_name << "\')";
353// c->m_cache[new_id] = it->second;
354// c->m_cache.erase(it);
355
356// std::lock_guard<std::mutex> scoped_lock(it->second->m_mutex);
357// it->second->p_UID = new_id;
358// }
359
360// // rename generated objects if any
361// auto range = c->m_t_cache.equal_range(old_id);
362// for (auto it = range.first; it != range.second;)
363// {
364// T * o = dynamic_cast<T*>(it->second);
365// it = c->m_t_cache.erase(it);
366// c->m_t_cache.emplace(new_id, o);
367// }
368// }
369
370
371template<class T> void
373 {
374 std::lock_guard<std::mutex> scoped_lock(m_else_mutex);
375
376 std::list<AttributeConverterBase*> * c = m_convert_map[typeid(T).name()];
377 if (c == 0)
378 {
379 c = m_convert_map[typeid(T).name()] = new std::list<AttributeConverterBase*>();
380 }
381
382 c->push_back(object);
383 }
384
385template<class T>
386 void
387 Configuration::convert(T& value, const ConfigObject& obj, const std::string& attr_name) noexcept
388 {
389 conffwk::map<std::list<AttributeConverterBase*> *>::const_iterator l = m_convert_map.find(typeid(T).name());
390 if (l != m_convert_map.end())
391 {
392 for (const auto& i : *l->second)
393 {
394 static_cast<AttributeConverter<T>*>(i)->convert(value, *this, obj, attr_name);
395 }
396 }
397 }
398
399template<class T>
400 void
401 Configuration::convert2(std::vector<T>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
402 {
403 conffwk::map<std::list<AttributeConverterBase*> *>::const_iterator l = m_convert_map.find(typeid(T).name());
404 if (l != m_convert_map.end())
405 {
406 for (auto& j : value)
407 {
408 for (const auto& i : *l->second)
409 {
410 static_cast<AttributeConverter<T>*>(i)->convert(j, *this, obj, attr_name);
411 }
412 }
413 }
414 }
415
416// inline void
417// CacheBase::increment_gets(Configuration& db) noexcept
418// {
419// ++db.p_number_of_cache_hits;
420// }
421
422
423
424
425} // namespace conffwk
426} // namespace dunedaq
427
428#endif /*__DUNEDAQ_CONFFWK_CONFIGURATION_HXX__ */
#define ERS_HERE
Represents database objects.
void register_converter(AttributeConverter< T > *object) noexcept
Register user function for attribute conversion.
const T * _find(const std::string &id)
Multi-thread unsafe version of find(const std::string&) method.
void _get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel, const std::vector< std::string > *rclasses)
void get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel=0, const std::vector< std::string > *rclasses=0)
Get object by class name and object id (multi-thread safe).
void destroy_obj(ConfigObject &object)
Destroy object.
void update(const std::vector< std::string > &modified, const std::vector< std::string > &removed, const std::vector< std::string > &created) noexcept
Update cache of objects in case of modification.
void referenced_by(const T &obj, std::vector< const V * > &objects, const std::string &relationship_name="*", bool check_composite_only=true, bool init=false, unsigned long rlevel=0, const std::vector< std::string > *rclasses=nullptr)
Get template DAL objects holding references on this object via given relationship (multi-thread safe)...
void create(const std::string &at, const std::string &class_name, const std::string &id, ConfigObject &object)
Create new object by class name and object id.
const T * _ref(ConfigObject &obj, const std::string &name, bool read_children)
Multi-thread unsafe version of ref(ConfigObject&, const std::string&, bool); The method should not be...
void _reset_objects() noexcept
Update state of objects after abort operations.
void destroy(T &obj)
Destroy object of given class.
static std::string mk_ref_by_ex_text(const std::string &cname, const std::string &rname, const ConfigObject &obj) noexcept
void convert(T &value, const ConfigObject &obj, const std::string &attr_name) noexcept
Converts single value.
bool try_cast(const std::string &target, const std::string &source) noexcept
Checks if cast from source class to target class is allowed.
void convert2(std::vector< T > &value, const ConfigObject &obj, const std::string &attr_name) noexcept
Converts vector of single values.
bool is_valid(const T *object) noexcept
Checks validity of pointer to an objects of given user class.
DalObject * get(ConfigObject &obj, bool upcast_unregistered=false)
void _reset_objects()
Update state of objects after abort operations.
const T * _ref(ConfigObject &obj, const std::string &name, bool read_children)
Get signle value of object's relation and instantiate result with it (multi-thread safe).
T * find(const std::string &id)
Find template object using ID.
Generic configuration exception.
Try to access non-existent object or class.
Definition Errors.hpp:47
void init(unordered_map< std::string, std::string > params)
Including Qt Headers.