Gaudi Framework, version v23r0

Home   Generated: Mon Jan 30 2012

RootCnvSvc.cpp

Go to the documentation of this file.
00001 // $Id: RootCnvSvc.cpp,v 1.12 2010-09-27 15:43:53 frankb Exp $
00002 //====================================================================
00003 //  RootCnvSvc implementation
00004 //--------------------------------------------------------------------
00005 //
00006 //  Description: Implementation of the ROOT data storage
00007 //
00008 //  Author     : M.Frank
00009 //
00010 //====================================================================
00011 
00012 // Framework include files
00013 #include "GaudiKernel/MsgStream.h"
00014 #include "GaudiKernel/IRegistry.h"
00015 #include "GaudiKernel/IUpdateable.h"
00016 #include "GaudiKernel/IIncidentSvc.h"
00017 #include "GaudiKernel/IDataManagerSvc.h"
00018 #include "GaudiKernel/IDataProviderSvc.h"
00019 #include "GaudiKernel/KeyedContainer.h"
00020 #include "GaudiKernel/DataIncident.h"
00021 #include "GaudiKernel/LinkManager.h"
00022 #include "GaudiKernel/Incident.h"
00023 #include "GaudiKernel/System.h"
00024 #include "GaudiUtils/IIODataManager.h"
00025 #include "RootCnv/RootRefs.h"
00026 #include "RootCnv/RootCnvSvc.h"
00027 #include "RootCnv/RootAddress.h"
00028 #include "RootCnv/RootConverter.h"
00029 #include "RootCnv/RootDatabaseCnv.h"
00030 #include "RootCnv/RootDirectoryCnv.h"
00031 #include "RootCnv/RootNTupleCnv.h"
00032 #include "RootCnv/RootDataConnection.h"
00033 #include "RootUtils.h"
00034 
00035 // ROOT include files
00036 #include "TROOT.h"
00037 #include "TClass.h"
00038 #include "TTree.h"
00039 #include "TBranch.h"
00040 
00041 using namespace std;
00042 using namespace Gaudi;
00043 typedef const string& CSTR;
00044 
00045 #define S_OK   StatusCode::SUCCESS
00046 #define S_FAIL StatusCode::FAILURE
00047 namespace GaudiRoot {  bool patchStreamers(MsgStream& log);    }
00048 
00049 namespace { 
00050   static map<string, TClass*> s_classesNames;
00051   static map<CLID, TClass*>   s_classesClids;
00052 }
00053 #define MBYTE 1024*1024
00054 
00055 // Standard constructor
00056 RootCnvSvc::RootCnvSvc(CSTR nam, ISvcLocator* svc)
00057 : ConversionSvc( nam, svc, ROOT_StorageType), 
00058   m_ioMgr(0), m_incidentSvc(0), m_current(0), m_setup(0)
00059 {
00060   m_classRefs = m_classDO = 0;
00061   m_setup = new RootConnectionSetup();
00062   m_setup->cacheBranches.push_back("*");
00063   declareProperty("IOPerfStats",      m_ioPerfStats);
00064   declareProperty("ShareFiles",       m_shareFiles          = "NO");
00065   declareProperty("EnableIncident",   m_incidentEnabled     = true);
00066   declareProperty("RecordsName",      m_recordName          = "/FileRecords");
00067 
00068   declareProperty("BasketSize",       m_setup->basketSize   = 40*MBYTE);
00069   declareProperty("CacheSize",        m_setup->cacheSize    = 10*MBYTE);
00070   declareProperty("AutoFlush",        m_setup->autoFlush    = 100);
00071   declareProperty("LearnEntries",     m_setup->learnEntries = 10);
00072   declareProperty("LoadSection",      m_setup->loadSection  = "Event");
00073   declareProperty("CacheBranches",    m_setup->cacheBranches);
00074   declareProperty("VetoBranches",     m_setup->vetoBranches);
00075 }
00076 
00077 // Standard destructor
00078 RootCnvSvc::~RootCnvSvc() {
00079   if (m_setup) m_setup->release();
00080 }
00081 
00082 // Small routine to issue exceptions
00083 StatusCode RootCnvSvc::error(CSTR msg)  {
00084   if ( m_log ) {
00085     log() << MSG::ERROR << "Error: " << msg << endmsg;
00086     return S_FAIL;
00087   }
00088   MsgStream m(msgSvc(),name());
00089   m << MSG::ERROR << "Error: " << msg << endmsg;
00090   return S_FAIL;
00091 }
00092 
00093 // Initialize the Db data persistency service
00094 StatusCode RootCnvSvc::initialize()  {
00095   string cname;
00096   StatusCode status = ConversionSvc::initialize();
00097   if ( !status.isSuccess() )
00098     return error("Failed to initialize ConversionSvc base class.");
00099   m_log = new MsgStream(msgSvc(),name());
00100   if( !(status=service("IODataManager", m_ioMgr)).isSuccess() )
00101     return error("Unable to localize interface from service:IODataManager");
00102   if( !(status=service("IncidentSvc", m_incidentSvc)).isSuccess() )
00103     return error("Unable to localize interface from service:IncidentSvc");
00104   m_setup->setMessageSvc(new MsgStream(msgSvc(),name()));
00105   GaudiRoot::patchStreamers(log());
00106   cname = System::typeinfoName(typeid(DataObject));
00107   m_classDO = gROOT->GetClass(cname.c_str());
00108   if ( 0 == m_classDO )
00109     return error("Unable to load class description for DataObject");    
00110   cname = System::typeinfoName(typeid(RootObjectRefs));
00111   m_classRefs = gROOT->GetClass(cname.c_str());
00112   if ( 0 == m_classRefs )
00113     return error("Unable to load class description for ObjectRefs");
00114   return S_OK;
00115 }
00116 
00117 // Finalize the Db data persistency service
00118 StatusCode RootCnvSvc::finalize()    {
00119   log() << MSG::INFO;
00120   if ( m_ioMgr )  {
00121     IIODataManager::Connections cons = m_ioMgr->connections(0);
00122     for(IIODataManager::Connections::iterator i=cons.begin(); i != cons.end(); ++i)  {
00123       RootDataConnection* pc = dynamic_cast<RootDataConnection*>(*i);
00124       if ( pc ) {
00125         if ( pc->owner() == this && !m_ioPerfStats.empty() )   {
00126           pc->saveStatistics(m_ioPerfStats);
00127         }
00128         if ( pc->lookupClient(this) )   {
00129           size_t num_clients = pc->removeClient(this);
00130           if ( num_clients == 0 ) {
00131             if ( m_ioMgr->disconnect(pc).isSuccess() )  {
00132               log() << "Disconnected data IO:" << pc->fid() 
00133                     << " [" << pc->pfn() << "]" << endmsg;
00134               delete pc;
00135             }
00136           }
00137         }
00138       }
00139     }
00140     releasePtr(m_ioMgr);
00141   }
00142   deletePtr(m_log);
00143   releasePtr(m_incidentSvc);
00144   return ConversionSvc::finalize();
00145 }
00146 
00147 // ConversionSvc overload: Create new Converter using factory
00148 IConverter* RootCnvSvc::createConverter(long typ,const CLID& wanted,const ICnvFactory*)   {
00149   if ( wanted == CLID_StatisticsFile )
00150     return new RootDatabaseCnv(typ,wanted,serviceLocator().get(),this);
00151   else if ( wanted == CLID_StatisticsDirectory )
00152     return new RootDirectoryCnv(typ,wanted,serviceLocator().get(),this);
00153   else if ( wanted == CLID_RowWiseTuple )
00154     return new RootNTupleCnv(typ,wanted,serviceLocator().get(),this);
00155   else if ( wanted == CLID_ColumnWiseTuple )
00156     return new RootNTupleCnv(typ,wanted,serviceLocator().get(),this);
00157   else
00158     return new RootConverter(typ,wanted,serviceLocator().get(),this);
00159 }
00160 
00161 // ConversionSvc overload: Load the class (dictionary) for the converter 
00162 void RootCnvSvc::loadConverter(DataObject* pObject) {
00163   if (pObject) {
00164     string cname = System::typeinfoName(typeid(*pObject));
00165     log() << MSG::DEBUG << "Trying to 'Autoload' dictionary for class " << cname << endmsg;
00166     TClass* cl = s_classesNames[cname];
00167     if ( 0 == cl ) {
00168       cl = gROOT->GetClass(cname.c_str());
00169       if ( cl ) {
00170         s_classesNames[cname] = cl;
00171         s_classesClids[pObject->clID()] = cl;
00172       }
00173     }
00174   }
00175 }  
00176 
00177 // Helper: Get TClass for a given DataObject pointer
00178 TClass* RootCnvSvc::getClass(DataObject* pObject) {
00179   map<CLID, TClass*>::iterator i=s_classesClids.find(pObject->clID());
00180   if ( i != s_classesClids.end() ) return (*i).second;
00181   loadConverter(pObject);
00182   i=s_classesClids.find(pObject->clID());
00183   if ( i != s_classesClids.end() ) return (*i).second;
00184 
00185   string cname = System::typeinfoName(typeid(*pObject));
00186   throw runtime_error("Unknown ROOT class for object:"+cname);
00187   return 0;
00188 }
00189 
00190 // Connect the output file to the service with open mode.
00191 StatusCode RootCnvSvc::connectOutput(CSTR dsn, CSTR openMode)   {
00192   StatusCode sc = S_FAIL;
00193   m_current = 0;
00194   m_currSection = "";
00195   if ( ::strncasecmp(openMode.c_str(),"RECREATE",3)==0 )
00196     sc = connectDatabase(dsn, IDataConnection::RECREATE, &m_current);
00197   else if ( ::strncasecmp(openMode.c_str(),"NEW",1)==0 )
00198     sc = connectDatabase(dsn, IDataConnection::CREATE, &m_current);
00199   else if ( ::strncasecmp(openMode.c_str(),"CREATE",1)==0 )
00200     sc = connectDatabase(dsn, IDataConnection::CREATE, &m_current);
00201   else if ( ::strncasecmp(openMode.c_str(),"UPDATE",1)==0 )
00202     sc = connectDatabase(dsn, IDataConnection::UPDATE, &m_current);
00203   if ( sc.isSuccess() && m_current && m_current->isConnected() )  {
00204     return S_OK;
00205   }
00206   m_incidentSvc->fireIncident(Incident(dsn,IncidentType::FailOutputFile));
00207   log() << MSG::ERROR << "The dataset " << dsn << " cannot be opened in mode " 
00208     << openMode << ". [Invalid mode]" << endmsg;
00209   return sc;
00210 }
00211 
00212 // Connect the output file to the service with open mode.
00213 StatusCode
00214 RootCnvSvc::connectDatabase(CSTR dataset, int mode, RootDataConnection** con)  {
00215   try {
00216     IDataConnection* c = m_ioMgr->connection(dataset);
00217     bool fire_incident = false;
00218     *con = 0;
00219     if ( !c )  {
00220       auto_ptr<IDataConnection> connection(new RootDataConnection(this,dataset,m_setup));
00221       StatusCode sc = (mode != IDataConnection::READ)
00222         ? m_ioMgr->connectWrite(connection.get(),IDataConnection::IoType(mode),"ROOT")
00223         : m_ioMgr->connectRead(false,connection.get());
00224       c = sc.isSuccess() ? m_ioMgr->connection(dataset) : 0;
00225       if ( c )   {
00226         fire_incident = m_incidentEnabled && (0 != (mode&(IDataConnection::UPDATE|IDataConnection::READ)));
00227         if ( 0 != (mode&IDataConnection::READ) ) {
00228           if ( !m_ioPerfStats.empty() ) {
00229             RootDataConnection* pc = dynamic_cast<RootDataConnection*>(c);
00230             pc->enableStatistics(m_setup->loadSection);
00231           }
00232         }
00233         connection.release();
00234       }
00235       else  {
00236         m_incidentSvc->fireIncident(Incident(dataset,mode == IDataConnection::READ
00237                                              ? IncidentType::FailInputFile
00238                                              : IncidentType::FailOutputFile));
00239         return error("Cannot open data file:"+dataset);
00240       }
00241     }
00242     RootDataConnection* pc = dynamic_cast<RootDataConnection*>(c);
00243     if ( pc )  {
00244       if ( !pc->isConnected() ) pc->connectRead();
00245       *con = pc;
00246       pc->resetAge();
00247       pc->addClient(this);
00248     }
00249     if ( *con )  {
00250       if ( fire_incident )   {
00251         IOpaqueAddress* pAddr = 0;
00252         string fid = pc->fid();
00253         string section = m_recordName[0] == '/' ? m_recordName.substr(1) : m_recordName;
00254         TBranch* b = pc->getBranch(section,m_recordName);
00255         log() << MSG::VERBOSE;
00256         if ( b ) {
00257           const string par[2] = { fid, m_recordName };
00258           unsigned long ipar[2] = { (unsigned long)(*con), (unsigned long)b->GetEntries()-1 };
00259           for(int i=0; i<b->GetEntries(); ++i) {
00260             ipar[1] = i;
00261             if ( !pc->mergeFIDs().empty() )
00262               fid = pc->mergeFIDs()[i];
00263             if ( !createAddress(repSvcType(),CLID_DataObject,par,ipar,pAddr).isSuccess() ) {
00264               log() << "Failed to create address for " << m_recordName << " in:" << fid
00265                 << " [" << pc->fid() << "][" << i << "]" << endmsg;
00266               continue;
00267             }
00268             log() << "Prepare " << m_recordName << " " << fid << " [" << par[0] << "][" << i << "]" << endmsg;
00269             m_incidentSvc->fireIncident(ContextIncident<IOpaqueAddress*>(fid,"FILE_OPEN_READ",pAddr));
00270           }
00271         }
00272         else {
00273           log() << "No valid Records " << m_recordName << " present in:" << pc->fid() << endmsg;
00274         }
00275       }
00276       // We can remove retired connections, which are no longer used....
00277       IIODataManager::Connections cons = m_ioMgr->connections(this);
00278       for(IIODataManager::Connections::iterator i=cons.begin(); i != cons.end(); ++i)  {
00279         if ( (*i) != *con && !(*i)->isConnected() )  {
00280           RootDataConnection* pc = dynamic_cast<RootDataConnection*>(*i);
00281           if ( pc && pc->lookupClient(this) )   {
00282             size_t num_client = pc->removeClient(this);
00283             if ( num_client == 0 ) {
00284               if ( m_ioMgr->disconnect(pc).isSuccess() )  {
00285                 log() << MSG::INFO << "Removed disconnected IO  stream:" << pc->fid() 
00286                       << " [" << pc->pfn() << "]" << endmsg;
00287                 delete pc;
00288               }
00289             }
00290           }
00291         }
00292       }
00293       return S_OK;
00294     }
00295     m_incidentSvc->fireIncident(Incident(dataset,IncidentType::FailOutputFile));
00296     return S_FAIL;
00297   }
00298   catch (exception& e)  {
00299     m_incidentSvc->fireIncident(Incident(dataset,IncidentType::FailOutputFile));
00300     return error(string("connectDatabase> Caught exception:")+e.what());
00301   }
00302   catch (...)   {
00303     m_incidentSvc->fireIncident(Incident(dataset,IncidentType::FailOutputFile));
00304     return error("connectDatabase> Unknown Fatal Exception for "+dataset);
00305   }
00306 }
00307 
00308 // Conect output stream (valid until overwritten)
00309 StatusCode RootCnvSvc::connectOutput(CSTR db_name)  {
00310   return connectOutput(db_name, "NEW");
00311 }
00312 
00313 // Commit pending output on open container
00314 StatusCode  RootCnvSvc::commitOutput(CSTR dsn, bool /* doCommit */) {
00315   if ( m_current ) {
00316     size_t len = m_currSection.find('/',1);   
00317     string section = m_currSection.substr(1,len==string::npos ? string::npos : len-1);
00318     TBranch* b = m_current->getBranch(section, m_currSection);
00319     if ( b ) {
00320       Long64_t evt = b->GetEntries();
00321       TTree* t = b->GetTree();
00322       TObjArray* a = t->GetListOfBranches();
00323       Int_t nb = a->GetEntriesFast();
00324       log() << MSG::DEBUG;
00326       for(Int_t i=0; i<nb; ++i) {
00327         TBranch* br_ptr = (TBranch*)a->UncheckedAt(i);
00328         Long64_t br_evt = br_ptr->GetEntries();
00329         if ( br_evt < evt ) {
00330           Long64_t num = evt-br_evt;
00331           br_ptr->SetAddress(0);
00332           while(num>0) { br_ptr->Fill(); --num; }
00333           log() << "commit: Added " << long(evt-br_evt) 
00334                 << " Section: " << evt << " Branch: " << br_ptr->GetEntries()
00335                 << " RefNo: " << br_ptr->GetEntries()-1 
00336                 << " NULL entries to:" << br_ptr->GetName() << endmsg;
00337         }
00338       }
00339 
00340       b->GetTree()->SetEntries(evt);
00341       if ( evt == 1 )  {
00342         b->GetTree()->OptimizeBaskets(m_setup->basketSize,1.1,"");
00343       }
00344       if ( evt > 0 && (evt%m_setup->autoFlush)==0 ) {
00345         if ( evt == m_setup->autoFlush ) {
00346           b->GetTree()->SetAutoFlush(m_setup->autoFlush);
00347           b->GetTree()->OptimizeBaskets(m_setup->basketSize,1.,"");
00348         }
00349         else   {
00350           b->GetTree()->FlushBaskets();
00351         }
00352       }
00353       log() << MSG::DEBUG << "Set section entries of " << m_currSection
00354         << " to " << long(evt) << " entries." << endmsg;
00355     }
00356     else {
00357       return error("commitOutput> Failed to update entry numbers on "+dsn);
00358     }
00359   }
00360   return S_OK;
00361 }
00362 
00363 // Disconnect from an existing data stream.
00364 StatusCode RootCnvSvc::disconnect(CSTR dataset)  {
00365   IDataConnection* c = m_ioMgr->connection(dataset);
00366   return c ? m_ioMgr->disconnect(c) : S_FAIL;
00367 }
00368 
00369 // IAddressCreator implementation: Address creation
00370 StatusCode RootCnvSvc::createAddress(long  typ,
00371                                      const CLID& clid,
00372                                      const string* par, 
00373                                      const unsigned long* ip,
00374                                      IOpaqueAddress*& refpAddress) 
00375 {
00376   refpAddress = new RootAddress(typ,clid,par[0],par[1],ip[0],ip[1]);
00377   return S_OK;
00378 }
00379 
00380 // Insert null marker for not existent transient object
00381 StatusCode RootCnvSvc::createNullRep(const std::string& path) {
00382   size_t len = path.find('/',1);
00383   string section = path.substr(1,len==string::npos ? string::npos : len-1);
00384   m_current->saveObj(section,path,0,0);
00385   return S_OK;
00386 }
00387 
00388 // Insert null marker for not existent transient object
00389 StatusCode RootCnvSvc::createNullRef(const std::string& path) {
00390   RootObjectRefs* refs = 0;
00391   size_t len = path.find('/',1);
00392   string section = path.substr(1,len==string::npos ? string::npos : len-1);
00393   pair<int,unsigned long> ret = m_current->save(section,path+"#R",0,refs);
00394   log() << MSG::VERBOSE << "Writing object:" << path << " " 
00395     << ret.first << " " << hex << ret.second << dec << " [NULL]" << endmsg;
00396   return S_OK;
00397 }
00398 
00399 // Mark an object for write given an object reference
00400 StatusCode RootCnvSvc::i__createRep(DataObject* pObj, IOpaqueAddress*& refpAddr)  {
00401   refpAddr = 0;
00402   if ( pObj ) {
00403     CLID       clid = pObj->clID();
00404     IRegistry* pR   = pObj->registry();
00405     string     p[2] = {m_current->fid(), pR->identifier()};
00406     TClass*    cl   = (clid == CLID_DataObject) ? m_classDO : getClass(pObj);
00407     size_t     len  = p[1].find('/',1);
00408     string     sect = p[1].substr(1,len==string::npos ? string::npos : len-1);
00409     pair<int,unsigned long> ret = m_current->saveObj(sect,p[1],cl,pObj,true);
00410     if ( ret.first > 1 || (clid == CLID_DataObject && ret.first==1) ) {
00411       unsigned long ip[2] = {0,ret.second};
00412       if ( m_currSection.empty() ) m_currSection = p[1];
00413       return createAddress(repSvcType(),clid,p,ip,refpAddr);
00414     }
00415     return error("Failed to write object data for:"+p[1]);
00416   }
00417   return error("createRep> Current Database is invalid!");
00418 }
00419 
00420 // Save object references to data file
00421 StatusCode RootCnvSvc::i__fillRepRefs(IOpaqueAddress* /* pA */, DataObject* pObj) {
00422   if ( pObj ) {
00423     typedef vector<IRegistry*> Leaves;
00424     Leaves leaves;
00425     RootObjectRefs refs;
00426     IRegistry* pR = pObj->registry();
00427     SmartIF<IDataManagerSvc> dataMgr(pR->dataSvc());
00428     if ( dataMgr ) {
00429       StatusCode status = dataMgr->objectLeaves(pObj, leaves);
00430       if ( status.isSuccess() )  {
00431         RootRef ref;
00432         const string& id    = pR->identifier();
00433         size_t        len   = id.find('/',1);
00434         string        sect  = id.substr(1,len==string::npos ? string::npos : len-1);
00435         LinkManager* pLinks = pObj->linkMgr();
00436         for(Leaves::iterator i=leaves.begin(), iend=leaves.end(); i != iend; ++i)  {
00437           if ( (*i)->address() ) {
00438             m_current->makeRef(*i,ref);
00439             ref.entry = (*i)->address()->ipar()[1];
00440             refs.refs.push_back(ref);
00441           }
00442         }
00443         for(int i = 0, n=pLinks->size(); i < n; ++i)  {
00444           LinkManager::Link* lnk = pLinks->link(i);
00445           int link_id = m_current->makeLink(lnk->path());
00446           refs.links.push_back(link_id);
00447         }
00448         pair<int,unsigned long> ret = m_current->save(sect,id+"#R",m_classRefs,&refs,true);
00449         if ( ret.first > 1 ) {
00450           log() << MSG::DEBUG << "Writing object:" << id << " " 
00451                 << ret.first << " " << hex << ret.second << dec << endmsg;
00452           return S_OK;
00453         }
00454       }
00455     }
00456   }
00457   return S_FAIL;
00458 }
00459 
00460 // Read existing object. Open transaction in read mode if not active
00461 StatusCode RootCnvSvc::i__createObj(IOpaqueAddress* pA, DataObject*& refpObj)  {
00462   refpObj = 0;
00463   if ( pA ) {
00464     RootDataConnection* con = 0;
00465     const string*  par  = pA->par();
00466     unsigned long* ipar = const_cast<unsigned long*>(pA->ipar());
00467     StatusCode sc = connectDatabase(par[0],IDataConnection::READ,&con);
00468     if ( sc.isSuccess() ) {
00469       ipar[0] = (unsigned long)con;
00470       DataObject* pObj = 0;
00471       size_t len = par[1].find('/',1);
00472       string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
00473 
00474       int nb = con->loadObj(section,par[1],ipar[1],pObj);
00475       if ( nb > 1 || (nb == 1 && pObj->clID() == CLID_DataObject) ) {
00476         refpObj = pObj;
00477         return S_OK;
00478       }
00479       delete pObj;
00480     }
00481     string tag = par[0]+":"+par[1];
00482     if ( m_badFiles.find(tag) == m_badFiles.end() ) {
00483       m_badFiles.insert(tag);
00484       return error("createObj> Cannot access the object:"+tag);
00485     }
00486     return S_FAIL;
00487   }
00488   return S_FAIL;
00489 }
00490 
00491 // Resolve the references of the created transient object.
00492 StatusCode RootCnvSvc::i__fillObjRefs(IOpaqueAddress* pA, DataObject* pObj) {
00493   if ( pA && pObj )  {
00494     const unsigned long* ipar = pA->ipar();
00495     RootDataConnection* con = (RootDataConnection*)ipar[0];
00496     if ( con ) {
00497       RootObjectRefs refs;
00498       const string* par = pA->par();
00499       size_t len = par[1].find('/',1);
00500       string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
00501       int nb = con->loadRefs(section,par[1],ipar[1],refs);
00502       log() << MSG::VERBOSE;
00503       if ( nb >= 1 ) {
00504         string npar[3];
00505         unsigned long nipar[2];
00506         IOpaqueAddress* nPA;
00507         IRegistry* pR = pObj->registry();
00508         SmartIF<IService> isvc(pR->dataSvc());
00509         SmartIF<IDataManagerSvc> dataMgr(pR->dataSvc());
00510         LinkManager* mgr = pObj->linkMgr();
00511         bool active = log().isActive();
00512         for(vector<int>::const_iterator i=refs.links.begin(); i!=refs.links.end();++i) {
00513           mgr->addLink(con->getLink(*i),0);
00514         }
00515         for(size_t j=0, n=refs.refs.size(); j<n; ++j)  {
00516           const RootRef& r = refs.refs[j];
00517           npar[0] = con->getDb(r.dbase);
00518           npar[1] = con->getCont(r.container);
00519           npar[2] = con->getLink(r.link);
00520           nipar[0] = 0;
00521           nipar[1] = r.entry;
00522           StatusCode sc = addressCreator()->createAddress(r.svc,r.clid,npar,nipar,nPA);
00523           if ( sc.isSuccess() ) {
00524             if ( active )  {
00525               log() << isvc->name() << " -> Register:" << pA->registry()->identifier() 
00526                 << "#" << npar[2] << "[" << r.entry << "]" << endmsg;
00527             }
00528             sc = dataMgr->registerAddress(pA->registry(),npar[2],nPA);
00529             if ( sc.isSuccess() ) {
00530               continue;
00531             }
00532           }
00533           log() << MSG::ERROR << con->fid() << ": Failed to create address!!!!" << endmsg;
00534           return S_FAIL;
00535         }
00536         return pObj->update();
00537       }
00538     }
00539     return S_FAIL;
00540   }
00541   return error("read> Cannot read object -- no valid object address present ");
00542 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Jan 30 2012 13:53:04 for Gaudi Framework, version v23r0 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004