The Gaudi Framework  v30r3 (a5ef0a68)
RootCnvSvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RootCnvSvc implementation
3 //--------------------------------------------------------------------
4 //
5 // Description: Implementation of the ROOT data storage
6 //
7 // Author : M.Frank
8 //
9 //====================================================================
10 
11 // Framework include files
12 #include "RootCnv/RootCnvSvc.h"
17 #include "GaudiKernel/IRegistry.h"
19 #include "GaudiKernel/Incident.h"
22 #include "GaudiKernel/MsgStream.h"
23 #include "GaudiKernel/System.h"
24 #include "RootCnv/RootAddress.h"
25 #include "RootCnv/RootConverter.h"
29 #include "RootCnv/RootNTupleCnv.h"
30 #include "RootCnv/RootRefs.h"
31 #include "RootUtils.h"
32 
33 using namespace std;
34 using namespace Gaudi;
35 typedef const string& CSTR;
36 
37 #define S_OK StatusCode::SUCCESS
38 #define S_FAIL StatusCode::FAILURE
39 namespace GaudiRoot
40 {
41  bool patchStreamers( MsgStream& log );
42 }
43 
44 namespace
45 {
46  static map<string, TClass*> s_classesNames;
47  static map<CLID, TClass*> s_classesClids;
48 }
49 #define MBYTE ( 1024 * 1024 )
50 #define kBYTE 1024
51 // Standard constructor
52 RootCnvSvc::RootCnvSvc( CSTR nam, ISvcLocator* svc )
53  : ConversionSvc( nam, svc, ROOT_StorageType ), m_setup{new RootConnectionSetup()}
54 {
55  m_setup->cacheBranches.push_back( "*" );
56  declareProperty( "LoadSection", m_setup->loadSection = "Event" );
57 
58  // ROOT Read parameters: must be shared for the entire file!
59  declareProperty( "CacheSize", m_setup->cacheSize = 10 * MBYTE );
60  declareProperty( "LearnEntries", m_setup->learnEntries = 10 );
61  declareProperty( "CacheBranches", m_setup->cacheBranches );
62  declareProperty( "VetoBranches", m_setup->vetoBranches );
63 }
64 
65 // Small routine to issue exceptions
67 {
68  if ( m_log ) {
69  log() << MSG::ERROR << "Error: " << msg << endmsg;
70  return S_FAIL;
71  }
72  MsgStream m( msgSvc(), name() );
73  m << MSG::ERROR << "Error: " << msg << endmsg;
74  return S_FAIL;
75 }
76 
77 // Initialize the Db data persistency service
79 {
80  string cname;
82  if ( !status.isSuccess() ) {
83  return error( "Failed to initialize ConversionSvc base class." );
84  }
85  m_log.reset( new MsgStream( msgSvc(), name() ) );
86  if ( !m_compression.empty() ) {
87  log() << MSG::INFO << "Setting global ROOT compression to:" << m_compression.value() << endmsg;
88  if ( !( status = RootConnectionSetup::setCompression( m_compression.value() ) ).isSuccess() ) {
89  return error( "Unable to interprete ROOT compression encoding:" + m_compression );
90  }
91  }
92  m_ioMgr = service( "IODataManager" );
93  if ( !m_ioMgr ) return error( "Unable to localize interface from service:IODataManager" );
94  m_incidentSvc = service( "IncidentSvc" );
95  if ( !m_incidentSvc ) return error( "Unable to localize interface from service:IncidentSvc" );
96  m_setup->setMessageSvc( new MsgStream( msgSvc(), name() ) );
97  m_setup->setIncidentSvc( m_incidentSvc.get() );
99  cname = System::typeinfoName( typeid( DataObject ) );
100  m_classDO = TClass::GetClass( cname.c_str() );
101  if ( !m_classDO ) return error( "Unable to load class description for DataObject" );
102  cname = System::typeinfoName( typeid( RootObjectRefs ) );
103  m_classRefs = TClass::GetClass( cname.c_str() );
104  if ( !m_classRefs ) return error( "Unable to load class description for ObjectRefs" );
105  return S_OK;
106 }
107 
108 // Finalize the Db data persistency service
110 {
111  log() << MSG::INFO;
112  if ( m_ioMgr ) {
113  IIODataManager::Connections cons = m_ioMgr->connections( nullptr );
114  for ( auto& i : cons ) {
115  auto pc = dynamic_cast<RootDataConnection*>( i );
116  if ( pc ) {
117  if ( pc->owner() == this && !m_ioPerfStats.empty() ) {
118  pc->saveStatistics( m_ioPerfStats.value() );
119  }
120  if ( pc->lookupClient( this ) ) {
121  size_t num_clients = pc->removeClient( this );
122  if ( num_clients == 0 ) {
123  if ( m_ioMgr->disconnect( pc ).isSuccess() ) {
124  log() << "Disconnected data IO:" << pc->fid() << " [" << pc->pfn() << "]" << endmsg;
125  delete pc;
126  }
127  }
128  }
129  }
130  }
131  m_ioMgr.reset();
132  }
133  m_log.reset();
135  m_setup->setIncidentSvc( nullptr );
136  return ConversionSvc::finalize();
137 }
138 
139 // ConversionSvc overload: Create new Converter using factory
140 IConverter* RootCnvSvc::createConverter( long typ, const CLID& wanted, const ICnvFactory* )
141 {
142  if ( wanted == CLID_StatisticsFile )
143  return new RootDatabaseCnv( typ, wanted, serviceLocator().get(), this );
144  else if ( wanted == CLID_StatisticsDirectory )
145  return new RootDirectoryCnv( typ, wanted, serviceLocator().get(), this );
146  else if ( wanted == CLID_RowWiseTuple )
147  return new RootNTupleCnv( typ, wanted, serviceLocator().get(), this );
148  else if ( wanted == CLID_ColumnWiseTuple )
149  return new RootNTupleCnv( typ, wanted, serviceLocator().get(), this );
150  else
151  return new RootConverter( typ, wanted, serviceLocator().get(), this );
152 }
153 
154 // ConversionSvc overload: Load the class (dictionary) for the converter
156 {
157  if ( pObject ) {
158  string cname = System::typeinfoName( typeid( *pObject ) );
159  if ( log().level() <= MSG::DEBUG )
160  log() << MSG::DEBUG << "Trying to 'Autoload' dictionary for class " << cname << endmsg;
161  TClass* cl = s_classesNames[cname];
162  if ( nullptr == cl ) {
163  cl = TClass::GetClass( cname.c_str() );
164  if ( cl ) {
165  s_classesNames[cname] = cl;
166  s_classesClids[pObject->clID()] = cl;
167  }
168  }
169  }
170 }
171 
172 // Helper: Get TClass for a given DataObject pointer
173 TClass* RootCnvSvc::getClass( DataObject* pObject )
174 {
175  auto i = s_classesClids.find( pObject->clID() );
176  if ( i != s_classesClids.end() ) return i->second;
177  loadConverter( pObject );
178  i = s_classesClids.find( pObject->clID() );
179  if ( i != s_classesClids.end() ) return i->second;
180 
181  string cname = System::typeinfoName( typeid( *pObject ) );
182  throw runtime_error( "Unknown ROOT class for object:" + cname );
183  return nullptr;
184 }
185 
186 // Connect the output file to the service with open mode.
188 {
189  StatusCode sc = S_FAIL;
190  m_current = nullptr;
192  if (::strncasecmp( openMode.c_str(), "RECREATE", 3 ) == 0 )
194  else if (::strncasecmp( openMode.c_str(), "NEW", 1 ) == 0 )
196  else if (::strncasecmp( openMode.c_str(), "CREATE", 1 ) == 0 )
198  else if (::strncasecmp( openMode.c_str(), "UPDATE", 1 ) == 0 )
200  if ( sc.isSuccess() && m_current && m_current->isConnected() ) {
201  return S_OK;
202  }
203  m_incidentSvc->fireIncident( Incident( dsn, IncidentType::FailOutputFile ) );
204  log() << MSG::ERROR << "The dataset " << dsn << " cannot be opened in mode " << openMode << ". [Invalid mode]"
205  << endmsg;
206  return sc;
207 }
208 
209 // Connect the output file to the service with open mode.
211 {
212  try {
213  IDataConnection* c = m_ioMgr->connection( dataset );
214  bool fire_incident = false;
215  *con = nullptr;
216  if ( !c ) {
217  auto connection = std::make_unique<RootDataConnection>( this, dataset, m_setup );
218  StatusCode sc = ( mode != IDataConnection::READ )
219  ? m_ioMgr->connectWrite( connection.get(), IDataConnection::IoType( mode ), "ROOT" )
220  : m_ioMgr->connectRead( false, connection.get() );
221  c = sc.isSuccess() ? m_ioMgr->connection( dataset ) : nullptr;
222  if ( c ) {
223  bool writable = 0 != ( mode & ( IDataConnection::UPDATE | IDataConnection::RECREATE ) );
224  fire_incident = m_incidentEnabled && ( 0 != ( mode & ( IDataConnection::UPDATE | IDataConnection::READ ) ) );
225  if ( writable ) {
227  ContextIncident<TFile*>( connection->pfn(), "CONNECTED_OUTPUT", connection->file() ) );
228  }
229  if ( 0 != ( mode & IDataConnection::READ ) ) {
230  if ( !m_ioPerfStats.empty() ) {
231  connection->enableStatistics( m_setup->loadSection );
232  }
233  }
234  connection.release();
235  } else {
237  dataset, mode == IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
238  // An error message was already printed by the IODataManager. no need to do it here!
239  return StatusCode::FAILURE;
240  }
241  }
242  RootDataConnection* pc = dynamic_cast<RootDataConnection*>( c );
243  if ( pc ) {
244  if ( !pc->isConnected() ) pc->connectRead();
245  *con = pc;
246  pc->resetAge();
247  pc->addClient( this );
248  }
249  if ( *con ) {
250  if ( fire_incident ) {
251  IOpaqueAddress* pAddr = nullptr;
252  string fid = pc->fid();
253  string section = m_recordName[0] == '/' ? m_recordName.value().substr( 1 ) : m_recordName.value();
254  TBranch* b = pc->getBranch( section, m_recordName.value() );
255  if ( b ) {
256  const string par[2] = {fid, m_recordName};
257  unsigned long ipar[2] = {(unsigned long)( *con ), (unsigned long)b->GetEntries() - 1};
258  for ( int i = 0; i < b->GetEntries(); ++i ) {
259  ipar[1] = i;
260  if ( !pc->mergeFIDs().empty() ) fid = pc->mergeFIDs()[i];
261  if ( !createAddress( repSvcType(), CLID_DataObject, par, ipar, pAddr ).isSuccess() ) {
262  if ( log().level() <= MSG::VERBOSE )
263  log() << MSG::VERBOSE << "Failed to create address for " << m_recordName << " in:" << fid << " ["
264  << pc->fid() << "][" << i << "]" << endmsg;
265  continue;
266  }
267  if ( log().level() <= MSG::VERBOSE )
268  log() << MSG::VERBOSE << "Prepare " << m_recordName << " " << fid << " [" << par[0] << "][" << i << "]"
269  << endmsg;
270  m_incidentSvc->fireIncident( ContextIncident<IOpaqueAddress*>( fid, "FILE_OPEN_READ", pAddr ) );
271  }
272  } else {
273  if ( log().level() <= MSG::VERBOSE )
274  log() << MSG::VERBOSE << "No valid Records " << m_recordName << " present in:" << pc->fid() << endmsg;
275  }
276  }
277 
278  // We can remove retired connections, which are no longer used....
279  for ( auto& i : m_ioMgr->connections( this ) ) {
280  if ( i != *con && !i->isConnected() ) {
281  RootDataConnection* pc = dynamic_cast<RootDataConnection*>( i );
282  if ( pc && pc->lookupClient( this ) ) {
283  size_t num_client = pc->removeClient( this );
284  if ( num_client == 0 ) {
285  if ( m_ioMgr->disconnect( pc ).isSuccess() ) {
286  log() << MSG::INFO << "Removed disconnected IO stream:" << pc->fid() << " [" << pc->pfn() << "]"
287  << endmsg;
288  delete pc;
289  }
290  }
291  }
292  }
293  }
294  return S_OK;
295  }
296  m_incidentSvc->fireIncident( Incident( dataset, IncidentType::FailOutputFile ) );
297  return S_FAIL;
298  } catch ( exception& e ) {
299  m_incidentSvc->fireIncident( Incident( dataset, IncidentType::FailOutputFile ) );
300  return error( string( "connectDatabase> Caught exception:" ) + e.what() );
301  } catch ( ... ) {
302  m_incidentSvc->fireIncident( Incident( dataset, IncidentType::FailOutputFile ) );
303  return error( "connectDatabase> Unknown Fatal Exception for " + dataset );
304  }
305 }
306 
307 // Conect output stream (valid until overwritten)
308 StatusCode RootCnvSvc::connectOutput( CSTR db_name ) { return connectOutput( db_name, "NEW" ); }
309 
310 // Commit pending output on open container
311 StatusCode RootCnvSvc::commitOutput( CSTR dsn, bool /* doCommit */ )
312 {
313  if ( m_current ) {
314  size_t len = m_currSection.find( '/', 1 );
315  string section = m_currSection.substr( 1, len == string::npos ? string::npos : len - 1 );
316  TBranch* b = m_current->getBranch( section, m_currSection );
317  if ( b ) {
318  Long64_t evt = b->GetEntries();
319  TTree* t = b->GetTree();
320  TObjArray* a = t->GetListOfBranches();
321  Int_t nb = a->GetEntriesFast();
323  for ( Int_t i = 0; i < nb; ++i ) {
324  TBranch* br_ptr = (TBranch*)a->UncheckedAt( i );
325  Long64_t br_evt = br_ptr->GetEntries();
326  if ( br_evt < evt ) {
327  Long64_t num = evt - br_evt;
328  br_ptr->SetAddress( nullptr );
329  while ( num > 0 ) {
330  br_ptr->Fill();
331  --num;
332  }
333  if ( log().level() <= MSG::DEBUG )
334  log() << MSG::DEBUG << "commit: Added " << long( evt - br_evt ) << " Section: " << evt
335  << " Branch: " << br_ptr->GetEntries() << " RefNo: " << br_ptr->GetEntries() - 1
336  << " NULL entries to:" << br_ptr->GetName() << endmsg;
337  }
338  }
339 
340  b->GetTree()->SetEntries( evt );
341  if ( evt == 1 ) {
342  b->GetTree()->OptimizeBaskets( m_basketSize, 1.1, "" );
343  }
344  if ( evt > 0 && ( evt % m_autoFlush ) == 0 ) {
345  if ( evt == m_autoFlush ) {
346  b->GetTree()->SetAutoFlush( m_autoFlush );
347  b->GetTree()->OptimizeBaskets( m_basketSize, 1., "" );
348  } else {
349  b->GetTree()->FlushBaskets();
350  }
351  }
352  if ( log().level() <= MSG::DEBUG )
353  log() << MSG::DEBUG << "Set section entries of " << m_currSection << " to " << long( evt ) << " entries."
354  << endmsg;
355  } else {
356  return error( "commitOutput> Failed to update entry numbers on " + dsn );
357  }
358  }
359  return S_OK;
360 }
361 
362 // Disconnect from an existing data stream.
364 {
365  IDataConnection* c = m_ioMgr->connection( dataset );
366  return c ? m_ioMgr->disconnect( c ) : S_FAIL;
367 }
368 
369 // IAddressCreator implementation: Address creation
370 StatusCode RootCnvSvc::createAddress( long typ, const CLID& clid, const string* par, const unsigned long* ip,
371  IOpaqueAddress*& refpAddress )
372 {
373  refpAddress = new RootAddress( typ, clid, par[0], par[1], ip[0], ip[1] );
374  return S_OK;
375 }
376 
377 // Insert null marker for not existent transient object
379 {
380  size_t len = path.find( '/', 1 );
381  string section = path.substr( 1, len == string::npos ? string::npos : len - 1 );
382  m_current->saveObj( section, path, nullptr, nullptr, m_bufferSize, m_splitLevel );
383  return S_OK;
384 }
385 
386 // Insert null marker for not existent transient object
388 {
389  RootObjectRefs* refs = nullptr;
390  size_t len = path.find( '/', 1 );
391  string section = path.substr( 1, len == string::npos ? string::npos : len - 1 );
392  pair<int, unsigned long> ret = m_current->save( section, path + "#R", nullptr, refs, m_bufferSize, m_splitLevel );
393  if ( log().level() <= MSG::VERBOSE )
394  log() << MSG::VERBOSE << "Writing object:" << path << " " << ret.first << " " << hex << ret.second << dec
395  << " [NULL]" << endmsg;
396  return S_OK;
397 }
398 
399 // Mark an object for write given an object reference
401 {
402  refpAddr = nullptr;
403  if ( !pObj ) return error( "createRep> Current Database is invalid!" );
404  CLID clid = pObj->clID();
405  IRegistry* pR = pObj->registry();
406  string p[2] = {m_current->fid(), pR->identifier()};
407  TClass* cl = ( clid == CLID_DataObject ) ? m_classDO : getClass( pObj );
408  size_t len = p[1].find( '/', 1 );
409  string sect = p[1].substr( 1, len == string::npos ? string::npos : len - 1 );
410  pair<int, unsigned long> ret = m_current->saveObj( sect, p[1], cl, pObj, m_bufferSize, m_splitLevel, true );
411  if ( ret.first > 1 || ( clid == CLID_DataObject && ret.first == 1 ) ) {
412  unsigned long ip[2] = {0, ret.second};
413  if ( m_currSection.empty() ) m_currSection = p[1];
414  return createAddress( repSvcType(), clid, p, ip, refpAddr );
415  }
416  return error( "Failed to write object data for:" + p[1] );
417 }
418 
419 // Save object references to data file
421 {
422  if ( pObj ) {
423  typedef vector<IRegistry*> Leaves;
424  Leaves leaves;
425  RootObjectRefs refs;
426  IRegistry* pR = pObj->registry();
427  auto dataMgr = SmartIF<IDataManagerSvc>{pR->dataSvc()};
428  if ( dataMgr ) {
429  StatusCode status = dataMgr->objectLeaves( pObj, leaves );
430  if ( status.isSuccess() ) {
431  RootRef ref;
432  const string& id = pR->identifier();
433  size_t len = id.find( '/', 1 );
434  string sect = id.substr( 1, len == string::npos ? string::npos : len - 1 );
435  LinkManager* pLinks = pObj->linkMgr();
436  for ( auto& i : leaves ) {
437  if ( i->address() ) {
438  m_current->makeRef( *i, ref );
439  ref.entry = i->address()->ipar()[1];
440  refs.refs.push_back( ref );
441  }
442  }
443  for ( int i = 0, n = pLinks->size(); i < n; ++i ) {
444  LinkManager::Link* lnk = pLinks->link( i );
445  int link_id = m_current->makeLink( lnk->path() );
446  refs.links.push_back( link_id );
447  }
449  m_current->save( sect, id + "#R", m_classRefs, &refs, m_bufferSize, m_splitLevel, true );
450  if ( ret.first > 1 ) {
451  if ( log().level() <= MSG::DEBUG )
452  log() << MSG::DEBUG << "Writing object:" << id << " " << ret.first << " " << hex << ret.second << dec
453  << endmsg;
454  return S_OK;
455  }
456  }
457  }
458  }
459  return S_FAIL;
460 }
461 
462 // Read existing object. Open transaction in read mode if not active
464 {
465  refpObj = nullptr;
466  if ( !pA ) return S_FAIL;
467  RootDataConnection* con = nullptr;
468  const string* par = pA->par();
469  unsigned long* ipar = const_cast<unsigned long*>( pA->ipar() );
470  StatusCode sc = connectDatabase( par[0], IDataConnection::READ, &con );
471  if ( sc.isSuccess() ) {
472  ipar[0] = (unsigned long)con;
473  DataObject* pObj = nullptr;
474  size_t len = par[1].find( '/', 1 );
475  string section = par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
476 
477  int nb = con->loadObj( section, par[1], ipar[1], pObj );
478  if ( nb > 1 || ( nb == 1 && pObj->clID() == CLID_DataObject ) ) {
479  refpObj = pObj;
480  return S_OK;
481  }
482  delete pObj;
483  }
484  string tag = par[0] + ":" + par[1];
485  if ( m_badFiles.find( tag ) == m_badFiles.end() ) {
486  m_badFiles.insert( tag );
487  return error( "createObj> Cannot access the object:" + tag );
488  }
489  return S_FAIL;
490 }
491 
492 // Resolve the references of the created transient object.
494 {
495  if ( !pA || !pObj ) return error( "read> Cannot read object -- no valid object address present " );
496 
497  const unsigned long* ipar = pA->ipar();
498  RootDataConnection* con = (RootDataConnection*)ipar[0];
499  if ( con ) {
500  RootObjectRefs refs;
501  const string* par = pA->par();
502  size_t len = par[1].find( '/', 1 );
503  string section = par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
504  int nb = con->loadRefs( section, par[1], ipar[1], refs );
505  if ( nb >= 1 ) {
506  string npar[3];
507  unsigned long nipar[2];
508  IRegistry* pR = pObj->registry();
509  auto dataMgr = SmartIF<IDataManagerSvc>{pR->dataSvc()};
510  LinkManager* mgr = pObj->linkMgr();
511  for ( const auto& i : refs.links ) mgr->addLink( con->getLink( i ), nullptr );
512  for ( auto& r : refs.refs ) {
513  npar[0] = con->getDb( r.dbase );
514  npar[1] = con->getCont( r.container );
515  npar[2] = con->getLink( r.link );
516  nipar[0] = 0;
517  nipar[1] = r.entry;
518  IOpaqueAddress* nPA = nullptr;
519  StatusCode sc = addressCreator()->createAddress( r.svc, r.clid, npar, nipar, nPA );
520  if ( sc.isSuccess() ) {
521  if ( log().level() <= MSG::VERBOSE )
522  log() << MSG::VERBOSE << dataMgr.as<IService>()->name() << " -> Register:" << pA->registry()->identifier()
523  << "#" << npar[2] << "[" << r.entry << "]" << endmsg;
524  sc = dataMgr->registerAddress( pA->registry(), npar[2], nPA );
525  if ( sc.isSuccess() ) continue;
526  }
527  log() << MSG::ERROR << con->fid() << ": Failed to create address!!!!" << endmsg;
528  return S_FAIL;
529  }
530  return pObj->update();
531  } else if ( nb < 0 ) {
532  string tag = par[0] + ":" + par[1];
533  if ( m_badFiles.find( tag ) == m_badFiles.end() ) {
534  m_badFiles.insert( tag );
535  return error( "createObj> Cannot access the object:" + tag + " [Corrupted file]" );
536  }
537  }
538  }
539  return S_FAIL;
540 }
void addClient(const IInterface *client)
Add new client to this data source.
bool lookupClient(const IInterface *client) const
Lookup client for this data source.
constexpr static const auto FAILURE
Definition: StatusCode.h:88
std::pair< int, unsigned long > saveObj(boost::string_ref section, boost::string_ref cnt, TClass *cl, DataObject *pObj, int buff_siz, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
Definition: DataObject.cpp:71
MsgStream & log() const
Helper: Use message streamer.
Definition: RootCnvSvc.h:99
Gaudi::Property< int > m_autoFlush
Definition: RootCnvSvc.h:65
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
T empty(T...args)
Description:
Definition: RootAddress.h:37
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
The data converters are responsible to translate data from one representation into another...
Definition: IConverter.h:58
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:288
const std::string & fid() const
Access file id.
std::string m_currSection
Property: ROOT section name.
Definition: RootCnvSvc.h:88
Gaudi::Property< std::string > m_recordName
Definition: RootCnvSvc.h:61
virtual StatusCode createNullRef(const std::string &path)
Insert null marker for not existent transient object.
Definition: RootCnvSvc.cpp:387
IoType
I/O Connection types.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
Definition: RootCnvSvc.h:78
bool isConnected() const override
Check if connected to data source.
const std::string & getDb(int which) const
Access database/file name from saved index.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:332
int loadRefs(boost::string_ref section, boost::string_ref cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
virtual StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ipar, IOpaqueAddress *&refpAddress)=0
Create a Generic address using explicit arguments to identify a single object.
StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
IAddressCreator implementation: Address creation.
Definition: RootCnvSvc.cpp:370
bool isSuccess() const
Definition: StatusCode.h:287
T log(T...args)
int makeLink(boost::string_ref p)
Convert path string to path index.
std::shared_ptr< RootConnectionSetup > m_setup
Setup structure (ref-counted) and passed to data connections.
Definition: RootCnvSvc.h:86
void loadConverter(DataObject *pObj) override
ConversionSvc overload: Load the class (dictionary) for the converter.
Definition: RootCnvSvc.cpp:155
MsgStream & dec(MsgStream &log)
Definition: MsgStream.h:299
virtual IRegistry * registry() const =0
Update branch name.
Gaudi::Property< std::string > m_compression
Definition: RootCnvSvc.h:72
size_t removeClient(const IInterface *client)
Remove client from this data source.
constexpr double pc
STL namespace.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Details::PropertyBase &prop)
Declare a property.
bool patchStreamers(MsgStream &log)
StatusCode initialize() override
ConversionSvc overload: initialize Db service.
Definition: RootCnvSvc.cpp:78
const std::string & getLink(int which) const
Access link name from saved index.
T end(T...args)
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
Definition: RootCnvSvc.cpp:210
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
Definition: RootRefs.h:64
StatusCode finalize() override
ConversionSvc overload: Finalize Db service.
Definition: RootCnvSvc.cpp:109
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:304
Gaudi::Property< int > m_splitLevel
Definition: RootCnvSvc.h:71
Gaudi::Property< int > m_bufferSize
Definition: RootCnvSvc.h:69
virtual const std::string * par() const =0
Retrieve String parameters.
const std::string & pfn() const
Access physical file name.
STL class.
StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
Commit pending output.
Definition: RootCnvSvc.cpp:311
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:73
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
Definition: RootRefs.h:60
LinkManager * linkMgr() const
Retrieve Link manager.
Definition: DataObject.h:75
STL class.
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
Persistent reference object.
Definition: RootRefs.h:31
T push_back(T...args)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
Definition: DataObject.cpp:62
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const id_type & identifier() const =0
Full identifier (or key)
T what(T...args)
std::pair< int, unsigned long > save(boost::string_ref section, boost::string_ref cnt, TClass *cl, void *pObj, int buff_siz, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
Gaudi::Property< std::string > m_ioPerfStats
Definition: RootCnvSvc.h:56
General service interface definition.
Definition: IService.h:18
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
std::unique_ptr< MsgStream > m_log
Message streamer.
Definition: RootCnvSvc.h:94
constexpr double m
Definition: SystemOfUnits.h:94
#define S_OK
Definition: RootCnvSvc.cpp:37
int loadObj(boost::string_ref section, boost::string_ref cnt, unsigned long entry, DataObject *&pObj)
Load object.
Statistics file converter class definition.
static StatusCode setCompression(boost::string_ref compression)
Set the global compression level.
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
TClass * m_classDO
TClass pointer to DataObject class.
Definition: RootCnvSvc.h:84
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
const long ROOT_StorageType
Definition: ClassID.h:52
virtual StatusCode i__createObj(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create transient object from persistent data.
Definition: RootCnvSvc.cpp:463
T reset(T...args)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
const std::string & getCont(int which) const
Access container name from saved index.
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
T clear(T...args)
NTuple converter class definition for NTuples writted/read using ROOT.
Definition: RootNTupleCnv.h:36
STL class.
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
Definition: RootCnvSvc.cpp:363
std::vector< int > links
The links of the link manager.
Definition: RootRefs.h:62
const StringVec & mergeFIDs() const
Access merged FIDs.
IConverter * createConverter(long typ, const CLID &wanted, const ICnvFactory *fac) override
ConversionSvc overload: Create new Converter using factory.
Definition: RootCnvSvc.cpp:140
T insert(T...args)
std::set< std::string > m_badFiles
Set with bad files/tables.
Definition: RootCnvSvc.h:91
#define MBYTE
Definition: RootCnvSvc.cpp:49
TBranch * getBranch(boost::string_ref section, boost::string_ref branch_name)
Access data branch by name: Get existing branch in read only mode.
Description: NTuple directory converter class definition Definition of the converter to manage the di...
virtual StatusCode createNullRep(const std::string &path)
Insert null marker for not existent transient object.
Definition: RootCnvSvc.cpp:378
T find(T...args)
StatusCode connectRead() override
Open data stream in read mode.
STL class.
ABC describing basic data connection.
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
Definition: RootCnvSvc.h:76
void resetAge()
Reset age.
T c_str(T...args)
Base class for all Incidents (computing events).
Definition: Incident.h:17
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
Definition: RootCnvSvc.cpp:420
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
Definition: RootCnvSvc.cpp:493
T substr(T...args)
Gaudi::Property< int > m_basketSize
Definition: RootCnvSvc.h:67
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn&#39;t already exist.
Definition: Service.h:84
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
MSG::Level level() const
Retrieve output level.
Definition: MsgStream.h:108
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:92
Opaque address interface definition.
Base class for all conversion services.
Definition: ConversionSvc.h:45
#define S_FAIL
Definition: RootCnvSvc.cpp:38
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
Concrete implementation of the IDataConnection interface to access ROOT files.
StatusCode finalize() override
stop the service.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:291
Helper functions to set/get the application return code.
Definition: __init__.py:1
virtual StatusCode i__createRep(DataObject *pObj, IOpaqueAddress *&refpAddr)
Convert the transient object to the requested persistent representation.
Definition: RootCnvSvc.cpp:400
StatusCode initialize() override
Initialize the service.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
Gaudi::Property< bool > m_incidentEnabled
Definition: RootCnvSvc.h:60
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
evt
Definition: IOTest.py:96
Description: Definition of the ROOT data converter.
Definition: RootConverter.h:33
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
Definition: RootCnvSvc.h:80
const string & CSTR
Definition: RootCnvSvc.cpp:35
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.
Definition: RootCnvSvc.cpp:173
TClass * m_classRefs
TClass pointer to reference class.
Definition: RootCnvSvc.h:82