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