artdaq_mfextensions  v1_06_02
ma_hitmap.cpp
1 
2 #include "ErrorHandler/MessageAnalyzer/ma_hitmap.h"
3 #include "ErrorHandler/MessageAnalyzer/ma_condition.h"
4 
5 using namespace novadaq::errorhandler;
6 
7 const std::string ma_hitmap::global_s = "__S_GLOBAL__";
8 const std::string ma_hitmap::global_t = "__T_GLOBAL__";
9 
10 const size_t ma_hitmap::cap_increment = 20;
11 
12 ma_hitmap::ma_hitmap()
13  : src_idx()
14  , tgt_idx()
15  , src_cap(20)
16  , tgt_cap(20)
17  , cond(0)
18  , hitmap(boost::extents[src_cap][tgt_cap])
19 {
20 }
21 
22 void ma_hitmap::reset()
23 {
24  src_idx.clear();
25  tgt_idx.clear();
26 
27  for (size_t s = 0; s < src_cap; ++s)
28  for (size_t t = 0; t < tgt_cap; ++t)
29  hitmap[s][t].reset();
30 }
31 
32 unsigned int
33 ma_hitmap::capture(qt_mf_msg const& msg, std::string const& src, std::string const& tgt, boost::smatch const& what)
34 {
35  size_t s_idx = 0;
36  size_t t_idx = 0;
37 
38  unsigned int result = 0x00;
39 
40  // find source index
41  if (!cond->per_source())
42  {
43  if (src_idx.empty())
44  {
45  src_idx[global_s] = 0;
46  result |= SOURCE_CHANGE;
47  }
48 
49  s_idx = 0;
50  }
51  else
52  {
53  idx_t::const_iterator it = src_idx.find(src);
54  if (it == src_idx.end())
55  {
56  s_idx = src_idx.size();
57  src_idx.insert(std::make_pair(src, s_idx));
58  result |= SOURCE_CHANGE;
59  }
60  else
61  {
62  s_idx = it->second;
63  }
64  }
65 
66  // find target index
67  if (!cond->per_target())
68  {
69  if (tgt_idx.empty())
70  {
71  tgt_idx[global_t] = 0;
72  result |= TARGET_CHANGE;
73  }
74 
75  t_idx = 0;
76  }
77  else
78  {
79  idx_t::const_iterator it = tgt_idx.find(tgt);
80  if (it == tgt_idx.end())
81  {
82  t_idx = tgt_idx.size();
83  tgt_idx.insert(std::make_pair(tgt, t_idx));
84  result |= TARGET_CHANGE;
85  }
86  else
87  {
88  t_idx = it->second;
89  }
90  }
91 
92  // resize the array if needed
93  bool resize = false;
94 
95  if (s_idx >= src_cap)
96  {
97  src_cap += cap_increment;
98  resize = true;
99  }
100 
101  if (t_idx >= tgt_cap)
102  {
103  tgt_cap += cap_increment;
104  resize = true;
105  }
106 
107  if (resize)
108  {
109  hitmap.resize(boost::extents[src_cap][tgt_cap]);
110  }
111 
112  // knock the cell
113  return hitmap[s_idx][t_idx].hit(msg, what, *cond, s_idx, t_idx)
114  ? (result | STATUS_CHANGE)
115  : (result);
116 }
117 
118 bool ma_hitmap::event(size_t src, size_t tgt, time_t t)
119 {
120  return hitmap[src][tgt].event(t, *cond);
121 }
122 
123 int ma_hitmap::find_source(std::string const& src)
124 {
125  idx_t::const_iterator it = src_idx.find(src);
126  if (it == src_idx.end())
127  return D_NIL;
128  else
129  return it->second;
130 }
131 
132 int ma_hitmap::find_target(std::string const& tgt)
133 {
134  idx_t::const_iterator it = tgt_idx.find(tgt);
135  if (it == tgt_idx.end())
136  return D_NIL;
137  else
138  return it->second;
139 }
140 
141 // get src/tgt string from idx
142 const std::string&
143 ma_hitmap::get_source(ma_cond_domain v) const
144 {
145  int idx = v.first;
146  assert(!src_idx.empty());
147 
148  if (idx == D_NIL) throw std::runtime_error("get_source: nil idx");
149  if (idx == D_ANY) return src_idx.begin()->first;
150 
151  assert((unsigned)idx < src_idx.size());
152 
153  for (idx_t::const_iterator it = src_idx.begin(); it != src_idx.end(); ++it)
154  if ((unsigned)idx == it->second) return it->first;
155 
156  throw std::runtime_error("get_source: idx not found");
157 }
158 
159 const std::string&
160 ma_hitmap::get_target(ma_cond_domain v) const
161 {
162  int idx = v.second;
163  assert(!tgt_idx.empty());
164 
165  if (idx == D_NIL) throw std::runtime_error("get_target: nil idx");
166  if (idx == D_ANY) return tgt_idx.begin()->first;
167 
168  assert((unsigned)idx < tgt_idx.size());
169 
170  for (idx_t::const_iterator it = tgt_idx.begin(); it != tgt_idx.end(); ++it)
171  if ((unsigned)idx == it->second) return it->first;
172 
173  throw std::runtime_error("get_source: idx not found");
174 }
175 
176 std::string
177 ma_hitmap::get_message(ma_cond_domain v) const
178 {
179  assert(!src_idx.empty());
180  assert(!tgt_idx.empty());
181 
182  if (v.first == D_NIL || v.second == D_NIL)
183  throw std::runtime_error("get_message: nil idx");
184 
185  v.first = (v.first == D_ANY) ? 0 : v.first;
186  v.second = (v.second == D_ANY) ? 0 : v.second;
187 
188  return hitmap[v.first][v.second].get_latest_message();
189 }
190 
191 std::string
192 ma_hitmap::get_message_group(ma_cond_domain v, size_t g) const
193 {
194  assert(!src_idx.empty());
195  assert(!tgt_idx.empty());
196 
197  if (v.first == D_NIL || v.second == D_NIL)
198  throw std::runtime_error("get_message: nil idx");
199 
200  v.first = (v.first == D_ANY) ? 0 : v.first;
201  v.second = (v.second == D_ANY) ? 0 : v.second;
202 
203  return hitmap[v.first][v.second].get_message_group(g);
204 }
205 
206 // if the cell has been triggered
207 bool ma_hitmap::get_status(ma_cond_domain v) const
208 {
209  bool r = hitmap[v.first][v.second].is_on();
210 
211  TLOG(TLVL_DEBUG) << "hitmap::get_status @ "
212  << v.first << ", " << v.second << " = " << r;
213  return r;
214 }
215 
216 int ma_hitmap::get_alarm_count(ma_cond_domain v, arg_t arg) const
217 {
218  ma_cond_range src, tgt;
219  get_cond_range(v, src, tgt);
220 
221  int count = 0;
222  ;
223  if (arg == NONE)
224  {
225  for (int s = src.first; s <= src.second; ++s)
226  for (int t = tgt.first; t <= tgt.second; ++t)
227  count += hitmap[s][t].get_message_count();
228  }
229  else if (arg == SOURCE)
230  {
231  for (int s = src.first; s <= src.second; ++s)
232  for (int t = tgt.first; t <= tgt.second; ++t)
233  if (hitmap[s][t].is_on())
234  {
235  ++count;
236  break;
237  }
238  }
239  else
240  {
241  for (int t = tgt.first; t <= tgt.second; ++t)
242  for (int s = src.first; s <= src.second; ++s)
243  if (hitmap[s][t].is_on())
244  {
245  ++count;
246  break;
247  }
248  }
249 
250  return count;
251 }
252 
253 // get a range of src/target
254 void ma_hitmap::get_cond_range(ma_cond_domain d, ma_cond_range& src, ma_cond_range& tgt) const
255 {
256  if (domain_is_null(d))
257  throw std::runtime_error("get_cond_range: NIL domain");
258 
259  if (d.first == D_ANY)
260  src.first = 0, src.second = src_idx.size() - 1;
261  else
262  src.first = d.first, src.second = d.first;
263 
264  if (d.second == D_ANY)
265  tgt.first = 0, tgt.second = tgt_idx.size() - 1;
266  else
267  tgt.first = d.second, tgt.second = d.second;
268 }
269 
270 // get a view to the hitmap
271 const hitmap_view_t
272 ma_hitmap::get_domain_view(ma_cond_domain const& d)
273 {
274  if (domain_is_null(d))
275  throw std::runtime_error("get_domain_view: null domain");
276 
277  return hitmap[boost::indices[d.first == D_ANY ? range() : range(d.first)]
278  [d.second == D_ANY ? range() : range(d.second)]];
279 }
Qt wrapper around MessageFacility message
Definition: qt_mf_msg.hh:37