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