00001
00002
00003
00004
00005
00006 #include <string>
00007 #include <set>
00008 #include <map>
00009 #include <math.h>
00010
00011
00012
00013 #include "GaudiKernel/MsgStream.h"
00014 #include "GaudiKernel/Tokenizer.h"
00015 #include "GaudiKernel/DataObject.h"
00016 #include "GaudiKernel/IAlgorithm.h"
00017 #include "GaudiKernel/ISvcLocator.h"
00018 #include "GaudiKernel/IAlgManager.h"
00019 #include "GaudiKernel/IIncidentSvc.h"
00020 #include "GaudiKernel/DataIncident.h"
00021 #include "GaudiKernel/IDataProviderSvc.h"
00022 #include "GaudiKernel/IToolSvc.h"
00023 #include "GaudiKernel/TypeNameString.h"
00024 #include "GaudiKernel/ToStream.h"
00025 #include "GaudiKernel/Chrono.h"
00026 #include "GaudiKernel/LockedChrono.h"
00027
00028
00029
00030 #include "DataOnDemandSvc.h"
00031
00032
00033
00034 #ifdef __ICC
00035
00036
00037 #pragma warning(disable:2259)
00038 #endif
00039 #include "boost/format.hpp"
00040 #include "boost/lexical_cast.hpp"
00041 #include "GaudiKernel/Property.h"
00042
00043
00044
00045 DataOnDemandSvc::DataOnDemandSvc
00046 ( const std::string& name, ISvcLocator* svc )
00047 : base_class(name, svc)
00048 , m_incSvc ( 0 )
00049 , m_algMgr ( 0 )
00050 , m_dataSvc ( 0 )
00051
00052 , m_trapType ( "DataFault")
00053 , m_dataSvcName ( "EventDataSvc" )
00054 , m_partialPath ( true )
00055 , m_dump ( false )
00056 , m_init ( false )
00057 , m_allowInitFailure(false)
00058
00059 , m_algMapping ()
00060 , m_nodeMapping ()
00061
00062 , m_algMap ( )
00063 , m_nodeMap ( )
00064
00065 , m_updateRequired ( true )
00066 , m_prefix ( "/Event/" )
00067 , m_log ( 0 )
00068 , m_total ( )
00069 , m_statAlg ( 0 )
00070 , m_statNode ( 0 )
00071 , m_stat ( 0 )
00072
00073 , m_timer_nodes ()
00074 , m_timer_algs ()
00075 , m_timer_all ()
00076 , m_locked_nodes ( false )
00077 , m_locked_algs ( false )
00078 , m_locked_all ( false )
00079
00080 {
00081
00082 declareProperty
00083 ( "IncidentName" ,
00084 m_trapType ,
00085 "The type of handled Incident" ) ;
00086
00087 declareProperty ( "DataSvc" , m_dataSvcName ) ;
00088
00089 declareProperty ( "UsePreceedingPath" , m_partialPath ) ;
00090 declareProperty
00091 ( "Dump" ,
00092 m_dump ,
00093 "Dump the configuration and stastics" ) ->
00094 declareUpdateHandler ( &DataOnDemandSvc::update_dump , this ) ;
00095
00096 declareProperty
00097 ( "PreInitialize" ,
00098 m_init ,
00099 "Flag to (pre)initialize all algorithms" ) ;
00100 declareProperty
00101 ( "AllowPreInitializeFailure" ,
00102 m_allowInitFailure ,
00103 "Allow (pre)initialization of algorithms to fail without stopping the application" ) ;
00104
00105 declareProperty ( "Algorithms" , m_algMapping ) ->
00106 declareUpdateHandler ( &DataOnDemandSvc::update_2 , this ) ;
00107 declareProperty ( "Nodes" , m_nodeMapping ) ->
00108 declareUpdateHandler ( &DataOnDemandSvc::update_3 , this ) ;
00109
00110 declareProperty ( "AlgMap" , m_algMap ) ->
00111 declareUpdateHandler ( &DataOnDemandSvc::update_1 , this ) ;
00112 declareProperty ( "NodeMap" , m_nodeMap ) ->
00113 declareUpdateHandler ( &DataOnDemandSvc::update_1 , this ) ;
00114
00115 declareProperty ( "Prefix" , m_prefix ) ;
00116
00117 declareProperty("NodeMappingTools", m_nodeMapTools,
00118 "List of tools of type IDODNodeMapper");
00119 declareProperty("AlgMappingTools", m_algMapTools,
00120 "List of tools of type IDODAlgMapper");
00121
00122 }
00123
00124
00125
00126 void DataOnDemandSvc::update_1 ( Property& p )
00127 {
00128 stream() << MSG::VERBOSE << " I am update handler for property " << p << endmsg ;
00129
00130 m_updateRequired = true ;
00131 }
00132
00133
00134
00135 void DataOnDemandSvc::update_3 ( Property& )
00136 {
00137 stream() << MSG::WARNING
00138 << "The property 'Nodes' is obsolete, switch to map-like 'NodeMap' "
00139 << " = { 'data' : 'type' } "
00140 << endmsg ;
00141
00142 m_updateRequired = true ;
00143 }
00144
00145
00146
00147 void DataOnDemandSvc::update_2 ( Property& )
00148 {
00149 stream() << MSG::WARNING
00150 << "The property 'Algorithms' is obsolete, switch to map-like 'AlgMap' "
00151 << " = { 'data' : 'algorithm' } "
00152 << endmsg ;
00153
00154 m_updateRequired = true ;
00155 }
00156
00157
00158
00159 void DataOnDemandSvc::update_dump ( Property& )
00160 {
00161
00162 if ( FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
00163
00164 if ( m_dump ) { dump ( MSG::ALWAYS ) ; }
00165 }
00166
00167
00168
00169 namespace
00170 {
00171
00177 inline std::string no_prefix
00178 ( const std::string& value ,
00179 const std::string& prefix )
00180 {
00181 return
00182 !prefix.empty() && 0 == value.find(prefix) ?
00183 std::string( value , prefix.size() ) : value ;
00184 }
00185
00192 template <class MAP>
00193 inline size_t add_prefix ( MAP& _map , const std::string& prefix )
00194 {
00195
00196 if ( prefix.empty() ) { return 0 ; }
00198 for ( typename MAP::iterator it = _map.begin() ; _map.end() != it ; ++it )
00199 {
00200 if ( 0 != it->first.find(prefix) )
00201 {
00202 std::string key = prefix + it->first ;
00203 std::string value = it->second ;
00204 _map.erase ( it ) ;
00205 _map[ key ] = value ;
00206 return 1 + add_prefix ( _map , prefix ) ;
00207 }
00208 }
00209
00210 return 0 ;
00211 }
00212
00218 template <class SET>
00219 inline size_t get_dir ( const std::string& object , SET& _set )
00220 {
00221 std::string::size_type ifind = object.rfind('/') ;
00222
00223 if ( std::string::npos == ifind ) { return 0 ; }
00224 if ( 0 == ifind ) { return 0 ; }
00225
00226 const std::string top = std::string( object , 0 , ifind) ;
00227 _set.insert( top ) ;
00228 return 1 + get_dir ( top , _set ) ;
00229 }
00230
00236 template <class MAP, class SET>
00237 inline size_t get_dirs ( const MAP& _map, SET& _set )
00238 {
00239 size_t size = _set.size() ;
00240 for ( typename MAP::const_iterator item = _map.begin() ;
00241 _map.end() != item ; ++item ) { get_dir ( item->first , _set ) ; }
00242 return _set.size() - size ;
00243 }
00244
00245 }
00246
00247 void DataOnDemandSvc::i_setNodeHandler(const std::string &name, const std::string &type){
00248 ClassH cl = ROOT::Reflex::Type::ByName(type) ;
00249 if (!cl) {
00250 warning()
00251 << "Failed to access dictionary class for "
00252 << name << " of type:" << type << endmsg;
00253 }
00254 m_nodes[name] = Node(cl, false, type);
00255 }
00256
00257 StatusCode DataOnDemandSvc::i_setAlgHandler(const std::string &name, const Gaudi::Utils::TypeNameString &alg){
00258 Leaf leaf(alg.type(), alg.name());
00259 if (m_init)
00260 {
00261 StatusCode sc = configureHandler(leaf);
00262 if (sc.isFailure()) {
00263 if (m_allowInitFailure) {
00264
00265
00266 leaf = Leaf(alg.type(), alg.name());
00267 }
00268 else
00269 return sc;
00270 }
00271 }
00272 m_algs[name] = leaf;
00273 return StatusCode::SUCCESS;
00274 }
00275
00276
00277
00278
00279 StatusCode DataOnDemandSvc::update ()
00280 {
00281 if ( !m_updateRequired ) { return StatusCode::SUCCESS ; }
00282
00284 StatusCode sc = setupNodeHandlers() ;
00285 if ( sc.isFailure() )
00286 {
00287 stream() << MSG::ERROR << "Failed to setup old \"Nodes\"" << endmsg ;
00288 return sc ;
00289 }
00291 sc = setupAlgHandlers() ;
00292 if ( sc.isFailure() )
00293 {
00294 stream() << MSG::ERROR << "Failed to setup old \"Algorithms\"" << endmsg ;
00295 return sc ;
00296 }
00298 add_prefix ( m_algMap , m_prefix ) ;
00300 add_prefix ( m_nodeMap , m_prefix ) ;
00302 typedef std::set<std::string> Set ;
00303 Set dirs ;
00304 if ( m_partialPath ){ get_dirs ( m_algMap , dirs ) ; }
00305 if ( m_partialPath ){ get_dirs ( m_nodeMap , dirs ) ; }
00306
00307 Set::iterator _e = dirs.find("/Event") ;
00308 if ( dirs.end() != _e ) { dirs.erase( _e ) ; }
00309
00310 for ( Set::const_iterator dir = dirs.begin() ; dirs.end() != dir ; ++dir )
00311 {
00312 if ( m_algMap .end () != m_algMap .find ( *dir ) ) { continue ; }
00313 if ( m_nodeMap .end () != m_nodeMap .find ( *dir ) ) { continue ; }
00314 m_nodeMap [*dir] = "DataObject" ;
00315 }
00316
00317 m_algs .clear () ;
00318 m_nodes .clear () ;
00319
00321 for ( Map::const_iterator ialg = m_algMap.begin() ;
00322 m_algMap.end() != ialg ; ++ialg )
00323 {
00324 if (i_setAlgHandler(ialg->first, ialg->second).isFailure())
00325 return StatusCode::FAILURE;
00326 }
00328 for ( Map::const_iterator inode = m_nodeMap.begin() ;
00329 m_nodeMap.end() != inode ; ++inode )
00330 {
00331 i_setNodeHandler(inode->first, inode->second);
00332 }
00334 m_updateRequired = false ;
00335
00336 return StatusCode::SUCCESS ;
00337 }
00338
00339
00340
00341 DataOnDemandSvc::~DataOnDemandSvc()
00342 { if ( 0 != m_log ) { delete m_log ; m_log = 0 ; } }
00343
00344
00345
00346 StatusCode DataOnDemandSvc::initialize()
00347 {
00348
00349 StatusCode sc = Service::initialize();
00350 if ( sc.isFailure() ) { return sc; }
00351 sc = setup();
00352 if ( sc.isFailure() ) { return sc; }
00353
00354 if ( m_dump ) { dump ( MSG::INFO ) ; }
00355 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00356
00357 if ( m_init ) { return update () ; }
00358
00359 return StatusCode::SUCCESS ;
00360 }
00361
00362
00363
00364 StatusCode DataOnDemandSvc::finalize()
00365 {
00366
00367 stream ()
00368 << MSG::INFO
00369 << "Handled \"" << m_trapType << "\" incidents: "
00370 << m_statAlg << "/" << m_statNode << "/" << m_stat << "(Alg/Node/Total)."
00371 << endmsg ;
00372 if ( m_dump || MSG::DEBUG >= outputLevel() )
00373 {
00374 stream ()
00375 << MSG::INFO
00376 << m_total.outputUserTime
00377 ( "Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00378 << m_total.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00379 stream ()
00380 << MSG::INFO
00381 << m_timer_nodes.outputUserTime
00382 ( "Nodes timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00383 << m_timer_nodes.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00384 stream ()
00385 << MSG::INFO
00386 << m_timer_algs .outputUserTime
00387 ( "Algs timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00388 << m_timer_algs .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00389 stream ()
00390 << MSG::INFO
00391 << m_timer_all .outputUserTime
00392 ( "All timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00393 << m_timer_all .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00394 }
00395
00396 if ( m_dump ) { dump ( MSG::INFO , false ) ; }
00397 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG , false ) ; }
00398
00399 if ( m_incSvc )
00400 {
00401 m_incSvc->removeListener(this, m_trapType);
00402 m_incSvc.reset();
00403 }
00404 m_algMgr.reset();
00405 m_dataSvc.reset();
00406 if (m_toolSvc) {
00407
00408 if (SmartIF<IStateful>(m_toolSvc)->FSMState() > Gaudi::StateMachine::CONFIGURED) {
00409 for(std::list<IDODNodeMapper*>::iterator i = m_nodeMappers.begin(); i != m_nodeMappers.end(); ++i)
00410 m_toolSvc->releaseTool(*i).ignore();
00411 for(std::list<IDODAlgMapper*>::iterator i = m_algMappers.begin(); i != m_algMappers.end(); ++i)
00412 m_toolSvc->releaseTool(*i).ignore();
00413 } else {
00414 warning() << "ToolSvc already finalized: cannot release tools. Check options." << endmsg;
00415 }
00416 m_nodeMappers.clear();
00417 m_algMappers.clear();
00418 m_toolSvc.reset();
00419 }
00420 return Service::finalize();
00421 }
00422
00424
00425 StatusCode DataOnDemandSvc::reinitialize()
00426 {
00427
00428 if ( 0 != m_incSvc )
00429 {
00430 m_incSvc -> removeListener ( this , m_trapType );
00431 m_incSvc.reset();
00432 }
00433 m_algMgr.reset();
00434 m_dataSvc.reset();
00435 for(std::list<IDODNodeMapper*>::iterator i = m_nodeMappers.begin(); i != m_nodeMappers.end(); ++i)
00436 m_toolSvc->releaseTool(*i).ignore();
00437 m_nodeMappers.clear();
00438 for(std::list<IDODAlgMapper*>::iterator i = m_algMappers.begin(); i != m_algMappers.end(); ++i)
00439 m_toolSvc->releaseTool(*i).ignore();
00440 m_algMappers.clear();
00441 m_toolSvc.reset();
00442 if ( 0 != m_log ) { delete m_log ; m_log = 0 ; }
00443
00444 StatusCode sc = Service::reinitialize();
00445 if ( sc.isFailure() ) { return sc; }
00446
00447 sc = setup() ;
00448 if ( sc.isFailure() ) { return sc; }
00449
00450 if ( m_dump ) { dump ( MSG::INFO ) ; }
00451 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00452
00453 return StatusCode::SUCCESS ;
00454 }
00455
00456
00457
00458 StatusCode DataOnDemandSvc::setup()
00459 {
00460 if ( !(m_algMgr = serviceLocator()) )
00461 {
00462 error() << "Failed to retrieve the IAlgManager interface." << endmsg;
00463 return StatusCode::FAILURE;
00464 }
00465
00466 if ( !(m_incSvc = serviceLocator()->service("IncidentSvc")) )
00467 {
00468 error() << "Failed to retrieve Incident service." << endmsg;
00469 return StatusCode::FAILURE;
00470 }
00471 m_incSvc->addListener(this, m_trapType);
00472
00473 if ( !(m_dataSvc = serviceLocator()->service(m_dataSvcName)) )
00474 {
00475 error()
00476 << "Failed to retrieve the data provider interface of "
00477 << m_dataSvcName << endmsg;
00478 return StatusCode::FAILURE;
00479 }
00480
00481
00482 if (!(m_nodeMapTools.empty() && m_algMapTools.empty())) {
00483 if ( !(m_toolSvc = serviceLocator()->service("ToolSvc")) )
00484 {
00485 error() << "Failed to retrieve ToolSvc" << endmsg;
00486 return StatusCode::FAILURE;
00487 }
00488
00489
00490 std::vector<std::string>::iterator i;
00491 IDODNodeMapper *nodetool = 0;
00492 for(i = m_nodeMapTools.begin(); i != m_nodeMapTools.end(); ++i) {
00493 const StatusCode sc = m_toolSvc->retrieveTool(*i, nodetool);
00494 if (sc.isFailure()) return sc;
00495 m_nodeMappers.push_back(nodetool);
00496 }
00497 IDODAlgMapper *algtool = 0;
00498 for(i = m_algMapTools.begin(); i != m_algMapTools.end(); ++i) {
00499 const StatusCode sc = m_toolSvc->retrieveTool(*i, algtool);
00500 if (sc.isFailure()) return sc;
00501 m_algMappers.push_back(algtool);
00502 }
00503 }
00504 return update();
00505 }
00506
00507
00508
00509 StatusCode DataOnDemandSvc::setupNodeHandlers()
00510 {
00511 Setup::const_iterator j;
00512 std::string nam, typ, tag;
00513 StatusCode sc = StatusCode::SUCCESS;
00514
00515 for ( j=m_nodeMapping.begin(); j != m_nodeMapping.end(); ++j)
00516 {
00517 Tokenizer tok(true);
00518 tok.analyse(*j, " ", "", "", "=", "'", "'");
00519 for ( Tokenizer::Items::iterator i = tok.items().begin();
00520 i != tok.items().end(); i++ ) {
00521 const std::string& t = (*i).tag();
00522 const std::string& v = (*i).value();
00523 switch( ::toupper(t[0]) ) {
00524 case 'D':
00525 tag = v;
00526 break;
00527 case 'T':
00528 nam = v;
00529 break;
00530 }
00531 }
00532 if ( m_algMap .end () != m_algMap .find ( tag ) ||
00533 m_nodeMap .end () != m_nodeMap .find ( tag ) )
00534 {
00535 stream()
00536 << MSG::WARNING
00537 << "The obsolete property 'Nodes' redefines the action for '"
00538 + tag + "' to be '" +nam+"'"
00539 << endmsg ;
00540 }
00541 m_nodeMap[tag] = nam ;
00542 }
00543
00544 m_updateRequired = true ;
00545
00546 return sc;
00547 }
00548
00549
00550
00551 StatusCode DataOnDemandSvc::setupAlgHandlers()
00552 {
00553 Setup::const_iterator j;
00554 std::string typ, tag;
00555
00556 for(j=m_algMapping.begin(); j != m_algMapping.end(); ++j)
00557 {
00558 Tokenizer tok(true);
00559 tok.analyse(*j, " ", "", "", "=", "'", "'");
00560 for(Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++ ) {
00561 const std::string& t = (*i).tag();
00562 const std::string& v = (*i).value();
00563 switch( ::toupper(t[0]) ) {
00564 case 'D':
00565 tag = v;
00566 break;
00567 case 'T':
00568 typ = v;
00569 break;
00570 }
00571 }
00572 Gaudi::Utils::TypeNameString item(typ);
00573 if ( m_algMap .end () != m_algMap .find ( tag ) ||
00574 m_nodeMap .end () != m_nodeMap .find ( tag ) )
00575 {
00576 stream()
00577 << MSG::WARNING
00578 << "The obsolete property 'Algorithms' redefines the action for '"
00579 + tag + "' to be '" +item.type() +"/"+item.name()+"'"
00580 << endmsg ;
00581 }
00582 m_algMap[tag] = item.type() + "/" + item.name() ;
00583 }
00584 m_updateRequired = true ;
00585 return StatusCode::SUCCESS;
00586 }
00587
00589
00590 StatusCode DataOnDemandSvc::configureHandler(Leaf& l)
00591 {
00592 if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00593 if ( 0 == m_algMgr ) { return StatusCode::FAILURE ; }
00594 l.algorithm = m_algMgr->algorithm(l.name, false);
00595 if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00596
00597 StatusCode sc = m_algMgr->createAlgorithm ( l.type , l.name , l.algorithm , true ) ;
00598 if ( sc.isFailure() )
00599 {
00600 stream()
00601 << MSG::ERROR
00602 << "Failed to create algorithm "
00603 << l.type << "('" << l.name<< "')" << endmsg;
00604 l.algorithm = 0 ;
00605 return sc ;
00606 }
00607 if ( l.algorithm->isInitialized() ) { return StatusCode:: SUCCESS ;}
00608
00609 sc = l.algorithm -> sysInitialize () ;
00610 if ( sc.isFailure() )
00611 {
00612 stream()
00613 << MSG::ERROR
00614 << "Failed to initialize algorithm "
00615 << l.type << "('" << l.name<< "')" << endmsg;
00616 l.algorithm = 0 ;
00617 return sc ;
00618 }
00619 if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() )
00620 { return StatusCode::SUCCESS ; }
00621
00622 sc = l.algorithm->sysStart() ;
00623 if ( sc.isFailure() )
00624 {
00625 stream()
00626 << MSG::ERROR
00627 << "Failed to 'run' algorithm "
00628 << l.type << "('" << l.name<< "')" << endmsg;
00629 l.algorithm = 0 ;
00630 return sc ;
00631 }
00632 return StatusCode::SUCCESS ;
00633 }
00634
00635
00636 namespace {
00639 struct ToolGetter {
00641 std::string path;
00643 ToolGetter(const std::string &_path): path(_path) {}
00645 inline std::string operator() (IDODNodeMapper *t) const {
00646 return t->nodeTypeForPath(path);
00647 }
00649 inline Gaudi::Utils::TypeNameString operator() (IDODAlgMapper *t) const {
00650 return t->algorithmForPath(path);
00651 }
00652 };
00653
00656 inline bool isGood(const std::string& r) {return !r.empty();}
00657 inline bool isGood(const Gaudi::Utils::TypeNameString& r) {return !r.name().empty();}
00659
00662 class Finder {
00663 const ToolGetter getter;
00664 const std::list<IDODNodeMapper*> &nodes;
00665 const std::list<IDODAlgMapper*> &algs;
00667 template <class R, class T>
00668 R find(const std::list<T*> &l) const {
00669 typename std::list<T*>::const_iterator i;
00670 for(i = l.begin(); i != l.end(); ++i) {
00671 R result = getter(*i);
00672 if (isGood(result)) return result;
00673 }
00674 return R("");
00675 }
00676 public:
00678 Finder(const std::string &_path,
00679 const std::list<IDODNodeMapper*> &_nodes,
00680 const std::list<IDODAlgMapper*> &_algs): getter(_path), nodes(_nodes), algs(_algs) {
00681 }
00683 inline std::string node() const {
00684 return find<std::string>(nodes);
00685 }
00687 inline Gaudi::Utils::TypeNameString alg() const {
00688 return find<Gaudi::Utils::TypeNameString>(algs);
00689 }
00690
00691 };
00692
00693 }
00694
00695
00696
00697
00698 void DataOnDemandSvc::handle ( const Incident& incident )
00699 {
00700
00701 Gaudi::Utils::LockedChrono timer ( m_timer_all , m_locked_all ) ;
00702
00703 ++m_stat ;
00704
00705 if ( incident.type() != m_trapType ) { return ; }
00706 const DataIncident* inc = dynamic_cast<const DataIncident*>(&incident);
00707 if ( 0 == inc ) { return ; }
00708
00709 if ( m_updateRequired ) { update() ; }
00710
00711 if ( MSG::VERBOSE >= outputLevel() )
00712 {
00713 verbose()
00714 << "Incident: [" << incident.type () << "] "
00715 << " = " << incident.source ()
00716 << " Location:" << inc->tag() << endmsg;
00717 }
00718
00719
00720 Gaudi::StringKey tag ( inc->tag() ) ;
00721
00722 NodeMap::iterator icl = m_nodes.find ( tag ) ;
00723 if ( icl != m_nodes.end() )
00724 {
00725 StatusCode sc = execHandler ( tag , icl->second ) ;
00726 if ( sc.isSuccess() ) { ++m_statNode ; }
00727 return ;
00728 }
00729
00730 AlgMap::iterator ialg = m_algs.find ( tag ) ;
00731 if ( ialg != m_algs.end() )
00732 {
00733 StatusCode sc = execHandler ( tag , ialg->second ) ;
00734 if ( sc.isSuccess() ) { ++m_statAlg ; }
00735 return ;
00736 }
00737
00738
00739 if (m_toolSvc) {
00740 if (MSG::VERBOSE >= outputLevel())
00741 verbose() << "Try to find mapping with mapping tools" << endmsg;
00742 Finder finder(no_prefix(inc->tag(), m_prefix), m_nodeMappers, m_algMappers);
00743
00744 std::string node = finder.node();
00745 if (isGood(node)) {
00746
00747 if (MSG::VERBOSE >= outputLevel())
00748 verbose() << "Found Node handler: " << node << endmsg;
00749 i_setNodeHandler(inc->tag(), node);
00750 handle(incident);
00751 --m_stat;
00752 return;
00753 }
00754
00755 Gaudi::Utils::TypeNameString alg = finder.alg();
00756 if (isGood(alg)) {
00757
00758 if (MSG::VERBOSE >= outputLevel())
00759 verbose() << "Found Algorithm handler: " << alg << endmsg;
00760 i_setAlgHandler(inc->tag(), alg).ignore();
00761 handle(incident);
00762 --m_stat;
00763 return;
00764 }
00765 }
00766 }
00767
00768
00769
00770 StatusCode
00771 DataOnDemandSvc::execHandler ( const std::string& tag, Node& n)
00772 {
00773
00774 Gaudi::Utils::LockedChrono timer ( m_timer_nodes , m_locked_nodes ) ;
00775
00776 if ( n.executing ) { return StatusCode::FAILURE ; }
00777
00778 Protection p(n.executing);
00779
00780 DataObject* object= 0 ;
00781
00782 if ( n.dataObject ) { object = new DataObject() ; }
00783 else
00784 {
00785
00786 if ( !n.clazz ) { n.clazz = ROOT::Reflex::Type::ByName(n.name) ; }
00787 if ( !n.clazz )
00788 {
00789 stream()
00790 << MSG::ERROR
00791 << "Failed to get dictionary for class '"
00792 << n.name
00793 << "' for location:" << tag << endmsg;
00794 return StatusCode::FAILURE ;
00795 }
00796
00797 ROOT::Reflex::Object obj = n.clazz.Construct();
00798
00799 object = (DataObject*) obj.Address();
00800
00801 if ( !object )
00802 {
00803 stream()
00804 << MSG::ERROR
00805 << "Failed to create an object of type:"
00806 << n.clazz.Name(ROOT::Reflex::SCOPED) << " for location:" << tag
00807 << endmsg;
00808 return StatusCode::FAILURE ;
00809 }
00810 }
00811
00812 StatusCode sc = m_dataSvc->registerObject(tag, object );
00813 if ( sc.isFailure() )
00814 {
00815 stream()
00816 << MSG::ERROR << "Failed to register an object of type:"
00817 << n.name << " at location:" << tag
00818 << endmsg;
00819 return sc ;
00820 }
00821 ++n.num ;
00822
00823 return StatusCode::SUCCESS ;
00824 }
00825
00826
00827
00828 StatusCode
00829 DataOnDemandSvc::execHandler(const std::string& tag, Leaf& l)
00830 {
00831 Gaudi::Utils::LockedChrono timer ( m_timer_algs , m_locked_algs ) ;
00832
00833 if ( l.executing ) { return StatusCode::FAILURE ; }
00834
00835 if ( 0 == l.algorithm )
00836 {
00837 StatusCode sc = configureHandler ( l ) ;
00838 if ( sc.isFailure() )
00839 {
00840 stream()
00841 << MSG::ERROR
00842 << "Failed to configure handler for: "
00843 << l.name << "[" << l.type << "] " << tag << endmsg;
00844 return sc ;
00845 }
00846 }
00847
00848 Chrono atimer ( m_total ) ;
00849
00850 Protection p(l.executing);
00851 StatusCode sc = l.algorithm->sysExecute();
00852 if ( sc.isFailure() )
00853 {
00854 stream() << MSG::ERROR
00855 << "Failed to execute the algorithm:"
00856 << l.algorithm->name() << " for location:" << tag << endmsg;
00857 return sc ;
00858 }
00859 ++l.num ;
00860
00861 return StatusCode::SUCCESS ;
00862 }
00863
00864
00865
00866
00867
00868
00869 void DataOnDemandSvc::dump
00870 ( const MSG::Level level ,
00871 const bool mode ) const
00872 {
00873 if ( m_algs.empty() && m_nodes.empty() ) { return ; }
00874
00875 typedef std::pair<std::string,std::string> Pair ;
00876 typedef std::map<std::string,Pair> PMap ;
00877
00878 PMap _m ;
00879 for ( AlgMap::const_iterator alg = m_algs.begin() ;
00880 m_algs.end() != alg ; ++alg )
00881 {
00882 PMap::const_iterator check = _m.find(alg->first) ;
00883 if ( _m.end() != check )
00884 {
00885 stream()
00886 << MSG::WARNING
00887 << " The data item is activated for '"
00888 << check->first << "' as '" << check->second.first << "'" << endmsg ;
00889 }
00890 const Leaf& l = alg->second ;
00891 std::string nam = ( l.name == l.type ? l.type : (l.type+"/"+l.name) ) ;
00892
00893 if ( !mode && 0 == l.num ) { continue ; }
00894
00895 std::string val ;
00896 if ( mode ) { val = ( 0 == l.algorithm ) ? "F" : "T" ; }
00897 else { val = boost::lexical_cast<std::string>( l.num ) ; }
00898
00899 _m[ no_prefix ( alg->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00900 }
00901
00902 for ( NodeMap::const_iterator node = m_nodes.begin() ;
00903 m_nodes.end() != node ; ++node )
00904 {
00905 PMap::const_iterator check = _m.find(node->first) ;
00906 if ( _m.end() != check )
00907 {
00908 stream()
00909 << MSG::WARNING
00910 << " The data item is already activated for '"
00911 << check->first << "' as '" << check->second.first << "'" << endmsg ;
00912 }
00913 const Node& n = node->second ;
00914 std::string nam = "'" + n.name + "'" ;
00915
00916 std::string val ;
00917
00918 if ( !mode && 0 == n.num ) { continue ; }
00919
00920 if ( mode ) { val = ( 0 == n.clazz ) ? "F" : "T" ; }
00921 else { val = boost::lexical_cast<std::string>( n.num ) ; }
00922
00923 _m[ no_prefix ( node->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00924 }
00925
00926 if ( _m.empty() ) { return ; }
00927
00928
00929 size_t n1 = 0 ;
00930 size_t n2 = 0 ;
00931 size_t n3 = 0 ;
00932 for ( PMap::const_iterator it = _m.begin() ; _m.end() != it ; ++it )
00933 {
00934 n1 = std::max ( n1 , it->first.size() ) ;
00935 n2 = std::max ( n2 , it->second.first.size() ) ;
00936 n3 = std::max ( n3 , it->second.second.size() ) ;
00937 }
00938 if ( 10 > n1 ) { n1 = 10 ; }
00939 if ( 10 > n2 ) { n2 = 10 ; }
00940 if ( 60 < n1 ) { n1 = 60 ; }
00941 if ( 60 < n2 ) { n2 = 60 ; }
00942
00943
00944 const std::string _f = " | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |" ;
00945 boost::format _ff ( _f ) ;
00946 _ff % n1 % n2 % n3 ;
00947
00948 const std::string _format = _ff.str() ;
00949
00950 MsgStream& msg = stream() << level ;
00951
00952 if ( mode ) { msg << "Data-On-Demand Actions enabled for:" ; }
00953 else { msg << "Data-On-Demand Actions has been used for:" ; }
00954
00955 boost::format fmt1( _format) ;
00956 fmt1 % "Address" % "Creator" % ( mode ? "S" : "#" ) ;
00957
00958 const std::string header = fmt1.str() ;
00959 std::string line = std::string( header.size() , '-' ) ;
00960 line[0] = ' ' ;
00961
00962 msg << std::endl << line
00963 << std::endl << header
00964 << std::endl << line ;
00965
00966
00967 for ( PMap::const_iterator item = _m.begin() ;
00968 _m.end() != item ; ++item )
00969 {
00970 boost::format fmt( _format) ;
00971 msg << std::endl <<
00972 ( fmt % item->first % item->second.first % item->second.second ) ;
00973 }
00974
00975 msg << std::endl << line << endmsg ;
00976
00977 }
00978
00982 DECLARE_SERVICE_FACTORY(DataOnDemandSvc)
00983
00984
00985
00986
00987