00001
00002
00003
00004
00005
00006
00007 #include <utility>
00008 #include <vector>
00009 #include <algorithm>
00010 #include <functional>
00011
00012
00013
00014 #include "GaudiKernel/ICounterSvc.h"
00015 #include "GaudiKernel/ISvcLocator.h"
00016 #include "GaudiKernel/SvcFactory.h"
00017 #include "GaudiKernel/MsgStream.h"
00018 #include "GaudiKernel/Service.h"
00019 #include "GaudiKernel/HashMap.h"
00020
00027 class CounterSvc: public extends1<Service, ICounterSvc> {
00028 public:
00030 CounterSvc ( const std::string& name ,
00031 ISvcLocator* svcLoc )
00032 : base_class(name, svcLoc)
00033 , m_counts ()
00034 , m_print ( true )
00035
00036
00037 , m_header ( " Counter :: Group | # | sum | mean/eff^* | rms/err^* | min | max |")
00038
00039 , m_format1 ( " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" )
00040
00041 , m_format2 ( "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |" )
00042
00043 , m_useEffFormat ( true )
00044
00045 {
00046 declareProperty ("PrintStat" , m_print ) ;
00047
00048 declareProperty
00049 ( "StatTableHeader" , m_header ,
00050 "The header row for the output Stat-table" ) ;
00051
00052 declareProperty
00053 ( "RegularRowFormat" , m_format1 ,
00054 "The format for the regular row in the output Stat-table" ) ;
00055
00056 declareProperty
00057 ( "EfficiencyRowFormat" , m_format2 ,
00058 "The format for the regular row in the outptu Stat-table" ) ;
00059
00060 declareProperty
00061 ( "UseEfficiencyRowFormat" , m_useEffFormat ,
00062 "Use the special format for printout of efficiency counters" ) ;
00063 }
00065 virtual ~CounterSvc() { remove().ignore() ; }
00067 virtual StatusCode finalize()
00068 {
00069 if ( outputLevel() <= MSG::DEBUG || m_print ) { print () ; }
00070 remove().ignore() ;
00071
00072 return Service::finalize() ;
00073 }
00074
00082 virtual Counter* get
00083 ( const std::string& group ,
00084 const std::string& name ) const;
00086 virtual ICounterSvc::Counters get ( const std::string& group ) const ;
00099 virtual StatusCode create
00100 ( const std::string& group ,
00101 const std::string& name ,
00102 longlong initial_value ,
00103 Counter*& refpCounter ) ;
00115 virtual CountObject create
00116 ( const std::string& group ,
00117 const std::string& name ,
00118 longlong initial_value = 0 ) ;
00128 virtual StatusCode remove
00129 ( const std::string& group ,
00130 const std::string& name ) ;
00136 virtual StatusCode remove
00137 ( const std::string& group ) ;
00139 virtual StatusCode remove();
00147 virtual StatusCode print
00148 ( const std::string& group,
00149 const std::string& name,
00150 Printout& printer) const;
00158 virtual StatusCode print
00159 (const std::string& group,
00160 Printout& printer) const;
00167 virtual StatusCode print
00168 ( const Counter* pCounter,
00169 Printout& printer) const;
00176 virtual StatusCode print
00177 ( const CountObject& pCounter,
00178 Printout& printer) const;
00182 virtual StatusCode print(Printout& printer) const;
00184 virtual StatusCode defaultPrintout
00185 ( MsgStream& log,
00186 const Counter* pCounter) const ;
00187 private:
00188
00189 inline std::pair<std::string,std::string> _find ( const Counter* c ) const
00190 {
00191 if ( 0 == c ) { return std::pair<std::string,std::string>() ; }
00192 for ( CountMap::const_iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
00193 {
00194 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
00195 { if ( j->second == c ) { return std::make_pair( i->first , j->first ) ; } }
00196 }
00197 return std::pair<std::string,std::string>() ;
00198 }
00199
00200 inline size_t num () const
00201 {
00202 size_t result = 0 ;
00203 {
00204 for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
00205 {
00206 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
00207 { if ( 0 != j->second ) { ++result ; } ; }
00208 }
00209 }
00210 return result ;
00211 }
00212 public:
00214 void print () const ;
00215 private:
00216 typedef GaudiUtils::HashMap<std::string,Counter*> NameMap ;
00217 typedef GaudiUtils::HashMap<std::string,NameMap> CountMap ;
00218
00219 CountMap m_counts ;
00220
00221 bool m_print ;
00222
00223 std::string m_header ;
00224
00225 std::string m_format1 ;
00226
00227 std::string m_format2 ;
00228
00229 bool m_useEffFormat ;
00230 } ;
00231
00232
00233
00234 DECLARE_SERVICE_FACTORY(CounterSvc)
00235
00236
00237
00238 CounterSvc::Counter* CounterSvc::get
00239 ( const std::string& grp ,
00240 const std::string& nam ) const
00241 {
00242 CountMap::const_iterator i = m_counts.find ( grp ) ;
00243 if ( m_counts.end() == i ) { return 0 ; }
00244 NameMap::const_iterator j = i->second.find ( nam ) ;
00245 if ( i->second.end() == j ) { return 0 ; }
00246 return j->second ;
00247 }
00248
00249
00250
00251 ICounterSvc::Counters CounterSvc::get ( const std::string& group ) const
00252 {
00253 ICounterSvc::Counters result ;
00254 CountMap::const_iterator i = m_counts.find ( group ) ;
00255 if ( m_counts.end() == i ) { return result ; }
00256 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
00257 { result.push_back( CountObject ( j->second, i->first , j->first ) ) ; }
00258 return result ;
00259 }
00260
00261
00262
00263 #ifdef __ICC
00264
00265 #pragma warning(push)
00266 #pragma warning(disable:2259)
00267 #endif
00268 StatusCode CounterSvc::create
00269 ( const std::string& grp ,
00270 const std::string& nam ,
00271 longlong initial_value ,
00272 Counter*& refpCounter )
00273 {
00274
00275 refpCounter = get ( grp , nam ) ;
00276 if ( 0 != refpCounter ) { return COUNTER_EXISTS ; }
00277
00278 Counter* newc = new Counter() ;
00279 refpCounter = newc ;
00280 if ( 0 != initial_value ) {
00281 refpCounter->addFlag ( static_cast<double>(initial_value) ) ;
00282 }
00283
00284 CountMap::iterator i = m_counts.find ( grp ) ;
00285
00286 if ( m_counts.end() == i )
00287 { i = m_counts.insert ( std::make_pair ( grp , NameMap() ) ).first ; }
00288
00289 i->second.insert( std::make_pair( nam , newc ) ).first ;
00290 return StatusCode::SUCCESS ;
00291 }
00292 #ifdef __ICC
00293
00294 #pragma warning(pop)
00295 #endif
00296
00297
00298
00299 CounterSvc::CountObject CounterSvc::create
00300 ( const std::string& group ,
00301 const std::string& name ,
00302 longlong initial_value )
00303 {
00304 Counter* p = 0;
00305 StatusCode sc = create ( group, name, initial_value, p ) ;
00306 if ( sc.isSuccess() && 0 != p ) { return CountObject ( p , group , name ) ; }
00307 throw std::runtime_error("CounterSvc::Counter('"+group+"::"+name+"') exists already!");
00308 }
00309
00310
00311
00312 StatusCode CounterSvc::remove
00313 ( const std::string& grp ,
00314 const std::string& nam )
00315 {
00316 CountMap::iterator i = m_counts.find ( grp ) ;
00317 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
00318 NameMap::iterator j = i->second.find ( nam ) ;
00319 if ( i->second.end() == j ) { return COUNTER_NOT_PRESENT ; }
00320 delete j->second ;
00321 i->second.erase ( j ) ;
00322 return StatusCode::SUCCESS ;
00323 }
00324
00325
00326
00327 StatusCode CounterSvc::remove ( const std::string& grp )
00328 {
00329 CountMap::iterator i = m_counts.find ( grp ) ;
00330 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
00331 for ( NameMap::iterator j = i->second.begin() ; i->second.end() != j ; ++j )
00332 { delete j->second ; }
00333 i->second.clear() ;
00334 return StatusCode::SUCCESS ;
00335 }
00336
00337
00338
00339 StatusCode CounterSvc::remove()
00340 {
00341
00342 for ( CountMap::iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
00343 { remove ( i->first ).ignore () ; }
00344 m_counts.clear() ;
00345 return StatusCode::SUCCESS;
00346 }
00347
00348
00349
00350 StatusCode CounterSvc::print
00351 ( const std::string& grp,
00352 const std::string& nam,
00353 Printout& printer) const
00354 {
00355 const Counter* c = get( grp , nam ) ;
00356 if ( 0 == c ) { return COUNTER_NOT_PRESENT ; }
00357
00358 MsgStream log ( msgSvc() , name() ) ;
00359 return printer ( log , c ) ;
00360 }
00361
00362 namespace {
00364 class conditionalPrint {
00365 private:
00366 CounterSvc::Printout *printer;
00367 MsgStream *log;
00368 public:
00369 conditionalPrint(CounterSvc::Printout &_p, MsgStream &_l): printer(&_p), log(&_l) {}
00370 template<class Pair>
00371 void operator() (const Pair &p) {
00372 if (p.second) {
00373 (*printer)(*log, p.second).ignore();
00374 }
00375 }
00376 };
00377 }
00378
00379
00380
00381 StatusCode CounterSvc::print
00382 ( const std::string& grp ,
00383 Printout& printer ) const
00384 {
00385 CountMap::const_iterator i = m_counts.find ( grp ) ;
00386 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
00387
00388 MsgStream log(msgSvc(), name());
00389
00390 typedef std::map<std::string, Counter*> sorted_map_t;
00391 sorted_map_t sorted_map(i->second.begin(), i->second.end());
00392 std::for_each(sorted_map.begin(), sorted_map.end(),
00393 conditionalPrint(printer, log));
00394 return StatusCode::SUCCESS;
00395 }
00396
00397
00398
00399 StatusCode CounterSvc::print
00400 ( const Counter* pCounter,
00401 Printout& printer ) const
00402 {
00403 MsgStream log(msgSvc(), name() ) ;
00404 return printer ( log , pCounter ) ;
00405 }
00406
00407
00408
00409 StatusCode CounterSvc::print
00410 ( const CountObject& refCounter,
00411 Printout& printer) const
00412 { return print( refCounter.counter() , printer ) ; }
00413
00414
00415
00416 StatusCode CounterSvc::print( Printout& printer ) const
00417 {
00418 MsgStream log ( msgSvc() , name() ) ;
00419
00420 typedef std::map<std::pair<std::string,std::string>, Counter*> sorted_map_t;
00421 sorted_map_t sorted_map;
00422 for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
00423 {
00424 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
00425 {
00426 sorted_map[std::make_pair(i->first, j->first)] = j->second;
00427 }
00428 }
00429 std::for_each(sorted_map.begin(), sorted_map.end(),
00430 conditionalPrint(printer, log));
00431 return StatusCode::SUCCESS;
00432 }
00433
00434
00435
00436 StatusCode CounterSvc::defaultPrintout
00437 ( MsgStream& log,
00438 const Counter* c ) const
00439 {
00440 if ( 0 == c ) { return StatusCode::FAILURE ; }
00441 std::pair<std::string,std::string> p = _find ( c ) ;
00442
00443 log << MSG::ALWAYS
00444 << CountObject( const_cast<Counter*>(c) , p.first , p.second )
00445 << endmsg ;
00446
00447 return StatusCode::SUCCESS;
00448 }
00449
00450
00451
00452 void CounterSvc::print () const
00453 {
00454 MsgStream log ( msgSvc() , name() ) ;
00455
00456 const size_t _num = num() ;
00457 if ( 0 != _num )
00458 {
00459 log << MSG::ALWAYS
00460 << "Number of counters : " << _num << endmsg
00461 << m_header << endmsg ;
00462 }
00463 {
00464
00465 typedef std::map<std::pair<std::string,std::string>, Counter*> sorted_map_t;
00466 sorted_map_t sorted_map;
00467 for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
00468 {
00469 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
00470 {
00471 Counter* c = j->second ;
00472 if ( 0 == c ) { continue ; }
00473 sorted_map[std::make_pair(i->first, j->first)] = c;
00474 }
00475 }
00476 for (sorted_map_t::const_iterator i = sorted_map.begin(); i != sorted_map.end(); ++i )
00477 log << Gaudi::Utils::formatAsTableRow( i->first.second
00478 , i->first.first
00479 , *i->second
00480 , m_useEffFormat
00481 , m_format1
00482 , m_format2 )
00483 << endmsg ;
00484 }
00485 }
00486
00487
00488
00489
00490