Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

DataOnDemandSvc.cpp

Go to the documentation of this file.
00001 // $Id: DataOnDemandSvc.cpp,v 1.16 2008/10/01 14:33:07 marcocle Exp $
00002 // ============================================================================
00003 // CVS tag $Name:  $
00004 // ============================================================================
00005 // Incldue files
00006 // ============================================================================
00007 // STD & STL
00008 // ============================================================================
00009 #include <string>
00010 #include <set>
00011 #include <map>
00012 #include <math.h>
00013 // ============================================================================
00014 // GaudiKernel
00015 // ============================================================================
00016 #include "GaudiKernel/MsgStream.h"
00017 #include "GaudiKernel/Tokenizer.h"
00018 #include "GaudiKernel/DataObject.h"
00019 #include "GaudiKernel/IAlgorithm.h"
00020 #include "GaudiKernel/ISvcLocator.h"
00021 #include "GaudiKernel/IAlgManager.h"
00022 #include "GaudiKernel/IIncidentSvc.h"
00023 #include "GaudiKernel/DataIncident.h"
00024 #include "GaudiKernel/IDataProviderSvc.h"
00025 #include "GaudiKernel/TypeNameString.h"
00026 #include "GaudiKernel/ToStream.h"
00027 #include "GaudiKernel/Chrono.h"
00028 #include "GaudiKernel/LockedChrono.h"
00029 // ============================================================================
00030 // Local
00031 // ============================================================================
00032 #include "DataOnDemandSvc.h"
00033 // ============================================================================
00034 // Boost
00035 // ============================================================================
00036 #ifdef __ICC
00037 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
00038 //   TODO: To be removed, since it comes from Boost
00039 #pragma warning(disable:2259)
00040 #endif
00041 #include "boost/format.hpp"
00042 #include "boost/lexical_cast.hpp"
00043 // ============================================================================
00044 // Constructors and Destructor
00045 // ============================================================================
00046 DataOnDemandSvc::DataOnDemandSvc
00047 ( const std::string& name, ISvcLocator* svc )
00048   : base_class(name, svc)
00049   , m_incSvc   ( 0 )
00050   , m_algMgr   ( 0 )
00051   , m_dataSvc  ( 0 )
00052   //
00053   , m_trapType    ( "DataFault")
00054   , m_dataSvcName ( "EventDataSvc" )
00055   , m_partialPath ( true  )
00056   , m_dump        ( false )
00057   , m_init        ( false )
00058   , m_allowInitFailure(false)
00059   //
00060   , m_algMapping  ()
00061   , m_nodeMapping ()
00062   //
00063   , m_algMap   (   )
00064   , m_nodeMap  (   )
00065   //
00066   , m_updateRequired ( true )
00067   , m_prefix         ( "/Event/" )
00068   , m_log      ( 0 )
00069   , m_total    (   )
00070   , m_statAlg  ( 0 )
00071   , m_statNode ( 0 )
00072   , m_stat     ( 0 )
00073   //
00074   , m_timer_nodes  ()
00075   , m_timer_algs   ()
00076   , m_timer_all    ()
00077   , m_locked_nodes ( false )
00078   , m_locked_algs  ( false )
00079   , m_locked_all   ( false )
00080   //
00081 {
00082   // ==========================================================================
00083   declareProperty
00084     ( "IncidentName"       ,
00085       m_trapType           ,
00086       "The type of handled Incident" ) ;
00087   //
00088   declareProperty ( "DataSvc"            , m_dataSvcName ) ;
00089   //
00090   declareProperty ( "UsePreceedingPath"  , m_partialPath ) ;
00091   declareProperty
00092     ( "Dump"        ,
00093       m_dump        ,
00094       "Dump the configuration and stastics" )  ->
00095     declareUpdateHandler ( &DataOnDemandSvc::update_dump , this ) ;
00096   //
00097   declareProperty
00098     ( "PreInitialize" ,
00099       m_init          ,
00100       "Flag to (pre)initialize all algorithms" ) ;
00101   declareProperty
00102     ( "AllowPreInitializeFailure" ,
00103       m_allowInitFailure          ,
00104       "Allow (pre)initialization of algorithms to fail without stopping the application" ) ;
00105   //
00106   declareProperty ( "Algorithms"         , m_algMapping  )  ->
00107     declareUpdateHandler ( &DataOnDemandSvc::update_2 , this ) ;
00108   declareProperty ( "Nodes"              , m_nodeMapping ) ->
00109     declareUpdateHandler ( &DataOnDemandSvc::update_3 , this ) ;
00110   //
00111   declareProperty ( "AlgMap"  , m_algMap  ) ->
00112     declareUpdateHandler ( &DataOnDemandSvc::update_1 , this ) ;
00113   declareProperty ( "NodeMap" , m_nodeMap ) ->
00114     declareUpdateHandler ( &DataOnDemandSvc::update_1 , this ) ;
00115   //
00116   declareProperty ( "Prefix"             , m_prefix      ) ;
00117   // ==========================================================================
00118 }
00119 // ============================================================================
00120 // Update handler
00121 // ============================================================================
00122 void DataOnDemandSvc::update_1 ( Property& p )
00123 {
00124   stream() << MSG::VERBOSE << " I am update handler for property " << p << endmsg ;
00125   // force update
00126   m_updateRequired = true ;
00127 }
00128 // ============================================================================
00129 // Update handler
00130 // ============================================================================
00131 void DataOnDemandSvc::update_3 ( Property& /* p */ )
00132 {
00133   stream() << MSG::WARNING
00134            << "The property 'Nodes'      is obsolete, switch to map-like 'NodeMap' "
00135            << " = { 'data' : 'type'      } "
00136            << endmsg ;
00137   // force update
00138   m_updateRequired = true ;
00139 }
00140 // ============================================================================
00141 // Update handler
00142 // ============================================================================
00143 void DataOnDemandSvc::update_2 ( Property& /* p */ )
00144 {
00145   stream() << MSG::WARNING
00146            << "The property 'Algorithms' is obsolete, switch to map-like 'AlgMap'  "
00147            << " = { 'data' : 'algorithm' } "
00148            << endmsg ;
00149   // force update
00150   m_updateRequired = true ;
00151 }
00152 // ============================================================================
00153 // Update handler
00154 // ============================================================================
00155 void DataOnDemandSvc::update_dump ( Property& /* p */ )
00156 {
00157   // no action if not yet initialized
00158   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
00159   // dump the configuration:
00160   if ( m_dump ) { dump ( MSG::ALWAYS ) ; }
00161 }
00162 // ============================================================================
00163 // anonymous namespace to hide few local functions
00164 // ============================================================================
00165 namespace
00166 {
00167   // ==========================================================================
00173   inline std::string no_prefix
00174   ( const std::string& value  ,
00175     const std::string& prefix )
00176   {
00177     return
00178       !prefix.empty() && 0 == value.find(prefix) ?
00179       std::string( value , prefix.size() ) : value ;
00180   }
00181   // ==========================================================================
00188   template <class MAP>
00189   inline size_t add_prefix ( MAP& _map , const std::string& prefix )
00190   {
00191     // empty  prefix
00192     if ( prefix.empty() ) { return 0 ; }                    // RETURN
00194     for ( typename MAP::iterator it = _map.begin() ; _map.end() != it ; ++it )
00195     {
00196       if ( 0 != it->first.find(prefix) )  // valid prefix?
00197       {
00198         std::string key   = prefix + it->first ;
00199         std::string value = it->second ;
00200         _map.erase ( it ) ;
00201         _map[ key ] = value  ;
00202         return 1 + add_prefix ( _map , prefix ) ;    // RETURN, recursion
00203       }
00204     }
00205     //
00206     return 0 ;
00207   }
00208   // ==========================================================================
00214   template <class SET>
00215   inline size_t get_dir ( const std::string& object , SET& _set )
00216   {
00217     std::string::size_type ifind = object.rfind('/') ;
00218     // stop recursion
00219     if ( std::string::npos == ifind ) { return 0 ; } // RETURN
00220     if ( 0 == ifind                 ) { return 0 ; }
00221     //
00222     const std::string top = std::string( object , 0 , ifind) ;
00223     _set.insert( top ) ;
00224     return 1 + get_dir ( top , _set ) ;   // RETURN, recursion
00225   }
00226   // ==========================================================================
00232   template <class MAP, class SET>
00233   inline size_t get_dirs ( const MAP& _map, SET& _set )
00234   {
00235     size_t size = _set.size() ;
00236     for ( typename MAP::const_iterator item = _map.begin() ;
00237           _map.end() != item ; ++item ) {  get_dir ( item->first , _set ) ; }
00238     return _set.size() - size ;
00239   }
00240   // ==========================================================================
00241 } // end of anonymous namespace
00242 // ============================================================================
00243 // update the content of Data-On-Demand actions
00244 // ============================================================================
00245 StatusCode DataOnDemandSvc::update ()
00246 {
00247   if ( !m_updateRequired ) { return StatusCode::SUCCESS  ; }
00248 
00250   StatusCode sc = setupNodeHandlers() ; // convert "Nodes"      new "NodeMap"
00251   if ( sc.isFailure() )
00252   {
00253     stream() << MSG::ERROR << "Failed to setup old \"Nodes\""      << endmsg ;
00254     return sc ;
00255   }
00257   sc = setupAlgHandlers()   ; // convert "Algorithms" into "AlgMap"
00258   if ( sc.isFailure() )
00259   {
00260     stream() << MSG::ERROR << "Failed to setup old \"Algorithms\"" << endmsg ;
00261     return sc ;
00262   }
00264   add_prefix ( m_algMap  , m_prefix ) ;
00266   add_prefix ( m_nodeMap , m_prefix ) ;
00268   typedef std::set<std::string> Set ;
00269   Set dirs ;
00270   if ( m_partialPath ){ get_dirs ( m_algMap  , dirs ) ; }
00271   if ( m_partialPath ){ get_dirs ( m_nodeMap , dirs ) ; }
00272   //
00273   Set::iterator _e = dirs.find("/Event") ;
00274   if ( dirs.end() != _e ) { dirs.erase( _e ) ; }
00275   // add all directories as nodes
00276   for ( Set::const_iterator dir = dirs.begin() ; dirs.end() != dir ; ++dir )
00277   {
00278     if ( m_algMap  .end () != m_algMap  .find ( *dir ) ) { continue ; }
00279     if ( m_nodeMap .end () != m_nodeMap .find ( *dir ) ) { continue ; }
00280     m_nodeMap [*dir] = "DataObject" ;
00281   }
00282   //
00283   m_algs  .clear  () ;
00284   m_nodes .clear  () ;
00285   //
00287   for ( Map::const_iterator ialg = m_algMap.begin() ;
00288         m_algMap.end() != ialg ; ++ialg )
00289   {
00290     Gaudi::Utils::TypeNameString alg ( ialg->second ) ;
00291     Leaf leaf ( alg.type() , alg.name() ) ;
00292     if  ( m_init )
00293     {
00294       sc = configureHandler(leaf);
00295       if (sc.isFailure()) {
00296         if (m_allowInitFailure) {
00297           // re-store the content of the leaf object to try again to initialize
00298           // the algorithm later (on demand)
00299           leaf = Leaf(alg.type(), alg.name());
00300         }
00301         else
00302           return sc;
00303       }
00304     }
00305     m_algs[ialg->first] =  leaf ;
00306   }
00308   for ( Map::const_iterator inode = m_nodeMap.begin() ;
00309         m_nodeMap.end() != inode ; ++inode )
00310   {
00311     ClassH cl = ROOT::Reflex::Type::ByName( inode->second ) ;
00312     if ( !cl )
00313     {
00314       stream() << MSG::WARNING
00315                << "Failed to access dictionary class for "
00316                << inode->first << " of type:" << inode->second << endmsg;
00317     }
00318     m_nodes[inode->first] = Node ( cl , false , inode->second ) ;
00319   }
00321   m_updateRequired = false ;
00322   //
00323   return StatusCode::SUCCESS ;
00324 }
00325 // ============================================================================
00326 // destructor
00327 // ============================================================================
00328 DataOnDemandSvc::~DataOnDemandSvc()
00329 { if ( 0 != m_log      ) { delete m_log      ; m_log      = 0 ; } }
00330 //=============================================================================
00331 // Inherited Service overrides:
00332 //=============================================================================
00333 StatusCode DataOnDemandSvc::initialize()
00334 {
00335   // initialize the Service Base class
00336   StatusCode sc = Service::initialize();
00337   if ( sc.isFailure() )  { return sc; }
00338   sc = setup();
00339   if ( sc.isFailure() )  { return sc; }
00340   //
00341   if      ( m_dump )                      { dump ( MSG::INFO  ) ; }
00342   else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00343   //
00344   if ( m_init ) { return update () ; }
00345   //
00346   return StatusCode::SUCCESS ;
00347 }
00348 // ============================================================================
00349 // finalization of the service
00350 // ============================================================================
00351 StatusCode DataOnDemandSvc::finalize()
00352 {
00353   //
00354   stream ()
00355     << MSG::INFO
00356     << "Handled \"" << m_trapType << "\" incidents: "
00357     << m_statAlg  << "/" << m_statNode << "/" << m_stat << "(Alg/Node/Total)."
00358     << endmsg ;
00359   if ( m_dump || MSG::DEBUG >= outputLevel() )
00360   {
00361     stream ()
00362       << MSG::INFO
00363       << m_total.outputUserTime
00364       ( "Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00365       << m_total.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00366     stream ()
00367       << MSG::INFO
00368       << m_timer_nodes.outputUserTime
00369       ( "Nodes     timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00370       << m_timer_nodes.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00371     stream ()
00372       << MSG::INFO
00373       << m_timer_algs .outputUserTime
00374       ( "Algs      timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00375       << m_timer_algs .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00376     stream ()
00377       << MSG::INFO
00378       << m_timer_all  .outputUserTime
00379       ( "All       timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00380       << m_timer_all  .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00381   }
00382   // dump it!
00383   if      ( m_dump )                      { dump ( MSG::INFO  , false ) ; }
00384   else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG , false ) ; }
00385   //
00386   if ( m_incSvc )
00387   {
00388     m_incSvc->removeListener(this, m_trapType);
00389     m_incSvc->release();
00390     m_incSvc = 0;
00391   }
00392   if ( 0 != m_algMgr  ) { m_algMgr   -> release () ; m_algMgr  = 0 ; }
00393   if ( 0 != m_dataSvc ) { m_dataSvc  -> release () ; m_dataSvc = 0 ; }
00394   //
00395   return Service::finalize();
00396 }
00397 // ============================================================================
00399 // ============================================================================
00400 StatusCode DataOnDemandSvc::reinitialize()
00401 {
00402   // reinitialize the Service Base class
00403   if ( 0 != m_incSvc )
00404   {
00405     m_incSvc -> removeListener ( this , m_trapType );
00406     m_incSvc -> release ();
00407     m_incSvc = 0;
00408   }
00409   if ( 0 != m_algMgr  ) { m_algMgr   -> release() ; m_algMgr  = 0 ; }
00410   if ( 0 != m_dataSvc ) { m_dataSvc  -> release() ; m_dataSvc = 0 ; }
00411   if ( 0 != m_log     ) { delete m_log ; m_log = 0 ; }
00412   //
00413   StatusCode sc = Service::reinitialize();
00414   if ( sc.isFailure() )  { return sc; }
00415   //
00416   sc = setup() ;
00417   if ( sc.isFailure() )  { return sc; }
00418   //
00419   if ( m_dump ) { dump ( MSG::INFO ) ; }
00420   else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG  ) ; }
00421   //
00422   return StatusCode::SUCCESS ;
00423 }
00424 // ============================================================================
00425 // setup service
00426 // ============================================================================
00427 StatusCode DataOnDemandSvc::setup()
00428 {
00429   m_algMgr = 0;
00430   StatusCode sc =
00431     serviceLocator()->queryInterface(IAlgManager::interfaceID(), pp_cast<void>(&m_algMgr));
00432   if ( sc.isFailure () )
00433   {
00434     stream()
00435       << MSG::ERROR
00436       << "Failed to retrieve the IAlgManager interface." << endmsg;
00437     return sc;
00438   }
00439   sc = service("IncidentSvc", m_incSvc, true);
00440   if ( sc.isFailure () )
00441   {
00442     stream()
00443       << MSG::ERROR << "Failed to retrieve Incident service." << endmsg;
00444     return sc;
00445   }
00446   m_incSvc->addListener(this, m_trapType);
00447   sc = service(m_dataSvcName, m_dataSvc, true);
00448   if ( sc.isFailure () )
00449   {
00450     stream()
00451       << MSG::ERROR
00452       << "Failed to retrieve the data provider interface of "
00453       << m_dataSvcName << endmsg;
00454     return sc;
00455   }
00456   return update() ;
00457 }
00458 // ============================================================================
00459 // setup node handlers
00460 // ============================================================================
00461 StatusCode DataOnDemandSvc::setupNodeHandlers()
00462 {
00463   Setup::const_iterator j;
00464   std::string nam, typ, tag;
00465   StatusCode sc = StatusCode::SUCCESS;
00466   // Setup for node leafs, where simply a constructor is called...
00467   for ( j=m_nodeMapping.begin(); j != m_nodeMapping.end(); ++j)
00468   {
00469     Tokenizer tok(true);
00470     tok.analyse(*j, " ", "", "", "=", "'", "'");
00471     for ( Tokenizer::Items::iterator i = tok.items().begin();
00472           i != tok.items().end(); i++ )   {
00473       const std::string& t = (*i).tag();
00474       const std::string& v = (*i).value();
00475       switch( ::toupper(t[0]) )    {
00476       case 'D':
00477         tag = v;
00478         break;
00479       case 'T':
00480         nam = v;
00481         break;
00482       }
00483     }
00484     if ( m_algMap  .end () != m_algMap  .find ( tag ) ||
00485          m_nodeMap .end () != m_nodeMap .find ( tag ) )
00486     {
00487       stream()
00488         << MSG::WARNING
00489         << "The obsolete property 'Nodes' redefines the action for '"
00490         + tag + "' to be '" +nam+"'"
00491         << endmsg ;
00492     }
00493     m_nodeMap[tag] = nam ;
00494   }
00495   //
00496   m_updateRequired = true ;
00497   //
00498   return sc;
00499 }
00500 // ============================================================================
00501 // setup algorithm  handlers
00502 // ============================================================================
00503 StatusCode DataOnDemandSvc::setupAlgHandlers()
00504 {
00505   Setup::const_iterator j;
00506   std::string typ, tag;
00507 
00508   for(j=m_algMapping.begin(); j != m_algMapping.end(); ++j)
00509   {
00510     Tokenizer tok(true);
00511     tok.analyse(*j, " ", "", "", "=", "'", "'");
00512     for(Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++ )   {
00513       const std::string& t = (*i).tag();
00514       const std::string& v = (*i).value();
00515       switch( ::toupper(t[0]) )    {
00516       case 'D':
00517         tag = v;
00518         break;
00519       case 'T':
00520         typ = v;
00521         break;
00522       }
00523     }
00524     Gaudi::Utils::TypeNameString item(typ);
00525     if ( m_algMap  .end () != m_algMap  .find ( tag ) ||
00526          m_nodeMap .end () != m_nodeMap .find ( tag ) )
00527     {
00528       stream()
00529         << MSG::WARNING
00530         << "The obsolete property 'Algorithms' redefines the action for '"
00531         + tag + "' to be '" +item.type() +"/"+item.name()+"'"
00532         << endmsg ;
00533     }
00534     m_algMap[tag] = item.type() + "/" + item.name() ;
00535   }
00536   m_updateRequired = true ;
00537   return StatusCode::SUCCESS;
00538 }
00539 // ============================================================================
00541 // ============================================================================
00542 StatusCode DataOnDemandSvc::configureHandler(Leaf& l)
00543 {
00544   if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00545   if ( 0 == m_algMgr  ) { return StatusCode::FAILURE ; }
00546   l.algorithm = m_algMgr->algorithm(l.name, false);
00547   if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00548   // create it!
00549   StatusCode sc = m_algMgr->createAlgorithm ( l.type , l.name , l.algorithm , true ) ;
00550   if ( sc.isFailure() )
00551   {
00552     stream()
00553       << MSG::ERROR
00554       << "Failed to create algorithm "
00555       << l.type << "('" << l.name<< "')" << endmsg;
00556     l.algorithm = 0 ;
00557     return sc ;                                                    // RETURN
00558   }
00559   if ( l.algorithm->isInitialized() ) { return StatusCode:: SUCCESS ;}
00560   // initialize it!
00561   sc = l.algorithm -> sysInitialize () ;
00562   if ( sc.isFailure() )
00563   {
00564     stream()
00565       << MSG::ERROR
00566       << "Failed to initialize algorithm "
00567       << l.type << "('" << l.name<< "')" << endmsg;
00568     l.algorithm = 0 ;
00569     return sc ;                                                    // RETURN
00570   }
00571   if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() )
00572   { return StatusCode::SUCCESS ; }
00573   // run it!
00574   sc = l.algorithm->sysStart() ;
00575   if ( sc.isFailure() )
00576   {
00577     stream()
00578       << MSG::ERROR
00579       << "Failed to 'run'      algorithm "
00580       << l.type << "('" << l.name<< "')" << endmsg;
00581     l.algorithm = 0 ;
00582     return sc ;                                                    // RETURN
00583   }
00584   return StatusCode::SUCCESS  ;
00585 }
00586 // ===========================================================================
00587 // IIncidentListener interfaces overrides: incident handling
00588 // ===========================================================================
00589 void DataOnDemandSvc::handle ( const Incident& incident )
00590 {
00591 
00592   Gaudi::Utils::LockedChrono timer ( m_timer_all , m_locked_all ) ;
00593 
00594   ++m_stat ;
00595   // proper incident type?
00596   if ( incident.type() != m_trapType ) { return ; }             // RETURN
00597   const DataIncident* inc = dynamic_cast<const DataIncident*>(&incident);
00598   if ( 0 == inc                      ) { return ; }             // RETURN
00599   // update if needed!
00600   if ( m_updateRequired ) { update() ; }
00601 
00602   if ( MSG::VERBOSE >= outputLevel() )
00603   {
00604     stream()
00605       << MSG::VERBOSE
00606       << "Incident: [" << incident.type   () << "] "
00607       << " = "         << incident.source ()
00608       << " Location:"  << inc->tag()         << endmsg;
00609   }
00610   // ==========================================================================
00611   // const std::string& tag = inc->tag();
00612   Gaudi::StringKey tag ( inc->tag() ) ;
00613   // ==========================================================================
00614   NodeMap::iterator icl = m_nodes.find ( tag ) ;
00615   if ( icl != m_nodes.end() )
00616   {
00617     StatusCode sc = execHandler ( tag , icl->second ) ;
00618     if ( sc.isSuccess() ) { ++m_statNode ; }
00619     return ;                                                        // RETURN
00620   }
00621   // ==========================================================================
00622   AlgMap::iterator ialg = m_algs.find ( tag ) ;
00623   if ( ialg != m_algs.end() )
00624   {
00625     StatusCode sc = execHandler ( tag , ialg->second ) ;
00626     if ( sc.isSuccess() ) { ++m_statAlg ; }
00627     return ;                                                        // RETURN
00628   }
00629 }
00630 // ===========================================================================
00631 // ecxecute the handler
00632 // ===========================================================================
00633 StatusCode
00634 DataOnDemandSvc::execHandler ( const std::string& tag, Node& n)
00635 {
00636 
00637   Gaudi::Utils::LockedChrono timer ( m_timer_nodes ,  m_locked_nodes ) ;
00638 
00639   if ( n.executing ) { return StatusCode::FAILURE ; }            // RETURN
00640 
00641   Protection p(n.executing);
00642 
00643   DataObject* object= 0 ;
00644 
00645   if ( n.dataObject )  { object = new DataObject() ; }
00646   else
00647   {
00648     // try to recover the handler
00649     if ( !n.clazz  ) { n.clazz = ROOT::Reflex::Type::ByName(n.name) ; }
00650     if ( !n.clazz  )
00651     {
00652       stream()
00653         << MSG::ERROR
00654         << "Failed to get dictionary for class '"
00655         << n.name
00656         << "' for location:" << tag << endmsg;
00657       return StatusCode::FAILURE ;                               // RETURN
00658     }
00659     //
00660     ROOT::Reflex::Object obj = n.clazz.Construct();
00661 
00662     object = (DataObject*) obj.Address();
00663 
00664     if ( !object )
00665     {
00666       stream()
00667         << MSG::ERROR
00668         << "Failed to create an object of type:"
00669         << n.clazz.Name(ROOT::Reflex::SCOPED) << " for location:" << tag
00670         << endmsg;
00671       return StatusCode::FAILURE  ;                               // RETURN
00672     }
00673   }
00674   //
00675   StatusCode sc = m_dataSvc->registerObject(tag, object );
00676   if ( sc.isFailure() )
00677   {
00678     stream()
00679       << MSG::ERROR << "Failed to register an object of type:"
00680       << n.name << " at location:" << tag
00681       << endmsg;
00682     return sc ;                                                  // RETURN
00683   }
00684   ++n.num ;
00685   //
00686   return StatusCode::SUCCESS ;
00687 }
00688 // ===========================================================================
00689 // execute the handler
00690 // ===========================================================================
00691 StatusCode
00692 DataOnDemandSvc::execHandler(const std::string& tag, Leaf& l)
00693 {
00694   Gaudi::Utils::LockedChrono timer ( m_timer_algs ,  m_locked_algs ) ;
00695   //
00696   if ( l.executing ) { return StatusCode::FAILURE ; }             // RETURN
00697   //
00698   if ( 0 == l.algorithm )
00699   {
00700     StatusCode sc = configureHandler ( l ) ;
00701     if ( sc.isFailure() )
00702     {
00703       stream()
00704         << MSG::ERROR
00705         << "Failed to configure handler for: "
00706         << l.name << "[" << l.type << "] " << tag << endmsg;
00707       return sc ;                                                 // RETURN
00708     }
00709   }
00710   //
00711   Chrono atimer ( m_total ) ;
00712   //
00713   Protection p(l.executing);
00714   StatusCode sc = l.algorithm->sysExecute();
00715   if ( sc.isFailure() )
00716   {
00717     stream() << MSG::ERROR
00718              << "Failed to execute the algorithm:"
00719              << l.algorithm->name() << " for location:" << tag << endmsg;
00720     return sc ;                                                       // RETURN
00721   }
00722   ++l.num ;
00723   //
00724   return StatusCode::SUCCESS ;
00725 }
00726 // ============================================================================
00727 /* dump the content of DataOnDemand service
00728  *  @param level the printout level
00729  *  @param mode  the printout mode
00730  */
00731 // ============================================================================
00732 void DataOnDemandSvc::dump
00733 ( const MSG::Level level ,
00734   const bool       mode  )  const
00735 {
00736   if ( m_algs.empty()  &&  m_nodes.empty() ) { return ; }
00737 
00738   typedef std::pair<std::string,std::string> Pair ;
00739   typedef std::map<std::string,Pair>         PMap ;
00740 
00741   PMap _m ;
00742   for ( AlgMap::const_iterator alg = m_algs.begin() ;
00743         m_algs.end() != alg ; ++alg )
00744   {
00745     PMap::const_iterator check = _m.find(alg->first) ;
00746     if ( _m.end() != check )
00747     {
00748       stream()
00749         << MSG::WARNING
00750         << " The data item is activated for '"
00751         << check->first << "' as '" << check->second.first << "'" << endmsg ;
00752     }
00753     const Leaf& l = alg->second ;
00754     std::string nam = ( l.name == l.type ? l.type  : (l.type+"/"+l.name) ) ;
00755     //
00756     if ( !mode && 0 == l.num ) { continue ; }
00757     //
00758     std::string val ;
00759     if ( mode ) { val = ( 0 == l.algorithm ) ? "F" : "T" ; }
00760     else { val = boost::lexical_cast<std::string>( l.num ) ; }
00761     //
00762     _m[ no_prefix ( alg->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00763   }
00764   // nodes:
00765   for ( NodeMap::const_iterator node = m_nodes.begin() ;
00766         m_nodes.end() != node ; ++node )
00767   {
00768     PMap::const_iterator check = _m.find(node->first) ;
00769     if ( _m.end() != check )
00770     {
00771       stream()
00772         << MSG::WARNING
00773         << " The data item is already activated for '"
00774         << check->first << "' as '" << check->second.first << "'" << endmsg ;
00775     }
00776     const Node& n = node->second ;
00777     std::string nam = "'" + n.name + "'"  ;
00778     //
00779     std::string val ;
00780 
00781     if ( !mode && 0 == n.num ) { continue ; }
00782 
00783     if ( mode ) { val = ( 0 == n.clazz ) ? "F" : "T" ; }
00784     else { val = boost::lexical_cast<std::string>( n.num ) ; }
00785     //
00786     _m[ no_prefix ( node->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00787   }
00788   //
00789   if ( _m.empty() ) { return ; }
00790 
00791   // find the correct formats
00792   size_t n1 = 0 ;
00793   size_t n2 = 0 ;
00794   size_t n3 = 0 ;
00795   for  ( PMap::const_iterator it = _m.begin() ; _m.end() != it ; ++it )
00796   {
00797     n1 = std::max ( n1 , it->first.size()         ) ;
00798     n2 = std::max ( n2 , it->second.first.size()  ) ;
00799     n3 = std::max ( n3 , it->second.second.size() ) ;
00800   }
00801   if ( 10 > n1 ) { n1 = 10 ; }
00802   if ( 10 > n2 ) { n2 = 10 ; }
00803   if ( 60 < n1 ) { n1 = 60 ; }
00804   if ( 60 < n2 ) { n2 = 60 ; }
00805   //
00806 
00807   const std::string _f = " | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |" ;
00808   boost::format _ff ( _f ) ;
00809   _ff % n1 % n2 % n3 ;
00810 
00811   const std::string _format  = _ff.str() ;
00812 
00813   MsgStream& msg = stream() << level ;
00814 
00815   if ( mode ) { msg << "Data-On-Demand Actions enabled for:"       ; }
00816   else        { msg << "Data-On-Demand Actions has been used for:" ; }
00817 
00818   boost::format fmt1( _format)  ;
00819   fmt1 % "Address" % "Creator" % ( mode ? "S" : "#" ) ;
00820   //
00821   const std::string header = fmt1.str() ;
00822   std::string line = std::string( header.size() , '-' ) ;
00823   line[0] = ' ' ;
00824 
00825   msg << std::endl << line
00826       << std::endl << header
00827       << std::endl << line ;
00828 
00829   // make the actual printout:
00830   for ( PMap::const_iterator item = _m.begin() ;
00831         _m.end() != item ; ++item )
00832   {
00833     boost::format fmt( _format)  ;
00834     msg << std::endl <<
00835       ( fmt % item->first % item->second.first % item->second.second ) ;
00836   }
00837 
00838   msg << std::endl << line << endmsg ;
00839 
00840 }
00841 // ============================================================================
00845 DECLARE_SERVICE_FACTORY(DataOnDemandSvc)
00846 // ============================================================================
00847 
00848 // ============================================================================
00849 // The END
00850 // ============================================================================
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Wed Feb 9 16:25:02 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004