| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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