![]() |
|
|
Generated: 8 Jan 2009 |
00001 // $Id: CounterSvc.cpp,v 1.6 2007/09/24 19:15:57 marcocle Exp $ 00002 // ============================================================================ 00003 // CVS tag $Name: $, verison $Revision: 1.6 $ 00004 // ============================================================================ 00005 // STD & SLT 00006 // ============================================================================ 00007 #include <utility> 00008 #include <vector> 00009 #include <algorithm> 00010 #include <functional> 00011 // ============================================================================ 00012 // GaudiKernel 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 00028 : virtual public ICounterSvc 00029 , public Service 00030 { 00031 public: 00033 CounterSvc ( const std::string& name , 00034 ISvcLocator* svcLoc ) 00035 : Service(name, svcLoc) 00036 , m_counts () 00037 , m_print ( true ) 00038 // 00039 // the header row 00040 , m_header ( " Counter :: Group | # | sum | mean/eff^* | rms/err^* | min | max |") 00041 // format for regular statistical printout rows 00042 , m_format1 ( " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" ) 00043 // format for "efficiency" statistical printout rows 00044 , m_format2 ( "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |" ) 00045 // flag to use the special "efficiency" format 00046 , m_useEffFormat ( true ) 00047 // 00048 { 00049 declareProperty ("PrintStat" , m_print ) ; 00050 // 00051 declareProperty 00052 ( "StatTableHeader" , m_header , 00053 "The header row for the output Stat-table" ) ; 00054 // 00055 declareProperty 00056 ( "RegularRowFormat" , m_format1 , 00057 "The format for the regular row in the output Stat-table" ) ; 00058 // 00059 declareProperty 00060 ( "EfficiencyRowFormat" , m_format2 , 00061 "The format for the regular row in the outptu Stat-table" ) ; 00062 // 00063 declareProperty 00064 ( "UseEfficiencyRowFormat" , m_useEffFormat , 00065 "Use the special format for printout of efficiency counters" ) ; 00066 } 00068 virtual ~CounterSvc() { remove().ignore() ; }; 00070 virtual StatusCode queryInterface 00071 ( const InterfaceID& riid , void** ppvI ) 00072 { 00073 // valid placeholder? 00074 if ( 0 == ppvI ) { return StatusCode::FAILURE ; } // RETURN 00075 if ( ICounterSvc::interfaceID() == riid ) 00076 { 00077 *ppvI = static_cast<ICounterSvc*>(this); 00078 addRef(); // NB! : inrement the reference count! 00079 return StatusCode::SUCCESS; // RETURN 00080 } 00081 // Interface is not directly availible: try out a base class 00082 return Service::queryInterface( riid, ppvI ); 00083 } 00085 virtual StatusCode finalize() 00086 { 00087 if ( outputLevel() <= MSG::DEBUG || m_print ) { print () ; } 00088 remove().ignore() ; 00089 // finalize the base class 00090 return Service::finalize() ; 00091 } 00092 // ========================================================================== 00100 virtual Counter* get 00101 ( const std::string& group , 00102 const std::string& name ) const; 00104 virtual ICounterSvc::Counters get ( const std::string& group ) const ; 00117 virtual StatusCode create 00118 ( const std::string& group , 00119 const std::string& name , 00120 longlong initial_value , 00121 Counter*& refpCounter ) ; 00133 virtual CountObject create 00134 ( const std::string& group , 00135 const std::string& name , 00136 longlong initial_value = 0 ) ; 00146 virtual StatusCode remove 00147 ( const std::string& group , 00148 const std::string& name ) ; 00154 virtual StatusCode remove 00155 ( const std::string& group ) ; 00157 virtual StatusCode remove(); 00165 virtual StatusCode print 00166 ( const std::string& group, 00167 const std::string& name, 00168 Printout& printer) const; 00176 virtual StatusCode print 00177 (const std::string& group, 00178 Printout& printer) const; 00185 virtual StatusCode print 00186 ( const Counter* pCounter, 00187 Printout& printer) const; 00194 virtual StatusCode print 00195 ( const CountObject& pCounter, 00196 Printout& printer) const; 00200 virtual StatusCode print(Printout& printer) const; 00202 virtual StatusCode defaultPrintout 00203 ( MsgStream& log, 00204 const Counter* pCounter) const ; 00205 private: 00206 // find group/name for the counter: 00207 inline std::pair<std::string,std::string> _find ( const Counter* c ) const 00208 { 00209 if ( 0 == c ) { return std::pair<std::string,std::string>() ; } 00210 for ( CountMap::const_iterator i = m_counts.begin() ; m_counts.end() != i ; ++i ) 00211 { 00212 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00213 { if ( j->second == c ) { return std::make_pair( i->first , j->first ) ; } } 00214 } 00215 return std::pair<std::string,std::string>() ; 00216 } 00217 // get the overall number of counters 00218 inline size_t num () const 00219 { 00220 size_t result = 0 ; 00221 { 00222 for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i ) 00223 { 00224 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00225 { if ( 0 != j->second ) { ++result ; } ; } 00226 } 00227 } 00228 return result ; 00229 } 00230 public: 00232 void print () const ; 00233 private: 00234 typedef GaudiUtils::HashMap<std::string,Counter*> NameMap ; 00235 typedef GaudiUtils::HashMap<std::string,NameMap> CountMap ; 00236 // the actual map of counters 00237 CountMap m_counts ; 00238 // boolean flag to print statistics 00239 bool m_print ; 00240 // the header row 00241 std::string m_header ; 00242 // format for regular statistical printout rows 00243 std::string m_format1 ; 00244 // format for "efficiency" statistical printout rows 00245 std::string m_format2 ; 00246 // flag to use the special "efficiency" format 00247 bool m_useEffFormat ; 00248 } ; 00249 // =========================================================================== 00250 // Instantiation of a static factory class used by clients 00251 // =========================================================================== 00252 DECLARE_SERVICE_FACTORY(CounterSvc) 00253 // =========================================================================== 00254 // Access a counter object by name and group 00255 // =========================================================================== 00256 CounterSvc::Counter* CounterSvc::get 00257 ( const std::string& grp , 00258 const std::string& nam ) const 00259 { 00260 CountMap::const_iterator i = m_counts.find ( grp ) ; 00261 if ( m_counts.end() == i ) { return 0 ; } // RETURN 00262 NameMap::const_iterator j = i->second.find ( nam ) ; 00263 if ( i->second.end() == j ) { return 0 ; } // RETURN 00264 return j->second ; // RETURN 00265 } 00266 // =========================================================================== 00267 // get all counters form the given group: 00268 // =========================================================================== 00269 ICounterSvc::Counters CounterSvc::get ( const std::string& group ) const 00270 { 00271 ICounterSvc::Counters result ; 00272 CountMap::const_iterator i = m_counts.find ( group ) ; 00273 if ( m_counts.end() == i ) { return result ; } // RETURN 00274 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00275 { result.push_back( CountObject ( j->second, i->first , j->first ) ) ; } 00276 return result ; 00277 } 00278 // =========================================================================== 00279 // Create/get a counter object. 00280 // =========================================================================== 00281 StatusCode CounterSvc::create 00282 ( const std::string& grp , 00283 const std::string& nam , 00284 longlong initial_value , 00285 Counter*& refpCounter ) 00286 { 00287 // try to find existing counter: 00288 refpCounter = get ( grp , nam ) ; 00289 if ( 0 != refpCounter ) { return COUNTER_EXISTS ; } // RETURN 00290 // create the new counter 00291 Counter* newc = new Counter() ; 00292 refpCounter = newc ; 00293 if ( 0 != initial_value ) { 00294 refpCounter->addFlag ( static_cast<double>(initial_value) ) ; 00295 } 00296 // find a proper group 00297 CountMap::iterator i = m_counts.find ( grp ) ; 00298 // (create a group if needed) 00299 if ( m_counts.end() == i ) 00300 { i = m_counts.insert ( std::make_pair ( grp , NameMap() ) ).first ; } 00301 // insert new counter with priper name into proper group: 00302 i->second.insert( std::make_pair( nam , newc ) ).first ; 00303 return StatusCode::SUCCESS ; // RETURN 00304 } 00305 // =========================================================================== 00306 // Create a new counter object. If the counter object exists already, 00307 // =========================================================================== 00308 CounterSvc::CountObject CounterSvc::create 00309 ( const std::string& group , 00310 const std::string& name , 00311 longlong initial_value ) 00312 { 00313 Counter* p = 0; 00314 StatusCode sc = create ( group, name, initial_value, p ) ; 00315 if ( sc.isSuccess() && 0 != p ) { return CountObject ( p , group , name ) ; } 00316 throw std::runtime_error("CounterSvc::Counter('"+group+"::"+name+"') exists already!"); 00317 } 00318 // =========================================================================== 00319 // Remove a counter object. The tuple (group,name) identifies the counter uniquely 00320 // =========================================================================== 00321 StatusCode CounterSvc::remove 00322 ( const std::string& grp , 00323 const std::string& nam ) 00324 { 00325 CountMap::iterator i = m_counts.find ( grp ) ; 00326 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN 00327 NameMap::iterator j = i->second.find ( nam ) ; 00328 if ( i->second.end() == j ) { return COUNTER_NOT_PRESENT ; } // RETURN 00329 delete j->second ; 00330 i->second.erase ( j ) ; 00331 return StatusCode::SUCCESS ; 00332 } 00333 // =========================================================================== 00334 // Remove a group of counter objects. 00335 // =========================================================================== 00336 StatusCode CounterSvc::remove ( const std::string& grp ) 00337 { 00338 CountMap::iterator i = m_counts.find ( grp ) ; 00339 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN 00340 for ( NameMap::iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00341 { delete j->second ; } 00342 i->second.clear() ; 00343 return StatusCode::SUCCESS ; 00344 } 00345 // =========================================================================== 00346 // Remove all known counter objects 00347 // =========================================================================== 00348 StatusCode CounterSvc::remove() 00349 { 00350 // remove group by group 00351 for ( CountMap::iterator i = m_counts.begin() ; m_counts.end() != i ; ++i ) 00352 { remove ( i->first ).ignore () ; } 00353 m_counts.clear() ; 00354 return StatusCode::SUCCESS; 00355 } 00356 // =========================================================================== 00357 // Print counter value 00358 // =========================================================================== 00359 StatusCode CounterSvc::print 00360 ( const std::string& grp, 00361 const std::string& nam, 00362 Printout& printer) const 00363 { 00364 const Counter* c = get( grp , nam ) ; 00365 if ( 0 == c ) { return COUNTER_NOT_PRESENT ; } // RETURN 00366 // create the stream and use it! 00367 MsgStream log ( msgSvc() , name() ) ; 00368 return printer ( log , c ) ; 00369 } 00370 // =========================================================================== 00371 // Print the counter valuee for thre whole group of counters 00372 // =========================================================================== 00373 StatusCode CounterSvc::print 00374 ( const std::string& grp , 00375 Printout& printer ) const 00376 { 00377 CountMap::const_iterator i = m_counts.find ( grp ) ; 00378 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } 00379 MsgStream log(msgSvc(), name()); 00380 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00381 { printer ( log , j->second ).ignore() ; } 00382 // 00383 return StatusCode::SUCCESS; // RETURN 00384 } 00385 // =========================================================================== 00386 // Print counter value 00387 // =========================================================================== 00388 StatusCode CounterSvc::print 00389 ( const Counter* pCounter, 00390 Printout& printer ) const 00391 { 00392 MsgStream log(msgSvc(), name() ) ; 00393 return printer ( log , pCounter ) ; 00394 } 00395 // =========================================================================== 00396 // Print counter value 00397 // =========================================================================== 00398 StatusCode CounterSvc::print 00399 ( const CountObject& refCounter, 00400 Printout& printer) const 00401 { return print( refCounter.counter() , printer ) ; } 00402 // =========================================================================== 00403 // Print all known counters 00404 // =========================================================================== 00405 StatusCode CounterSvc::print( Printout& printer ) const 00406 { 00407 MsgStream log ( msgSvc() , name() ) ; 00408 for( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i) 00409 { 00410 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00411 { printer ( log , j->second ).ignore() ; } 00412 } 00413 return StatusCode::SUCCESS; 00414 } 00415 // =========================================================================== 00416 // Print counter value 00417 // =========================================================================== 00418 StatusCode CounterSvc::defaultPrintout 00419 ( MsgStream& log, 00420 const Counter* c ) const 00421 { 00422 if ( 0 == c ) { return StatusCode::FAILURE ; } 00423 std::pair<std::string,std::string> p = _find ( c ) ; 00424 00425 log << MSG::ALWAYS 00426 << CountObject( const_cast<Counter*>(c) , p.first , p.second ) 00427 << endreq ; 00428 00429 return StatusCode::SUCCESS; 00430 } 00431 // =========================================================================== 00432 // "standard" printout a'la GaudiCommon 00433 // =========================================================================== 00434 void CounterSvc::print () const 00435 { 00436 MsgStream log ( msgSvc() , name() ) ; 00437 // number of counters 00438 const size_t _num = num() ; 00439 if ( 0 != _num ) 00440 { 00441 log << MSG::ALWAYS 00442 << "Number of counters : " << _num << endreq 00443 << m_header << endreq ; 00444 } 00445 for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i ) 00446 { 00447 for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j ) 00448 { 00449 Counter* c = j->second ; 00450 if ( 0 == c ) { continue ; } 00451 log << 00452 Gaudi::Utils::formatAsTableRow 00453 ( j->first , i->first , *c , m_useEffFormat , m_format1 , m_format2 ) 00454 << endreq ; 00455 } 00456 } 00457 } 00458 // ============================================================================ 00459 00460 // ============================================================================ 00461 // The END 00462 // ============================================================================