EMANE  1.2.1
statisticservice.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013,2015 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
34 #include "statisticservice.h"
35 
36 #include <iterator>
37 
39  const std::string & sName,
40  Any::Type type,
41  const StatisticProperties & properties,
42  const std::string & sDescription,
43  Statistic * pStatistic)
44 {
45  if(std::find_if_not(sName.begin(),sName.end(),[](int ch){return isalnum(ch) || ch == '.';}) != sName.end())
46  {
47  throw makeException<RegistrarException>("Invalid charater in the statistic name: %s",
48  sName.c_str());
49  }
50 
51  StatisticInfo info{sName,
52  type,
53  properties,
54  sDescription};
55 
56  std::unique_ptr<Statistic> pStat{pStatistic};
57 
58  auto iter = buildIdStatisticStore_.find(buildId);
59 
60  if(iter != buildIdStatisticStore_.end())
61  {
62  auto & store = iter->second;
63 
64  if(!store.insert(std::make_pair(sName,std::make_pair(std::move(pStat),std::move(info)))).second)
65  {
66  throw makeException<RegistrarException>("Statistic already registered: %s",
67  sName.c_str());
68  }
69  }
70  else
71  {
72  StatisticStore store;
73  store.insert(std::make_pair(sName,std::make_pair(std::move(pStat),std::move(info))));
74  buildIdStatisticStore_.insert(std::make_pair(buildId,std::move(store)));
75  }
76 }
77 
79  const std::string & sName,
80  const StatisticProperties & properties,
81  const std::string & sDescription,
82  StatisticTablePublisher * pStatisticTablePublisher,
83  std::function<void(StatisticTablePublisher *)> clearFunc)
84 {
85  if(std::find_if_not(sName.begin(),sName.end(),[](int ch){return isalnum(ch) || ch == '.';}) != sName.end())
86  {
87  throw makeException<RegistrarException>("Invalid charater in the statistic table name: %s",
88  sName.c_str());
89  }
90 
91  StatisticTableInfo info{sName,properties,sDescription};
92 
93  std::unique_ptr<StatisticTablePublisher> pTable{pStatisticTablePublisher};
94 
95  auto iter = buildIdTableStore_.find(buildId);
96 
97  if(iter != buildIdTableStore_.end())
98  {
99  auto & store = iter->second;
100 
101  if(!store.insert(std::make_pair(sName,std::make_tuple(std::move(pTable),std::move(info),std::move(clearFunc)))).second)
102  {
103  throw makeException<RegistrarException>("Statistic table already registered: %s",
104  sName.c_str());
105  }
106  }
107  else
108  {
109  TableStore store;
110  store.insert(std::make_pair(sName,std::make_tuple(std::move(pTable),std::move(info),std::move(clearFunc))));
111  buildIdTableStore_.insert(std::make_pair(buildId,std::move(store)));
112  }
113 }
114 
115 
116 
117 std::map<std::string,EMANE::Any>
119  const std::vector<std::string> & names) const
120 {
121  std::map<std::string,Any> values;
122 
123  auto iter = buildIdStatisticStore_.find(buildId);
124 
125  if(iter != buildIdStatisticStore_.end())
126  {
127  auto & store = iter->second;
128 
129  if(names.empty())
130  {
131  std::transform(store.begin(),
132  store.end(),
133  std::inserter(values,values.end()),
134  [](const StatisticStore::value_type & p)
135  {
136  return std::make_pair(p.first,p.second.first->asAny());
137  });
138 
139  }
140  else
141  {
142  for_each(names.begin(),
143  names.end(),
144  [&store,&values](const std::string & s)
145  {
146  auto iter = store.find(s);
147 
148  if(iter != store.end())
149  {
150  values.insert(std::make_pair(s,iter->second.first->asAny()));
151  }
152  else
153  {
154  throw makeException<RegistrarException>("Unknown statistic name: %s",
155  s.c_str());
156  }
157  });
158  }
159  }
160 
161  return values;
162 
163 }
164 
165 void
167  const std::vector<std::string> & names) const
168 {
169  auto iter = buildIdStatisticStore_.find(buildId);
170 
171  if(iter != buildIdStatisticStore_.end())
172  {
173  auto & store = iter->second;
174 
175  if(names.empty())
176  {
177  std::for_each(store.begin(),
178  store.end(),
179  [](const StatisticStore::value_type & p)
180  {
181  if(p.second.second.isClearable())
182  {
183  p.second.first->clear();
184  }
185  });
186 
187  }
188  else
189  {
190  std::vector<Statistic *> statsToClear;
191 
192  // store references to all the requested statistics to clear
193  // this a transactional API call so either all requested items
194  // are valid names and clearable or none will be cleared
195  for_each(names.begin(),
196  names.end(),
197  [&store,&statsToClear](const std::string & s)
198  {
199  auto iter = store.find(s);
200 
201  if(iter != store.end())
202  {
203  if(iter->second.second.isClearable())
204  {
205  statsToClear.push_back(iter->second.first.get());
206  }
207  else
208  {
209  throw makeException<RegistrarException>("Statistic not clearable: %s",
210  s.c_str());
211  }
212  }
213  else
214  {
215  throw makeException<RegistrarException>("Unknown statistic name: %s",
216  s.c_str());
217  }
218  });
219 
220  for_each(statsToClear.begin(),
221  statsToClear.end(),
222  bind(&Statistic::clear,
223  std::placeholders::_1));
224  }
225  }
226 }
227 
228 std::map<std::string,std::pair<EMANE::StatisticTableLabels,EMANE::StatisticTableValues>>
230  const std::vector<std::string> & names) const
231 {
232  std::map<std::string,std::pair<StatisticTableLabels,StatisticTableValues>> values;
233 
234  auto iter = buildIdTableStore_.find(buildId);
235 
236  if(iter != buildIdTableStore_.end())
237  {
238  auto & store = iter->second;
239 
240  if(names.empty())
241  {
242  std::transform(store.begin(),
243  store.end(),
244  std::inserter(values,values.end()),
245  [](const TableStore::value_type & p)
246  {
247  auto pTable = std::get<0>(p.second).get();
248  return std::make_pair(p.first,
249  std::make_pair(pTable->getLabels(),
250  pTable->getValues()));
251  });
252 
253  }
254  else
255  {
256  for_each(names.begin(),
257  names.end(),
258  [&store,&values](const std::string & s)
259  {
260  auto iter = store.find(s);
261 
262  if(iter != store.end())
263  {
264  auto pTable = std::get<0>(iter->second).get();
265 
266  values.insert(std::make_pair(s,
267  std::make_pair(pTable->getLabels(),
268  pTable->getValues())));
269  }
270  else
271  {
272  throw makeException<RegistrarException>("Unknown statistic table name: %s",
273  s.c_str());
274  }
275  });
276  }
277  }
278 
279  return values;
280 
281 }
282 
283 
285 {
287 
288  auto iter = buildIdStatisticStore_.find(buildId);
289 
290  if(iter != buildIdStatisticStore_.end())
291  {
292  std::transform(iter->second.begin(),
293  iter->second.end(),
294  std::back_inserter(manifest),
295  std::bind(&StatisticStore::value_type::second_type::second,
296  std::bind(&StatisticStore::value_type::second,
297  std::placeholders::_1)));
298  }
299 
300  return manifest;
301 }
302 
303 
305 {
307 
308  auto iter = buildIdTableStore_.find(buildId);
309 
310  if(iter != buildIdTableStore_.end())
311  {
312  std::transform(iter->second.begin(),
313  iter->second.end(),
314  std::back_inserter(manifest),
315  std::bind([&manifest](const TableStore::value_type::second_type & t)
316  {return std::get<1>(t);},
317  std::bind(&TableStore::value_type::second,
318  std::placeholders::_1)));
319  }
320 
321  return manifest;
322 }
323 
324 void
326  const std::vector<std::string> & names) const
327 {
328  auto iter = buildIdTableStore_.find(buildId);
329 
330  if(iter != buildIdTableStore_.end())
331  {
332  // store references to all the requested statistics to clear
333  // this a transactional API call so either all requested items
334  // are valid names and clearable or none will be cleared
335  std::vector<std::function<void()>> tablesToClear;
336 
337  auto & store = iter->second;
338 
339  if(names.empty())
340  {
341  std::for_each(store.begin(),
342  store.end(),
343  [&tablesToClear](const TableStore::value_type & p)
344  {
345  if(std::get<1>(p.second).isClearable())
346  {
347  tablesToClear.push_back(std::bind(std::get<2>(p.second),
348  std::get<0>(p.second).get()));
349  }
350  });
351 
352  }
353  else
354  {
355  for_each(names.begin(),
356  names.end(),
357  [&store,&tablesToClear](const std::string & s)
358  {
359  auto iter = store.find(s);
360 
361  if(iter != store.end())
362  {
363  if(std::get<1>(iter->second).isClearable())
364  {
365  tablesToClear.push_back(std::bind(std::get<2>(iter->second),
366  std::get<0>(iter->second).get()));
367  }
368  else
369  {
370  throw makeException<RegistrarException>("Table not clearable: %s",
371  s.c_str());
372  }
373  }
374  else
375  {
376  throw makeException<RegistrarException>("Unknown table name: %s",
377  s.c_str());
378  }
379  });
380  }
381 
382  for_each(tablesToClear.begin(),
383  tablesToClear.end(),
384  [](const std::function<void()> & f)
385  {f();});
386 
387 
388  }
389 }
A StatisticTablePublisher produces two dimensional tables of Anys.
void clearStatistic(BuildId, const std::vector< std::string > &names) const
std::string manifest(BuildId buildId, const std::string &sName)
Definition: manifest.cc:42
Type
Definition: any.h:52
std::vector< StatisticInfo > StatisticManifest
virtual void clear()=0
std::vector< StatisticTableInfo > StatisticTableManifest
std::map< std::string, std::pair< StatisticTableLabels, StatisticTableValues > > queryTable(BuildId, const std::vector< std::string > &names) const
StatisticManifest getStatisticManifest(BuildId id) const
Holds name, type, property and description of a Statistic.
Definition: statisticinfo.h:50
void registerStatistic(BuildId buildId, const std::string &sName, Any::Type type, const StatisticProperties &properties, const std::string &sDescription, Statistic *pStatistic)
StatisticTableManifest getTableManifest(BuildId id) const
The Statistic interface is the base class of all statistics. It provided methods to access and clear ...
Definition: statistic.h:48
Holds name, property and description of a StatisticTable.
void registerTable(BuildId buildId, const std::string &sName, const StatisticProperties &properties, const std::string &sDescription, StatisticTablePublisher *pStatisticTablePublisher, std::function< void(StatisticTablePublisher *)> clearFunc)
std::map< std::string, EMANE::Any > queryStatistic(BuildId, const std::vector< std::string > &names) const
void clearTable(BuildId, const std::vector< std::string > &names) const
std::uint32_t BuildId
Definition: types.h:60