| # Gaudi Framework, version v21r6 |

Home |  | Generated: 11 Nov 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: 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 StatusCode CounterSvc::create
    00264 ( const std::string& grp ,
    00265   const std::string& nam ,
    00266   longlong initial_value ,
    00267   Counter*& refpCounter  )
    00268 {
    00269   // try to find existing counter:
    00270   refpCounter = get ( grp , nam ) ;
    00271   if ( 0 != refpCounter ) { return COUNTER_EXISTS ; }                // RETURN
    00272   // create the new counter
    00273   Counter* newc = new Counter() ;
    00274   refpCounter = newc ;
    00275   if ( 0 != initial_value ) {
    00276         refpCounter->addFlag ( static_cast<double>(initial_value) ) ;
    00277   }
    00278   // find a proper group
    00279   CountMap::iterator i = m_counts.find  ( grp ) ;
    00280   // (create a group if needed)
    00281   if (  m_counts.end() == i )
    00282   { i = m_counts.insert ( std::make_pair ( grp , NameMap() ) ).first ; }
    00283   // insert new counter with proper name into proper group:
    00284   i->second.insert( std::make_pair( nam , newc ) ).first ;
    00285   return StatusCode::SUCCESS ;                                     // RETURN
    00286 }
    00287 // ===========================================================================
    00288 // Create a new counter object. If the counter object exists already,
    00289 // ===========================================================================
    00290 CounterSvc::CountObject CounterSvc::create
    00291 ( const std::string& group ,
    00292   const std::string& name  ,
    00293   longlong initial_value   )
    00294 {
    00295   Counter* p = 0;
    00296   StatusCode sc = create ( group, name, initial_value, p ) ;
    00297   if ( sc.isSuccess() && 0 != p ) { return CountObject ( p , group , name ) ; }
    00298   throw std::runtime_error("CounterSvc::Counter('"+group+"::"+name+"') exists already!");
    00299 }
    00300 // ===========================================================================
    00301 // Remove a counter object. The tuple (group,name) identifies the counter uniquely
    00302 // ===========================================================================
    00303 StatusCode CounterSvc::remove
    00304 ( const std::string& grp ,
    00305   const std::string& nam )
    00306 {
    00307   CountMap::iterator i = m_counts.find  ( grp ) ;
    00308   if (  m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }  // RETURN
    00309   NameMap::iterator  j = i->second.find ( nam ) ;
    00310   if ( i->second.end() == j ) { return COUNTER_NOT_PRESENT ; }  // RETURN
    00311   delete j->second ;
    00312   i->second.erase ( j ) ;
    00313   return StatusCode::SUCCESS ;
    00314 }
    00315 // ===========================================================================
    00316 // Remove a group of counter objects.
    00317 // ===========================================================================
    00318 StatusCode CounterSvc::remove ( const std::string& grp )
    00319 {
    00320   CountMap::iterator i = m_counts.find ( grp  ) ;
    00321   if (  m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }  // RETURN
    00322   for ( NameMap::iterator j = i->second.begin() ; i->second.end() != j ; ++j )
    00323   { delete j->second ; }
    00324   i->second.clear() ;
    00325   return StatusCode::SUCCESS ;
    00326 }
    00327 // ===========================================================================
    00328 // Remove all known counter objects
    00329 // ===========================================================================
    00330 StatusCode CounterSvc::remove()
    00331 {
    00332   // remove group by group
    00333   for ( CountMap::iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
    00334   { remove ( i->first ).ignore () ; }
    00335   m_counts.clear() ;
    00336   return StatusCode::SUCCESS;
    00337 }
    00338 // ===========================================================================
    00339 // Print counter value
    00340 // ===========================================================================
    00341 StatusCode CounterSvc::print
    00342 ( const std::string& grp,
    00343   const std::string& nam,
    00344   Printout& printer) const
    00345 {
    00346   const Counter* c = get( grp , nam ) ;
    00347   if ( 0 == c ) { return COUNTER_NOT_PRESENT ; }                  // RETURN
    00348   // create the stream and use it!
    00349   MsgStream log ( msgSvc() , name() ) ;
    00350   return printer ( log , c ) ;
    00351 }
    00352
    00353 namespace {
    00355   class conditionalPrint {
    00356   private:
    00357     CounterSvc::Printout *printer;
    00358     MsgStream *log;
    00359   public:
    00360     conditionalPrint(CounterSvc::Printout &_p, MsgStream &_l): printer(&_p), log(&_l) {}
    00361     template<class Pair>
    00362     void operator() (const Pair &p) {
    00363       if (p.second) {
    00364         (*printer)(*log, p.second).ignore();
    00365       }
    00366     }
    00367   };
    00368 }
    00369 // ===========================================================================
    00370 // Print the counter value for the whole group of counters
    00371 // ===========================================================================
    00372 StatusCode CounterSvc::print
    00373 ( const std::string& grp ,
    00374   Printout& printer      ) const
    00375 {
    00376   CountMap::const_iterator i = m_counts.find ( grp ) ;
    00377   if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
    00378
    00379   MsgStream log(msgSvc(), name());
    00380   // Force printing in alphabetical order
    00381   typedef std::map<std::string, Counter*> sorted_map_t;
    00382   sorted_map_t sorted_map(i->second.begin(), i->second.end());
    00383   std::for_each(sorted_map.begin(), sorted_map.end(),
    00384                 conditionalPrint(printer, log));
    00385   return StatusCode::SUCCESS;   // RETURN
    00386 }
    00387 // ===========================================================================
    00388 // Print counter value
    00389 // ===========================================================================
    00390 StatusCode CounterSvc::print
    00391 ( const Counter* pCounter,
    00392   Printout& printer ) const
    00393 {
    00394   MsgStream log(msgSvc(), name() ) ;
    00395   return printer ( log , pCounter ) ;
    00396 }
    00397 // ===========================================================================
    00398 // Print counter value
    00399 // ===========================================================================
    00400 StatusCode CounterSvc::print
    00401 ( const CountObject& refCounter,
    00402   Printout& printer) const
    00403 { return print( refCounter.counter() , printer ) ; }
    00404 // ===========================================================================
    00405 // Print all known counters
    00406 // ===========================================================================
    00407 StatusCode CounterSvc::print( Printout& printer ) const
    00408 {
    00409   MsgStream log ( msgSvc() , name() ) ;
    00410   // Force printing in alphabetical order
    00411   typedef std::map<std::pair<std::string,std::string>, Counter*> sorted_map_t;
    00412   sorted_map_t sorted_map;
    00413   for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
    00414   {
    00415     for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
    00416     {
    00417       sorted_map[std::make_pair(i->first, j->first)] = j->second;
    00418     }
    00419   }
    00420   std::for_each(sorted_map.begin(), sorted_map.end(),
    00421                 conditionalPrint(printer, log));
    00422   return StatusCode::SUCCESS;
    00423 }
    00424 // ===========================================================================
    00425 // Print counter value
    00426 // ===========================================================================
    00427 StatusCode CounterSvc::defaultPrintout
    00428 ( MsgStream& log,
    00429   const Counter* c ) const
    00430 {
    00431   if ( 0 == c ) { return StatusCode::FAILURE ; }
    00432   std::pair<std::string,std::string> p = _find ( c ) ;
    00433
    00434   log << MSG::ALWAYS
    00435       << CountObject( const_cast<Counter*>(c) , p.first , p.second )
    00436       << endmsg ;
    00437
    00438   return StatusCode::SUCCESS;
    00439 }
    00440 // ===========================================================================
    00441 // "standard" printout a'la GaudiCommon
    00442 // ===========================================================================
    00443 void CounterSvc::print () const
    00444 {
    00445   MsgStream log ( msgSvc() , name() ) ;
    00446   // number of counters
    00447   const size_t _num = num() ;
    00448   if ( 0 != _num )
    00449   {
    00450     log << MSG::ALWAYS
    00451         << "Number of counters : "  << _num << endmsg
    00452         << m_header << endmsg ;
    00453   }
    00454   {
    00455     // Force printing in alphabetical order
    00456     typedef std::map<std::pair<std::string,std::string>, Counter*> sorted_map_t;
    00457     sorted_map_t sorted_map;
    00458     for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
    00459     {
    00460       for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
    00461       {
    00462         Counter* c = j->second ;
    00463         if ( 0 == c ) { continue ; }
    00464         sorted_map[std::make_pair(i->first, j->first)] = c;
    00465       }
    00466     }
    00467     for (sorted_map_t::const_iterator i = sorted_map.begin(); i != sorted_map.end(); ++i )
    00468       log << Gaudi::Utils::formatAsTableRow( i->first.second
    00469                                            , i->first.first
    00470                                            , *i->second
    00471                                            , m_useEffFormat
    00472                                            , m_format1
    00473                                            , m_format2 )
    00474           << endmsg ;
    00475   }
    00476 }
    00477 // ============================================================================
    00478
    00479 // ============================================================================
    00480 // The END
    00481 // ============================================================================