Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CounterSvc.cpp
Go to the documentation of this file.
1 // $Id: CounterSvc.cpp,v 1.6 2007/09/24 19:15:57 marcocle Exp $
2 // ============================================================================
3 // CVS tag $Name: $, verison $Revision: 1.6 $
4 // ============================================================================
5 // STD & SLT
6 // ============================================================================
7 #include <utility>
8 #include <vector>
9 #include <algorithm>
10 #include <functional>
11 // ============================================================================
12 // GaudiKernel
13 // ============================================================================
16 #include "GaudiKernel/SvcFactory.h"
17 #include "GaudiKernel/MsgStream.h"
18 #include "GaudiKernel/Service.h"
19 #include "GaudiKernel/HashMap.h"
20 // ============================================================================
27 class CounterSvc: public extends1<Service, ICounterSvc> {
28 public:
31  ISvcLocator* svcLoc )
32  : base_class(name, svcLoc)
33  , m_counts ()
34  , m_print ( true )
35  //
36  // the header row
37  , m_header ( " Counter :: Group | # | sum | mean/eff^* | rms/err^* | min | max |")
38  // format for regular statistical printout rows
39  , m_format1 ( " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" )
40  // format for "efficiency" statistical printout rows
41  , m_format2 ( "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |" )
42  // flag to use the special "efficiency" format
43  , m_useEffFormat ( true )
44  //
45  {
46  declareProperty ("PrintStat" , m_print ) ;
47  //
49  ( "StatTableHeader" , m_header ,
50  "The header row for the output Stat-table" ) ;
51  //
53  ( "RegularRowFormat" , m_format1 ,
54  "The format for the regular row in the output Stat-table" ) ;
55  //
57  ( "EfficiencyRowFormat" , m_format2 ,
58  "The format for the regular row in the outptu Stat-table" ) ;
59  //
61  ( "UseEfficiencyRowFormat" , m_useEffFormat ,
62  "Use the special format for printout of efficiency counters" ) ;
63  }
65  virtual ~CounterSvc() { remove().ignore() ; }
67  virtual StatusCode finalize()
68  {
69  if ( outputLevel() <= MSG::DEBUG || m_print ) { print () ; }
70  remove().ignore() ;
71  // finalize the base class
72  return Service::finalize() ;
73  }
74  // ==========================================================================
82  virtual Counter* get
83  ( const std::string& group ,
84  const std::string& name ) const;
86  virtual ICounterSvc::Counters get ( const std::string& group ) const ;
99  virtual StatusCode create
100  ( const std::string& group ,
101  const std::string& name ,
102  longlong initial_value ,
103  Counter*& refpCounter ) ;
115  virtual CountObject create
116  ( const std::string& group ,
117  const std::string& name ,
118  longlong initial_value = 0 ) ;
128  virtual StatusCode remove
129  ( const std::string& group ,
130  const std::string& name ) ;
136  virtual StatusCode remove
137  ( const std::string& group ) ;
139  virtual StatusCode remove();
147  virtual StatusCode print
148  ( const std::string& group,
149  const std::string& name,
150  Printout& printer) const;
158  virtual StatusCode print
159  (const std::string& group,
160  Printout& printer) const;
167  virtual StatusCode print
168  ( const Counter* pCounter,
169  Printout& printer) const;
176  virtual StatusCode print
177  ( const CountObject& pCounter,
178  Printout& printer) const;
182  virtual StatusCode print(Printout& printer) const;
185  ( MsgStream& log,
186  const Counter* pCounter) const ;
187 private:
188  // find group/name for the counter:
190  {
191  if ( 0 == c ) { return std::pair<std::string,std::string>() ; }
192  for ( CountMap::const_iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
193  {
194  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
195  { if ( j->second == c ) { return std::make_pair( i->first , j->first ) ; } }
196  }
198  }
199  // get the overall number of counters
200  inline size_t num () const
201  {
202  size_t result = 0 ;
203  {
204  for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
205  {
206  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
207  { if ( 0 != j->second ) { ++result ; } ; }
208  }
209  }
210  return result ;
211  }
212 public:
214  void print () const ;
215 private:
218  // the actual map of counters
220  // boolean flag to print statistics
221  bool m_print ;
222  // the header row
224  // format for regular statistical printout rows
226  // format for "efficiency" statistical printout rows
228  // flag to use the special "efficiency" format
230 } ;
231 // ===========================================================================
232 // Instantiation of a static factory class used by clients
233 // ===========================================================================
235 // ===========================================================================
236 // Access a counter object by name and group
237 // ===========================================================================
238 CounterSvc::Counter* CounterSvc::get
239 ( const std::string& grp ,
240  const std::string& nam ) const
241 {
242  CountMap::const_iterator i = m_counts.find ( grp ) ;
243  if ( m_counts.end() == i ) { return 0 ; } // RETURN
244  NameMap::const_iterator j = i->second.find ( nam ) ;
245  if ( i->second.end() == j ) { return 0 ; } // RETURN
246  return j->second ; // RETURN
247 }
248 // ===========================================================================
249 // get all counters form the given group:
250 // ===========================================================================
252 {
253  ICounterSvc::Counters result ;
255  if ( m_counts.end() == i ) { return result ; } // RETURN
256  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
257  { result.push_back( CountObject ( j->second, i->first , j->first ) ) ; }
258  return result ;
259 }
260 // ===========================================================================
261 // Create/get a counter object.
262 // ===========================================================================
263 #ifdef __ICC
264 // disable icc remark #2259: non-pointer conversion from "longlong={long long}" to "double" may lose significant bits
265 #pragma warning(push)
266 #pragma warning(disable:2259)
267 #endif
269 ( const std::string& grp ,
270  const std::string& nam ,
271  longlong initial_value ,
272  Counter*& refpCounter )
273 {
274  // try to find existing counter:
275  refpCounter = get ( grp , nam ) ;
276  if ( 0 != refpCounter ) { return COUNTER_EXISTS ; } // RETURN
277  // create the new counter
278  Counter* newc = new Counter() ;
279  refpCounter = newc ;
280  if ( 0 != initial_value ) {
281  refpCounter->addFlag ( static_cast<double>(initial_value) ) ; // icc remark #2259
282  }
283  // find a proper group
284  CountMap::iterator i = m_counts.find ( grp ) ;
285  // (create a group if needed)
286  if ( m_counts.end() == i )
287  { i = m_counts.insert ( std::make_pair ( grp , NameMap() ) ).first ; }
288  // insert new counter with proper name into proper group:
289  i->second.insert( std::make_pair( nam , newc ) );
290  return StatusCode::SUCCESS ; // RETURN
291 }
292 #ifdef __ICC
293 // re-enable icc remark #2259
294 #pragma warning(pop)
295 #endif
296 // ===========================================================================
297 // Create a new counter object. If the counter object exists already,
298 // ===========================================================================
300 ( const std::string& group ,
301  const std::string& name ,
302  longlong initial_value )
303 {
304  Counter* p = 0;
305  StatusCode sc = create ( group, name, initial_value, p ) ;
306  if ( sc.isSuccess() && 0 != p ) { return CountObject ( p , group , name ) ; }
307  throw std::runtime_error("CounterSvc::Counter('"+group+"::"+name+"') exists already!");
308 }
309 // ===========================================================================
310 // Remove a counter object. The tuple (group,name) identifies the counter uniquely
311 // ===========================================================================
313 ( const std::string& grp ,
314  const std::string& nam )
315 {
316  CountMap::iterator i = m_counts.find ( grp ) ;
317  if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN
318  NameMap::iterator j = i->second.find ( nam ) ;
319  if ( i->second.end() == j ) { return COUNTER_NOT_PRESENT ; } // RETURN
320  delete j->second ;
321  i->second.erase ( j ) ;
322  return StatusCode::SUCCESS ;
323 }
324 // ===========================================================================
325 // Remove a group of counter objects.
326 // ===========================================================================
328 {
329  CountMap::iterator i = m_counts.find ( grp ) ;
330  if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN
331  for ( NameMap::iterator j = i->second.begin() ; i->second.end() != j ; ++j )
332  { delete j->second ; }
333  i->second.clear() ;
334  return StatusCode::SUCCESS ;
335 }
336 // ===========================================================================
337 // Remove all known counter objects
338 // ===========================================================================
340 {
341  // remove group by group
342  for ( CountMap::iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
343  { remove ( i->first ).ignore () ; }
344  m_counts.clear() ;
345  return StatusCode::SUCCESS;
346 }
347 // ===========================================================================
348 // Print counter value
349 // ===========================================================================
351 ( const std::string& grp,
352  const std::string& nam,
353  Printout& printer) const
354 {
355  const Counter* c = get( grp , nam ) ;
356  if ( 0 == c ) { return COUNTER_NOT_PRESENT ; } // RETURN
357  // create the stream and use it!
358  MsgStream log ( msgSvc() , name() ) ;
359  return printer ( log , c ) ;
360 }
361 
362 namespace {
364  class conditionalPrint {
365  private:
366  CounterSvc::Printout *printer;
367  MsgStream *log;
368  public:
369  conditionalPrint(CounterSvc::Printout &_p, MsgStream &_l): printer(&_p), log(&_l) {}
370  template<class Pair>
371  void operator() (const Pair &p) {
372  if (p.second) {
373  (*printer)(*log, p.second).ignore();
374  }
375  }
376  };
377 }
378 // ===========================================================================
379 // Print the counter value for the whole group of counters
380 // ===========================================================================
382 ( const std::string& grp ,
383  Printout& printer ) const
384 {
385  CountMap::const_iterator i = m_counts.find ( grp ) ;
386  if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
387 
388  MsgStream log(msgSvc(), name());
389  // Force printing in alphabetical order
390  typedef std::map<std::string, Counter*> sorted_map_t;
391  sorted_map_t sorted_map(i->second.begin(), i->second.end());
392  std::for_each(sorted_map.begin(), sorted_map.end(),
393  conditionalPrint(printer, log));
394  return StatusCode::SUCCESS; // RETURN
395 }
396 // ===========================================================================
397 // Print counter value
398 // ===========================================================================
400 ( const Counter* pCounter,
401  Printout& printer ) const
402 {
403  MsgStream log(msgSvc(), name() ) ;
404  return printer ( log , pCounter ) ;
405 }
406 // ===========================================================================
407 // Print counter value
408 // ===========================================================================
410 ( const CountObject& refCounter,
411  Printout& printer) const
412 { return print( refCounter.counter() , printer ) ; }
413 // ===========================================================================
414 // Print all known counters
415 // ===========================================================================
417 {
418  MsgStream log ( msgSvc() , name() ) ;
419  // Force printing in alphabetical order
421  sorted_map_t sorted_map;
422  for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
423  {
424  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
425  {
426  sorted_map[std::make_pair(i->first, j->first)] = j->second;
427  }
428  }
429  std::for_each(sorted_map.begin(), sorted_map.end(),
430  conditionalPrint(printer, log));
431  return StatusCode::SUCCESS;
432 }
433 // ===========================================================================
434 // Print counter value
435 // ===========================================================================
438  const Counter* c ) const
439 {
440  if ( 0 == c ) { return StatusCode::FAILURE ; }
441  std::pair<std::string,std::string> p = _find ( c ) ;
442 
443  log << MSG::ALWAYS
444  << CountObject( const_cast<Counter*>(c) , p.first , p.second )
445  << endmsg ;
446 
447  return StatusCode::SUCCESS;
448 }
449 // ===========================================================================
450 // "standard" printout a'la GaudiCommon
451 // ===========================================================================
452 void CounterSvc::print () const
453 {
454  MsgStream log ( msgSvc() , name() ) ;
455  // number of counters
456  const size_t _num = num() ;
457  if ( 0 != _num )
458  {
459  log << MSG::ALWAYS
460  << "Number of counters : " << _num << endmsg
461  << m_header << endmsg ;
462  }
463  {
464  // Force printing in alphabetical order
466  sorted_map_t sorted_map;
467  for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
468  {
469  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
470  {
471  Counter* c = j->second ;
472  if ( 0 == c ) { continue ; }
473  sorted_map[std::make_pair(i->first, j->first)] = c;
474  }
475  }
476  for (sorted_map_t::const_iterator i = sorted_map.begin(); i != sorted_map.end(); ++i )
477  log << Gaudi::Utils::formatAsTableRow( i->first.second
478  , i->first.first
479  , *i->second
481  , m_format1
482  , m_format2 )
483  << endmsg ;
484  }
485 }
486 // ============================================================================
487 
488 // ============================================================================
489 // The END
490 // ============================================================================

Generated at Wed Dec 4 2013 14:33:07 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004