34 using namespace Gaudi;
35 typedef const string&
CSTR;
37 #define S_OK StatusCode::SUCCESS 38 #define S_FAIL StatusCode::FAILURE 47 #define MBYTE ( 1024 * 1024 ) 52 m_setup->cacheBranches.push_back(
"*" );
77 if ( !status.
isSuccess() ) {
return error(
"Failed to initialize ConversionSvc base class." ); }
86 if ( !
m_ioMgr )
return error(
"Unable to localize interface from service:IODataManager" );
88 if ( !
m_incidentSvc )
return error(
"Unable to localize interface from service:IncidentSvc" );
94 if ( !
m_classDO )
return error(
"Unable to load class description for DataObject" );
97 if ( !
m_classRefs )
return error(
"Unable to load class description for ObjectRefs" );
106 for (
auto& i : cons ) {
110 if (
pc->lookupClient(
this ) ) {
111 size_t num_clients =
pc->removeClient(
this );
112 if ( num_clients == 0 ) {
113 if (
m_ioMgr->disconnect(
pc ).isSuccess() ) {
114 log() <<
"Disconnected data IO:" <<
pc->fid() <<
" [" <<
pc->pfn() <<
"]" <<
endmsg;
125 m_setup->setIncidentSvc(
nullptr );
131 if ( wanted == CLID_StatisticsFile )
133 else if ( wanted == CLID_StatisticsDirectory )
135 else if ( wanted == CLID_RowWiseTuple )
137 else if ( wanted == CLID_ColumnWiseTuple )
149 TClass* cl = s_classesNames[cname];
150 if (
nullptr == cl ) {
151 cl = TClass::GetClass( cname.
c_str() );
153 s_classesNames[cname] = cl;
154 s_classesClids[pObject->
clID()] = cl;
162 auto i = s_classesClids.find( pObject->
clID() );
163 if ( i != s_classesClids.end() )
return i->second;
165 i = s_classesClids.find( pObject->
clID() );
166 if ( i != s_classesClids.end() )
return i->second;
169 throw runtime_error(
"Unknown ROOT class for object:" + cname );
178 if ( ::strncasecmp( openMode.
c_str(),
"RECREATE", 3 ) == 0 )
180 else if ( ::strncasecmp( openMode.
c_str(),
"NEW", 1 ) == 0 )
182 else if ( ::strncasecmp( openMode.
c_str(),
"CREATE", 1 ) == 0 )
184 else if ( ::strncasecmp( openMode.
c_str(),
"UPDATE", 1 ) == 0 )
188 log() <<
MSG::ERROR <<
"The dataset " << dsn <<
" cannot be opened in mode " << openMode <<
". [Invalid mode]" 197 bool fire_incident =
false;
200 auto connection = std::make_unique<RootDataConnection>(
this, dataset,
m_setup );
203 :
m_ioMgr->connectRead(
false, connection.get() );
204 c = sc.isSuccess() ?
m_ioMgr->connection( dataset ) :
nullptr;
215 connection.release();
218 dataset, mode ==
IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
231 if ( fire_incident ) {
233 string fid = pc->
fid();
238 unsigned long ipar[2] = {(
unsigned long)( *con ), (
unsigned long)b->GetEntries() - 1};
239 for (
int i = 0; i < b->GetEntries(); ++i ) {
244 log() <<
MSG::VERBOSE <<
"Failed to create address for " << m_recordName <<
" in:" << fid <<
" [" 245 << pc->
fid() <<
"][" << i <<
"]" <<
endmsg;
249 log() <<
MSG::VERBOSE <<
"Prepare " << m_recordName <<
" " << fid <<
" [" << par[0] <<
"][" << i <<
"]" 260 for (
auto& i :
m_ioMgr->connections(
this ) ) {
265 if ( num_client == 0 ) {
266 if (
m_ioMgr->disconnect( pc ).isSuccess() ) {
267 log() <<
MSG::INFO <<
"Removed disconnected IO stream:" << pc->
fid() <<
" [" << pc->
pfn() <<
"]" 281 return error(
string(
"connectDatabase> Caught exception:" ) + e.
what() );
284 return error(
"connectDatabase> Unknown Fatal Exception for " + dataset );
298 Long64_t
evt = b->GetEntries();
299 TTree* t = b->GetTree();
300 TObjArray* a = t->GetListOfBranches();
301 Int_t nb = a->GetEntriesFast();
303 for ( Int_t i = 0; i < nb; ++i ) {
304 TBranch* br_ptr = (TBranch*)a->UncheckedAt( i );
305 Long64_t br_evt = br_ptr->GetEntries();
306 if ( br_evt < evt ) {
307 Long64_t num = evt - br_evt;
308 br_ptr->SetAddress(
nullptr );
314 log() <<
MSG::DEBUG <<
"commit: Added " << long( evt - br_evt ) <<
" Section: " << evt
315 <<
" Branch: " << br_ptr->GetEntries() <<
" RefNo: " << br_ptr->GetEntries() - 1
316 <<
" NULL entries to:" << br_ptr->GetName() <<
endmsg;
320 b->GetTree()->SetEntries( evt );
321 if ( evt == 1 ) { b->GetTree()->OptimizeBaskets(
m_basketSize, 1.1,
"" ); }
323 if ( evt == m_autoFlush ) {
324 b->GetTree()->SetAutoFlush( m_autoFlush );
327 b->GetTree()->FlushBaskets();
334 return error(
"commitOutput> Failed to update entry numbers on " + dsn );
349 refpAddress =
new RootAddress( typ, clid, par[0], par[1], ip[0], ip[1] );
355 size_t len = path.
find(
'/', 1 );
356 string section = path.
substr( 1, len == string::npos ? string::npos : len - 1 );
364 size_t len = path.
find(
'/', 1 );
365 string section = path.
substr( 1, len == string::npos ? string::npos : len - 1 );
368 log() <<
MSG::VERBOSE <<
"Writing object:" << path <<
" " << ret.first <<
" " <<
hex << ret.second <<
dec 376 if ( !pObj )
return error(
"createRep> Current Database is invalid!" );
381 size_t len = p[1].
find(
'/', 1 );
382 string sect = p[1].
substr( 1, len == string::npos ? string::npos : len - 1 );
384 if ( ret.first > 1 || ( clid == CLID_DataObject && ret.first == 1 ) ) {
385 unsigned long ip[2] = {0, ret.second};
389 return error(
"Failed to write object data for:" + p[1] );
401 StatusCode status = dataMgr->objectLeaves( pObj, leaves );
405 size_t len =
id.
find(
'/', 1 );
406 string sect =
id.substr( 1, len == string::npos ? string::npos : len - 1 );
408 for (
auto& i : leaves ) {
409 if ( i->address() ) {
411 ref.
entry = i->address()->ipar()[1];
415 for (
int i = 0,
n = pLinks->
size(); i <
n; ++i ) {
422 if ( ret.first > 1 ) {
424 log() <<
MSG::DEBUG <<
"Writing object:" <<
id <<
" " << ret.first <<
" " <<
hex << ret.second <<
dec 439 const string*
par = pA->
par();
440 unsigned long* ipar =
const_cast<unsigned long*
>( pA->
ipar() );
443 ipar[0] = (
unsigned long)con;
445 size_t len = par[1].
find(
'/', 1 );
446 string section = par[1].
substr( 1, len == string::npos ? string::npos : len - 1 );
448 int nb = con->
loadObj( section, par[1], ipar[1], pObj );
449 if ( nb > 1 || ( nb == 1 && pObj->
clID() == CLID_DataObject ) ) {
455 string tag = par[0] +
":" + par[1];
458 return error(
"createObj> Cannot access the object:" + tag );
465 if ( !pA || !pObj )
return error(
"read> Cannot read object -- no valid object address present " );
467 const unsigned long* ipar = pA->
ipar();
471 const string*
par = pA->
par();
472 size_t len = par[1].
find(
'/', 1 );
473 string section = par[1].
substr( 1, len == string::npos ? string::npos : len - 1 );
474 int nb = con->
loadRefs( section, par[1], ipar[1], refs );
477 unsigned long nipar[2];
482 for (
auto& r : refs.
refs ) {
483 npar[0] = con->
getDb( r.dbase );
484 npar[1] = con->
getCont( r.container );
485 npar[2] = con->
getLink( r.link );
493 <<
"#" << npar[2] <<
"[" << r.entry <<
"]" <<
endmsg;
494 sc = dataMgr->registerAddress( pA->
registry(), npar[2], nPA );
501 }
else if ( nb < 0 ) {
502 string tag = par[0] +
":" + par[1];
505 return error(
"createObj> Cannot access the object:" + tag +
" [Corrupted file]" );
void addClient(const IInterface *client)
Add new client to this data source.
bool lookupClient(const IInterface *client) const
Lookup client for this data source.
const std::string & path() const
Access to path of object.
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.
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
MsgStream & log() const
Helper: Use message streamer.
Gaudi::Property< int > m_autoFlush
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
The data converters are responsible to translate data from one representation into another...
const std::string & name() const override
Retrieve name of the service.
const std::string & fid() const
Access file id.
std::string m_currSection
Property: ROOT section name.
Gaudi::Property< std::string > m_recordName
virtual StatusCode createNullRef(const std::string &path)
Insert null marker for not existent transient object.
IoType
I/O Connection types.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
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.
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.
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.
void loadConverter(DataObject *pObj) override
ConversionSvc overload: Load the class (dictionary) for the converter.
MsgStream & dec(MsgStream &log)
virtual IRegistry * registry() const =0
Update branch name.
Gaudi::Property< std::string > m_compression
size_t removeClient(const IInterface *client)
Remove client from this data source.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Details::PropertyBase &prop)
Declare a property.
bool patchStreamers(MsgStream &log)
StatusCode initialize() override
ConversionSvc overload: initialize Db service.
const std::string & getLink(int which) const
Access link name from saved index.
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
long addLink(const std::string &path, const DataObject *pObject) const
Add link by object reference and path.
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
StatusCode finalize() override
ConversionSvc overload: Finalize Db service.
MsgStream & hex(MsgStream &log)
Gaudi::Property< int > m_splitLevel
Gaudi::Property< int > m_bufferSize
virtual const std::string * par() const =0
Retrieve String parameters.
const std::string & pfn() const
Access physical file name.
StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
Commit pending output.
IRegistry * registry() const
Get pointer to Registry.
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
LinkManager * linkMgr() const
Retrieve Link manager.
TYPE * get() const
Get interface pointer.
Persistent reference object.
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.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const id_type & identifier() const =0
Full identifier (or key)
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
General service interface definition.
This class is used for returning status codes from appropriate routines.
std::unique_ptr< MsgStream > m_log
Message streamer.
Link * link(long id)
Retrieve symbolic link identified by ID.
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.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
const long ROOT_StorageType
virtual StatusCode i__createObj(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create transient object from persistent data.
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.
NTuple converter class definition for NTuples writted/read using ROOT.
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
std::vector< int > links
The links of the link manager.
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.
std::set< std::string > m_badFiles
Set with bad files/tables.
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.
StatusCode connectRead() override
Open data stream in read mode.
ABC describing basic data connection.
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
void resetAge()
Reset age.
Base class for all Incidents (computing events).
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
constexpr static const auto FAILURE
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
Gaudi::Property< int > m_basketSize
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
MSG::Level level() const
Retrieve output level.
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Embedded class defining a symbolic link Note: No copy constructor; bitwise copy (done by the compiler...
Opaque address interface definition.
Base class for all conversion services.
A DataObject is the base class of any identifiable object on any data store.
Concrete implementation of the IDataConnection interface to access ROOT files.
StatusCode finalize() override
stop the service.
A LinkManager is the object aggregated into a DataObject, which is responsible for the handling of no...
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Helper functions to set/get the application return code.
virtual StatusCode i__createRep(DataObject *pObj, IOpaqueAddress *&refpAddr)
Convert the transient object to the requested persistent representation.
StatusCode initialize() override
Initialize the service.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Gaudi::Property< bool > m_incidentEnabled
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
Description: Definition of the ROOT data converter.
long size() const
Retrieve number of link present.
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.
TClass * m_classRefs
TClass pointer to reference class.