Gaudi Framework, version v22r1

Home   Generated: Mon Feb 28 2011

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: 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     // the header row
00037     , m_header  ( "       Counter :: Group         |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |")
00038     // format for regular statistical printout rows
00039     , m_format1 ( " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |"         )
00040     // format for "efficiency" statistical printout rows
00041     , m_format2 ( "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%|   -------   |   -------   |" )
00042     // flag to use the special "efficiency" format
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     // finalize the base class
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   // find group/name for the counter:
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   // get the overall number of counters
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   // the actual map of counters
00219   CountMap m_counts ; 
00220   // boolean flag to print statistics
00221   bool     m_print  ; 
00222   // the header row
00223   std::string    m_header  ; 
00224   // format for regular statistical printout rows
00225   std::string    m_format1 ; 
00226   // format for "efficiency" statistical printout rows
00227   std::string    m_format2 ; 
00228   // flag to use the special "efficiency" format
00229   bool           m_useEffFormat ; 
00230 } ;
00231 // ===========================================================================
00232 // Instantiation of a static factory class used by clients
00233 // ===========================================================================
00234 DECLARE_SERVICE_FACTORY(CounterSvc)
00235 // ===========================================================================
00236 // Access a counter object by name and group
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 ; }                    // RETURN
00244   NameMap::const_iterator  j = i->second.find ( nam ) ;
00245   if ( i->second.end() == j ) { return 0 ; }                    // RETURN
00246   return j->second ;                                            // RETURN
00247 }
00248 // ===========================================================================
00249 // get all counters form the given group:
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 ; } // RETURN
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 // Create/get a counter object.
00262 // ===========================================================================
00263 #ifdef __ICC
00264 // disable icc remark #2259: non-pointer conversion from "longlong={long long}" to "double" may lose significant bits
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   // try to find existing counter:
00275   refpCounter = get ( grp , nam ) ;
00276   if ( 0 != refpCounter ) { return COUNTER_EXISTS ; }                // RETURN
00277   // create the new counter
00278   Counter* newc = new Counter() ;
00279   refpCounter = newc ;
00280   if ( 0 != initial_value ) {
00281     refpCounter->addFlag ( static_cast<double>(initial_value) ) ; // icc remark #2259
00282   }
00283   // find a proper group
00284   CountMap::iterator i = m_counts.find  ( grp ) ;
00285   // (create a group if needed)
00286   if (  m_counts.end() == i )
00287   { i = m_counts.insert ( std::make_pair ( grp , NameMap() ) ).first ; }
00288   // insert new counter with proper name into proper group:
00289   i->second.insert( std::make_pair( nam , newc ) ).first ;
00290   return StatusCode::SUCCESS ;                                     // RETURN
00291 }
00292 #ifdef __ICC
00293 // re-enable icc remark #2259
00294 #pragma warning(pop)
00295 #endif
00296 // ===========================================================================
00297 // Create a new counter object. If the counter object exists already,
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 // Remove a counter object. The tuple (group,name) identifies the counter uniquely
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 ; }  // RETURN
00318   NameMap::iterator  j = i->second.find ( nam ) ;
00319   if ( i->second.end() == j ) { return COUNTER_NOT_PRESENT ; }  // RETURN
00320   delete j->second ;
00321   i->second.erase ( j ) ;
00322   return StatusCode::SUCCESS ;
00323 }
00324 // ===========================================================================
00325 // Remove a group of counter objects.
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 ; }  // RETURN
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 // Remove all known counter objects
00338 // ===========================================================================
00339 StatusCode CounterSvc::remove()
00340 {
00341   // remove group by group
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 // Print counter value
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 ; }                  // RETURN
00357   // create the stream and use it!
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 // Print the counter value for the whole group of counters
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   // Force printing in alphabetical order
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;   // RETURN
00395 }
00396 // ===========================================================================
00397 // Print counter value
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 // Print counter value
00408 // ===========================================================================
00409 StatusCode CounterSvc::print
00410 ( const CountObject& refCounter,
00411   Printout& printer) const
00412 { return print( refCounter.counter() , printer ) ; }
00413 // ===========================================================================
00414 // Print all known counters
00415 // ===========================================================================
00416 StatusCode CounterSvc::print( Printout& printer ) const
00417 {
00418   MsgStream log ( msgSvc() , name() ) ;
00419   // Force printing in alphabetical order
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 // Print counter value
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 // "standard" printout a'la GaudiCommon
00451 // ===========================================================================
00452 void CounterSvc::print () const
00453 {
00454   MsgStream log ( msgSvc() , name() ) ;
00455   // number of counters
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     // Force printing in alphabetical order
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 // The END
00490 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Feb 28 2011 18:27:18 for Gaudi Framework, version v22r1 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004