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