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 ) 53 declareProperty(
"LoadSection", m_setup->loadSection =
"Event" );
56 declareProperty(
"CacheSize", m_setup->cacheSize = 10 *
MBYTE );
57 declareProperty(
"LearnEntries", m_setup->learnEntries = 10 );
58 declareProperty(
"CacheBranches", m_setup->cacheBranches );
59 declareProperty(
"VetoBranches", m_setup->vetoBranches );
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 ) {
107 auto pc = dynamic_cast<RootDataConnection*>( i );
110 if (
pc->lookupClient(
this ) ) {
111 size_t num_clients =
pc->removeClient(
this );
112 if ( num_clients == 0 ) {
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 );
215 connection.release();
218 dataset, mode ==
IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
225 if ( !
pc->isConnected() )
pc->connectRead();
228 pc->addClient(
this );
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 ) {
241 if ( !
pc->mergeFIDs().empty() ) fid =
pc->mergeFIDs()[i];
245 <<
pc->fid() <<
"][" << i <<
"]" <<
endmsg;
263 if (
pc &&
pc->lookupClient(
this ) ) {
264 size_t num_client =
pc->removeClient(
this );
265 if ( num_client == 0 ) {
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 );
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,
"" ); }
327 b->GetTree()->FlushBaskets();
334 return error(
"commitOutput> Failed to update entry numbers on " + dsn );
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 );
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() );
442 if ( sc.isSuccess() ) {
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]" );
virtual const std::string * par() const =0
Retrieve String parameters.
Definition of the MsgStream class used to transmit messages.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
Gaudi::Property< int > m_autoFlush
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.
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 SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
IRegistry * registry() const
Get pointer to Registry.
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.
std::pair< int, unsigned long > save(std::string_view section, std::string_view 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_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
std::pair< int, unsigned long > saveObj(std::string_view section, std::string_view 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.
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.
int makeLink(std::string_view p)
Convert path string to path index.
LinkManager * linkMgr() const
Retrieve Link manager.
StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
IAddressCreator implementation: Address creation.
int loadRefs(std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
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)
Gaudi::Property< std::string > m_compression
virtual Connection * connection(const std::string &dsn) const =0
Retrieve known connection.
bool patchStreamers(MsgStream &log)
const std::string & fid() const
Access file id.
StatusCode initialize() override
ConversionSvc overload: initialize Db service.
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
const std::string & getDb(int which) const
Access database/file name from saved index.
StatusCode finalize() override
ConversionSvc overload: Finalize Db service.
MsgStream & hex(MsgStream &log)
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
Gaudi::Property< int > m_splitLevel
Gaudi::Property< int > m_bufferSize
TYPE * get() const
Get interface pointer.
StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
Commit pending output.
std::vector< int > links
The links of the link manager.
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject.
MsgStream & log() const
Helper: Use message streamer.
virtual StatusCode disconnect(IDataConnection *con)=0
Release data stream.
bool isConnected() const override
Check if connected to data source.
Persistent reference object.
const std::string & name() const override
Retrieve name of the service.
static StatusCode setCompression(std::string_view compression)
Set the global compression level.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
const std::string & getCont(int which) const
Access container name from saved index.
virtual IRegistry * registry() const =0
Update branch name.
Gaudi::Property< std::string > m_ioPerfStats
General service interface definition.
This class is used for returning status codes from appropriate routines.
const std::string & path() const
Access to path of object.
std::unique_ptr< MsgStream > m_log
Message streamer.
virtual Connections connections(const IInterface *owner) const =0
Get connection by owner instance (0=ALL)
Link * link(long id)
Retrieve symbolic link identified by ID.
const std::string & getLink(int which) const
Access link name from saved index.
Statistics file converter class definition.
virtual StatusCode connectRead(bool keep_open, IDataConnection *con)=0
Open data stream in read mode.
TClass * m_classDO
TClass pointer to DataObject class.
StringVec cacheBranches
Vector of strings with branches to be cached for input files.
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.
unsigned int CLID
Class ID definition.
NTuple converter class definition for NTuples writted/read using ROOT.
int loadObj(std::string_view section, std::string_view cnt, unsigned long entry, DataObject *&pObj)
Load object.
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
IConverter * createConverter(long typ, const CLID &wanted, const ICnvFactory *fac) override
ConversionSvc overload: Create new Converter using factory.
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
std::set< std::string > m_badFiles
Set with bad files/tables.
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.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
ABC describing basic data connection.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
Base class for all Incidents (computing events).
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
long size() const
Retrieve number of link present.
constexpr static const auto FAILURE
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
MSG::Level level() const
Retrieve output level.
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
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.
virtual const id_type & identifier() const =0
Full identifier (or key)
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.
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
virtual StatusCode connectWrite(IDataConnection *con, IoType mode=Connection::CREATE, const std::string &doctype="UNKNOWN")=0
Open data stream in write mode.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
A LinkManager is the object aggregated into a DataObject, which is responsible for the handling of no...
Header file for std:chrono::duration-based Counters.
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.
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.
long addLink(const std::string &path, const DataObject *pObject) const
Add link by object reference and path.
TClass * m_classRefs
TClass pointer to reference class.