Line data Source code
1 : #ifndef ERROR_HANDLER_MA_DOMAIN_OPS_H
2 : #define ERROR_HANDLER_MA_DOMAIN_OPS_H
3 :
4 : #include "ErrorHandler/MessageAnalyzer/ma_types.h"
5 :
6 : namespace novadaq {
7 : namespace errorhandler {
8 :
9 : // ----------------------------------------------------------------
10 : // intersection of domains
11 :
12 : // element op
13 : inline int and_op(int i, int j);
14 :
15 : // 1. (s_out, t_out) = (s1, t1) n (s2, t2), in-place and
16 : // intersection of two cond_domain objects
17 : inline ma_cond_domain&
18 : domain_intersect(ma_cond_domain& d1, ma_cond_domain const& d2);
19 :
20 : // copy version
21 : inline ma_cond_domain
22 : domain_intersect_copy(ma_cond_domain d1, ma_cond_domain const& d2);
23 :
24 : // 2. (s_out, t_out) = (s1, t1) n (s2, t2) n ... n (s_n, t_n), in-place and
25 : // intersection of multiple cond_domain objects
26 : inline ma_cond_domain&
27 : domain_intersect(ma_cond_domains& d);
28 :
29 : // copy version
30 : inline ma_cond_domain
31 : domain_intersect_copy(ma_cond_domains d);
32 :
33 : // 3. intersection of two domain objects, result stores in the first
34 : inline ma_domain&
35 : domain_intersect(ma_domain& d1, ma_domain const& d2);
36 :
37 : // copy version
38 : inline ma_domain
39 : domain_intersect_copy(ma_domain d1, ma_domain const& d2);
40 :
41 : // 4. (so1, to1), (so2, to2) ...
42 : // = (s1_1, t1_1) n (s1_2, t1_2) n (s1_3, t1_3) ... ,
43 : // (s2_1, t2_1) n (s2_2, t2_2) n (s2_3, t2_3) ... ,
44 : // ...
45 : // intersection of multiple ma_domain objects
46 : // in-place calculation, result will be placed in d[0]
47 : inline ma_domain&
48 : domain_intersect(ma_domains& d);
49 :
50 : // copy version
51 : inline ma_domain
52 : domain_intersect_copy(ma_domains d);
53 :
54 : // ----------------------------------------------------------------
55 : // union of domains
56 :
57 : // element op -- test if a contains(>=) b
58 : inline bool contains_op(int a, int b);
59 :
60 : // 0. compare two cond_domains see if they contain one to another
61 : enum domain_compare_result_t
62 : {
63 : NO_COMMON,
64 : EQUAL,
65 : L_CONTAINS,
66 : R_CONTAINS
67 : };
68 :
69 : inline domain_compare_result_t
70 : domain_compare(ma_cond_domain const& d1, ma_cond_domain const& d2);
71 :
72 : // 1. add a new cond_domain to a list of cond_domains
73 : inline ma_cond_domains&
74 : domain_union(ma_cond_domains& ds, ma_cond_domain const& new_d);
75 :
76 : // 2. (s1_1, t1_1) U (s1_2, t1_2) U (s1_3, t1_3) ... ,
77 : // (s2_1, t2_1) U (s2_2, t2_2) U (s2_3, t2_3) ... ,
78 : // ...
79 : // * in-place union
80 : inline ma_domains&
81 : domain_union(ma_domains& ds);
82 :
83 : // utility functions
84 : inline bool
85 : domain_is_null(ma_cond_domain const& d);
86 :
87 : inline bool
88 : domain_is_null(ma_domain const& d);
89 :
90 : inline void
91 : domain_union_construct(ma_domains& ds, ma_domain& d, std::vector<ma_cond_domains>& mid, int depth, int max);
92 :
93 : // construct a null ma_cond_domain (nil, nil)
94 : inline ma_cond_domain
95 : ma_cond_domain_ctor_null();
96 :
97 : // construct a any ma_cond_domain (*,*)
98 : inline ma_cond_domain
99 : ma_cond_domain_ctor_any();
100 :
101 : // construct a ma_cond_domain from s and t
102 : inline ma_cond_domain
103 : ma_cond_domain_ctor(int s, int t);
104 :
105 : // construct a ma_cond_domain from a value and arg type (source or target)
106 : // ends up with a ma_cond_domain of (i,*) or (*,i)
107 : inline ma_cond_domain
108 : ma_cond_domain_ctor(int i, arg_t t);
109 :
110 : // construct a null ma_domain
111 : inline ma_domain
112 : ma_domain_ctor_null();
113 :
114 : // construct a null ma_domain
115 : inline ma_domain
116 : ma_domain_ctor_null(size_t size);
117 :
118 : // construct a any ma_domain with size s
119 : inline ma_domain
120 : ma_domain_ctor_any(size_t size);
121 :
122 : // construct a ma_domain object with size s and init'd to d
123 : inline ma_domain
124 : ma_domain_ctor(size_t size, ma_cond_domain d);
125 :
126 : } // end of namespace errorhandler
127 : } // end of namespace novadaq
128 :
129 : // ------------------------------------------------------------------
130 : // utility functions
131 :
132 : novadaq::errorhandler::ma_cond_domain
133 0 : novadaq::errorhandler::ma_cond_domain_ctor_null()
134 : {
135 0 : return ma_cond_domain_ctor(D_NIL, D_NIL);
136 : }
137 :
138 : novadaq::errorhandler::ma_cond_domain
139 0 : novadaq::errorhandler::ma_cond_domain_ctor_any()
140 : {
141 0 : return ma_cond_domain_ctor(D_ANY, D_ANY);
142 : }
143 :
144 : novadaq::errorhandler::ma_cond_domain
145 0 : novadaq::errorhandler::ma_cond_domain_ctor(int s, int t)
146 : {
147 0 : return ma_cond_domain(s, t);
148 : }
149 :
150 : novadaq::errorhandler::ma_cond_domain
151 0 : novadaq::errorhandler::ma_cond_domain_ctor(int i, arg_t t)
152 : {
153 0 : return (t == SOURCE) ? ma_cond_domain(i, D_ANY) : ma_cond_domain(D_ANY, i);
154 : }
155 :
156 : novadaq::errorhandler::ma_domain
157 0 : novadaq::errorhandler::ma_domain_ctor_null()
158 : {
159 0 : return ma_domain(1, ma_cond_domain_ctor_null());
160 : }
161 :
162 : novadaq::errorhandler::ma_domain
163 0 : novadaq::errorhandler::ma_domain_ctor_null(size_t size)
164 : {
165 0 : return ma_domain(size, ma_cond_domain_ctor_null());
166 : }
167 :
168 : novadaq::errorhandler::ma_domain
169 0 : novadaq::errorhandler::ma_domain_ctor_any(size_t size)
170 : {
171 0 : return ma_domain(size, ma_cond_domain_ctor_any());
172 : }
173 :
174 : novadaq::errorhandler::ma_domain
175 : novadaq::errorhandler::ma_domain_ctor(size_t size, ma_cond_domain d)
176 : {
177 : return ma_domain(size, d);
178 : }
179 :
180 : // ------------------------------------------------------------------
181 : // domain intersection
182 :
183 0 : int novadaq::errorhandler::and_op(int i, int j)
184 : {
185 0 : if (i == D_NIL || j == D_NIL) return D_NIL;
186 :
187 0 : if (i == j) return i;
188 0 : if (i == D_ANY) return j;
189 0 : if (j == D_ANY) return i;
190 :
191 0 : return D_NIL;
192 : }
193 :
194 : novadaq::errorhandler::ma_cond_domain&
195 0 : novadaq::errorhandler::domain_intersect(ma_cond_domain& d1, ma_cond_domain const& d2)
196 : {
197 0 : d1.first = and_op(d1.first, d2.first);
198 0 : d1.second = and_op(d1.second, d2.second);
199 :
200 0 : if (domain_is_null(d1))
201 0 : d1 = ma_cond_domain_ctor_null();
202 :
203 0 : return d1;
204 : }
205 :
206 : novadaq::errorhandler::ma_cond_domain
207 : novadaq::errorhandler::domain_intersect_copy(ma_cond_domain d1, ma_cond_domain const& d2)
208 : {
209 : return domain_intersect(d1, d2);
210 : }
211 :
212 : novadaq::errorhandler::ma_cond_domain&
213 : novadaq::errorhandler::domain_intersect(ma_cond_domains& ds)
214 : {
215 : if (ds.empty())
216 : {
217 : ds.push_back(ma_cond_domain_ctor_null());
218 : return ds.front();
219 : }
220 :
221 : ma_cond_domains::const_iterator it = ds.begin();
222 : while (++it != ds.end() && !domain_is_null(ds.front()))
223 : domain_intersect(ds.front(), *it);
224 :
225 : return ds.front();
226 : }
227 :
228 : novadaq::errorhandler::ma_cond_domain
229 : novadaq::errorhandler::domain_intersect_copy(ma_cond_domains d)
230 : {
231 : return domain_intersect(d);
232 : }
233 :
234 : novadaq::errorhandler::ma_domain&
235 0 : novadaq::errorhandler::domain_intersect(ma_domain& d1, ma_domain const& d2)
236 : {
237 0 : if (domain_is_null(d1) || domain_is_null(d2))
238 : {
239 0 : d1 = ma_domain_ctor_null();
240 0 : return d1;
241 : }
242 :
243 0 : if (d1.size() != d2.size())
244 0 : throw std::runtime_error("domain size incomparable while doing domain_intersect");
245 :
246 0 : for (size_t i = 0; i < d1.size(); ++i)
247 : {
248 0 : domain_intersect(d1[i], d2[i]);
249 :
250 0 : if (domain_is_null(d1[i]))
251 : {
252 0 : d1 = ma_domain_ctor_null();
253 0 : return d1;
254 : }
255 : }
256 :
257 0 : return d1;
258 : }
259 :
260 : novadaq::errorhandler::ma_domain
261 : novadaq::errorhandler::domain_intersect_copy(ma_domain d1, ma_domain const& d2)
262 : {
263 : return domain_intersect(d1, d2);
264 : }
265 :
266 : novadaq::errorhandler::ma_domain&
267 : novadaq::errorhandler::domain_intersect(ma_domains& ds)
268 : {
269 : if (ds.empty())
270 : {
271 : ds.push_back(ma_domain_ctor_null());
272 : return ds.front();
273 : }
274 :
275 : ma_domains::const_iterator it = ds.begin();
276 : while (++it != ds.end())
277 : {
278 : for (size_t i = 0; i < ds.front().size(); ++i)
279 : {
280 : domain_intersect(ds.front()[i], (*it)[i]);
281 :
282 : if (domain_is_null(ds.front()[i]))
283 : {
284 : ds.front() = ma_domain_ctor_null();
285 : goto exit;
286 : }
287 : }
288 : }
289 :
290 : exit:
291 :
292 : return ds.front();
293 : }
294 :
295 : novadaq::errorhandler::ma_domain
296 : novadaq::errorhandler::domain_intersect_copy(ma_domains ds)
297 : {
298 : return domain_intersect(ds);
299 : }
300 :
301 : // ------------------------------------------------------------------
302 : // domain union
303 :
304 : bool novadaq::errorhandler::contains_op(int a, int b)
305 : {
306 : return (a == b) ? (true) : ((a == D_ANY || b == D_NIL) ? true : false);
307 : }
308 :
309 0 : bool novadaq::errorhandler::domain_is_null(ma_cond_domain const& d)
310 : {
311 0 : return (d.first == D_NIL || d.second == D_NIL) ? true : false;
312 : }
313 :
314 0 : bool novadaq::errorhandler::domain_is_null(ma_domain const& d)
315 : {
316 0 : if (d.empty()) return true;
317 :
318 0 : for (size_t i = 0; i < d.size(); ++i)
319 0 : if (domain_is_null(d[i])) return true;
320 :
321 0 : return false;
322 : }
323 :
324 : novadaq::errorhandler::domain_compare_result_t
325 : novadaq::errorhandler::domain_compare(ma_cond_domain const& d1, ma_cond_domain const& d2)
326 : {
327 : if (d1.first == d2.first && d1.second == d2.second)
328 : return EQUAL;
329 :
330 : bool flag1 = false;
331 : bool flag2 = false;
332 :
333 : if (contains_op(d1.first, d2.first)) flag1 = true;
334 : if (contains_op(d1.second, d2.second)) flag2 = true;
335 :
336 : if (flag1 != flag2)
337 : return NO_COMMON;
338 :
339 : if (flag1)
340 : return L_CONTAINS;
341 : else
342 : return R_CONTAINS;
343 : }
344 :
345 : novadaq::errorhandler::ma_cond_domains&
346 : novadaq::errorhandler::domain_union(ma_cond_domains& ds, ma_cond_domain const& new_d)
347 : {
348 : if (domain_is_null(new_d)) return ds;
349 :
350 : ma_cond_domains::iterator it = ds.begin();
351 : while (it != ds.end())
352 : {
353 : domain_compare_result_t r = domain_compare(*it, new_d);
354 :
355 : if (r == EQUAL || r == L_CONTAINS)
356 : return ds;
357 :
358 : if (r == R_CONTAINS)
359 : {
360 : ds.erase(it);
361 : return domain_union(ds, new_d);
362 : }
363 :
364 : // NO_COMMON
365 : ++it;
366 : }
367 :
368 : ds.push_back(new_d);
369 : return ds;
370 : }
371 :
372 : void novadaq::errorhandler::domain_union_construct(ma_domains& ds, ma_domain& d, std::vector<ma_cond_domains>& mid, int depth, int max)
373 : {
374 : ma_cond_domains::const_iterator it = mid[depth].begin();
375 :
376 : while (it != mid[depth].end())
377 : {
378 : d[depth] = *it;
379 :
380 : if (depth != max)
381 : domain_union_construct(ds, d, mid, depth + 1, max);
382 : else
383 : ds.push_back(d);
384 :
385 : ++it;
386 : }
387 : }
388 :
389 : novadaq::errorhandler::ma_domains&
390 : novadaq::errorhandler::domain_union(ma_domains& ds)
391 : {
392 : if (ds.empty()) return ds;
393 :
394 : // domain size (how many conditions in a domain)
395 : size_t size = ds.front().size();
396 :
397 : // temp place to hold intermediate results
398 : std::vector<ma_cond_domains> mid(size);
399 :
400 : ma_domains::const_iterator it = ds.begin();
401 : while (it != ds.end())
402 : {
403 : for (size_t i = 0; i < size; ++i)
404 : domain_union(mid[i], (*it)[i]);
405 :
406 : ++it;
407 : }
408 :
409 : ma_domains result;
410 : ma_domain domain(size);
411 :
412 : domain_union_construct(result, domain, mid, 0, size - 1);
413 :
414 : ds = result;
415 : return ds;
416 : }
417 :
418 : #endif
|