34 using namespace Gaudi;
35 typedef const string&
CSTR;
37 #define S_OK StatusCode::SUCCESS 38 #define S_FAIL StatusCode::FAILURE 49 #define MBYTE ( 1024 * 1024 ) 55 m_setup->cacheBranches.push_back(
"*" );
83 return error(
"Failed to initialize ConversionSvc base class." );
93 if ( !
m_ioMgr )
return error(
"Unable to localize interface from service:IODataManager" );
95 if ( !
m_incidentSvc )
return error(
"Unable to localize interface from service:IncidentSvc" );
101 if ( !
m_classDO )
return error(
"Unable to load class description for DataObject" );
104 if ( !
m_classRefs )
return error(
"Unable to load class description for ObjectRefs" );
114 for (
auto& i : cons ) {
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;
135 m_setup->setIncidentSvc(
nullptr );
142 if ( wanted == CLID_StatisticsFile )
144 else if ( wanted == CLID_StatisticsDirectory )
146 else if ( wanted == CLID_RowWiseTuple )
148 else if ( wanted == CLID_ColumnWiseTuple )
161 TClass* cl = s_classesNames[cname];
162 if (
nullptr == cl ) {
163 cl = TClass::GetClass( cname.
c_str() );
165 s_classesNames[cname] = cl;
166 s_classesClids[pObject->
clID()] = cl;
175 auto i = s_classesClids.find( pObject->
clID() );
176 if ( i != s_classesClids.end() )
return i->second;
178 i = s_classesClids.find( pObject->
clID() );
179 if ( i != s_classesClids.end() )
return i->second;
182 throw runtime_error(
"Unknown ROOT class for object:" + cname );
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 )
204 log() <<
MSG::ERROR <<
"The dataset " << dsn <<
" cannot be opened in mode " << openMode <<
". [Invalid mode]" 214 bool fire_incident =
false;
217 auto connection = std::make_unique<RootDataConnection>(
this, dataset,
m_setup );
220 :
m_ioMgr->connectRead(
false, connection.get() );
221 c = sc.isSuccess() ?
m_ioMgr->connection( dataset ) :
nullptr;
231 connection->enableStatistics(
m_setup->loadSection );
234 connection.release();
237 dataset, mode ==
IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
250 if ( fire_incident ) {
252 string fid = pc->
fid();
257 unsigned long ipar[2] = {(
unsigned long)( *con ), (
unsigned long)b->GetEntries() - 1};
258 for (
int i = 0; i < b->GetEntries(); ++i ) {
263 log() <<
MSG::VERBOSE <<
"Failed to create address for " << m_recordName <<
" in:" << fid <<
" [" 264 << pc->
fid() <<
"][" << i <<
"]" <<
endmsg;
268 log() <<
MSG::VERBOSE <<
"Prepare " << m_recordName <<
" " << fid <<
" [" << par[0] <<
"][" << i <<
"]" 279 for (
auto& i :
m_ioMgr->connections(
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() <<
"]" 300 return error(
string(
"connectDatabase> Caught exception:" ) + e.
what() );
303 return error(
"connectDatabase> Unknown Fatal Exception for " + dataset );
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 );
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;
340 b->GetTree()->SetEntries( evt );
345 if ( evt == m_autoFlush ) {
346 b->GetTree()->SetAutoFlush( m_autoFlush );
349 b->GetTree()->FlushBaskets();
356 return error(
"commitOutput> Failed to update entry numbers on " + dsn );
373 refpAddress =
new RootAddress( typ, clid, par[0], par[1], ip[0], ip[1] );
380 size_t len = path.
find(
'/', 1 );
381 string section = path.
substr( 1, len == string::npos ? string::npos : len - 1 );
390 size_t len = path.
find(
'/', 1 );
391 string section = path.
substr( 1, len == string::npos ? string::npos : len - 1 );
394 log() <<
MSG::VERBOSE <<
"Writing object:" << path <<
" " << ret.first <<
" " <<
hex << ret.second <<
dec 403 if ( !pObj )
return error(
"createRep> Current Database is invalid!" );
408 size_t len = p[1].
find(
'/', 1 );
409 string sect = p[1].
substr( 1, len == string::npos ? string::npos : len - 1 );
411 if ( ret.first > 1 || ( clid == CLID_DataObject && ret.first == 1 ) ) {
412 unsigned long ip[2] = {0, ret.second};
416 return error(
"Failed to write object data for:" + p[1] );
429 StatusCode status = dataMgr->objectLeaves( pObj, leaves );
433 size_t len =
id.
find(
'/', 1 );
434 string sect =
id.substr( 1, len == string::npos ? string::npos : len - 1 );
436 for (
auto& i : leaves ) {
437 if ( i->address() ) {
439 ref.
entry = i->address()->ipar()[1];
443 for (
int i = 0,
n = pLinks->
size(); i <
n; ++i ) {
450 if ( ret.first > 1 ) {
452 log() <<
MSG::DEBUG <<
"Writing object:" <<
id <<
" " << ret.first <<
" " <<
hex << ret.second <<
dec 468 const string*
par = pA->
par();
469 unsigned long* ipar =
const_cast<unsigned long*
>( pA->
ipar() );
472 ipar[0] = (
unsigned long)con;
474 size_t len = par[1].
find(
'/', 1 );
475 string section = par[1].
substr( 1, len == string::npos ? string::npos : len - 1 );
477 int nb = con->
loadObj( section, par[1], ipar[1], pObj );
478 if ( nb > 1 || ( nb == 1 && pObj->
clID() == CLID_DataObject ) ) {
484 string tag = par[0] +
":" + par[1];
487 return error(
"createObj> Cannot access the object:" + tag );
495 if ( !pA || !pObj )
return error(
"read> Cannot read object -- no valid object address present " );
497 const unsigned long* ipar = pA->
ipar();
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 );
507 unsigned long nipar[2];
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 );
523 <<
"#" << npar[2] <<
"[" << r.entry <<
"]" <<
endmsg;
524 sc = dataMgr->registerAddress( pA->
registry(), npar[2], nPA );
531 }
else if ( nb < 0 ) {
532 string tag = par[0] +
":" + par[1];
535 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.
constexpr static const auto FAILURE
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.
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.