Line data Source code
1 : #include <stdlib.h>
2 :
3 : #include "conffwk/Configuration.hpp"
4 : #include "conffwk/ConfigurationImpl.hpp"
5 : #include "conffwk/Schema.hpp"
6 :
7 : namespace dunedaq {
8 : namespace conffwk {
9 :
10 0 : const char * bool2str(bool value) { return (value ? "yes" : "no"); }
11 :
12 14933 : attribute_t::attribute_t(
13 : const std::string& name, type_t type, const std::string& range,
14 : int_format_t int_format, bool is_not_null, bool is_multi_value,
15 : const std::string& default_value, const std::string& description
16 14933 : ) :
17 14933 : p_name (name),
18 14933 : p_type (type),
19 14933 : p_range (range),
20 14933 : p_int_format (int_format),
21 14933 : p_is_not_null (is_not_null),
22 14933 : p_is_multi_value (is_multi_value),
23 14933 : p_default_value (default_value),
24 14933 : p_description (description)
25 14933 : { ; }
26 :
27 0 : const char * attribute_t::type2str(type_t type)
28 : {
29 0 : switch(type) {
30 : case bool_type: return "boolean";
31 0 : case s8_type: return "8-bits signed integer";
32 0 : case u8_type: return "8-bits unsigned integer";
33 0 : case s16_type: return "16-bits signed integer";
34 0 : case u16_type: return "16-bits unsigned integer";
35 0 : case s32_type: return "32-bits signed integer";
36 0 : case u32_type: return "32-bits unsigned integer";
37 0 : case s64_type: return "64-bits signed integer";
38 0 : case u64_type: return "64-bits unsigned integer";
39 0 : case float_type: return "float";
40 0 : case double_type: return "double";
41 0 : case date_type: return "date";
42 0 : case time_type: return "time";
43 0 : case string_type: return "string";
44 0 : case enum_type: return "enumeration";
45 0 : case class_type: return "class reference";
46 0 : default: return "unknown";
47 : }
48 : }
49 :
50 0 : const char * attribute_t::type(type_t type)
51 : {
52 0 : switch(type) {
53 : case bool_type: return "bool";
54 0 : case s8_type: return "s8";
55 0 : case u8_type: return "u8";
56 0 : case s16_type: return "s16";
57 0 : case u16_type: return "u16";
58 0 : case s32_type: return "s32";
59 0 : case u32_type: return "u32";
60 0 : case s64_type: return "s64";
61 0 : case u64_type: return "u64";
62 0 : case float_type: return "float";
63 0 : case double_type: return "double";
64 0 : case date_type: return "date";
65 0 : case time_type: return "time";
66 0 : case string_type: return "string";
67 0 : case enum_type: return "enum";
68 0 : case class_type: return "class";
69 0 : default: return "unknown";
70 : }
71 : }
72 :
73 0 : const char * attribute_t::format2str(int_format_t type)
74 : {
75 0 : switch(type) {
76 : case oct_int_format: return "octal";
77 0 : case dec_int_format: return "decimal";
78 0 : case hex_int_format: return "hexadecimal";
79 0 : default: return "not applicable";
80 : }
81 : }
82 :
83 0 : void attribute_t::print(std::ostream& out, const std::string& prefix) const
84 : {
85 0 : out
86 0 : << prefix << "attribute \'" << p_name << "\'\n"
87 0 : << prefix << " type: \'" << type2str(p_type) << "\'\n"
88 0 : << prefix << " range: \'" << p_range << "\'\n";
89 :
90 0 : if(p_int_format != na_int_format) {
91 0 : out << prefix << " integer format: \'" << format2str(p_int_format) << "\'\n";
92 : }
93 :
94 0 : out
95 0 : << prefix << " is not null: " << bool2str(p_is_not_null) << '\n'
96 0 : << prefix << " is multi-value: " << bool2str(p_is_multi_value) << '\n'
97 0 : << prefix << " default value: \'" << p_default_value << "\'\n"
98 0 : << prefix << " description: \'" << p_description << '\'';
99 0 : }
100 :
101 0 : std::ostream& operator<<(std::ostream& out, const attribute_t& a)
102 : {
103 0 : a.print(out);
104 0 : return out;
105 : }
106 :
107 :
108 9998 : relationship_t::relationship_t(
109 : const std::string& name, const std::string& type, bool can_be_null,
110 : bool is_multi_value, bool is_aggregation, const std::string& description
111 9998 : ) :
112 9998 : p_name (name),
113 9998 : p_type (type),
114 9998 : p_cardinality (
115 9998 : (can_be_null && !is_multi_value) ? zero_or_one :
116 9033 : (can_be_null && is_multi_value ) ? zero_or_many :
117 3520 : (!can_be_null && is_multi_value ) ? one_or_many :
118 : only_one
119 : ),
120 9998 : p_is_aggregation (is_aggregation),
121 9998 : p_description (description)
122 9998 : { ; }
123 :
124 0 : const char * relationship_t::card2str(cardinality_t cardinality)
125 : {
126 0 : switch(cardinality) {
127 : case zero_or_one: return "zero or one";
128 0 : case zero_or_many: return "zero or many";
129 0 : case only_one: return "one";
130 0 : case one_or_many: return "one or many";
131 0 : default: return "unknown";
132 : }
133 : }
134 :
135 0 : void relationship_t::print(std::ostream& out, const std::string& prefix) const
136 : {
137 0 : out
138 0 : << prefix << "relationship \'" << p_name << "\'\n"
139 0 : << prefix << " class type: \'" << p_type << "\'\n"
140 0 : << prefix << " cardinality: \'" << card2str(p_cardinality) << "\'\n"
141 0 : << prefix << " is aggregation: \'" << bool2str(p_is_aggregation) << "\'\n"
142 0 : << prefix << " description: \'" << p_description << '\'';
143 0 : }
144 :
145 0 : std::ostream& operator<<(std::ostream& out, const relationship_t& r)
146 : {
147 0 : r.print(out);
148 0 : return out;
149 : }
150 :
151 5558 : class_t::class_t(
152 : const std::string& name,
153 : const std::string& description,
154 : const std::string& schema_path,
155 : bool is_abstract
156 5558 : ) :
157 5558 : p_name (name),
158 5558 : p_description (description),
159 5558 : p_schema_path (schema_path),
160 5558 : p_abstract (is_abstract)
161 5558 : { ; }
162 :
163 0 : void class_t::print(std::ostream& out, const std::string& prefix) const
164 : {
165 0 : out
166 0 : << prefix << "class \'" << p_name << "\'\n"
167 0 : << prefix << " is abstract: \'" << bool2str(p_abstract) << "\'\n"
168 0 : << prefix << " description: \'" << p_description << "\'\n"
169 0 : << prefix << " path: \'" << p_schema_path << "\'\n";
170 :
171 0 : if(p_superclasses.empty()) {
172 0 : out << prefix << " there are no superclasses\n";
173 : }
174 : else {
175 0 : out << prefix << " " << p_superclasses.size() << " superclass(es):\n";
176 0 : for(std::vector<std::string>::const_iterator i = p_superclasses.begin(); i != p_superclasses.end(); ++i) {
177 0 : out << prefix << " \'" << *i << "\'\n";
178 : }
179 : }
180 :
181 0 : if(p_subclasses.empty()) {
182 0 : out << prefix << " there are no subclasses\n";
183 : }
184 : else {
185 0 : out << prefix << " " << p_subclasses.size() << " subclass(es):\n";
186 0 : for(std::vector<std::string>::const_iterator i = p_subclasses.begin(); i != p_subclasses.end(); ++i) {
187 0 : out << prefix << " \'" << *i << "\'\n";
188 : }
189 : }
190 :
191 0 : std::string new_prefix(prefix);
192 0 : new_prefix += " ";
193 :
194 0 : if(p_attributes.empty()) {
195 0 : out << prefix << " there are no attributes\n";
196 : }
197 : else {
198 0 : out << prefix << " " << p_attributes.size() << " attribute(s):\n";
199 0 : for(std::vector<attribute_t>::const_iterator i = p_attributes.begin(); i != p_attributes.end(); ++i) {
200 0 : (*i).print(out, new_prefix.c_str());
201 0 : out << std::endl;
202 : }
203 : }
204 :
205 0 : if(p_relationships.empty()) {
206 0 : out << prefix << " there are no relationships\n";
207 : }
208 : else {
209 0 : out << prefix << " " << p_relationships.size() << " relationship(s):\n";
210 0 : for(std::vector<relationship_t>::const_iterator i = p_relationships.begin(); i != p_relationships.end(); ++i) {
211 0 : (*i).print(out, new_prefix.c_str());
212 0 : out << std::endl;
213 : }
214 : }
215 0 : }
216 :
217 0 : std::ostream& operator<<(std::ostream& out, const class_t& c)
218 : {
219 0 : c.print(out);
220 0 : return out;
221 : }
222 :
223 :
224 80 : ConfigurationImpl::ConfigurationImpl() noexcept :
225 80 : p_number_of_cache_hits (0),
226 80 : p_number_of_object_read (0),
227 80 : m_conf (0)
228 : {
229 80 : }
230 :
231 80 : ConfigurationImpl::~ConfigurationImpl()
232 : {
233 80 : clean();
234 80 : }
235 :
236 : void
237 0 : ConfigurationImpl::print_cache_info() noexcept
238 : {
239 0 : std::cout <<
240 : "Configuration implementation profiler report:\n"
241 0 : " number of read objects: " << p_number_of_object_read << "\n"
242 0 : " number of cache hits: " << p_number_of_cache_hits << std::endl;
243 0 : }
244 :
245 : ConfigObjectImpl *
246 1286 : ConfigurationImpl::get_impl_object(const std::string& name, const std::string& id) const noexcept
247 : {
248 :
249 1286 : conffwk::pmap<conffwk::map<ConfigObjectImpl *> *>::const_iterator i = m_impl_objects.find(&name);
250 :
251 1286 : const std::string * class_name = nullptr;
252 :
253 1286 : if(i != m_impl_objects.end()) {
254 606 : conffwk::map<ConfigObjectImpl *>::const_iterator j = i->second->find(id);
255 :
256 606 : if(j != i->second->end()) {
257 141 : p_number_of_cache_hits++;
258 141 : TLOG_DEBUG(4) << "\n * found the object with id = \'" << id << "\' in class \'" << name << '\'' ;
259 141 : return j->second;
260 : }
261 :
262 465 : class_name = i->first;
263 :
264 :
265 : // prepare and print out debug message
266 :
267 465 : if(ers::debug_level() >= 4) {
268 8 : TLOG_DEBUG(40) << " * there is no object with id = \'" << id << "\' found in the class \'" << name
269 8 : << "\' that has " << i->second->size() << " objects in cache: ";
270 27 : for(j=i->second->begin(); j != i->second->end();++j) {
271 19 : TLOG_DEBUG(40) << '\'' << j->first << '\'';
272 : }
273 : }
274 :
275 : }
276 : else {
277 680 : class_name = &DalFactory::instance().get_known_class_name_ref(name);
278 680 : TLOG_DEBUG(40) << " * there is no object with id = \'" << id << "\' found in the class \'" << name
279 680 : << "\' that has no objects in cache";
280 : }
281 :
282 : // check implementation objects of subclasses
283 :
284 1145 : if(m_conf) {
285 1145 : conffwk::fmap<conffwk::fset>::const_iterator subclasses = m_conf->subclasses().find(class_name);
286 :
287 1145 : if(subclasses != m_conf->subclasses().end()) {
288 402 : for(conffwk::fset::const_iterator k = subclasses->second.begin(); k != subclasses->second.end(); ++k) {
289 277 : i = m_impl_objects.find(*k);
290 277 : if(i != m_impl_objects.end()) {
291 5 : conffwk::map<ConfigObjectImpl *>::const_iterator j = i->second->find(id);
292 :
293 5 : if(j != i->second->end()) {
294 0 : p_number_of_cache_hits++;
295 0 : TLOG_DEBUG(40) << " * found the object with id = \'" << id << "\' in class \'" << *k << '\'';
296 :
297 0 : return j->second;
298 : }
299 :
300 :
301 : // prepare and print out debug message
302 :
303 5 : else if(ers::debug_level() >= 4) {
304 0 : TLOG_DEBUG(40) << " * there is no object with id = \'" << id << "\' found in the class \'" << *k
305 0 : << "\' that has " << i->second->size() << " objects in cache: ";
306 0 : for(j=i->second->begin(); j != i->second->end();++j) {
307 0 : TLOG_DEBUG(40) << '\'' << j->first << '\'';
308 : }
309 : }
310 :
311 :
312 : }
313 : else {
314 272 : TLOG_DEBUG(40) << " * there is no object with id = \'" << id << "\' found in the class \'" << *k
315 272 : << "\' that has no objects in cache\n";
316 : }
317 :
318 : }
319 : }
320 :
321 1145 : TLOG_DEBUG(40) << " * there is no object \'" << id << "\' in class \'" << name
322 1145 : << "\' and it's subclasses, returning NULL ...";
323 : }
324 : else {
325 0 : TLOG_DEBUG(40) << " * there is no object \'" << id << "\' in class \'" << name << "\', returning NULL ...";
326 : }
327 :
328 : return nullptr;
329 : }
330 :
331 :
332 : void
333 1145 : ConfigurationImpl::put_impl_object(const std::string& name, const std::string& id, ConfigObjectImpl * obj) noexcept
334 : {
335 1145 : p_number_of_object_read++;
336 :
337 1145 : conffwk::pmap<conffwk::map<ConfigObjectImpl *> * >::iterator i = m_impl_objects.find(&name);
338 :
339 1145 : if(i != m_impl_objects.end()) {
340 465 : (*i->second)[id] = obj;
341 465 : obj->m_class_name = i->first;
342 : }
343 : else {
344 680 : conffwk::map<ConfigObjectImpl *> * m = new conffwk::map<ConfigObjectImpl *>();
345 680 : obj->m_class_name = &DalFactory::instance().get_known_class_name_ref(name);
346 680 : m_impl_objects[obj->m_class_name] = m;
347 680 : (*m)[id] = obj;
348 : }
349 1145 : }
350 :
351 : void
352 0 : ConfigurationImpl::rename_impl_object(const std::string * class_name, const std::string& old_id, const std::string& new_id) noexcept
353 : {
354 0 : conffwk::pmap<conffwk::map<ConfigObjectImpl *> *>::iterator i = m_impl_objects.find(class_name);
355 :
356 0 : if (i != m_impl_objects.end())
357 : {
358 0 : conffwk::map<ConfigObjectImpl *>::iterator j = i->second->find(old_id);
359 :
360 0 : if (j != i->second->end())
361 : {
362 0 : ConfigObjectImpl*& obj = (*i->second)[new_id];
363 :
364 0 : if (obj != nullptr)
365 : {
366 0 : obj->m_state = dunedaq::conffwk::Unknown;
367 0 : m_tangled_objects.push_back(obj);
368 : }
369 :
370 0 : obj = j->second;
371 :
372 0 : TLOG_DEBUG(2) << "rename implementation " << (void *)j->second << " of object \'" << old_id << '@' << *class_name << "\' to \'" << new_id << '\'';
373 0 : i->second->erase(j);
374 : }
375 : }
376 0 : }
377 :
378 : void
379 240 : ConfigurationImpl::clean() noexcept
380 : {
381 920 : for (auto& i : m_impl_objects)
382 : {
383 1825 : for (auto& j : *i.second)
384 1145 : delete j.second;
385 :
386 680 : delete i.second;
387 : }
388 :
389 240 : m_impl_objects.clear();
390 :
391 240 : for (auto& x : m_tangled_objects)
392 0 : delete x;
393 :
394 240 : m_tangled_objects.clear();
395 240 : }
396 :
397 : std::mutex&
398 0 : ConfigurationImpl::get_conf_impl_mutex() const
399 : {
400 0 : return m_conf->m_impl_mutex;
401 : }
402 :
403 : void
404 70 : ConfigObjectImpl::convert(bool& value, const ConfigObject& obj, const std::string& attr_name) noexcept
405 : {
406 70 : m_impl->m_conf->convert(value, obj, attr_name);
407 70 : }
408 :
409 : void
410 5 : ConfigObjectImpl::convert(uint8_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
411 : {
412 5 : m_impl->m_conf->convert(value, obj, attr_name);
413 5 : }
414 :
415 : void
416 0 : ConfigObjectImpl::convert(int8_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
417 : {
418 0 : m_impl->m_conf->convert(value, obj, attr_name);
419 0 : }
420 :
421 : void
422 37 : ConfigObjectImpl::convert(uint16_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
423 : {
424 37 : m_impl->m_conf->convert(value, obj, attr_name);
425 37 : }
426 :
427 : void
428 0 : ConfigObjectImpl::convert(int16_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
429 : {
430 0 : m_impl->m_conf->convert(value, obj, attr_name);
431 0 : }
432 :
433 : void
434 1206 : ConfigObjectImpl::convert(uint32_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
435 : {
436 1206 : m_impl->m_conf->convert(value, obj, attr_name);
437 1206 : }
438 :
439 : void
440 64 : ConfigObjectImpl::convert(int32_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
441 : {
442 64 : m_impl->m_conf->convert(value, obj, attr_name);
443 64 : }
444 :
445 : void
446 5 : ConfigObjectImpl::convert(uint64_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
447 : {
448 5 : m_impl->m_conf->convert(value, obj, attr_name);
449 5 : }
450 :
451 : void
452 0 : ConfigObjectImpl::convert(int64_t& value, const ConfigObject& obj, const std::string& attr_name) noexcept
453 : {
454 0 : m_impl->m_conf->convert(value, obj, attr_name);
455 0 : }
456 :
457 : void
458 0 : ConfigObjectImpl::convert(float& value, const ConfigObject& obj, const std::string& attr_name) noexcept
459 : {
460 0 : m_impl->m_conf->convert(value, obj, attr_name);
461 0 : }
462 :
463 : void
464 0 : ConfigObjectImpl::convert(double& value, const ConfigObject& obj, const std::string& attr_name) noexcept
465 : {
466 0 : m_impl->m_conf->convert(value, obj, attr_name);
467 0 : }
468 :
469 : void
470 1041 : ConfigObjectImpl::convert(std::string& value, const ConfigObject& obj, const std::string& attr_name) noexcept
471 : {
472 1041 : m_impl->m_conf->convert(value, obj, attr_name);
473 1041 : }
474 :
475 :
476 : void
477 0 : ConfigObjectImpl::convert(std::vector<bool>& /*value*/, const ConfigObject& /*obj*/, const std::string& /*attr_name*/) noexcept
478 : {
479 : //m_impl->m_conf->convert2(value, obj, attr_name);
480 0 : }
481 :
482 : void
483 0 : ConfigObjectImpl::convert(std::vector<uint8_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
484 : {
485 0 : m_impl->m_conf->convert2(value, obj, attr_name);
486 0 : }
487 :
488 : void
489 0 : ConfigObjectImpl::convert(std::vector<int8_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
490 : {
491 0 : m_impl->m_conf->convert2(value, obj, attr_name);
492 0 : }
493 :
494 : void
495 0 : ConfigObjectImpl::convert(std::vector<uint16_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
496 : {
497 0 : m_impl->m_conf->convert2(value, obj, attr_name);
498 0 : }
499 :
500 : void
501 0 : ConfigObjectImpl::convert(std::vector<int16_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
502 : {
503 0 : m_impl->m_conf->convert2(value, obj, attr_name);
504 0 : }
505 :
506 : void
507 0 : ConfigObjectImpl::convert(std::vector<uint32_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
508 : {
509 0 : m_impl->m_conf->convert2(value, obj, attr_name);
510 0 : }
511 :
512 : void
513 0 : ConfigObjectImpl::convert(std::vector<int32_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
514 : {
515 0 : m_impl->m_conf->convert2(value, obj, attr_name);
516 0 : }
517 :
518 : void
519 0 : ConfigObjectImpl::convert(std::vector<uint64_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
520 : {
521 0 : m_impl->m_conf->convert2(value, obj, attr_name);
522 0 : }
523 :
524 : void
525 0 : ConfigObjectImpl::convert(std::vector<int64_t>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
526 : {
527 0 : m_impl->m_conf->convert2(value, obj, attr_name);
528 0 : }
529 :
530 : void
531 0 : ConfigObjectImpl::convert(std::vector<float>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
532 : {
533 0 : m_impl->m_conf->convert2(value, obj, attr_name);
534 0 : }
535 :
536 : void
537 0 : ConfigObjectImpl::convert(std::vector<double>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
538 : {
539 0 : m_impl->m_conf->convert2(value, obj, attr_name);
540 0 : }
541 :
542 : void
543 60 : ConfigObjectImpl::convert(std::vector<std::string>& value, const ConfigObject& obj, const std::string& attr_name) noexcept
544 : {
545 60 : m_impl->m_conf->convert2(value, obj, attr_name);
546 60 : }
547 :
548 : } // namespace conffwk
549 : } // namespace dunedaq
|