LCOV - code coverage report
Current view: top level - /opt/artdaq/srcs/artdaq-mfextensions/ErrorHandler/MessageAnalyzer - ma_domain_ops.h (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 0.0 % 45 0
Test Date: 2025-09-04 00:45:34 Functions: 0.0 % 12 0

            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
        

Generated by: LCOV version 2.0-1