47#define S_OK StatusCode::SUCCESS
48#define S_FAIL StatusCode::FAILURE
54 static map<string, TClass*> s_classesNames;
55 static map<CLID, TClass*> s_classesClids;
57#define MBYTE ( 1024 * 1024 )
62 m_setup->cacheBranches.push_back(
"*" );
93 if ( !status.
isSuccess() ) {
return error(
"Failed to initialize ConversionSvc base class." ); }
102 if ( !
m_ioMgr )
return error(
"Unable to localize interface from service:IODataManager" );
104 if ( !
m_incidentSvc )
return error(
"Unable to localize interface from service:IncidentSvc" );
109 m_classDO = TClass::GetClass( cname.c_str() );
110 if ( !
m_classDO )
return error(
"Unable to load class description for DataObject" );
113 if ( !
m_classRefs )
return error(
"Unable to load class description for ObjectRefs" );
122 for (
auto& i : cons ) {
126 if ( pc->lookupClient(
this ) ) {
127 size_t num_clients = pc->removeClient(
this );
128 if ( num_clients == 0 ) {
129 if (
m_ioMgr->disconnect( pc ).isSuccess() ) {
130 log() <<
"Disconnected data IO:" << pc->fid() <<
" [" << pc->pfn() <<
"]" <<
endmsg;
141 m_setup->setIncidentSvc(
nullptr );
147 if ( wanted == CLID_StatisticsFile )
149 else if ( wanted == CLID_StatisticsDirectory )
151 else if ( wanted == CLID_RowWiseTuple )
153 else if ( wanted == CLID_ColumnWiseTuple )
165 TClass* cl = s_classesNames[cname];
166 if (
nullptr == cl ) {
167 cl = TClass::GetClass( cname.c_str() );
169 s_classesNames[cname] = cl;
170 s_classesClids[pObject->
clID()] = cl;
178 auto i = s_classesClids.find( pObject->
clID() );
179 if ( i != s_classesClids.end() )
return i->second;
181 i = s_classesClids.find( pObject->
clID() );
182 if ( i != s_classesClids.end() )
return i->second;
185 throw runtime_error(
"Unknown ROOT class for object:" + cname );
194 if ( ::strncasecmp( openMode.c_str(),
"RECREATE", 3 ) == 0 )
196 else if ( ::strncasecmp( openMode.c_str(),
"NEW", 1 ) == 0 )
198 else if ( ::strncasecmp( openMode.c_str(),
"CREATE", 1 ) == 0 )
200 else if ( ::strncasecmp( openMode.c_str(),
"UPDATE", 1 ) == 0 )
204 log() <<
MSG::ERROR <<
"The dataset " << dsn <<
" cannot be opened in mode " << openMode <<
". [Invalid mode]"
213 bool fire_incident =
false;
216 auto connection = std::make_unique<RootDataConnection>(
this, dataset,
m_setup );
219 :
m_ioMgr->connectRead(
false, connection.get() );
233 connection.release();
236 dataset, mode ==
IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
243 if ( !pc->isConnected() )
244 if (
auto sc = pc->connectRead(); !sc )
return sc;
247 pc->addClient(
this );
250 if ( fire_incident ) {
252 string fid = pc->fid();
254 TBranch* b = pc->getBranch( section,
m_recordName.value() );
257 unsigned long ipar[2] = { (
unsigned long)( *con ), (
unsigned long)b->GetEntries() - 1 };
258 for (
int i = 0; i < b->GetEntries(); ++i ) {
260 if ( !pc->mergeFIDs().empty() ) fid = pc->mergeFIDs()[i];
264 << pc->fid() <<
"][" << i <<
"]" <<
endmsg;
279 for (
auto& i :
m_ioMgr->connections(
this ) ) {
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() <<
"]"
298 }
catch ( exception& e ) {
300 return error(
string(
"connectDatabase> Caught exception:" ) + e.what() );
303 return error(
"connectDatabase> Unknown Fatal Exception for " + dataset );
314 string section =
m_currSection.substr( 1, len == string::npos ? string::npos : len - 1 );
317 Long64_t evt = b->GetEntries();
318 TTree* t = b->GetTree();
319 TObjArray* a = t->GetListOfBranches();
320 Int_t nb = a->GetEntriesFast();
322 for ( Int_t i = 0; i < nb; ++i ) {
323 TBranch* br_ptr = (TBranch*)a->UncheckedAt( i );
324 Long64_t br_evt = br_ptr->GetEntries();
325 if ( br_evt < evt ) {
326 Long64_t num = evt - br_evt;
327 br_ptr->SetAddress(
nullptr );
333 log() <<
MSG::DEBUG <<
"commit: Added " << long( evt - br_evt ) <<
" Section: " << evt
334 <<
" Branch: " << br_ptr->GetEntries() <<
" RefNo: " << br_ptr->GetEntries() - 1
335 <<
" NULL entries to:" << br_ptr->GetName() <<
endmsg;
339 b->GetTree()->SetEntries( evt );
344 return error(
"commitOutput> Failed to update entry numbers on " + dsn );
359 refpAddress =
new RootAddress( typ, clid, par[0], par[1], ip[0], ip[1] );
365 size_t len = path.find(
'/', 1 );
366 string section = path.substr( 1, len == string::npos ? string::npos : len - 1 );
375 size_t len = path.find(
'/', 1 );
376 string section = path.substr( 1, len == string::npos ? string::npos : len - 1 );
380 log() <<
MSG::VERBOSE <<
"Writing object:" << path <<
" " << ret.first <<
" " << hex << ret.second << dec
388 if ( !pObj )
return error(
"createRep> Current Database is invalid!" );
393 size_t len = p[1].find(
'/', 1 );
394 string sect = p[1].substr( 1, len == string::npos ? string::npos : len - 1 );
397 if ( ret.first > 1 || ( clid == CLID_DataObject && ret.first == 1 ) ) {
398 unsigned long ip[2] = { 0, ret.second };
402 return error(
"Failed to write object data for:" + p[1] );
408 typedef vector<IRegistry*> Leaves;
414 StatusCode status = dataMgr->objectLeaves( pObj, leaves );
418 size_t len =
id.find(
'/', 1 );
419 string sect =
id.substr( 1, len == string::npos ? string::npos : len - 1 );
421 for (
auto& i : leaves ) {
422 if ( i->address() ) {
424 ref.entry = i->address()->ipar()[1];
425 refs.
refs.push_back( ref );
428 for (
int i = 0, n = pLinks->
size(); i < n; ++i ) {
431 refs.
links.push_back( link_id );
435 if ( ret.first > 1 ) {
437 log() <<
MSG::DEBUG <<
"Writing object:" <<
id <<
" " << ret.first <<
" " << hex << ret.second << dec
452 const string* par = pA->
par();
453 unsigned long* ipar =
const_cast<unsigned long*
>( pA->
ipar() );
456 ipar[0] = (
unsigned long)con;
458 size_t len = par[1].find(
'/', 1 );
459 string section = par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
461 int nb = con->
loadObj( section, par[1], ipar[1], pObj );
462 if ( nb > 1 || ( nb == 1 && pObj->
clID() == CLID_DataObject ) ) {
468 string tag = par[0] +
":" + par[1];
470 const auto [itr, new_bad] =
m_badFiles.insert( tag );
471 if ( new_bad ) {
return error(
"createObj> Cannot access the object:" + tag ); }
477 if ( !pA || !pObj )
return error(
"read> Cannot read object -- no valid object address present " );
479 const unsigned long* ipar = pA->
ipar();
483 const string* par = pA->
par();
484 size_t len = par[1].find(
'/', 1 );
485 string section = par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
486 int nb = con->
loadRefs( section, par[1], ipar[1], refs );
489 unsigned long nipar[2];
494 for (
auto& r : refs.
refs ) {
495 npar[0] = con->
getDb( r.dbase );
496 npar[1] = con->
getCont( r.container );
497 npar[2] = con->
getLink( r.link );
505 <<
"#" << npar[2] <<
"[" << r.entry <<
"]" <<
endmsg;
506 sc = dataMgr->registerAddress( pA->
registry(), npar[2], nPA );
513 }
else if ( nb < 0 ) {
514 string tag = par[0] +
":" + par[1];
516 const auto [itr, new_bad] =
m_badFiles.insert( tag );
517 if ( new_bad ) {
return error(
"createObj> Cannot access the object:" + tag +
" [Corrupted file]" ); }
unsigned int CLID
Class ID definition.
const long ROOT_StorageType
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
StatusCode finalize() override
stop the service.
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
StatusCode initialize() override
Initialize the service.
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
A DataObject is the base class of any identifiable object on any data store.
IRegistry * registry() const
Get pointer to Registry.
LinkManager * linkMgr()
Retrieve Link manager.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
ABC describing basic data connection.
const std::string & fid() const
Access file id.
IoType
I/O Connection types.
std::vector< Connection * > Connections
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
TClass * m_classDO
TClass pointer to DataObject class.
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
virtual StatusCode createNullRef(const std::string &path)
Insert null marker for not existent transient object.
Gaudi::Property< int > m_approxEventsPerBasket
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.
MsgStream & log() const
Helper: Use message streamer.
virtual StatusCode i__createRep(DataObject *pObj, IOpaqueAddress *&refpAddr)
Convert the transient object to the requested persistent representation.
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
Gaudi::Property< int > m_maxBufferSize
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
Gaudi::Property< bool > m_incidentEnabled
Gaudi::Property< int > m_splitLevel
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
IAddressCreator implementation: Address creation.
StatusCode finalize() override
ConversionSvc overload: Finalize Db service.
TClass * m_classRefs
TClass pointer to reference class.
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
StatusCode initialize() override
ConversionSvc overload: initialize Db service.
IConverter * createConverter(long typ, const CLID &wanted, const ICnvFactory *fac) override
ConversionSvc overload: Create new Converter using factory.
RootCnvSvc(const std::string &name, ISvcLocator *svc)
Standard constructor.
std::string m_currSection
Property: ROOT section name.
Gaudi::Property< std::string > m_compression
StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
Commit pending output.
std::shared_ptr< RootConnectionSetup > m_setup
Setup structure (ref-counted) and passed to data connections.
Gaudi::Property< std::string > m_ioPerfStats
virtual StatusCode createNullRep(const std::string &path)
Insert null marker for not existent transient object.
Gaudi::Property< std::string > m_recordName
std::unique_ptr< MsgStream > m_log
Message streamer.
Gaudi::Property< int > m_minBufferSize
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
void loadConverter(DataObject *pObj) override
ConversionSvc overload: Load the class (dictionary) for the converter.
std::set< std::string > m_badFiles
Set with bad files/tables.
virtual StatusCode i__createObj(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create transient object from persistent data.
static StatusCode setCompression(std::string_view compression)
Set the global compression level.
Description: Definition of the ROOT data converter.
Concrete implementation of the IDataConnection interface to access ROOT files.
const std::string & getLink(int which) const
Access link name from saved index.
bool isConnected() const override
Check if connected to data source.
const std::string & getDb(int which) const
Access database/file name from saved index.
int loadRefs(std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
int loadObj(std::string_view section, std::string_view cnt, unsigned long entry, DataObject *&pObj)
Load object.
const std::string & getCont(int which) const
Access container name from saved index.
Statistics file converter class definition.
Description: NTuple directory converter class definition Definition of the converter to manage the di...
NTuple converter class definition for NTuples writted/read using ROOT.
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.
The data converters are responsible to translate data from one representation into another.
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Opaque address interface definition.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const std::string * par() const =0
Retrieve String parameters.
virtual IRegistry * registry() const =0
Update branch name.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
virtual const id_type & identifier() const =0
Full identifier (or key)
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
General service interface definition.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Base class for all Incidents (computing events).
Embedded class defining a symbolic link Note: No explicit copy constructor; implicit compiler generat...
const std::string & path() const
Access to path of object.
A LinkManager is the object aggregated into a DataObject, which is responsible for the handling of no...
long addLink(const std::string &path, const DataObject *pObject)
Add link by object reference and path.
long size() const
Retrieve number of link present.
const Link * link(long id) const
Retrieve symbolic link identified by ID.
Definition of the MsgStream class used to transmit messages.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
const std::string & name() const override
Retrieve name of the service.
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ToolHandle< T > &hndl, const std::string &doc="none")
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
Small smart pointer class with automatic reference counting for IInterface.
This class is used for returning status codes from appropriate routines.
constexpr static const auto FAILURE
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
bool patchStreamers(MsgStream &log)
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject.
std::vector< int > links
The links of the link manager.
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
Persistent reference object.