| # 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