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