DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::conffwk::DalRegistry Class Reference

DalRegistry: A registry of DalObjects It provides a single interface to create, cache and manage DalObjecs. More...

#include <DalRegistry.hpp>

Collaboration diagram for dunedaq::conffwk::DalRegistry:
[legend]

Classes

struct  DalDomain

Public Member Functions

 DalRegistry (Configuration &confdb)
 Construct a new Dal Registry object.
 ~DalRegistry ()
Configuration & configuration ()
const Configuration & configuration () const
void clear ()
 Clear the content of the registy.
DalObject * get (ConfigObject &obj, bool upcast_unregistered=false)
std::vector< const DalObject * > get (std::vector< ConfigObject > &objs, bool upcast_unregistered=false)
template<class T>
T * get (ConfigObject &obj, bool init_children=false, bool init_object=true)
 Get template object from cache by conffwk object.
template<class T>
T * get (const std::string &name, bool init_children=false, bool init_object=true, unsigned long rlevel=0, const std::vector< std::string > *rclasses=nullptr)
 Get template object from cache by object's ID.
template<class T>
T * find (const std::string &id)
 Find template object using ID.
template<class T>
bool is_valid (const T *object) noexcept
 Checks validity of pointer to an objects of given user class.
template<class T>
void update (const std::vector< std::string > &modified, const std::vector< std::string > &removed, const std::vector< std::string > &created)
 Update cache of objects in case of modification.
void update (const std::string &class_name, const std::vector< std::string > &modified, const std::vector< std::string > &removed, const std::vector< std::string > &created)
void unread_all ()
 Set the status of all objects in cache to unread.
template<class T>
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).
template<class T>
void _ref (ConfigObject &obj, const std::string &name, std::vector< const T * > &results, bool read_children)
 Get multiple values of object's relation and instantiate result with them (multi-thread safe).
template<class T>
void _reset_objects ()
 Update state of objects after abort operations.
void _rename_object (std::string class_name, std::string old_id, std::string new_id)
 Rename object of given template class (multi-thread unsafe).
void update_class_maps ()
 Update the internal class domains map.

Private Member Functions

void update_class_domain_map ()

Private Attributes

Configuration & m_confdb
std::mutex m_mutex
conffwk::fmap< uint > m_class_domain_map
std::unordered_map< uint, DalDomain > m_cache_domains

Friends

class DalObject

Detailed Description

DalRegistry: A registry of DalObjects It provides a single interface to create, cache and manage DalObjecs.

Definition at line 18 of file DalRegistry.hpp.

Constructor & Destructor Documentation

◆ DalRegistry()

dunedaq::conffwk::DalRegistry::DalRegistry ( conffwk::Configuration & confdb)

Construct a new Dal Registry object.

Parameters
confdbReference to a Configuration object;

Definition at line 8 of file DalRegistry.cpp.

9 : m_confdb(confdb)
10{
11}

◆ ~DalRegistry()

dunedaq::conffwk::DalRegistry::~DalRegistry ( )

Definition at line 14 of file DalRegistry.cpp.

14{}

Member Function Documentation

◆ _ref() [1/2]

template<class T>
const T * dunedaq::conffwk::DalRegistry::_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).

The method is used by the code generated by the genconffwk utility.

Parameters
objobject
namename of the relationship
initif true, the object and it's referenced objects are initialized
Returns
Return non-null pointer to object of user class in case if relationship with such name exists and it's value is set. Otherwise the method returns 0.
Exceptions
dunedaq::conffwk::Genericin case of a problem (e.g. no relationship with such name, plug-in specific problem)

Definition at line 164 of file DalRegistry.hxx.

165{
166 ConfigObject res;
167
168 try {
169 obj.get(name, res);
170 } catch (dunedaq::conffwk::Generic& ex) {
171 throw(dunedaq::conffwk::Generic(
172 ERS_HERE, Configuration::mk_ref_ex_text("an object", T::s_class_name, name, obj).c_str(), ex));
173 }
174
175 return ((!res.is_null()) ? this->get<T>(res, read_children, read_children) : nullptr);
176}
#define ERS_HERE
static std::string mk_ref_ex_text(const char *what, const std::string &cname, const std::string &rname, const ConfigObject &obj) noexcept
msgpack::object obj

◆ _ref() [2/2]

template<class T>
void dunedaq::conffwk::DalRegistry::_ref ( ConfigObject & obj,
const std::string & name,
std::vector< const T * > & results,
bool read_children )

Get multiple values of object's relation and instantiate result with them (multi-thread safe).

The method is used by the code generated by the genconffwk utility.

Parameters
objobject
namename of the relationship
objectsreturned value
initif true, the objects and their referenced objects are initialized
Exceptions
dunedaq::conffwk::Genericin case of a problem (e.g. no relationship with such name, plug-in specific problem)

Definition at line 181 of file DalRegistry.hxx.

182{
183
184 std::vector<ConfigObject> objs;
185
186 results.clear();
187
188 try {
189 obj.get(name, objs);
190 results.reserve(objs.size());
191
192 for (auto& i : objs) {
193 auto ptr = this->get<T>(i, read_children, read_children);
194 results.push_back(ptr);
195 }
196 } catch (dunedaq::conffwk::Generic& ex) {
197 throw(dunedaq::conffwk::Generic(
198 ERS_HERE, Configuration::mk_ref_ex_text("objects", T::s_class_name, name, obj).c_str(), ex));
199 }
200}
DalObject * get(ConfigObject &obj, bool upcast_unregistered=false)

◆ _rename_object()

void dunedaq::conffwk::DalRegistry::_rename_object ( std::string class_name,
std::string old_id,
std::string new_id )

Rename object of given template class (multi-thread unsafe).

Is used by automatically generated data access libraries when an object has been renamed by user's code. Should not be explicitly used by user.

The method is used by the unread_all_objects() method.

Parameters
cache_ptrpointer to the cache of template object of given template class (has to be downcasted)
old_idold object ID
new_idnew object ID

Definition at line 197 of file DalRegistry.cpp.

198{
199 // Find the class domain of T
200 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(class_name));
201
202 // Class not known, this should not happen
203 if (it_dom == m_class_domain_map.end()) {
204 throw dunedaq::conffwk::NotFound(ERS_HERE, class_name.c_str(), old_id.c_str());
205 }
206
207 auto& domain = m_cache_domains[it_dom->second];
208
209 auto it = domain.cache.find(old_id);
210 if (it == domain.cache.end())
211 return;
212
213 domain.cache[new_id] = it->second;
214 domain.cache.erase(it);
215
216 std::lock_guard<std::mutex> scoped_lock(it->second->m_mutex);
217 it->second->p_UID = new_id;
218}
conffwk::fmap< uint > m_class_domain_map
std::unordered_map< uint, DalDomain > m_cache_domains

◆ _reset_objects()

template<class T>
void dunedaq::conffwk::DalRegistry::_reset_objects ( )

Update state of objects after abort operations.

It is used by automatically generated data access libraries.

Definition at line 236 of file DalRegistry.hxx.

237{
238
239 // Find the class domain of T
240 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(T::s_class_name));
241
242 // Class not known, this should not happen
243 if (it_dom == m_class_domain_map.end()) {
244 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", T::s_class_name.c_str());
245 }
246
247 auto& domain = m_cache_domains[it_dom->second];
248
249 // Loop over the objects in the domain and reset those inheriting from T
250 for (const auto& [uid, ptr] : domain.cache) {
251
252 T* obj_ptr = dynamic_cast<T*>(ptr);
253
254 if (!obj_ptr)
255 continue;
256
257 std::lock_guard<std::mutex> scoped_lock(domain.mutex);
258 obj_ptr->p_was_read = false;
259 }
260}

◆ clear()

void dunedaq::conffwk::DalRegistry::clear ( )

Clear the content of the registy.

Definition at line 87 of file DalRegistry.cpp.

88{
89 for (const auto& [index, domain] : m_cache_domains) {
90
91 for (const auto& [uid, ptr] : domain.cache) {
92 delete ptr;
93 }
94 }
95
96 m_class_domain_map.clear();
97}

◆ configuration() [1/2]

Configuration & dunedaq::conffwk::DalRegistry::configuration ( )
inline

Definition at line 38 of file DalRegistry.hpp.

38{ return m_confdb; }

◆ configuration() [2/2]

const Configuration & dunedaq::conffwk::DalRegistry::configuration ( ) const
inline

Definition at line 39 of file DalRegistry.hpp.

39{ return m_confdb; }

◆ find()

template<class T>
T * dunedaq::conffwk::DalRegistry::find ( const std::string & id)

Find template object using ID.

The method is suitable for generated template objects.

In case of success, the new object is put into cache and pointer to the object is returned. If there is no such object for given template class, then null pointer is returned.

Parameters
idID of generated object
Returns
Return pointer to object.
Exceptions
dunedaq::conffwk::Genericis no such class for loaded configuration DB schema or in case of an error

Definition at line 146 of file DalRegistry.hxx.

147{
148 std::lock_guard<std::mutex> scoped_lock(m_mutex);
149
150 auto it_dom = m_class_domain_map.find(&T::s_class_name);
151
152 if (it_dom == m_class_domain_map.end()) {
153 return nullptr;
154 }
155
156 auto& domain = m_cache_domains[it_dom.second];
157 auto it_obj = domain.cache.find(id);
158 return (it_obj != domain.cache.end() ? dynamic_cast<T*>(it_obj->second) : nullptr);
159}

◆ get() [1/4]

template<class T>
T * dunedaq::conffwk::DalRegistry::get ( ConfigObject & obj,
bool init_children = false,
bool init_object = true )

Get template object from cache by conffwk object.

The method searches an object with id of given conffwk object within the cache. If found, the method sets given conffwk object as implementation of the template object and returns pointer on the template object. If there is no such object in cache, then it is created from given conffwk object.

In case of success, the new object is put into cache and pointer to the object is returned. If there is no such object for given template class, then null pointer is returned.

Parameters
conffwkthe configuration object
objthe conffwk object used to set for the template object
init_childrenif true, the referenced objects are initialized (only applicable during creation of new object)
init_objectif true, the object's attributes and relationships are read(only applicable during creation of new object)
Returns
Return pointer to object.
Exceptions
dunedaq::conffwk::Genericis no such class for loaded configuration DB schema or in case of an error

Definition at line 12 of file DalRegistry.hxx.

13{
14
15 TLOG_DEBUG(50) << "Building object " << obj.UID() << " of class " << obj.class_name() << " and returning class "
16 << T::s_class_name;
17
18 // Ensure that T is a superclass of (or the same class as) obj.class_name()
19 if (not(m_confdb.is_superclass_of(obj.class_name(), T::s_class_name) ||
20 m_confdb.is_superclass_of(T::s_class_name, obj.class_name()))) {
21 // do nothing if this is the case
22 return nullptr;
23 }
24
25 // Find the class domain of T
26 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(T::s_class_name));
27
28 // Class not known, this should not happen
29 if (it_dom == m_class_domain_map.end()) {
30 const std::string id(obj.UID() + '@' + obj.class_name());
31 throw dunedaq::conffwk::NotFound(ERS_HERE, "object", id.c_str());
32 }
33
34 auto& domain = m_cache_domains[it_dom->second];
35
36 DalObject*& dal_ptr(domain.cache[obj.m_impl->m_id]);
37 T* result = dynamic_cast<T*>(dal_ptr);
38
39 if (result == nullptr) {
40 // result = new T(*this, obj);
41 dal_ptr = DalFactory::instance().make(*this, obj, T::s_class_name);
42
43 TLOG_DEBUG(50) << "Casting " << obj.UID() << " of class " << obj.class_name() << " to " << T::s_class_name;
44 result = dynamic_cast<T*>(dal_ptr);
45 TLOG_DEBUG(50) << "From " << (void*)dal_ptr << " to " << (void*)result;
46
47 if (init_object) {
48 std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
49 result->init(init_children);
50 }
51
52 } else if (obj.m_impl != result->p_obj.m_impl) {
53
54 std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
55 result->set(obj); // update implementation object; to be used in case if the object is re-created
56 }
57
58 TLOG_DEBUG(50) << "Returning " << (void*)result;
59
60 return result;
61}
bool is_superclass_of(const std::string &target, const std::string &source) noexcept
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116

◆ get() [2/4]

DalObject * dunedaq::conffwk::DalRegistry::get ( ConfigObject & obj,
bool upcast_unregistered = false )

Definition at line 101 of file DalRegistry.cpp.

102{
103
104 // Find the class domain of T
105 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(obj.class_name()));
106
107 // Class not known, this should not happen
108 if (it_dom == m_class_domain_map.end()) {
109 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", obj.class_name().c_str());
110 }
111
112 auto& domain = m_cache_domains[it_dom->second];
113
114 DalObject*& result(domain.cache[obj.m_impl->m_id]);
115 if (result == nullptr) {
116
117 result = DalFactory::instance().make(*this, obj, upcast_unregistered);
118
119 } else if (obj.m_impl != result->p_obj.m_impl) {
120
121 std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
122 result->set(obj); // update implementation object; to be used in case if the object is re-created
123 }
124
125 return result;
126}

◆ get() [3/4]

template<class T>
T * dunedaq::conffwk::DalRegistry::get ( const std::string & name,
bool init_children = false,
bool init_object = true,
unsigned long rlevel = 0,
const std::vector< std::string > * rclasses = nullptr )

Get template object from cache by object's ID.

The method searches an object with given id within the cache. If found, the method returns pointer on it. If there is no such object in cache, there is an attempt to create new object. In case of success, the new object is put into cache and pointer to the object is returned. If there is no such object for given template class, then null pointer is returned.

Parameters
conffwkthe configuration object
nameobject identity
init_childrenif true, the referenced objects are initialized (only applicable during creation of new object)
init_objectif true, the object's attributes and relationships are read(only applicable during creation of new object)
rleveloptional references level to optimize performance (defines how many objects referenced by given object have also to be read to the implementation cache during creation of new object)
rclassesoptional array of class names to optimize performance (defines which referenced objects have to be read to the implementation cache during creation of new object)
Returns
Return pointer to object. It can be null, if there is no such object found.
Exceptions
dunedaq::conffwk::Genericis no such class for loaded configuration DB schema or in case of an error

Definition at line 66 of file DalRegistry.hxx.

71{
72
73 TLOG_DEBUG(50) << "Building object " << name;
74
75 const std::string& ref_name = DalFactory::instance().get_known_class_name_ref(T::s_class_name);
76
77 TLOG_DEBUG(50) << "Ref name is " << ref_name;
78
79 // Find the class domain of T
80 auto it_dom = m_class_domain_map.find(&ref_name);
81
82 // Class not known, this should not happen
83 if (it_dom == m_class_domain_map.end()) {
84 const std::string id(name + '@' + T::s_class_name);
85 throw dunedaq::conffwk::NotFound(ERS_HERE, "object", id.c_str());
86 }
87
88 auto& domain = m_cache_domains[it_dom->second];
89
90 TLOG_DEBUG(50) << "Class domain for " << ref_name << " is " << it_dom->second;
91
92 auto it_ptr = domain.cache.find(ref_name);
93
94 TLOG_DEBUG(50) << "Cache found";
95
96 if (it_ptr == domain.cache.end()) {
97 try {
98 // Search for an ConfigObject of id 'name' of class 'T'
99 conffwk::ConfigObject obj;
100 m_confdb._get(T::s_class_name, name, obj, rlevel, rclasses);
101
102 DalObject*& dal_ptr(domain.cache[obj.m_impl->m_id]);
103
104 T* result = dynamic_cast<T*>(dal_ptr);
105
106 if (result == nullptr) {
107 // result = new T(*this, obj);
108 dal_ptr = DalFactory::instance().make(*this, obj, T::s_class_name);
109
110 TLOG_DEBUG(50) << "Casting " << obj.UID() << " of class " << obj.class_name() << " to " << T::s_class_name;
111 result = dynamic_cast<T*>(dal_ptr);
112 TLOG_DEBUG(50) << "From " << (void*)dal_ptr << " to " << (void*)result;
113
114 if (init_object) {
115 std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
116 result->init(init_children);
117 }
118 } else if (obj.m_impl != result->p_obj.m_impl) {
119 std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
120 result->set(obj); // update implementation object; to be used in case if the object is re-created
121 }
122
123 return result;
124
125 } catch (dunedaq::conffwk::NotFound& ex) {
126
127 if (!strcmp(ex.get_type(), "class")) {
128
129 std::ostringstream text;
130 text << "wrong database schema, cannot find class \"" << ex.get_data() << '\"';
131
132 throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());
133 }
134
135 return nullptr;
136 }
137 }
138
139 std::cout << "Found " << (void*)it_ptr->second << std::endl;
140 return dynamic_cast<T*>(it_ptr->second);
141}
void _get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel, const std::vector< std::string > *rclasses)

◆ get() [4/4]

std::vector< const DalObject * > dunedaq::conffwk::DalRegistry::get ( std::vector< ConfigObject > & objs,
bool upcast_unregistered = false )

Definition at line 130 of file DalRegistry.cpp.

131{
132 std::vector<const DalObject*> result;
133
134 for (auto& i : objs)
135 if (DalObject* o = this->get(i, upcast_unregistered))
136 result.push_back(o);
137
138 return result;
139}

◆ is_valid()

template<class T>
bool dunedaq::conffwk::DalRegistry::is_valid ( const T * object)
noexcept

Checks validity of pointer to an objects of given user class.

Check if the pointer to the object is a valid pointer in the cache. Dangling pointers to removed objects may appear after notification.

Returns
Return true if the pointer is valid and false otherwise.

Definition at line 205 of file DalRegistry.hxx.

206{
207
208 std::lock_guard<std::mutex> scoped_lock(m_mutex);
209
210 auto it_dom = m_class_domain_map.find(&T::s_class_name);
211 if (it_dom == m_class_domain_map.end()) {
212 return false;
213 }
214
215 for (const auto& [uid, ptr] : m_cache_domains[it_dom->second].cache) {
216 if (ptr == object) {
217 return true;
218 }
219 }
220}

◆ unread_all()

void dunedaq::conffwk::DalRegistry::unread_all ( )

Set the status of all objects in cache to unread.

Definition at line 182 of file DalRegistry.cpp.

183{
184
185 for (const auto& [dom_id, domain] : m_cache_domains) {
186
187 std::lock_guard<std::mutex> scoped_lock(domain.mutex);
188
189 for (const auto& [id, ptr] : domain.cache) {
190 ptr->p_was_read = false;
191 }
192 }
193}

◆ update() [1/2]

void dunedaq::conffwk::DalRegistry::update ( const std::string & class_name,
const std::vector< std::string > & modified,
const std::vector< std::string > & removed,
const std::vector< std::string > & created )

Definition at line 143 of file DalRegistry.cpp.

147{
148
149 // Find the class domain of T
150 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(class_name));
151
152 // Class not known, this should not happen
153 if (it_dom == m_class_domain_map.end()) {
154 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
155 }
156
157 // get the correct cache domain
158 auto& domain = m_cache_domains[it_dom->second];
159
160 for (const auto& [uid, ptr] : domain.cache) {
161
162 // Check if the ptr class is derived from class_name
163 m_confdb.is_superclass_of(ptr->class_name(), class_name);
164
165 if (!ptr)
166 continue;
167
168 bool update = ((std::find(modified.begin(), modified.end(), ptr->UID()) != modified.end()) or
169 (std::find(removed.begin(), removed.end(), ptr->UID()) != removed.end()) or
170 (std::find(created.begin(), created.end(), ptr->UID()) != created.end()));
171
172 if (!update)
173 continue;
174
175 std::lock_guard<std::mutex> scoped_lock(domain.mutex);
176 ptr->p_was_read = false;
177 }
178}
void update(const std::vector< std::string > &modified, const std::vector< std::string > &removed, const std::vector< std::string > &created)
Update cache of objects in case of modification.
T * find(const std::string &id)
Find template object using ID.

◆ update() [2/2]

template<class T>
void dunedaq::conffwk::DalRegistry::update ( const std::vector< std::string > & modified,
const std::vector< std::string > & removed,
const std::vector< std::string > & created )

Update cache of objects in case of modification.

Only is called, when a user subscription to related class is set. It is used by automatically generated data access libraries.

Parameters
modifiedvector of modified objects of given user class (objects to be re-read in cache)
removedvector of removed objects of given user class (objects to be removed from cache)
createdvector of created objects of given user class (objects to be reset in cache, if they were removed)

Definition at line 225 of file DalRegistry.hxx.

228{
229
230 this->update(T::s_class_name, modified, removed, created);
231}

◆ update_class_domain_map()

void dunedaq::conffwk::DalRegistry::update_class_domain_map ( )
private

Definition at line 69 of file DalRegistry.cpp.

70{
71
72 m_class_domain_map.clear();
73
74 auto domains = m_confdb.find_class_domains();
75 // TODO: keep a local copy of the domains
76 for (size_t i(0); i < domains.size(); ++i) {
77 const auto& dom = domains[i];
78 for (const auto& class_name : dom) {
79 m_class_domain_map[&conffwk::DalFactory::instance().get_known_class_name_ref(class_name)] = i;
80 TLOG_DEBUG(9) << " - " << class_name << " : " << i;
81 }
82 }
83}
std::deque< std::set< std::string > > find_class_domains()

◆ update_class_maps()

void dunedaq::conffwk::DalRegistry::update_class_maps ( )
inline

Update the internal class domains map.

Definition at line 223 of file DalRegistry.hpp.

◆ DalObject

friend class DalObject
friend

Definition at line 21 of file DalRegistry.hpp.

Member Data Documentation

◆ m_cache_domains

std::unordered_map<uint, DalDomain> dunedaq::conffwk::DalRegistry::m_cache_domains
private

Definition at line 234 of file DalRegistry.hpp.

◆ m_class_domain_map

conffwk::fmap<uint> dunedaq::conffwk::DalRegistry::m_class_domain_map
private

Definition at line 232 of file DalRegistry.hpp.

◆ m_confdb

Configuration& dunedaq::conffwk::DalRegistry::m_confdb
private

Definition at line 226 of file DalRegistry.hpp.

◆ m_mutex

std::mutex dunedaq::conffwk::DalRegistry::m_mutex
mutableprivate

Definition at line 228 of file DalRegistry.hpp.


The documentation for this class was generated from the following files: