Line data Source code
1 : #include "conffwk/DalObject.hpp"
2 : #include "conffwk/Schema.hpp"
3 :
4 : namespace dunedaq {
5 : namespace conffwk {
6 :
7 : //-----------------------------------------------------------------------------
8 95 : DalRegistry::DalRegistry(conffwk::Configuration& confdb)
9 95 : : m_confdb(confdb)
10 : {
11 95 : }
12 :
13 : //-----------------------------------------------------------------------------
14 95 : DalRegistry::~DalRegistry() {}
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,
40 : // intersection.begin()));
41 : // // non-zero intersection, overlap found
42 : // if (intersection.size() > 0) {
43 : // overlapping.push_back(d);
44 : // }
45 : // }
46 :
47 : // // If overlapping are found, add all overlapping to
48 : // // the new domain and remove them from the domain list
49 : // if (!overlapping.empty()) {
50 : // for (auto& d : overlapping) {
51 : // // merge the existing cluster in class_domain
52 : // class_domain.insert(d.begin(), d.end());
53 : // // Remove the old cluster from the list
54 : // auto it = std::find(domains.begin(), domains.end(), d);
55 : // if (it != domains.end()) {
56 : // domains.erase(it);
57 : // }
58 : // }
59 : // }
60 :
61 : // domains.push_back(class_domain);
62 : // }
63 :
64 : // return domains;
65 : // }
66 :
67 : //-----------------------------------------------------------------------------
68 : void
69 100 : DalRegistry::update_class_domain_map()
70 : {
71 :
72 100 : m_class_domain_map.clear();
73 :
74 100 : auto domains = m_confdb.find_class_domains();
75 : // TODO: keep a local copy of the domains
76 3342 : for (size_t i(0); i < domains.size(); ++i) {
77 3242 : const auto& dom = domains[i];
78 10744 : for (const auto& class_name : dom) {
79 7502 : m_class_domain_map[&conffwk::DalFactory::instance().get_known_class_name_ref(class_name)] = i;
80 7502 : TLOG_DEBUG(9) << " - " << class_name << " : " << i;
81 : }
82 : }
83 100 : }
84 :
85 : //-----------------------------------------------------------------------------
86 : void
87 95 : DalRegistry::clear()
88 : {
89 812 : for (const auto& [index, domain] : m_cache_domains) {
90 :
91 1995 : for (const auto& [uid, ptr] : domain.cache) {
92 1278 : delete ptr;
93 : }
94 : }
95 :
96 95 : m_class_domain_map.clear();
97 95 : }
98 :
99 : //-----------------------------------------------------------------------------
100 : DalObject*
101 0 : DalRegistry::get(ConfigObject& obj, bool upcast_unregistered)
102 : {
103 :
104 : // Find the class domain of T
105 0 : 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 0 : if (it_dom == m_class_domain_map.end()) {
109 0 : throw dunedaq::conffwk::NotFound(ERS_HERE, "class", obj.class_name().c_str());
110 : }
111 :
112 0 : auto& domain = m_cache_domains[it_dom->second];
113 :
114 0 : DalObject*& result(domain.cache[obj.m_impl->m_id]);
115 0 : if (result == nullptr) {
116 :
117 0 : result = DalFactory::instance().make(*this, obj, upcast_unregistered);
118 :
119 0 : } else if (obj.m_impl != result->p_obj.m_impl) {
120 :
121 0 : std::lock_guard<std::mutex> scoped_lock(result->m_mutex);
122 0 : result->set(obj); // update implementation object; to be used in case if the object is re-created
123 0 : }
124 :
125 0 : return result;
126 : }
127 :
128 : //-----------------------------------------------------------------------------
129 : std::vector<const DalObject*>
130 0 : DalRegistry::get(std::vector<ConfigObject>& objs, bool upcast_unregistered)
131 : {
132 0 : std::vector<const DalObject*> result;
133 :
134 0 : for (auto& i : objs)
135 0 : if (DalObject* o = this->get(i, upcast_unregistered))
136 0 : result.push_back(o);
137 :
138 0 : return result;
139 0 : }
140 :
141 : //-----------------------------------------------------------------------------
142 : void
143 0 : DalRegistry::update(const std::string& class_name,
144 : const std::vector<std::string>& modified,
145 : const std::vector<std::string>& removed,
146 : const std::vector<std::string>& created)
147 : {
148 :
149 : // Find the class domain of T
150 0 : 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 0 : if (it_dom == m_class_domain_map.end()) {
154 0 : throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
155 : }
156 :
157 : // get the correct cache domain
158 0 : auto& domain = m_cache_domains[it_dom->second];
159 :
160 0 : for (const auto& [uid, ptr] : domain.cache) {
161 :
162 : // Check if the ptr class is derived from class_name
163 0 : m_confdb.is_superclass_of(ptr->class_name(), class_name);
164 :
165 0 : if (!ptr)
166 0 : continue;
167 :
168 0 : bool update = ((std::find(modified.begin(), modified.end(), ptr->UID()) != modified.end()) or
169 0 : (std::find(removed.begin(), removed.end(), ptr->UID()) != removed.end()) or
170 0 : (std::find(created.begin(), created.end(), ptr->UID()) != created.end()));
171 :
172 0 : if (!update)
173 0 : continue;
174 :
175 0 : std::lock_guard<std::mutex> scoped_lock(domain.mutex);
176 0 : ptr->p_was_read = false;
177 0 : }
178 0 : }
179 :
180 : //-----------------------------------------------------------------------------
181 : void
182 0 : DalRegistry::unread_all()
183 : {
184 :
185 0 : for (const auto& [dom_id, domain] : m_cache_domains) {
186 :
187 0 : std::lock_guard<std::mutex> scoped_lock(domain.mutex);
188 :
189 0 : for (const auto& [id, ptr] : domain.cache) {
190 0 : ptr->p_was_read = false;
191 : }
192 0 : }
193 0 : }
194 :
195 : //-----------------------------------------------------------------------------
196 : void
197 0 : DalRegistry::_rename_object(std::string class_name, std::string old_id, std::string new_id)
198 : {
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 0 : }
219 :
220 : } // namespace conffwk
221 : } // namespace dunedaq
|