| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootCnvSvc.cpp
Go to the documentation of this file.
1 // $Id: RootCnvSvc.cpp,v 1.12 2010-09-27 15:43:53 frankb Exp $
2 //====================================================================
3 // RootCnvSvc implementation
4 //--------------------------------------------------------------------
5 //
6 // Description: Implementation of the ROOT data storage
7 //
8 // Author : M.Frank
9 //
10 //====================================================================
11
12 // Framework include files
13 #include "GaudiKernel/MsgStream.h"
14 #include "GaudiKernel/IRegistry.h"
15 #include "GaudiKernel/IUpdateable.h"
16 #include "GaudiKernel/IIncidentSvc.h"
17 #include "GaudiKernel/IDataManagerSvc.h"
18 #include "GaudiKernel/IDataProviderSvc.h"
19 #include "GaudiKernel/KeyedContainer.h"
20 #include "GaudiKernel/DataIncident.h"
21 #include "GaudiKernel/LinkManager.h"
22 #include "GaudiKernel/Incident.h"
23 #include "GaudiKernel/System.h"
24 #include "GaudiUtils/IIODataManager.h"
25 #include "RootCnv/RootRefs.h"
26 #include "RootCnv/RootCnvSvc.h"
27 #include "RootCnv/RootAddress.h"
28 #include "RootCnv/RootConverter.h"
29 #include "RootCnv/RootDatabaseCnv.h"
30 #include "RootCnv/RootDirectoryCnv.h"
31 #include "RootCnv/RootNTupleCnv.h"
32 #include "RootCnv/RootDataConnection.h"
33 #include "RootUtils.h"
34
35 using namespace std;
36 using namespace Gaudi;
37 typedef const string& CSTR;
38
39 #define S_OK StatusCode::SUCCESS
40 #define S_FAIL StatusCode::FAILURE
41 namespace GaudiRoot { bool patchStreamers(MsgStream& log); }
42
43 namespace {
44 static map<string, TClass*> s_classesNames;
45 static map<CLID, TClass*> s_classesClids;
46 }
47 #define MBYTE 1024*1024
48 #define kBYTE 1024
49 // Standard constructor
50 RootCnvSvc::RootCnvSvc(CSTR nam, ISvcLocator* svc)
51 : ConversionSvc( nam, svc, ROOT_StorageType),
52 m_ioMgr(0), m_incidentSvc(0), m_current(0), m_setup(0)
53 {
54 m_classRefs = m_classDO = 0;
55 m_setup = new RootConnectionSetup();
56 m_setup->cacheBranches.push_back("*");
57 declareProperty("IOPerfStats", m_ioPerfStats);
58 declareProperty("ShareFiles", m_shareFiles = "NO");
59 declareProperty("EnableIncident", m_incidentEnabled = true);
60 declareProperty("RecordsName", m_recordName = "/FileRecords");
61 declareProperty("LoadSection", m_setup->loadSection = "Event");
62
63 // ROOT Write parameters
64 declareProperty("AutoFlush", m_autoFlush = 100);
65 declareProperty("BasketSize", m_basketSize = 2*MBYTE);
66 declareProperty("BufferSize", m_bufferSize = 2*kBYTE);
67 declareProperty("SplitLevel", m_splitLevel = 0);
68 declareProperty("GlobalCompression",m_compression); // empty: do nothing
69
70 // ROOT Read parameters: must be shared for the entire file!
71 declareProperty("CacheSize", m_setup->cacheSize = 10*MBYTE);
72 declareProperty("LearnEntries", m_setup->learnEntries = 10);
73 declareProperty("CacheBranches", m_setup->cacheBranches);
74 declareProperty("VetoBranches", m_setup->vetoBranches);
75 }
76
77 // Standard destructor
78 RootCnvSvc::~RootCnvSvc() {
79 if (m_setup) m_setup->release();
80 }
81
82 // Small routine to issue exceptions
83 StatusCode RootCnvSvc::error(CSTR msg) {
84 if ( m_log ) {
85 log() << MSG::ERROR << "Error: " << msg << endmsg;
86 return S_FAIL;
87 }
88 MsgStream m(msgSvc(),name());
89 m << MSG::ERROR << "Error: " << msg << endmsg;
90 return S_FAIL;
91 }
92
93 // Initialize the Db data persistency service
94 StatusCode RootCnvSvc::initialize() {
95 string cname;
96 StatusCode status = ConversionSvc::initialize();
97 if ( !status.isSuccess() ) {
98 return error("Failed to initialize ConversionSvc base class.");
99 }
100 m_log = new MsgStream(msgSvc(),name());
101 if ( !m_compression.empty() ) {
102 log() << MSG::INFO << "Setting global ROOT compression to:" << m_compression << endmsg;
103 if ( !(status=RootConnectionSetup::setCompression(m_compression)).isSuccess() ) {
104 return error("Unable to interprete ROOT compression encoding:"+m_compression);
105 }
106 }
107 if( !(status=service("IODataManager", m_ioMgr)).isSuccess() )
108 return error("Unable to localize interface from service:IODataManager");
109 if( !(status=service("IncidentSvc", m_incidentSvc)).isSuccess() )
110 return error("Unable to localize interface from service:IncidentSvc");
111 m_setup->setMessageSvc(new MsgStream(msgSvc(),name()));
112 m_setup->setIncidentSvc(m_incidentSvc);
113 GaudiRoot::patchStreamers(log());
114 cname = System::typeinfoName(typeid(DataObject));
115 m_classDO = TClass::GetClass(cname.c_str());
116 if ( 0 == m_classDO )
117 return error("Unable to load class description for DataObject");
118 cname = System::typeinfoName(typeid(RootObjectRefs));
119 m_classRefs = TClass::GetClass(cname.c_str());
120 if ( 0 == m_classRefs )
121 return error("Unable to load class description for ObjectRefs");
122 return S_OK;
123 }
124
125 // Finalize the Db data persistency service
126 StatusCode RootCnvSvc::finalize() {
127 log() << MSG::INFO;
128 if ( m_ioMgr ) {
129 IIODataManager::Connections cons = m_ioMgr->connections(0);
130 for(IIODataManager::Connections::iterator i=cons.begin(); i != cons.end(); ++i) {
131 RootDataConnection* pc = dynamic_cast<RootDataConnection*>(*i);
132 if ( pc ) {
133 if ( pc->owner() == this && !m_ioPerfStats.empty() ) {
134 pc->saveStatistics(m_ioPerfStats);
135 }
136 if ( pc->lookupClient(this) ) {
137 size_t num_clients = pc->removeClient(this);
138 if ( num_clients == 0 ) {
139 if ( m_ioMgr->disconnect(pc).isSuccess() ) {
140 log() << "Disconnected data IO:" << pc->fid()
141 << " [" << pc->pfn() << "]" << endmsg;
142 delete pc;
143 }
144 }
145 }
146 }
147 }
148 releasePtr(m_ioMgr);
149 }
150 deletePtr(m_log);
151 releasePtr(m_incidentSvc);
152 m_setup->setIncidentSvc(0);
153 return ConversionSvc::finalize();
154 }
155
156 // ConversionSvc overload: Create new Converter using factory
157 IConverter* RootCnvSvc::createConverter(long typ,const CLID& wanted,const ICnvFactory*) {
158 if ( wanted == CLID_StatisticsFile )
159 return new RootDatabaseCnv(typ,wanted,serviceLocator().get(),this);
160 else if ( wanted == CLID_StatisticsDirectory )
161 return new RootDirectoryCnv(typ,wanted,serviceLocator().get(),this);
162 else if ( wanted == CLID_RowWiseTuple )
163 return new RootNTupleCnv(typ,wanted,serviceLocator().get(),this);
164 else if ( wanted == CLID_ColumnWiseTuple )
165 return new RootNTupleCnv(typ,wanted,serviceLocator().get(),this);
166 else
167 return new RootConverter(typ,wanted,serviceLocator().get(),this);
168 }
169
170 // ConversionSvc overload: Load the class (dictionary) for the converter
171 void RootCnvSvc::loadConverter(DataObject* pObject) {
172 if (pObject) {
173 string cname = System::typeinfoName(typeid(*pObject));
174 log() << MSG::DEBUG << "Trying to 'Autoload' dictionary for class " << cname << endmsg;
175 TClass* cl = s_classesNames[cname];
176 if ( 0 == cl ) {
177 cl = TClass::GetClass(cname.c_str());
178 if ( cl ) {
179 s_classesNames[cname] = cl;
180 s_classesClids[pObject->clID()] = cl;
181 }
182 }
183 }
184 }
185
186 // Helper: Get TClass for a given DataObject pointer
187 TClass* RootCnvSvc::getClass(DataObject* pObject) {
188 map<CLID, TClass*>::iterator i=s_classesClids.find(pObject->clID());
189 if ( i != s_classesClids.end() ) return (*i).second;
190 loadConverter(pObject);
191 i=s_classesClids.find(pObject->clID());
192 if ( i != s_classesClids.end() ) return (*i).second;
193
194 string cname = System::typeinfoName(typeid(*pObject));
195 throw runtime_error("Unknown ROOT class for object:"+cname);
196 return 0;
197 }
198
199 // Connect the output file to the service with open mode.
200 StatusCode RootCnvSvc::connectOutput(CSTR dsn, CSTR openMode) {
201 StatusCode sc = S_FAIL;
202 m_current = 0;
203 m_currSection = "";
204 if ( ::strncasecmp(openMode.c_str(),"RECREATE",3)==0 )
205 sc = connectDatabase(dsn, IDataConnection::RECREATE, &m_current);
206 else if ( ::strncasecmp(openMode.c_str(),"NEW",1)==0 )
207 sc = connectDatabase(dsn, IDataConnection::CREATE, &m_current);
208 else if ( ::strncasecmp(openMode.c_str(),"CREATE",1)==0 )
209 sc = connectDatabase(dsn, IDataConnection::CREATE, &m_current);
210 else if ( ::strncasecmp(openMode.c_str(),"UPDATE",1)==0 )
211 sc = connectDatabase(dsn, IDataConnection::UPDATE, &m_current);
212 if ( sc.isSuccess() && m_current && m_current->isConnected() ) {
213 return S_OK;
214 }
215 m_incidentSvc->fireIncident(Incident(dsn,IncidentType::FailOutputFile));
216 log() << MSG::ERROR << "The dataset " << dsn << " cannot be opened in mode "
217 << openMode << ". [Invalid mode]" << endmsg;
218 return sc;
219 }
220
221 // Connect the output file to the service with open mode.
222 StatusCode
223 RootCnvSvc::connectDatabase(CSTR dataset, int mode, RootDataConnection** con) {
224 try {
225 IDataConnection* c = m_ioMgr->connection(dataset);
226 bool fire_incident = false;
227 *con = 0;
228 if ( !c ) {
229 auto_ptr<RootDataConnection> connection(new RootDataConnection(this,dataset,m_setup));
230 StatusCode sc = (mode != IDataConnection::READ)
231 ? m_ioMgr->connectWrite(connection.get(),IDataConnection::IoType(mode),"ROOT")
232 : m_ioMgr->connectRead(false,connection.get());
233 c = sc.isSuccess() ? m_ioMgr->connection(dataset) : 0;
234 if ( c ) {
235 bool writable = 0 != (mode&(IDataConnection::UPDATE|IDataConnection::RECREATE));
236 fire_incident = m_incidentEnabled && (0 != (mode&(IDataConnection::UPDATE|IDataConnection::READ)));
237 if ( writable ) {
238 m_incidentSvc->fireIncident(ContextIncident<TFile*>(connection->pfn(),"CONNECTED_OUTPUT",connection->file()));
239 }
240 if ( 0 != (mode&IDataConnection::READ) ) {
241 if ( !m_ioPerfStats.empty() ) {
242 connection->enableStatistics(m_setup->loadSection);
243 }
244 }
245 connection.release();
246 }
247 else {
248 m_incidentSvc->fireIncident(Incident(dataset,mode == IDataConnection::READ
249 ? IncidentType::FailInputFile
250 : IncidentType::FailOutputFile));
251 // An error message was already printed by the IODataManager. no need to do it here!
252 return StatusCode::FAILURE;
253 }
254 }
255 RootDataConnection* pc = dynamic_cast<RootDataConnection*>(c);
256 if ( pc ) {
257 if ( !pc->isConnected() ) pc->connectRead();
258 *con = pc;
259 pc->resetAge();
260 pc->addClient(this);
261 }
262 if ( *con ) {
263 if ( fire_incident ) {
264 IOpaqueAddress* pAddr = 0;
265 string fid = pc->fid();
266 string section = m_recordName[0] == '/' ? m_recordName.substr(1) : m_recordName;
267 TBranch* b = pc->getBranch(section,m_recordName);
268 log() << MSG::VERBOSE;
269 if ( b ) {
270 const string par[2] = { fid, m_recordName };
271 unsigned long ipar[2] = { (unsigned long)(*con), (unsigned long)b->GetEntries()-1 };
272 for(int i=0; i<b->GetEntries(); ++i) {
273 ipar[1] = i;
274 if ( !pc->mergeFIDs().empty() )
275 fid = pc->mergeFIDs()[i];
276 if ( !createAddress(repSvcType(),CLID_DataObject,par,ipar,pAddr).isSuccess() ) {
277 log() << "Failed to create address for " << m_recordName << " in:" << fid
278 << " [" << pc->fid() << "][" << i << "]" << endmsg;
279 continue;
280 }
281 log() << "Prepare " << m_recordName << " " << fid << " [" << par[0] << "][" << i << "]" << endmsg;
282 m_incidentSvc->fireIncident(ContextIncident<IOpaqueAddress*>(fid,"FILE_OPEN_READ",pAddr));
283 }
284 }
285 else {
286 log() << "No valid Records " << m_recordName << " present in:" << pc->fid() << endmsg;
287 }
288 }
289 // We can remove retired connections, which are no longer used....
290 IIODataManager::Connections cons = m_ioMgr->connections(this);
291 for(IIODataManager::Connections::iterator i=cons.begin(); i != cons.end(); ++i) {
292 if ( (*i) != *con && !(*i)->isConnected() ) {
293 RootDataConnection* pc = dynamic_cast<RootDataConnection*>(*i);
294 if ( pc && pc->lookupClient(this) ) {
295 size_t num_client = pc->removeClient(this);
296 if ( num_client == 0 ) {
297 if ( m_ioMgr->disconnect(pc).isSuccess() ) {
298 log() << MSG::INFO << "Removed disconnected IO stream:" << pc->fid()
299 << " [" << pc->pfn() << "]" << endmsg;
300 delete pc;
301 }
302 }
303 }
304 }
305 }
306 return S_OK;
307 }
308 m_incidentSvc->fireIncident(Incident(dataset,IncidentType::FailOutputFile));
309 return S_FAIL;
310 }
311 catch (exception& e) {
312 m_incidentSvc->fireIncident(Incident(dataset,IncidentType::FailOutputFile));
313 return error(string("connectDatabase> Caught exception:")+e.what());
314 }
315 catch (...) {
316 m_incidentSvc->fireIncident(Incident(dataset,IncidentType::FailOutputFile));
317 return error("connectDatabase> Unknown Fatal Exception for "+dataset);
318 }
319 }
320
321 // Conect output stream (valid until overwritten)
322 StatusCode RootCnvSvc::connectOutput(CSTR db_name) {
323 return connectOutput(db_name, "NEW");
324 }
325
326 // Commit pending output on open container
327 StatusCode RootCnvSvc::commitOutput(CSTR dsn, bool /* doCommit */) {
328 if ( m_current ) {
329 size_t len = m_currSection.find('/',1);
330 string section = m_currSection.substr(1,len==string::npos ? string::npos : len-1);
331 TBranch* b = m_current->getBranch(section, m_currSection);
332 if ( b ) {
333 Long64_t evt = b->GetEntries();
334 TTree* t = b->GetTree();
335 TObjArray* a = t->GetListOfBranches();
336 Int_t nb = a->GetEntriesFast();
337 log() << MSG::DEBUG;
339 for(Int_t i=0; i<nb; ++i) {
340 TBranch* br_ptr = (TBranch*)a->UncheckedAt(i);
341 Long64_t br_evt = br_ptr->GetEntries();
342 if ( br_evt < evt ) {
343 Long64_t num = evt-br_evt;
344 br_ptr->SetAddress(0);
345 while(num>0) {
346 br_ptr->Fill();
347 --num;
348 }
349 log() << "commit: Added " << long(evt-br_evt)
350 << " Section: " << evt << " Branch: " << br_ptr->GetEntries()
351 << " RefNo: " << br_ptr->GetEntries()-1
352 << " NULL entries to:" << br_ptr->GetName() << endmsg;
353 }
354 }
355
356 b->GetTree()->SetEntries(evt);
357 if ( evt == 1 ) {
358 b->GetTree()->OptimizeBaskets(m_basketSize,1.1,"");
359 }
360 if ( evt > 0 && (evt%m_autoFlush)==0 ) {
361 if ( evt == m_autoFlush ) {
362 b->GetTree()->SetAutoFlush(m_autoFlush);
363 b->GetTree()->OptimizeBaskets(m_basketSize,1.,"");
364 }
365 else {
366 b->GetTree()->FlushBaskets();
367 }
368 }
369 log() << MSG::DEBUG << "Set section entries of " << m_currSection
370 << " to " << long(evt) << " entries." << endmsg;
371 }
372 else {
373 return error("commitOutput> Failed to update entry numbers on "+dsn);
374 }
375 }
376 return S_OK;
377 }
378
379 // Disconnect from an existing data stream.
380 StatusCode RootCnvSvc::disconnect(CSTR dataset) {
381 IDataConnection* c = m_ioMgr->connection(dataset);
382 return c ? m_ioMgr->disconnect(c) : S_FAIL;
383 }
384
385 // IAddressCreator implementation: Address creation
386 StatusCode RootCnvSvc::createAddress(long typ,
387 const CLID& clid,
388 const string* par,
389 const unsigned long* ip,
390 IOpaqueAddress*& refpAddress)
391 {
392 refpAddress = new RootAddress(typ,clid,par[0],par[1],ip[0],ip[1]);
393 return S_OK;
394 }
395
396 // Insert null marker for not existent transient object
397 StatusCode RootCnvSvc::createNullRep(const std::string& path) {
398 size_t len = path.find('/',1);
399 string section = path.substr(1,len==string::npos ? string::npos : len-1);
400 m_current->saveObj(section,path,0,0,m_bufferSize,m_splitLevel);
401 return S_OK;
402 }
403
404 // Insert null marker for not existent transient object
405 StatusCode RootCnvSvc::createNullRef(const std::string& path) {
406 RootObjectRefs* refs = 0;
407 size_t len = path.find('/',1);
408 string section = path.substr(1,len==string::npos ? string::npos : len-1);
409 pair<int,unsigned long> ret =
410 m_current->save(section,path+"#R",0,refs,m_bufferSize,m_splitLevel);
411 log() << MSG::VERBOSE << "Writing object:" << path << " "
412 << ret.first << " " << hex << ret.second << dec << " [NULL]" << endmsg;
413 return S_OK;
414 }
415
416 // Mark an object for write given an object reference
417 StatusCode RootCnvSvc::i__createRep(DataObject* pObj, IOpaqueAddress*& refpAddr) {
418 refpAddr = 0;
419 if ( pObj ) {
420 CLID clid = pObj->clID();
421 IRegistry* pR = pObj->registry();
422 string p[2] = {m_current->fid(), pR->identifier()};
423 TClass* cl = (clid == CLID_DataObject) ? m_classDO : getClass(pObj);
424 size_t len = p[1].find('/',1);
425 string sect = p[1].substr(1,len==string::npos ? string::npos : len-1);
426 pair<int,unsigned long> ret =
427 m_current->saveObj(sect,p[1],cl,pObj,m_bufferSize,m_splitLevel,true);
428 if ( ret.first > 1 || (clid == CLID_DataObject && ret.first==1) ) {
429 unsigned long ip[2] = {0,ret.second};
430 if ( m_currSection.empty() ) m_currSection = p[1];
431 return createAddress(repSvcType(),clid,p,ip,refpAddr);
432 }
433 return error("Failed to write object data for:"+p[1]);
434 }
435 return error("createRep> Current Database is invalid!");
436 }
437
438 // Save object references to data file
439 StatusCode RootCnvSvc::i__fillRepRefs(IOpaqueAddress* /* pA */, DataObject* pObj) {
440 if ( pObj ) {
441 typedef vector<IRegistry*> Leaves;
442 Leaves leaves;
443 RootObjectRefs refs;
444 IRegistry* pR = pObj->registry();
445 SmartIF<IDataManagerSvc> dataMgr(pR->dataSvc());
446 if ( dataMgr ) {
447 StatusCode status = dataMgr->objectLeaves(pObj, leaves);
448 if ( status.isSuccess() ) {
449 RootRef ref;
450 const string& id = pR->identifier();
451 size_t len = id.find('/',1);
452 string sect = id.substr(1,len==string::npos ? string::npos : len-1);
453 LinkManager* pLinks = pObj->linkMgr();
454 for(Leaves::iterator i=leaves.begin(), iend=leaves.end(); i != iend; ++i) {
455 if ( (*i)->address() ) {
456 m_current->makeRef(*i,ref);
457 ref.entry = (*i)->address()->ipar()[1];
458 refs.refs.push_back(ref);
459 }
460 }
461 for(int i = 0, n=pLinks->size(); i < n; ++i) {
462 LinkManager::Link* lnk = pLinks->link(i);
463 int link_id = m_current->makeLink(lnk->path());
464 refs.links.push_back(link_id);
465 }
466 pair<int,unsigned long> ret =
467 m_current->save(sect,id+"#R",m_classRefs,&refs,m_bufferSize,m_splitLevel,true);
468 if ( ret.first > 1 ) {
469 log() << MSG::DEBUG << "Writing object:" << id << " "
470 << ret.first << " " << hex << ret.second << dec << endmsg;
471 return S_OK;
472 }
473 }
474 }
475 }
476 return S_FAIL;
477 }
478
479 // Read existing object. Open transaction in read mode if not active
480 StatusCode RootCnvSvc::i__createObj(IOpaqueAddress* pA, DataObject*& refpObj) {
481 refpObj = 0;
482 if ( pA ) {
483 RootDataConnection* con = 0;
484 const string* par = pA->par();
485 unsigned long* ipar = const_cast<unsigned long*>(pA->ipar());
486 StatusCode sc = connectDatabase(par[0],IDataConnection::READ,&con);
487 if ( sc.isSuccess() ) {
488 ipar[0] = (unsigned long)con;
489 DataObject* pObj = 0;
490 size_t len = par[1].find('/',1);
491 string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
492
493 int nb = con->loadObj(section,par[1],ipar[1],pObj);
494 if ( nb > 1 || (nb == 1 && pObj->clID() == CLID_DataObject) ) {
495 refpObj = pObj;
496 return S_OK;
497 }
498 delete pObj;
499 }
500 string tag = par[0]+":"+par[1];
501 if ( m_badFiles.find(tag) == m_badFiles.end() ) {
502 m_badFiles.insert(tag);
503 return error("createObj> Cannot access the object:"+tag);
504 }
505 return S_FAIL;
506 }
507 return S_FAIL;
508 }
509
510 // Resolve the references of the created transient object.
511 StatusCode RootCnvSvc::i__fillObjRefs(IOpaqueAddress* pA, DataObject* pObj) {
512 if ( pA && pObj ) {
513 const unsigned long* ipar = pA->ipar();
514 RootDataConnection* con = (RootDataConnection*)ipar[0];
515 if ( con ) {
516 RootObjectRefs refs;
517 const string* par = pA->par();
518 size_t len = par[1].find('/',1);
519 string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
520 int nb = con->loadRefs(section,par[1],ipar[1],refs);
521 log() << MSG::VERBOSE;
522 if ( nb >= 1 ) {
523 string npar[3];
524 unsigned long nipar[2];
525 IOpaqueAddress* nPA;
526 IRegistry* pR = pObj->registry();
527 SmartIF<IService> isvc(pR->dataSvc());
528 SmartIF<IDataManagerSvc> dataMgr(pR->dataSvc());
529 LinkManager* mgr = pObj->linkMgr();
530 bool active = log().isActive();
531 for(vector<int>::const_iterator i=refs.links.begin(); i!=refs.links.end();++i) {
532 mgr->addLink(con->getLink(*i),0);
533 }
534 for(size_t j=0, n=refs.refs.size(); j<n; ++j) {
535 const RootRef& r = refs.refs[j];
536 npar[0] = con->getDb(r.dbase);
537 npar[1] = con->getCont(r.container);
538 npar[2] = con->getLink(r.link);
539 nipar[0] = 0;
540 nipar[1] = r.entry;
541 StatusCode sc = addressCreator()->createAddress(r.svc,r.clid,npar,nipar,nPA);
542 if ( sc.isSuccess() ) {
543 if ( active ) {
544 log() << isvc->name() << " -> Register:" << pA->registry()->identifier()
545 << "#" << npar[2] << "[" << r.entry << "]" << endmsg;
546 }
547 sc = dataMgr->registerAddress(pA->registry(),npar[2],nPA);
548 if ( sc.isSuccess() ) {
549 continue;
550 }
551 }
552 log() << MSG::ERROR << con->fid() << ": Failed to create address!!!!" << endmsg;
553 return S_FAIL;
554 }
555 return pObj->update();
556 }
557 else if ( nb < 0 ) {
558 string tag = par[0]+":"+par[1];
559 if ( m_badFiles.find(tag) == m_badFiles.end() ) {
560 m_badFiles.insert(tag);
561 return error("createObj> Cannot access the object:"+tag+" [Corrupted file]");
562 }
563 }
564 }
565 return S_FAIL;
566 }
567 return error("read> Cannot read object -- no valid object address present ");
568 }