artdaq_mfextensions  v1_05_00
ma_domain_cond.cpp
1 
2 #include "ErrorHandler/MessageAnalyzer/ma_domain_ops.h"
3 #include "ErrorHandler/MessageAnalyzer/ma_domain_cond.h"
4 #include "ErrorHandler/MessageAnalyzer/ma_domain_expr.h"
5 #include "ErrorHandler/MessageAnalyzer/ma_rule.h"
6 
7 
8 using namespace novadaq::errorhandler;
9 
10 ma_domain_cond::ma_domain_cond( )
11 : cond_type (COND)
12 , conds ()
13 , str_cond ()
14 , cond_size (0)
15 , expr ()
16 {
17 
18 }
19 
20 void ma_domain_cond::insert_expr( ma_domain_expr const & d_expr )
21 {
22  expr.reset(new ma_domain_expr(d_expr));
23  cond_type = EXPR;
24 }
25 
26 void ma_domain_cond::evaluate(ma_domains & domains) const
27 {
28 
29  ma_domains worksheet;
30 
31  // 1. '(' >> expr >> ')'
32 
33  if (cond_type == EXPR)
34  {
35  if (expr.get() == NULL)
36  throw std::runtime_error("expr not exist");
37 
38  expr->evaluate(worksheet);
39  }
40 
41  // 2. cond_1.$ = cond_2.$ = ... = 'string literal'
42 
43  else if (!str_cond.empty())
44  {
45  // # of conds must be not empty
46  if (conds.empty())
47  throw std::runtime_error("cond_arg_list cannot be empty");
48 
49  // init with (*,*) to all condition domains
50  ma_domain domain = ma_domain_ctor_any(cond_size);
51 
52  // whether to keep the domain
53  bool keep = true;
54 
55  // iterate
56  cond_arg_list_t::const_iterator it = conds.begin();
57  while(it!=conds.end())
58  {
59  ma_condition * c_ptr = it->first.first;
60  size_t c_idx = it->first.second;
61  arg_t c_arg = it->second;
62 
63  int idx = c_ptr->find_arg(str_cond, c_arg);
64 
65  if (idx==D_NIL) { keep = false; break; }
66  else domain[c_idx] = ma_cond_domain_ctor(idx, c_arg);
67 
68  ++it;
69  }
70 
71  // push the domain if not flagged
72  if (keep) worksheet.push_back(domain);
73  }
74 
75  // 3. cond_1.$ = cond_2.$ = ...
76 
77  else
78  {
79  // # of conds must be 1 or greater
80  if (conds.empty())
81  throw std::runtime_error("no cond in cond list of ma_domain_cond");
82 
83  // first condition in the list
84  ma_condition * c1_ptr = conds.front().first.first;
85  int c1_idx = conds.front().first.second;
86  arg_t c1_arg_type = conds.front().second;
87 
88  // get the src/target list
89  idx_t const & c1_args = c1_ptr->get_args(c1_arg_type);
90 
91  // loop through the arg list
92  idx_t::const_iterator it = c1_args.begin();
93  for ( ; it!=c1_args.end(); ++it)
94  {
95  // init everyone with (*,*)
96  ma_domain domain = ma_domain_ctor_any(cond_size);
97 
98  // whether to keep this domain or not
99  bool keep = true;
100 
101  // get the actual src/target string and index
102  std::string const & c1_arg_str = it->first;
103  size_t c1_arg_idx = it->second;
104 
105  // domain[c1_idx] = domain[c1_idx] n (c1_arg_idx, *)
106  domain_intersect( domain[c1_idx]
107  , ma_cond_domain_ctor(c1_arg_idx, c1_arg_type) );
108 
109  // iterate through the remaining conds
110  cond_arg_list_t::const_iterator cond_it = conds.begin();
111 
112  while( ++cond_it!=conds.end() )
113  {
114  // idx of current cond and its arg type (source/target)
115  ma_condition * c_ptr = cond_it->first.first;
116  size_t c_idx = cond_it->first.second;
117  arg_t c_arg_type = cond_it->second;
118 
119  // find arg_str_c1 from current cond
120  int c_arg_idx = c_ptr->find_arg(c1_arg_str, c_arg_type);
121 
122  // cannot find arg_str in the current cond. go for next arg_str
123  if (c_arg_idx == D_NIL)
124  {
125  keep = false;
126  break;
127  }
128 
129  // domain[idx_c] = domain[idx_c] n (arg_idx_c, *)
130  domain_intersect( domain[c_idx]
131  , ma_cond_domain_ctor(c_arg_idx, c_arg_type) );
132 
133  // stop if domain[idx_c] is null, go for next arg_str
134  if (domain_is_null(domain[c_idx]))
135  {
136  keep = false;
137  break;
138  }
139  }
140 
141  // push the domain to the worksheet
142  if (keep) worksheet.push_back(domain);
143  }
144  }
145 
146  // combine the domain list from the worksheet, and the list passed
147  // in from above levels
148 
149  and_merge(domains, worksheet);
150 
151 }
152 
153 ma_domains &
154  ma_domain_cond::and_merge( ma_domains & domains
155  , ma_domains & worksheet ) const
156 {
157  if (domains.empty())
158  {
159  domains.splice(domains.end(), worksheet);
160  return domains;
161  }
162 
163  // null worksheet will null everything in the domains
164  if (worksheet.empty())
165  {
166  domains.clear();
167  return domains;
168  }
169 
170  // first expand the domains to the size of
171  // N_domains * N_worksheet
172  size_t nw = worksheet.size();
173  ma_domains::iterator dit = domains.begin();
174  for ( ; dit!=domains.end(); ++dit)
175  domains.insert(dit, nw-1, *dit);
176 
177  // domain intersect operation
178  dit = domains.begin();
179  ma_domains::iterator wit = worksheet.begin();
180  for ( ; dit!=domains.end(); ++dit,++wit)
181  {
182  if ( wit==worksheet.end() ) wit = worksheet.begin();
183 
184  domain_intersect(*dit, *wit);
185  }
186 
187  // remove null domains
188  domains.remove(ma_domain_ctor_null());
189 
190  return domains;
191 }
192 
193 
194 
195 
196 
197 
198 
199