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 ()
 
Configurationconfiguration ()
 
const Configurationconfiguration () const
 
void clear ()
 Clear the content of the registy.
 
DalObjectget (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

Configurationm_confdb
 
std::mutex m_mutex
 
conffwk::fmap< uint > m_class_domain_map
 
std::unordered_map< uint, DalDomainm_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 19 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.

8 :
9 m_confdb(confdb) {
10}

◆ ~DalRegistry()

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

Definition at line 13 of file DalRegistry.cpp.

13 {
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(ERS_HERE, Configuration::mk_ref_ex_text("an object", T::s_class_name, name, obj).c_str(), ex));
172 }
173
174 return ((!res.is_null()) ? this->get<T>(res, read_children, read_children) : nullptr);
175}
#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
Generic configuration exception.

◆ _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 182 of file DalRegistry.hxx.

183{
184
185 std::vector<ConfigObject> objs;
186
187 results.clear();
188
189 try {
190 obj.get(name, objs);
191 results.reserve(objs.size());
192
193 for (auto& i : objs) {
194 auto ptr = this->get<T>(i, read_children, read_children);
195 results.push_back(ptr);
196 }
197 } catch (dunedaq::conffwk::Generic& ex) {
198 throw(dunedaq::conffwk::Generic(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 198 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
219}
std::unordered_map< uint, DalDomain > m_cache_domains
conffwk::fmap< uint > m_class_domain_map
Try to access non-existent object or class.
Definition Errors.hpp:47

◆ _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.

236 {
237
238 // Find the class domain of T
239 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(T::s_class_name));
240
241 // Class not known, this should not happen
242 if ( it_dom == m_class_domain_map.end() ) {
243 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", T::s_class_name.c_str());
244 }
245
246 auto& domain = m_cache_domains[it_dom->second];
247
248 // Loop over the objects in the domain and reset those inheriting from T
249 for( const auto& [uid, ptr] : domain.cache ) {
250
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 85 of file DalRegistry.cpp.

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

◆ configuration() [1/2]

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

Definition at line 37 of file DalRegistry.hpp.

37{ return m_confdb; }

◆ configuration() [2/2]

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

Definition at line 38 of file DalRegistry.hpp.

38{ 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.

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

◆ 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.

12 {
13
14 TLOG_DEBUG(50) << "Building object " << obj.UID() << " of class " << obj.class_name() << " and returning class " << T::s_class_name;
15
16 // Ensure that T is a superclass of (or the same class as) obj.class_name()
17 if ( not (
18 m_confdb.is_superclass_of(obj.class_name(), T::s_class_name) ||
19 m_confdb.is_superclass_of(T::s_class_name, obj.class_name())
20 )) {
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
59 TLOG_DEBUG(50) << "Returning " << (void*)result;
60
61 return result;
62}
bool is_superclass_of(const std::string &target, const std::string &source) noexcept
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112

◆ get() [2/4]

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

Definition at line 98 of file DalRegistry.cpp.

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

◆ 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 67 of file DalRegistry.hxx.

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

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

◆ 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.

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

◆ 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.

182 {
183
184 for( const auto& [dom_id, domain] : m_cache_domains ) {
185
186 std::lock_guard<std::mutex> scoped_lock(domain.mutex);
187
188 for( const auto& [id, ptr] : domain.cache ) {
189 ptr->p_was_read = false;
190 }
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 140 of file DalRegistry.cpp.

144 {
145
146 // Find the class domain of T
147 auto it_dom = m_class_domain_map.find(&DalFactory::instance().get_known_class_name_ref(class_name));
148
149 // Class not known, this should not happen
150 if ( it_dom == m_class_domain_map.end() ) {
151 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
152 }
153
154 // get the correct cache domain
155 auto& domain = m_cache_domains[it_dom->second];
156
157 for( const auto& [uid, ptr] : domain.cache ) {
158
159 // Check if the ptr class is derived from class_name
160 m_confdb.is_superclass_of(ptr->class_name(), class_name);
161
162 if (!ptr)
163 continue;
164
165 bool update = (
166 ( std::find(modified.begin(), modified.end(), ptr->UID()) != modified.end() ) or
167 ( std::find(removed.begin(), removed.end(), ptr->UID()) != removed.end() ) or
168 ( std::find(created.begin(), created.end(), ptr->UID()) != created.end() )
169 );
170
171 if (!update)
172 continue;
173
174 std::lock_guard<std::mutex> scoped_lock(domain.mutex);
175 ptr->p_was_read = false;
176 }
177}
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.
Factory couldn t find
Definition Issues.hpp:24

◆ 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.

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

◆ update_class_domain_map()

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

Definition at line 68 of file DalRegistry.cpp.

68 {
69
70 m_class_domain_map.clear();
71
72 auto domains = m_confdb.find_class_domains();
73 // TODO: keep a local copy of the domains
74 for (size_t i(0); i < domains.size(); ++i) {
75 const auto& dom = domains[i];
76 for (const auto& class_name : dom) {
77 m_class_domain_map[&conffwk::DalFactory::instance().get_known_class_name_ref(class_name)] = i;
78 TLOG_DEBUG(9) << " - " << class_name << " : " << i;
79 }
80 }
81}
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 211 of file DalRegistry.hpp.

211 {
213 }

Friends And Related Symbol Documentation

◆ 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 226 of file DalRegistry.hpp.

◆ m_class_domain_map

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

Definition at line 224 of file DalRegistry.hpp.

◆ m_confdb

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

Definition at line 218 of file DalRegistry.hpp.

◆ m_mutex

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

Definition at line 220 of file DalRegistry.hpp.


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