artdaq_mfextensions  v1_05_00
ma_domain_ops.h
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 { NO_COMMON
62  , EQUAL
63  , L_CONTAINS
64  , R_CONTAINS };
65 
66  inline domain_compare_result_t
67  domain_compare( ma_cond_domain const & d1
68  , ma_cond_domain const & d2 );
69 
70  // 1. add a new cond_domain to a list of cond_domains
71  inline ma_cond_domains &
72  domain_union( ma_cond_domains & ds, ma_cond_domain const & new_d );
73 
74  // 2. (s1_1, t1_1) U (s1_2, t1_2) U (s1_3, t1_3) ... ,
75  // (s2_1, t2_1) U (s2_2, t2_2) U (s2_3, t2_3) ... ,
76  // ...
77  // * in-place union
78  inline ma_domains &
79  domain_union( ma_domains & ds );
80 
81  // utility functions
82  inline bool
83  domain_is_null( ma_cond_domain const & d );
84 
85  inline bool
86  domain_is_null( ma_domain const & d );
87 
88  inline void
89  domain_union_construct ( ma_domains & ds
90  , ma_domain & d
91  , std::vector<ma_cond_domains> & mid
92  , int depth
93  , int max );
94 
95  // construct a null ma_cond_domain (nil, nil)
96  inline ma_cond_domain
97  ma_cond_domain_ctor_null ( );
98 
99  // construct a any ma_cond_domain (*,*)
100  inline ma_cond_domain
101  ma_cond_domain_ctor_any ( );
102 
103  // construct a ma_cond_domain from s and t
104  inline ma_cond_domain
105  ma_cond_domain_ctor ( int s, int t );
106 
107  // construct a ma_cond_domain from a value and arg type (source or target)
108  // ends up with a ma_cond_domain of (i,*) or (*,i)
109  inline ma_cond_domain
110  ma_cond_domain_ctor ( int i, arg_t t );
111 
112  // construct a null ma_domain
113  inline ma_domain
114  ma_domain_ctor_null ( );
115 
116  // construct a null ma_domain
117  inline ma_domain
118  ma_domain_ctor_null ( size_t size );
119 
120  // construct a any ma_domain with size s
121  inline ma_domain
122  ma_domain_ctor_any ( size_t size );
123 
124  // construct a ma_domain object with size s and init'd to d
125  inline ma_domain
126  ma_domain_ctor( size_t size, ma_cond_domain d );
127 
128 } // end of namespace errorhandler
129 } // end of namespace novadaq
130 
131 
132 // ------------------------------------------------------------------
133 // utility functions
134 
135 novadaq::errorhandler::ma_cond_domain
136  novadaq::errorhandler::ma_cond_domain_ctor_null ( )
137 {
138  return ma_cond_domain_ctor(D_NIL, D_NIL);
139 }
140 
141 novadaq::errorhandler::ma_cond_domain
142  novadaq::errorhandler::ma_cond_domain_ctor_any ( )
143 {
144  return ma_cond_domain_ctor(D_ANY, D_ANY);
145 }
146 
147 novadaq::errorhandler::ma_cond_domain
148  novadaq::errorhandler::ma_cond_domain_ctor ( int s, int t )
149 {
150  return ma_cond_domain(s, t);
151 }
152 
153 novadaq::errorhandler::ma_cond_domain
154  novadaq::errorhandler::ma_cond_domain_ctor ( int i, arg_t t )
155 {
156  return (t==SOURCE) ? ma_cond_domain(i, D_ANY) : ma_cond_domain(D_ANY, i);
157 }
158 
159 novadaq::errorhandler::ma_domain
160  novadaq::errorhandler::ma_domain_ctor_null ( )
161 {
162  return ma_domain(1, ma_cond_domain_ctor_null());
163 }
164 
165 novadaq::errorhandler::ma_domain
166  novadaq::errorhandler::ma_domain_ctor_null ( size_t size )
167 {
168  return ma_domain(size, ma_cond_domain_ctor_null());
169 }
170 
171 novadaq::errorhandler::ma_domain
172  novadaq::errorhandler::ma_domain_ctor_any ( size_t size )
173 {
174  return ma_domain(size, ma_cond_domain_ctor_any());
175 }
176 
177 novadaq::errorhandler::ma_domain
178  novadaq::errorhandler::ma_domain_ctor ( size_t size, ma_cond_domain d )
179 {
180  return ma_domain(size, d);
181 }
182 
183 
184 // ------------------------------------------------------------------
185 // domain intersection
186 
187 int
188  novadaq::errorhandler::and_op( int i, int j )
189 {
190  if (i==D_NIL || j==D_NIL) return D_NIL;
191 
192  if (i==j) return i;
193  if (i==D_ANY) return j;
194  if (j==D_ANY) return i;
195 
196  return D_NIL;
197 }
198 
199 novadaq::errorhandler::ma_cond_domain &
200  novadaq::errorhandler::domain_intersect( ma_cond_domain & d1
201  , ma_cond_domain const & d2 )
202 {
203  d1.first = and_op(d1.first, d2.first);
204  d1.second = and_op(d1.second, d2.second);
205 
206  if (domain_is_null(d1))
207  d1 = ma_cond_domain_ctor_null();
208 
209  return d1;
210 }
211 
212 novadaq::errorhandler::ma_cond_domain
213  novadaq::errorhandler::domain_intersect_copy( ma_cond_domain d1
214  , ma_cond_domain const & d2)
215 {
216  return domain_intersect(d1, d2);
217 }
218 
219 novadaq::errorhandler::ma_cond_domain &
220  novadaq::errorhandler::domain_intersect( ma_cond_domains & ds )
221 {
222  if (ds.empty())
223  {
224  ds.push_back(ma_cond_domain_ctor_null());
225  return ds.front();
226  }
227 
228  ma_cond_domains::const_iterator it = ds.begin();
229  while(++it!=ds.end() && !domain_is_null(ds.front()))
230  domain_intersect(ds.front(), *it);
231 
232  return ds.front();
233 }
234 
235 novadaq::errorhandler::ma_cond_domain
236  novadaq::errorhandler::domain_intersect_copy( ma_cond_domains d )
237 {
238  return domain_intersect(d);
239 }
240 
241 novadaq::errorhandler::ma_domain &
242  novadaq::errorhandler::domain_intersect( ma_domain & d1
243  , ma_domain const & d2 )
244 {
245  if (domain_is_null(d1) || domain_is_null(d2))
246  {
247  d1 = ma_domain_ctor_null();
248  return d1;
249  }
250 
251  if (d1.size() != d2.size())
252  throw std::runtime_error("domain size incomparable while doing domain_intersect");
253 
254  for(size_t i=0; i<d1.size(); ++i)
255  {
256  domain_intersect(d1[i], d2[i]);
257 
258  if (domain_is_null(d1[i]))
259  {
260  d1 = ma_domain_ctor_null();
261  return d1;
262  }
263  }
264 
265  return d1;
266 }
267 
268 novadaq::errorhandler::ma_domain
269  novadaq::errorhandler::domain_intersect_copy( ma_domain d1
270  , ma_domain const & d2 )
271 {
272  return domain_intersect(d1, d2);
273 }
274 
275 novadaq::errorhandler::ma_domain &
276  novadaq::errorhandler::domain_intersect( ma_domains & ds )
277 {
278  if (ds.empty())
279  {
280  ds.push_back(ma_domain_ctor_null());
281  return ds.front();
282  }
283 
284  ma_domains::const_iterator it = ds.begin();
285  while(++it!=ds.end())
286  {
287  for(size_t i=0; i<ds.front().size(); ++i)
288  {
289  domain_intersect(ds.front()[i], (*it)[i]);
290 
291  if (domain_is_null(ds.front()[i]))
292  {
293  ds.front() = ma_domain_ctor_null();
294  goto exit;
295  }
296  }
297  }
298 
299 exit:
300 
301  return ds.front();
302 }
303 
304 novadaq::errorhandler::ma_domain
305  novadaq::errorhandler::domain_intersect_copy( ma_domains ds )
306 {
307  return domain_intersect(ds);
308 }
309 
310 
311 // ------------------------------------------------------------------
312 // domain union
313 
314 bool
315  novadaq::errorhandler::contains_op( int a, int b )
316 {
317  return (a==b) ? (true) : ( (a==D_ANY || b==D_NIL) ? true : false );
318 }
319 
320 bool
321 novadaq::errorhandler::domain_is_null( ma_cond_domain const & d )
322 {
323  return (d.first==D_NIL || d.second==D_NIL) ? true : false;
324 }
325 
326 bool
327 novadaq::errorhandler::domain_is_null( ma_domain const & d )
328 {
329  if (d.empty()) return true;
330 
331  for (size_t i=0; i<d.size(); ++i)
332  if (domain_is_null(d[i])) return true;
333 
334  return false;
335 }
336 
337 novadaq::errorhandler::domain_compare_result_t
338  novadaq::errorhandler::domain_compare( ma_cond_domain const & d1
339  , ma_cond_domain const & d2 )
340 {
341  if (d1.first==d2.first && d1.second==d2.second)
342  return EQUAL;
343 
344  bool flag1 = false;
345  bool flag2 = false;
346 
347  if (contains_op(d1.first, d2.first)) flag1 = true;
348  if (contains_op(d1.second, d2.second)) flag2 = true;
349 
350  if (flag1 != flag2)
351  return NO_COMMON;
352 
353  if (flag1)
354  return L_CONTAINS;
355  else
356  return R_CONTAINS;
357 }
358 
359 novadaq::errorhandler::ma_cond_domains &
360  novadaq::errorhandler::domain_union( ma_cond_domains & ds
361  , ma_cond_domain const & new_d )
362 {
363  if (domain_is_null(new_d)) return ds;
364 
365  ma_cond_domains::iterator it = ds.begin();
366  while(it!=ds.end())
367  {
368  domain_compare_result_t r = domain_compare(*it, new_d);
369 
370  if (r == EQUAL || r == L_CONTAINS)
371  return ds;
372 
373  if (r == R_CONTAINS)
374  {
375  ds.erase(it);
376  return domain_union(ds, new_d);
377  }
378 
379  // NO_COMMON
380  ++it;
381  }
382 
383  ds.push_back(new_d);
384  return ds;
385 }
386 
387 void
388  novadaq::errorhandler::domain_union_construct
389  ( ma_domains & ds
390  , ma_domain & d
391  , std::vector<ma_cond_domains> & mid
392  , int depth
393  , int max )
394 {
395  ma_cond_domains::const_iterator it = mid[depth].begin();
396 
397  while(it!=mid[depth].end())
398  {
399  d[depth] = *it;
400 
401  if (depth != max)
402  domain_union_construct(ds, d, mid, depth+1, max);
403  else
404  ds.push_back(d);
405 
406  ++it;
407  }
408 }
409 
410 
411 novadaq::errorhandler::ma_domains &
412  novadaq::errorhandler::domain_union( ma_domains & ds )
413 {
414  if (ds.empty()) return ds;
415 
416  // domain size (how many conditions in a domain)
417  size_t size = ds.front().size();
418 
419  // temp place to hold intermediate results
420  std::vector<ma_cond_domains> mid(size);
421 
422  ma_domains::const_iterator it = ds.begin();
423  while(it!=ds.end())
424  {
425  for(size_t i=0; i<size; ++i)
426  domain_union(mid[i], (*it)[i]);
427 
428  ++it;
429  }
430 
431  ma_domains result;
432  ma_domain domain(size);
433 
434  domain_union_construct(result, domain, mid, 0, size-1);
435 
436  ds = result;
437  return ds;
438 }
439 
440 #endif
441 
442 
443 
444 
445 
446 
447 
448 
449