![]() |
|
|
Generated: 18 Jul 2008 |
00001 // $Id: ChronoStatSvc.cpp,v 1.18 2008/05/13 12:37:19 marcocle Exp $ 00002 // ============================================================================ 00003 // CVS tag $Name: v17r1 $, version $Revision: 1.18 $ 00004 // ============================================================================ 00005 #ifdef _WIN32 00006 #pragma warning( disable : 4786 ) 00007 #endif 00008 // ============================================================================ 00009 // STD & STL 00010 // ============================================================================ 00011 #include <iostream> 00012 #include <iomanip> 00013 #include <string> 00014 #include <algorithm> 00015 #include <functional> 00016 #include <fstream> 00017 #include <iomanip> 00018 // ============================================================================ 00019 // GaudiKernel 00020 // ============================================================================ 00021 #include "GaudiKernel/Kernel.h" 00022 #include "GaudiKernel/StatusCode.h" 00023 #include "GaudiKernel/SvcFactory.h" 00024 #include "GaudiKernel/IChronoStatSvc.h" 00025 #include "GaudiKernel/MsgStream.h" 00026 #include "GaudiKernel/ChronoEntity.h" 00027 #include "GaudiKernel/StatEntity.h" 00028 #include "GaudiKernel/Stat.h" 00029 // ============================================================================ 00031 // ============================================================================ 00032 #include "ChronoStatSvc.h" 00033 // ============================================================================ 00036 // ============================================================================ 00037 DECLARE_SERVICE_FACTORY(ChronoStatSvc) 00038 // ============================================================================ 00045 // ============================================================================ 00046 // ============================================================================ 00047 // comparison functor 00048 // ============================================================================ 00049 class ComparePairOfChronoEntityAndChronoTag 00050 : public std::binary_function< 00051 const std::pair<ChronoEntity*,const IChronoStatSvc::ChronoTag*> , 00052 const std::pair<ChronoEntity*,const IChronoStatSvc::ChronoTag*> , bool > 00053 { 00054 public: 00055 inline bool operator() 00056 ( const std::pair<ChronoEntity*, 00057 const IChronoStatSvc::ChronoTag*>& p1 , 00058 const std::pair< ChronoEntity*, 00059 const IChronoStatSvc::ChronoTag*>& p2 ) const 00060 { 00061 const ChronoEntity* e1 = p1.first; 00062 const ChronoEntity* e2 = p2.first; 00063 return ( ( 0 == e1 || 0 == e2 ) ? true : (*e1)<(*e2) ) ; 00064 } 00065 }; 00066 // ============================================================================ 00067 // comparison functor 00068 // ============================================================================ 00069 class ComparePairOfStatEntityAndStatTag 00070 : public std::binary_function< 00071 const std::pair<const StatEntity*,const IChronoStatSvc::StatTag*> , 00072 const std::pair<const StatEntity*,const IChronoStatSvc::StatTag*> , bool > 00073 { 00074 public: 00076 inline bool operator() 00077 ( const std::pair<const StatEntity*, 00078 const IChronoStatSvc::StatTag*>& p1, 00079 const std::pair<const StatEntity*, 00080 const IChronoStatSvc::StatTag*>& p2 ) const 00081 { 00082 const StatEntity* se1 = p1.first; 00083 const StatEntity* se2 = p2.first; 00084 return ( 0 == se1 || 0 == se2 ) ? true : (*se1)<(*se2) ; 00085 } 00086 }; 00087 // ============================================================================ 00088 // Constructor 00089 // ============================================================================ 00090 ChronoStatSvc::ChronoStatSvc 00091 ( const std::string& name, ISvcLocator* svcloc ) 00092 : Service( name , svcloc ) 00093 , m_chronoEntities () 00094 , m_chronoPrintLevel ( MSG::INFO ) 00095 , m_statEntities () 00096 , m_statPrintLevel ( MSG::INFO ) 00097 // 00098 // the header row 00099 , m_header ( " Counter | # | sum | mean/eff^* | rms/err^* | min | max |") 00100 // format for regular statistical printout rows 00101 , m_format1 ( " %|-15.15s|%|17t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" ) 00102 // format for "efficiency" statistical printout rows 00103 , m_format2 ( "*%|-15.15s|%|17t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |" ) 00104 // flag to use the special "efficiency" format 00105 , m_useEffFormat ( true ) 00106 { 00108 declareProperty ( "ChronoPrintOutTable" , 00109 m_chronoTableFlag = true ); 00111 declareProperty ( "ChronoDestinationCout" , 00112 m_chronoCoutFlag = false ); 00114 declareProperty ( "ChronoPrintLevel" , 00115 m_intChronoPrintLevel = MSG::INFO ); 00118 declareProperty ( "ChronoTableToBeOrdered" , 00119 m_chronoOrderFlag = true ); 00121 declareProperty ( "PrintUserTime" , 00122 m_printUserTime = true ); 00124 declareProperty ( "PrintSystemTime" , 00125 m_printSystemTime = false ); 00127 declareProperty ( "PrintEllapsedTime" , 00128 m_printEllapsedTime = false ); 00131 declareProperty ( "StatPrintOutTable" , 00132 m_statTableFlag = true ); 00134 declareProperty ( "StatDestinationCout" , 00135 m_statCoutFlag = false ); 00137 declareProperty ( "StatPrintLevel" , 00138 m_intStatPrintLevel = MSG::INFO ); 00141 declareProperty ( "StatTableToBeOrdered" , 00142 m_statOrderFlag = true ); 00143 00144 // specify the number of events to be skipped by the memory auditor 00145 // in order to better spot memory leak 00146 declareProperty ( "NumberOfSkippedEventsForMemStat" , 00147 m_numberOfSkippedEventsForMemStat = -1 ) ; 00148 00149 declareProperty( "AsciiStatsOutputFile", 00150 m_statsOutFileName = "", 00151 "Name of the output file storing the stats. If empty, no" 00152 " statistics will be saved (default)" ); 00153 00154 declareProperty 00155 ( "StatTableHeader" , m_header , 00156 "The header row for the output Stat-table" ) ; 00157 declareProperty 00158 ( "RegularRowFormat" , m_format1 , 00159 "The format for the regular row in the output Stat-table" ) ; 00160 declareProperty 00161 ( "EfficiencyRowFormat" , m_format2 , 00162 "The format for the regular row in the outptu Stat-table" ) ; 00163 declareProperty 00164 ( "UseEfficiencyRowFormat" , m_useEffFormat , 00165 "Use the special format for printout of efficiency counters" ) ; 00166 } 00167 // ============================================================================ 00168 // Destructor. 00169 // ============================================================================ 00170 ChronoStatSvc::~ChronoStatSvc() 00171 { 00172 // clear the container of chrono entities 00173 m_chronoEntities.clear(); 00174 // clear the container of stat entities 00175 m_statEntities.clear(); 00176 } 00177 // ============================================================================ 00178 // Implementation of IService::initialize() 00179 // ============================================================================ 00180 StatusCode ChronoStatSvc::initialize() 00181 { 00182 StatusCode sc = Service::initialize(); 00183 if ( sc.isFailure() ) return sc; 00185 MsgStream log( msgSvc() , this->name() ); 00186 00187 // Set my own properties 00188 sc = setProperties(); 00189 00190 if (sc.isFailure()) { 00191 log << MSG::ERROR << "setting my properties" << endreq; 00192 return StatusCode::FAILURE; 00193 } 00194 00195 log << MSG::INFO << " Number of skipped events for MemStat" 00196 << m_numberOfSkippedEventsForMemStat << endreq ; 00197 00201 m_statPrintLevel = 00202 ( MSG::FATAL < m_intStatPrintLevel ) ? MSG::FATAL : 00203 ( MSG::NIL > m_intStatPrintLevel ) ? MSG::NIL : 00204 ( MSG::Level ) m_intStatPrintLevel ; 00206 m_chronoPrintLevel = 00207 ( MSG::FATAL < m_intChronoPrintLevel ) ? MSG::FATAL : 00208 ( MSG::NIL > m_intChronoPrintLevel ) ? MSG::NIL : 00209 ( MSG::Level ) m_intChronoPrintLevel ; 00211 if( m_chronoTableFlag && 00212 !m_printUserTime && 00213 !m_printSystemTime && 00214 !m_printEllapsedTime ) { m_printUserTime = true ; } 00216 if( m_printUserTime || 00217 m_printSystemTime || 00218 m_printEllapsedTime ) { m_chronoTableFlag = true ; } 00221 chronoStart( name() ) ; 00223 return StatusCode::SUCCESS; 00224 } 00225 // ============================================================================ 00226 // Implementation of IService::finalize() 00227 // ============================================================================ 00228 StatusCode ChronoStatSvc::finalize() 00229 { 00230 std::string local = name()+".finalize()"; 00232 MsgStream log( msgSvc() , local ); 00235 chronoStop( name() ) ; 00236 00239 if ( m_chronoTableFlag && 00240 !m_chronoEntities.empty() && 00241 ( m_printUserTime || m_printSystemTime ) ) 00242 { 00244 MsgStream log( msgSvc() , "*****Chrono*****" ); 00245 const std::string stars( ( m_chronoCoutFlag ) ? 126 : 100 , '*' ); 00246 if( m_chronoCoutFlag ) 00247 { 00248 std::cout << stars << std::endl; 00249 std::cout << local << " The Final CPU consumption (Chrono) Table " 00250 << ( m_chronoOrderFlag ? "(ordered)" : "(not ordered)" ) << std::endl; 00251 std::cout << stars << std::endl; 00252 } 00253 else 00254 { 00255 log << (MSG::Level) m_chronoPrintLevel 00256 << stars << endreq; 00257 log << (MSG::Level) m_chronoPrintLevel 00258 << " The Final CPU consumption ( Chrono ) Table " 00259 << ( m_chronoOrderFlag ? "(ordered)" : "(not ordered)" ) << endreq; 00260 log << (MSG::Level) m_chronoPrintLevel << stars << endreq; 00261 } 00263 { // prepare container for printing 00264 typedef std::pair<ChronoEntity*,const ChronoTag*> MPair; 00265 typedef std::vector<MPair> MCont; 00266 MCont tmpCont; 00267 for( ChronoMap::iterator it = m_chronoEntities.begin() ; 00268 m_chronoEntities.end() != it ; ++it ) 00269 { tmpCont.push_back( MPair( &(it->second) , &(it->first) ) ) ; } 00270 // sort it 00271 if( m_chronoOrderFlag ) 00272 { std::sort( tmpCont.begin() , 00273 tmpCont.end() , 00274 ComparePairOfChronoEntityAndChronoTag() ); } 00275 // print User Time statistics 00276 if( m_printUserTime ) 00277 { 00278 for( MCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter ) 00279 { 00280 // 00281 ChronoEntity* entity = iter->first ; if( 0 == entity ) { continue ; } 00282 const ChronoTag* tag = iter->second ; if( 0 == tag ) { continue ; } 00283 00284 entity->stop(); 00285 00286 if ( m_chronoCoutFlag ) 00287 { std::cout << *tag << "\t" << entity->outputUserTime () << std::endl ; } 00288 else 00289 { 00290 MsgStream log( msgSvc() , *tag ) ; 00291 log << m_chronoPrintLevel << entity->outputUserTime () << endreq ; 00292 } 00293 // 00294 } 00295 } 00297 if( m_printSystemTime ) 00298 { 00301 if ( m_printUserTime && m_chronoCoutFlag ) 00302 { std::cout << stars << std::endl; } 00303 else if ( m_printUserTime && !m_chronoCoutFlag ) 00304 { log << (MSG::Level) m_chronoPrintLevel << stars << endreq; } 00306 for( MCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter ) 00307 { 00309 ChronoEntity* entity = iter->first ; if( 0 == entity ) { continue ; } 00310 const ChronoTag* tag = iter->second ; if( 0 == tag ) { continue ; } 00311 00312 entity->stop(); 00313 00314 if ( m_chronoCoutFlag ) 00315 { std::cout << *tag << "\t" << entity->outputSystemTime() << std::endl ; } 00316 else 00317 { 00318 MsgStream log( msgSvc() , *tag ) ; 00319 log << m_chronoPrintLevel << entity->outputSystemTime() << endreq ; 00320 } 00321 // 00322 } 00323 } 00325 if( m_printEllapsedTime ) 00326 { 00329 if ( ( m_printUserTime || m_printSystemTime ) && m_chronoCoutFlag ) 00330 { std::cout << stars << std::endl; } 00331 else if ( ( m_printUserTime || m_printSystemTime ) && !m_chronoCoutFlag ) 00332 { log << (MSG::Level) m_chronoPrintLevel << stars << endreq; } 00334 for( MCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter ) 00335 { 00337 ChronoEntity* entity = iter->first ; if( 0 == entity ) { continue ; } 00338 const ChronoTag* tag = iter->second ; if( 0 == tag ) { continue ; } 00339 00340 entity->stop(); 00341 00342 if ( m_chronoCoutFlag ) 00343 { std::cout << *tag << "\t" << entity->outputElapsedTime() << std::endl ; } 00344 else 00345 { 00346 MsgStream log( msgSvc() , *tag ) ; 00347 log << m_chronoPrintLevel << entity->outputElapsedTime() << endreq ; 00348 } 00349 // 00350 } 00351 } 00353 tmpCont.clear(); 00354 } 00356 if( m_chronoCoutFlag ) { std::cout << stars << std::endl; } 00357 else { log << m_chronoPrintLevel << stars << endreq; } 00358 } 00359 00361 00363 if ( m_statTableFlag ) { printStats () ; } 00364 00365 if ( !m_statsOutFileName.value().empty() ) { 00366 saveStats(); 00367 } 00368 00369 log << MSG::INFO << " Service finalized succesfully " << endreq; 00370 00371 return Service::finalize(); 00372 } 00373 // ============================================================================ 00374 // Implementation of IInterface::queryInterface() 00375 // ============================================================================ 00376 StatusCode 00377 ChronoStatSvc::queryInterface 00378 ( const InterfaceID& riid , 00379 void** ppvInterface ) 00380 { 00381 if ( 0 == ppvInterface ) { return StatusCode::FAILURE ; } 00382 else if ( IChronoSvc::interfaceID() == riid ) 00383 { *ppvInterface = static_cast<IChronoSvc*> (this) ; } 00384 else if ( IStatSvc::interfaceID() == riid ) 00385 { *ppvInterface = static_cast<IStatSvc*> (this) ; } 00386 else if ( IChronoStatSvc::interfaceID() == riid ) 00387 { *ppvInterface = static_cast<IChronoStatSvc*> (this) ; } 00388 else { return Service::queryInterface(riid, ppvInterface) ; } 00389 addRef(); 00390 return StatusCode::SUCCESS; 00391 } 00392 // ============================================================================ 00393 // Implementation of IChronoStatSvc::chronoStart 00394 // ============================================================================ 00395 ChronoEntity* 00396 ChronoStatSvc::chronoStart 00397 ( const ChronoTag& chronoTag ) 00398 { 00399 ChronoEntity& entity = m_chronoEntities [ chronoTag ] ; 00400 entity.start() ; 00401 return &entity ; 00402 } 00403 // ============================================================================ 00404 // Implementation of IChronoStatSvc::chronoStop 00405 // ============================================================================ 00406 const ChronoEntity* 00407 ChronoStatSvc::chronoStop 00408 ( const IChronoStatSvc::ChronoTag& chronoTag ) 00409 { 00410 ChronoEntity& entity = m_chronoEntities [ chronoTag ] ; 00411 entity.stop() ; 00412 return &entity ; 00413 } 00414 // ============================================================================ 00415 // Implementation of IChronoStatSvc::chronoDelta 00416 // ============================================================================ 00417 IChronoStatSvc::ChronoTime 00418 ChronoStatSvc::chronoDelta 00419 ( const IChronoStatSvc::ChronoTag& chronoTag, 00420 IChronoStatSvc::ChronoType theType ) 00421 { 00422 return m_chronoEntities[ chronoTag ].delta( theType ); 00423 } 00424 // ============================================================================ 00425 // Implementation of IChronoStatSvc::chronoPrint 00426 // ============================================================================ 00427 void ChronoStatSvc::chronoPrint 00428 ( const IChronoStatSvc::ChronoTag& chronoTag ) 00429 { 00430 MsgStream log ( msgSvc() , chronoTag ); 00431 if( m_printUserTime ) { 00432 log << (MSG::Level) m_chronoPrintLevel 00433 << m_chronoEntities[ chronoTag ].outputUserTime () 00434 << endreq; 00435 } 00436 if( m_printSystemTime ) { 00437 log << (MSG::Level) m_chronoPrintLevel 00438 << m_chronoEntities[ chronoTag ].outputSystemTime() 00439 << endreq; 00440 } 00441 } 00442 // ============================================================================ 00443 // Implementation of IChronoSvc::chronoStatus 00444 // ============================================================================ 00445 IChronoStatSvc::ChronoStatus 00446 ChronoStatSvc::chronoStatus 00447 ( const IChronoStatSvc::ChronoTag& chronoTag ) 00448 { return m_chronoEntities[ chronoTag ].status(); } 00449 // ============================================================================ 00450 // Implementation of IChronoStatSvc::stat 00451 // ============================================================================ 00452 void ChronoStatSvc::stat 00453 ( const IChronoStatSvc::StatTag & statTag , 00454 const IChronoStatSvc::StatFlag & statFlag ) 00455 { 00456 StatMap::iterator theIter=m_statEntities.find(statTag); 00457 00458 StatEntity * theStat=0 ; 00459 // if new entity, specify the neumber of events to be skipped 00460 if (theIter==m_statEntities.end()){ 00461 // new stat entity 00462 StatEntity& theSe = m_statEntities[ statTag ]; 00463 theStat=& theSe; 00464 theStat->setnEntriesBeforeReset(m_numberOfSkippedEventsForMemStat); 00465 } 00466 else 00467 { 00468 //existing stat entity 00469 theStat=&((*theIter).second); 00470 } 00471 00472 theStat->addFlag ( statFlag ) ; 00473 } 00474 // ============================================================================ 00475 // Implementation of IChronoStatSvc::statPrint 00476 // ============================================================================ 00477 void ChronoStatSvc::statPrint 00478 ( const IChronoStatSvc::StatTag& statTag ) 00479 { 00480 MsgStream log ( msgSvc() , statTag ) ; 00481 log << (MSG::Level) m_statPrintLevel << m_statEntities[ statTag ] << endreq; 00482 } 00483 // ============================================================================ 00484 /* extract the chrono entity for the given tag (name) 00485 * @see IChronoStatSvc 00486 * @param t chrono tag(name) 00487 * @return pointer to chrono entity 00488 */ 00489 // ============================================================================ 00490 const ChronoEntity* ChronoStatSvc::chrono 00491 ( const IChronoStatSvc::ChronoTag& t ) const 00492 { 00493 ChronoMap::const_iterator it = m_chronoEntities.find ( t ) ; 00494 if ( m_chronoEntities.end() != it ) { return &(it->second) ; } 00495 return 0 ; 00496 } 00497 // ============================================================================ 00498 /* extract the stat entity for the given tag (name) 00499 * @see IChronoStatSvc 00500 * @param t stat tag(name) 00501 * @return pointer to stat entity 00502 */ 00503 // ============================================================================ 00504 const StatEntity* ChronoStatSvc::stat 00505 ( const IChronoStatSvc::StatTag& t ) const 00506 { 00507 StatMap::const_iterator it = m_statEntities.find ( t ) ; 00508 if ( m_statEntities.end() != it ) { return &(it->second) ; } 00509 return 0 ; 00510 } 00511 // ============================================================================ 00512 // dump all the statistics into an ASCII file 00513 // ============================================================================ 00514 void ChronoStatSvc::saveStats() 00515 { 00516 std::ofstream out( m_statsOutFileName.value().c_str(), 00517 std::ios_base::out | std::ios_base::trunc ); 00518 if ( !out.good() ) { 00519 MsgStream msg( msgSvc() , name() ); 00520 msg << MSG::INFO 00521 << "Could not open the output file for writing chrono statistics [" 00522 << m_statsOutFileName.value() << "]" 00523 << endreq; 00524 return; 00525 } else { 00526 // format it our way 00527 out << std::scientific << std::setprecision(8) ; 00528 } 00529 00530 // ChronoEntity 00531 typedef std::pair<ChronoEntity*, const ChronoTag*> MPair; 00532 typedef std::vector<MPair> MCont; 00533 MCont chronos; 00534 00535 for( ChronoMap::iterator it = m_chronoEntities.begin() ; 00536 m_chronoEntities.end() != it ; ++it ) { 00537 chronos.push_back( MPair( &(it->second) , &(it->first) ) ) ; 00538 } 00539 00540 // sort it 00541 std::sort( chronos.begin() , 00542 chronos.end() , 00543 ComparePairOfChronoEntityAndChronoTag() ); 00544 00545 // print User Time statistics 00546 for( MCont::iterator iter = chronos.begin() ; 00547 chronos.end() != iter; 00548 ++iter ) { 00549 // 00550 const ChronoEntity* entity = iter->first; 00551 if( 0 == entity ) { continue ; } 00552 00553 const ChronoTag* tag = iter->second ; 00554 if( 0 == tag ) { continue ; } 00555 00556 // create an entry in the .INI-like table 00557 out << "\n[" << *tag << "]\n"; 00558 00559 // user 00560 out << "cpu_user_total = " << entity->uTotalTime() << "\n"; 00561 out << "cpu_user_min = " << entity->uMinimalTime() << "\n"; 00562 out << "cpu_user_mean = " << entity->uMeanTime() << "\n"; 00563 out << "cpu_user_RMS = " << entity->uRMSTime() << "\n"; 00564 out << "cpu_user_max = " << entity->uMaximalTime() << "\n"; 00565 out << "cpu_user_nbr = " << entity->nOfMeasurements() << "\n"; 00566 00567 // system 00568 out << "\n"; // just for clarity 00569 out << "cpu_system_total = " << entity->kTotalTime() << "\n"; 00570 out << "cpu_system_min = " << entity->kMinimalTime() << "\n"; 00571 out << "cpu_system_mean = " << entity->kMeanTime() << "\n"; 00572 out << "cpu_system_RMS = " << entity->kRMSTime() << "\n"; 00573 out << "cpu_system_max = " << entity->kMaximalTime() << "\n"; 00574 out << "cpu_system_nbr = " << entity->nOfMeasurements() << "\n"; 00575 00576 // real 00577 out << "\n"; // just for clarity 00578 out << "cpu_real_total = " << entity->eTotalTime() << "\n"; 00579 out << "cpu_real_min = " << entity->eMinimalTime() << "\n"; 00580 out << "cpu_real_mean = " << entity->eMeanTime() << "\n"; 00581 out << "cpu_real_RMS = " << entity->eRMSTime() << "\n"; 00582 out << "cpu_real_max = " << entity->eMaximalTime() << "\n"; 00583 out << "cpu_real_nbr = " << entity->nOfMeasurements() << "\n"; 00584 00585 } 00586 00587 out << std::endl; 00588 } 00589 // ============================================================================ 00590 // print the "Stat" part of the ChronoStatSvc 00591 // ============================================================================ 00592 void ChronoStatSvc::printStats() 00593 { 00595 if ( m_statEntities.empty() ) { return ; } 00596 00597 MsgStream log ( msgSvc() , "******Stat******" ) ; 00599 const std::string stars( ( m_statCoutFlag ) ? 126 : 100 , '*' ) ; 00601 if ( m_statCoutFlag ) 00602 { 00603 std::cout << stars << std::endl; 00604 std::cout << " The Final stat Table " 00605 << ( m_statOrderFlag ? "(ordered)" : "(not ordered)" ) << std::endl; 00606 std::cout << stars << std::endl; 00607 } 00608 else 00609 { 00610 log << m_statPrintLevel << stars << endreq; 00611 log << m_statPrintLevel << " The Final stat Table " 00612 << ( m_statOrderFlag ? "(ordered)" : "(not ordered)" ) << endreq; 00613 log << m_statPrintLevel << stars << endreq; 00614 } 00615 00616 { 00617 // prepare container for printing 00618 typedef std::pair<const StatEntity*,const StatTag*> SPair; 00619 typedef std::vector<SPair> SCont; 00620 SCont tmpCont; 00621 for( StatMap::const_iterator it = m_statEntities.begin(); 00622 it != m_statEntities.end(); it++ ) 00623 { tmpCont.push_back( SPair( &(it->second) , &(it->first) ) ) ; } 00624 // sort it 00625 if ( m_statOrderFlag ) 00626 { std::sort( tmpCont.begin() , 00627 tmpCont.end() , 00628 ComparePairOfStatEntityAndStatTag() ); } 00629 00630 00631 { 00632 // print the table header 00633 if ( m_statCoutFlag ) { std::cout << m_header << std::endl ; } 00634 else { log << m_statPrintLevel << m_header << endreq ; } 00635 } 00636 // loop over counters and print them: 00637 for ( SCont::iterator iter = tmpCont.begin() ; tmpCont.end() != iter ; ++iter ) 00638 { 00640 const StatEntity* entity = iter->first ; 00641 if ( 0 == entity ) { continue ; } 00642 const StatTag* tag = iter->second ; 00643 if ( 0 == tag ) { continue ; } 00644 00645 if ( m_statCoutFlag ) 00646 { 00647 std::cout 00648 << Gaudi::Utils::formatAsTableRow 00649 ( *tag , *entity , m_useEffFormat , m_format1 , m_format2 ) 00650 << std::endl; 00651 } 00652 else 00653 { 00654 log 00655 << m_statPrintLevel 00656 << Gaudi::Utils::formatAsTableRow 00657 ( *tag , *entity , m_useEffFormat , m_format1 , m_format2 ) 00658 << endreq ; 00659 } 00660 } 00661 tmpCont.clear(); 00662 } 00664 if ( m_statCoutFlag ) { std::cout << stars << std::endl; } 00665 else { log << m_statPrintLevel << stars << endreq; } 00666 } 00667 00668 // ============================================================================ 00669 // The END 00670 // ============================================================================