Line data Source code
1 : #include "conffwk/Schema.hpp"
2 : #include "conffwk/DalObject.hpp"
3 :
4 : namespace dunedaq {
5 : namespace conffwk {
6 :
7 : //-----------------------------------------------------------------------------
8 80 : DalRegistry::DalRegistry( conffwk::Configuration& confdb ) :
9 80 : m_confdb(confdb) {
10 80 : }
11 :
12 : //-----------------------------------------------------------------------------
13 80 : DalRegistry::~DalRegistry() {
14 80 : }
15 :
16 : // //-----------------------------------------------------------------------------
17 : // std::deque<std::set<std::string>>
18 : // DalRegistry::find_class_domains() {
19 :
20 : // std::deque<std::set<std::string>> domains;
21 :
22 : // std::deque<dunedaq::conffwk::class_t> seeds;
23 : // for (const auto& c : m_confdb.get_class_list()) {
24 : // auto ci = m_confdb._get_class_info(c);
25 : // if (ci.p_superclasses.empty())
26 : // seeds.push_back(ci);
27 : // }
28 :
29 : // for (const auto& ci : seeds) {
30 : // // Make a candidate domain based using the seed subclasses
31 : // std::set<std::string> class_domain;
32 : // class_domain.insert(ci.p_name);
33 : // class_domain.insert(ci.p_subclasses.begin(), ci.p_subclasses.end());
34 :
35 : // // Look for overlaps with other domains
36 : // std::deque<std::set<std::string>> overlapping;
37 : // for (auto& d : domains) {
38 : // std::set<std::string> intersection;
39 : // std::set_intersection(d.begin(), d.end(), class_domain.begin(), class_domain.end(), std::inserter(intersection, intersection.begin()));
40 : // // non-zero intersection, overlap found
41 : // if (intersection.size() > 0) {
42 : // overlapping.push_back(d);
43 : // }
44 : // }
45 :
46 : // // If overlapping are found, add all overlapping to
47 : // // the new domain and remove them from the domain list
48 : // if (!overlapping.empty()) {
49 : // for (auto& d : overlapping) {
50 : // // merge the existing cluster in class_domain
51 : // class_domain.insert(d.begin(), d.end());
52 : // // Remove the old cluster from the list
53 : // auto it = std::find(domains.begin(), domains.end(), d);
54 : // if (it != domains.end()) {
55 : // domains.erase(it);
56 : // }
57 : // }
58 : // }
59 :
60 : // domains.push_back(class_domain);
61 : // }
62 :
63 : // return domains;
64 : // }
65 :
66 : //-----------------------------------------------------------------------------
67 : void
68 84 : DalRegistry::update_class_domain_map() {
69 :
70 84 : m_class_domain_map.clear();
71 :
72 84 : auto domains = m_confdb.find_class_domains();
73 : // TODO: keep a local copy of the domains
74 2478 : for (size_t i(0); i < domains.size(); ++i) {
75 2394 : const auto& dom = domains[i];
76 7951 : for (const auto& class_name : dom) {
77 5557 : m_class_domain_map[&conffwk::DalFactory::instance().get_known_class_name_ref(class_name)] = i;
78 5557 : TLOG_DEBUG(9) << " - " << class_name << " : " << i;
79 : }
80 : }
81 84 : }
82 :
83 : //-----------------------------------------------------------------------------
84 : void
85 80 : DalRegistry::clear() {
86 666 : for( const auto& [index, domain] : m_cache_domains ) {
87 :
88 1708 : for(const auto& [uid, ptr] : domain.cache ) {
89 1122 : delete ptr;
90 : }
91 : }
92 :
93 80 : m_class_domain_map.clear();
94 80 : }
95 :
96 : //-----------------------------------------------------------------------------
97 : DalObject*
98 0 : DalRegistry::get(ConfigObject& obj, bool upcast_unregistered) {
99 :
100 : // Find the class domain of T
101 0 : 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 0 : if ( it_dom == m_class_domain_map.end() ) {
105 0 : throw dunedaq::conffwk::NotFound(ERS_HERE, "class", obj.class_name().c_str());
106 : }
107 :
108 0 : auto& domain = m_cache_domains[it_dom->second];
109 :
110 0 : DalObject*& result(domain.cache[obj.m_impl->m_id]);
111 0 : if (result == nullptr) {
112 :
113 0 : result = DalFactory::instance().make(*this, obj, upcast_unregistered);
114 :
115 0 : } else if (obj.m_impl != result->p_obj.m_impl) {
116 :
117 0 : std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
118 0 : result->set(obj); // update implementation object; to be used in case if the object is re-created
119 :
120 0 : }
121 :
122 0 : return result;
123 : }
124 :
125 : //-----------------------------------------------------------------------------
126 : std::vector<const DalObject*>
127 0 : DalRegistry::get(std::vector<ConfigObject>& objs, bool upcast_unregistered)
128 : {
129 0 : std::vector<const DalObject*> result;
130 :
131 0 : for (auto &i : objs)
132 0 : if (DalObject *o = this->get(i,upcast_unregistered))
133 0 : result.push_back(o);
134 :
135 0 : return result;
136 0 : }
137 :
138 : //-----------------------------------------------------------------------------
139 : void
140 0 : DalRegistry::update(
141 : const std::string& class_name,
142 : const std::vector<std::string>& modified,
143 : const std::vector<std::string>& removed,
144 : const std::vector<std::string>& created) {
145 :
146 : // Find the class domain of T
147 0 : 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 0 : if ( it_dom == m_class_domain_map.end() ) {
151 0 : throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
152 : }
153 :
154 : // get the correct cache domain
155 0 : auto& domain = m_cache_domains[it_dom->second];
156 :
157 0 : for( const auto& [uid, ptr] : domain.cache ) {
158 :
159 : // Check if the ptr class is derived from class_name
160 0 : m_confdb.is_superclass_of(ptr->class_name(), class_name);
161 :
162 0 : if (!ptr)
163 0 : continue;
164 :
165 0 : bool update = (
166 0 : ( std::find(modified.begin(), modified.end(), ptr->UID()) != modified.end() ) or
167 0 : ( std::find(removed.begin(), removed.end(), ptr->UID()) != removed.end() ) or
168 0 : ( std::find(created.begin(), created.end(), ptr->UID()) != created.end() )
169 0 : );
170 :
171 0 : if (!update)
172 0 : continue;
173 :
174 0 : std::lock_guard<std::mutex> scoped_lock(domain.mutex);
175 0 : ptr->p_was_read = false;
176 0 : }
177 0 : }
178 :
179 :
180 : //-----------------------------------------------------------------------------
181 : void
182 0 : DalRegistry::unread_all() {
183 :
184 0 : for( const auto& [dom_id, domain] : m_cache_domains ) {
185 :
186 0 : std::lock_guard<std::mutex> scoped_lock(domain.mutex);
187 :
188 0 : for( const auto& [id, ptr] : domain.cache ) {
189 0 : ptr->p_was_read = false;
190 : }
191 :
192 0 : }
193 0 : }
194 :
195 :
196 : //-----------------------------------------------------------------------------
197 : void
198 0 : DalRegistry::_rename_object(std::string class_name, std::string old_id, std::string new_id) {
199 : // Find the class domain of T
200 0 : 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 0 : if ( it_dom == m_class_domain_map.end() ) {
204 0 : throw dunedaq::conffwk::NotFound(ERS_HERE, class_name.c_str(), old_id.c_str());
205 : }
206 :
207 0 : auto& domain = m_cache_domains[it_dom->second];
208 :
209 0 : auto it = domain.cache.find(old_id);
210 0 : if (it == domain.cache.end())
211 0 : return;
212 :
213 0 : domain.cache[new_id] = it->second;
214 0 : domain.cache.erase(it);
215 :
216 0 : std::lock_guard<std::mutex> scoped_lock(it->second->m_mutex);
217 0 : it->second->p_UID = new_id;
218 :
219 0 : }
220 :
221 :
222 : } // namespace conffwk
223 : } // namespace dunedaq
|