Gaudi Framework, version v20r4

Generated: 8 Jan 2009

CounterSvc.cpp

Go to the documentation of this file.
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 // ============================================================================

Generated at Thu Jan 8 17:44:23 2009 for Gaudi Framework, version v20r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004