Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
3 : // Fork baseline commit: oks-08-03-04 (2022-04-14).
4 : // Renamed since fork: no.
5 :
6 : #define _OksBuildDll_
7 :
8 : #include "oks/index.hpp"
9 : #include "oks/attribute.hpp"
10 : #include "oks/class.hpp"
11 :
12 : namespace dunedaq {
13 : namespace oks {
14 :
15 : size_t
16 0 : OksIndex::get_offset(OksClass* cl, OksAttribute* a)
17 : {
18 0 : OksDataInfo::Map::const_iterator x = cl->p_data_info->find(a->p_name);
19 0 : return (x == cl->p_data_info->end()) ? 0 : x->second->offset;
20 : }
21 :
22 0 : OksIndex::OksIndex(OksClass* cl, OksAttribute* attr)
23 : : std::multiset<OksObject*, OksObjectSortBy>(get_offset(cl, attr))
24 0 : , c(cl)
25 0 : , a(attr)
26 : {
27 0 : const char* fname = "OksIndex::OksIndex(OksClass *, OksAttribute *";
28 :
29 0 : if (!c) {
30 0 : Oks::error_msg(fname) << "Can't build index for NIL class\n";
31 : return;
32 : }
33 :
34 0 : if (c->get_is_abstract()) {
35 0 : Oks::error_msg(fname) << "Can't build index for ABSTRACT class \"" << c->get_name() << "\"\n";
36 : return;
37 : }
38 :
39 0 : if (!a) {
40 0 : Oks::error_msg(fname) << "Can't build index for NIL attribute\n";
41 : return;
42 : }
43 :
44 0 : if (c->find_attribute(a->get_name()) == 0) {
45 0 : Oks::error_msg(fname) << "Can't find attribute \"" << a->p_name << "\" in class \"" << c->get_name()
46 0 : << "\" to build index.\n";
47 : return;
48 : }
49 :
50 0 : if (c->p_indices && c->p_indices->find(a) != c->p_indices->end()) {
51 0 : Oks::error_msg(fname) << "Class \"" << c->get_name() << "\" already has index for attribute \"" << a->p_name
52 0 : << "\".\n";
53 : return;
54 : }
55 :
56 0 : offset = ((*c->p_data_info)[a->p_name])->offset;
57 :
58 0 : if (!c->p_indices)
59 0 : c->p_indices = new OksIndex::Map();
60 :
61 0 : (*c->p_indices)[a] = this;
62 :
63 0 : if (c->p_objects && !c->p_objects->empty()) {
64 0 : for (OksObject::Map::iterator i = c->p_objects->begin(); i != c->p_objects->end(); ++i)
65 0 : insert((*i).second);
66 : }
67 :
68 0 : std::cout << "Build index for attribute \'" << a->p_name << "\' in class \'" << c->get_name() << "\' for " << size()
69 0 : << " instances\n";
70 :
71 : #ifdef DEBUG_INDICES
72 : for (int j = 0; j < entries(); j++) {
73 : OksObject* obj = at(j);
74 :
75 : std::cout << j << ".\tobject id \'" << obj->GetId() << "\' "
76 : << "\tvalue: \'" << obj->data[offset] << "\'\n";
77 : }
78 : #endif
79 0 : }
80 :
81 0 : OksIndex::~OksIndex()
82 : {
83 0 : if (c && a) {
84 0 : c->p_indices->erase(a);
85 :
86 0 : if (c->p_indices->empty()) {
87 0 : delete c->p_indices;
88 0 : c->p_indices = 0;
89 : }
90 : }
91 0 : }
92 :
93 : OksObject*
94 0 : OksIndex::remove_obj(OksObject* o)
95 : {
96 0 : std::pair<Position, Position> positions = equal_range(o);
97 0 : Position i = positions.first;
98 0 : Position i2 = positions.second;
99 :
100 0 : for (; i != i2; ++i) {
101 0 : if (o == *i) {
102 0 : erase(i);
103 0 : return o;
104 : }
105 : }
106 :
107 : return 0;
108 : }
109 :
110 : OksObject*
111 0 : OksIndex::FindFirst(OksData* d) const
112 : {
113 0 : OksObject test_o(offset, d);
114 :
115 0 : ConstPosition pos = lower_bound(&test_o);
116 :
117 0 : if (pos != end())
118 0 : return *pos;
119 :
120 : return 0;
121 0 : }
122 :
123 : void
124 0 : OksIndex::find_interval(OksData* d, OksQuery::Comparator f, ConstPosition& i1, ConstPosition& i2) const
125 : {
126 0 : i1 = i2 = end();
127 :
128 0 : if (empty())
129 0 : return;
130 :
131 0 : OksObject test_o(offset, d);
132 :
133 0 : if (f == OksQuery::equal_cmp) {
134 0 : i1 = lower_bound(&test_o);
135 :
136 0 : if (i1 != end()) {
137 0 : if ((*i1)->data[offset] == *d) {
138 0 : i2 = upper_bound(&test_o);
139 : } else {
140 0 : i2 = i1;
141 : }
142 : }
143 0 : } else if (f == OksQuery::less_or_equal_cmp || f == OksQuery::less_cmp) {
144 0 : i1 = begin();
145 :
146 0 : if (f == OksQuery::less_cmp) {
147 0 : i2 = lower_bound(&test_o);
148 : } else {
149 0 : i2 = upper_bound(&test_o);
150 : }
151 0 : } else if (f == OksQuery::greater_or_equal_cmp || f == OksQuery::greater_cmp) {
152 0 : i2 = end();
153 :
154 0 : if (f == OksQuery::greater_cmp) {
155 0 : i1 = upper_bound(&test_o);
156 : } else {
157 0 : i1 = lower_bound(&test_o);
158 : }
159 : }
160 0 : }
161 :
162 : OksObject::List*
163 0 : OksIndex::find_all(OksData* d, OksQuery::Comparator f) const
164 : {
165 0 : OksObject::List* olist = 0;
166 :
167 0 : ConstPosition pos1, pos2;
168 :
169 0 : find_interval(d, f, pos1, pos2);
170 :
171 0 : if (pos1 != pos2) {
172 0 : olist = new OksObject::List();
173 0 : for (; pos1 != pos2; ++pos1)
174 0 : olist->push_back(*pos1);
175 : }
176 :
177 0 : return olist;
178 : }
179 :
180 : OksObject::List*
181 0 : OksIndex::find_all(bool andOperation, OksData* d1, OksQuery::Comparator f1, OksData* d2, OksQuery::Comparator f2) const
182 : {
183 0 : OksObject::List* olist = 0;
184 :
185 0 : ConstPosition a1, b1;
186 :
187 0 : find_interval(d1, f1, a1, b1);
188 :
189 0 : if ((andOperation == true) && (a1 == b1))
190 : return 0;
191 :
192 0 : ConstPosition a2, b2;
193 :
194 0 : find_interval(d2, f2, a2, b2);
195 :
196 0 : if (andOperation == true) {
197 0 : if (a2 == b2)
198 0 : return 0;
199 :
200 : //
201 : // find intersection ([pos1,pos2] or NIL) of [a1,b1] and [a2,b2]
202 : // where begin() <= {a1,b1,a2,b2} <= end())
203 : //
204 : // (note that a1 and a2 are not equal to end() but b1 nad b2 have to be tested)
205 : //
206 :
207 0 : ConstPosition pos1, pos2;
208 :
209 0 : if ((*a2)->data[offset] <= (*a1)->data[offset]) {
210 0 : if ((b2 != end()) && ((*b2)->data[offset] < (*a1)->data[offset]))
211 0 : return 0;
212 0 : pos1 = a1;
213 : } else {
214 0 : if ((b1 != end()) && (*a2)->data[offset] > (*b1)->data[offset])
215 0 : return 0;
216 0 : pos1 = a2;
217 : }
218 :
219 0 : if (b2 == end() || b1 == end()) {
220 0 : pos2 = (b2 != end()) ? b2 : b1;
221 : } else
222 0 : pos2 = ((*b2)->data[offset] <= (*b1)->data[offset]) ? b2 : b1;
223 :
224 0 : olist = new OksObject::List();
225 0 : for (; pos1 != pos2; ++pos1)
226 0 : olist->push_back(*pos1);
227 : } else {
228 0 : if (a1 != b1 && a2 == b2) {
229 0 : olist = new OksObject::List();
230 0 : for (; a1 != b1; ++a1)
231 0 : olist->push_back(*a1);
232 0 : } else if (a2 != b2 && a1 == b1) {
233 0 : olist = new OksObject::List();
234 0 : for (; a2 != b2; ++a2)
235 0 : olist->push_back(*a2);
236 0 : } else if (a1 != b1 && a2 != b2) {
237 0 : olist = new OksObject::List();
238 :
239 : //
240 : // find union of [a1,b1] and [a2,b2] (i.e. [pos1,pos2] or [a1,b1],[a2,b2])
241 : // where begin() <= {a1,b1,a2,b2} <= end())
242 : //
243 : // (note that a1 and a2 are not equal to end() but b1 nad b2 have to be tested)
244 : //
245 :
246 0 : ConstPosition pos1, pos2;
247 :
248 0 : if ((*a2)->data[offset] <= (*a1)->data[offset]) {
249 0 : if (b2 != end() && (*b2)->data[offset] < (*a1)->data[offset]) {
250 0 : for (; a2 != b2; ++a2)
251 0 : olist->push_back(*a2);
252 0 : for (; a1 != b1; ++a1)
253 0 : olist->push_back(*a1);
254 :
255 0 : return olist;
256 : }
257 :
258 0 : pos1 = a2;
259 : } else {
260 0 : if (b1 != end() && (*a2)->data[offset] > (*b1)->data[offset]) {
261 0 : for (; a1 != b1; ++a1)
262 0 : olist->push_back(*a1);
263 0 : for (; a2 != b2; ++a2)
264 0 : olist->push_back(*a2);
265 :
266 : return olist;
267 : }
268 :
269 0 : pos1 = a1;
270 : }
271 :
272 0 : if (b2 == end() || b1 == end()) {
273 0 : pos2 = (b2 == end()) ? b2 : b1;
274 : } else
275 0 : pos2 = ((*b2)->data[offset] >= (*b1)->data[offset]) ? b2 : b1;
276 :
277 0 : for (; pos1 != pos2; ++pos1)
278 0 : olist->push_back(*pos1);
279 : }
280 : }
281 :
282 : return olist;
283 : }
284 :
285 : } // namespace oks
286 : } // namespace dunedaq
|