36 using namespace Gaudi;
37 typedef const string&
CSTR;
39 #define S_OK StatusCode::SUCCESS
40 #define S_FAIL StatusCode::FAILURE
47 #define MBYTE 1024*1024
52 m_ioMgr(0), m_incidentSvc(0), m_current(0), m_setup(0)
78 RootCnvSvc::~RootCnvSvc() {
79 if (m_setup) m_setup->release();
98 return error(
"Failed to initialize ConversionSvc base class.");
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);
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);
115 m_classDO = gROOT->GetClass(cname.c_str());
116 if ( 0 == m_classDO )
117 return error(
"Unable to load class description for DataObject");
119 m_classRefs = gROOT->GetClass(cname.c_str());
120 if ( 0 == m_classRefs )
121 return error(
"Unable to load class description for ObjectRefs");
130 for(IIODataManager::Connections::iterator
i=cons.
begin();
i != cons.
end(); ++
i) {
133 if ( pc->
owner() ==
this && !m_ioPerfStats.empty() ) {
138 if ( num_clients == 0 ) {
139 if ( m_ioMgr->disconnect(pc).isSuccess() ) {
140 log() <<
"Disconnected data IO:" << pc->
fid()
151 releasePtr(m_incidentSvc);
152 m_setup->setIncidentSvc(0);
157 IConverter* RootCnvSvc::createConverter(
long typ,
const CLID& wanted,
const ICnvFactory*) {
163 return new RootNTupleCnv(typ,wanted,serviceLocator().
get(),
this);
165 return new RootNTupleCnv(typ,wanted,serviceLocator().
get(),
this);
167 return new RootConverter(typ,wanted,serviceLocator().
get(),
this);
175 TClass* cl = s_classesNames[cname];
177 cl = gROOT->GetClass(cname.c_str());
179 s_classesNames[cname] = cl;
180 s_classesClids[pObject->
clID()] = cl;
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;
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() ) {
216 log() <<
MSG::ERROR <<
"The dataset " << dsn <<
" cannot be opened in mode "
217 << openMode <<
". [Invalid mode]" <<
endmsg;
226 bool fire_incident =
false;
230 StatusCode sc = (mode != IDataConnection::READ)
232 : m_ioMgr->connectRead(
false,connection.
get());
233 c = sc.
isSuccess() ? m_ioMgr->connection(dataset) : 0;
235 bool writable = 0 != (mode&(IDataConnection::UPDATE|IDataConnection::RECREATE));
236 fire_incident = m_incidentEnabled && (0 != (mode&(IDataConnection::UPDATE|IDataConnection::READ)));
240 if ( 0 != (mode&IDataConnection::READ) ) {
241 if ( !m_ioPerfStats.empty() ) {
242 connection->enableStatistics(m_setup->loadSection);
248 m_incidentSvc->fireIncident(
Incident(dataset,mode == IDataConnection::READ
263 if ( fire_incident ) {
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);
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) {
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;
281 log() <<
"Prepare " << m_recordName <<
" " << fid <<
" [" << par[0] <<
"][" <<
i <<
"]" <<
endmsg;
286 log() <<
"No valid Records " << m_recordName <<
" present in:" << pc->
fid() <<
endmsg;
291 for(IIODataManager::Connections::iterator
i=cons.
begin();
i != cons.
end(); ++
i) {
296 if ( num_client == 0 ) {
297 if ( m_ioMgr->disconnect(pc).isSuccess() ) {
313 return error(
string(
"connectDatabase> Caught exception:")+e.
what());
317 return error(
"connectDatabase> Unknown Fatal Exception for "+dataset);
323 return connectOutput(db_name,
"NEW");
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);
333 Long64_t
evt = b->GetEntries();
334 TTree* t = b->GetTree();
335 TObjArray* a = t->GetListOfBranches();
336 Int_t nb = a->GetEntriesFast();
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);
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;
356 b->GetTree()->SetEntries(evt);
358 b->GetTree()->OptimizeBaskets(m_basketSize,1.1,
"");
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.,
"");
366 b->GetTree()->FlushBaskets();
369 log() <<
MSG::DEBUG <<
"Set section entries of " << m_currSection
370 <<
" to " << long(evt) <<
" entries." <<
endmsg;
373 return error(
"commitOutput> Failed to update entry numbers on "+dsn);
389 const unsigned long* ip,
392 refpAddress =
new RootAddress(typ,clid,par[0],par[1],ip[0],ip[1]);
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);
407 size_t len = path.find(
'/',1);
408 string section = path.substr(1,len==string::npos ? string::npos : len-1);
410 m_current->save(section,path+
"#R",0,refs,m_bufferSize,m_splitLevel);
422 string p[2] = {m_current->fid(), pR->
identifier()};
424 size_t len = p[1].find(
'/',1);
425 string sect = p[1].substr(1,len==string::npos ? string::npos : len-1);
427 m_current->saveObj(sect,p[1],cl,pObj,m_bufferSize,m_splitLevel,
true);
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);
433 return error(
"Failed to write object data for:"+p[1]);
435 return error(
"createRep> Current Database is invalid!");
447 StatusCode status = dataMgr->objectLeaves(pObj, leaves);
451 size_t len =
id.find(
'/',1);
452 string sect =
id.substr(1,len==string::npos ? string::npos : len-1);
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];
461 for(
int i = 0, n=pLinks->
size();
i < n; ++
i) {
463 int link_id = m_current->makeLink(lnk->
path());
467 m_current->save(sect,
id+
"#R",m_classRefs,&refs,m_bufferSize,m_splitLevel,
true);
468 if ( ret.
first > 1 ) {
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);
488 ipar[0] = (
unsigned long)con;
490 size_t len = par[1].find(
'/',1);
491 string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
493 int nb = con->
loadObj(section,par[1],ipar[1],pObj);
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);
513 const unsigned long* ipar = pA->
ipar();
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);
524 unsigned long nipar[2];
530 bool active =
log().isActive();
534 for(
size_t j=0, n=refs.
refs.
size(); j<n; ++j) {
545 <<
"#" << npar[2] <<
"[" << r.
entry <<
"]" <<
endmsg;
547 sc = dataMgr->registerAddress(pA->
registry(),npar[2],nPA);
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]");
567 return error(
"read> Cannot read object -- no valid object address present ");