Gaudi Framework, version v21r7p1

Home   Generated: 15 Feb 2010

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

Generated at Mon Feb 15 17:27:35 2010 for Gaudi Framework, version v21r7p1 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004