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