Go to the documentation of this file.
44 using namespace Gaudi;
45 typedef const string&
CSTR;
47 #define S_OK StatusCode::SUCCESS
48 #define S_FAIL StatusCode::FAILURE
57 #define MBYTE ( 1024 * 1024 )
63 declareProperty(
"LoadSection", m_setup->loadSection =
"Event" );
66 declareProperty(
"CacheSize", m_setup->cacheSize = 10 *
MBYTE );
67 declareProperty(
"LearnEntries", m_setup->learnEntries = 10 );
68 declareProperty(
"CacheBranches", m_setup->cacheBranches );
69 declareProperty(
"VetoBranches", m_setup->vetoBranches );
71 declareProperty( m_setup->produceReproducibleFiles );
72 m_setup->produceReproducibleFiles.setOwnerType<
RootCnvSvc>();
74 declareProperty( m_setup->root630ForwardCompatibility );
75 m_setup->root630ForwardCompatibility.setOwnerType<
RootCnvSvc>();
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" );
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();
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() <<
"]"
300 return error(
string(
"connectDatabase> Caught exception:" ) + e.
what() );
303 return error(
"connectDatabase> Unknown Fatal Exception for " + dataset );
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 );
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 );
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 );
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] );
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];
428 for (
int i = 0,
n = pLinks->
size(); i <
n; ++i ) {
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];
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];
517 if ( new_bad ) {
return error(
"createObj> Cannot access the object:" + tag +
" [Corrupted file]" ); }
StatusCode finalize() override
ConversionSvc overload: Finalize Db service.
Gaudi::Property< int > m_maxBufferSize
MsgStream & hex(MsgStream &log)
bool isConnected() const override
Check if connected to data source.
void loadConverter(DataObject *pObj) override
ConversionSvc overload: Load the class (dictionary) for the converter.
Embedded class defining a symbolic link Note: No explicit copy constructor; implicit compiler generat...
virtual const std::string * par() const =0
Retrieve String parameters.
StringVec cacheBranches
Vector of strings with branches to be cached for input files.
StatusCode initialize() override
ConversionSvc overload: initialize Db service.
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
StatusCode error(const std::string &msg)
Standard way to print errors.
Gaudi::Property< int > m_minBufferSize
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
const std::string & getLink(int which) const
Access link name from saved index.
get
decorate the vector of properties
Gaudi::Property< bool > m_incidentEnabled
std::pair< int, unsigned long > saveObj(std::string_view section, std::string_view cnt, TClass *cl, DataObject *pObj, int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
std::unique_ptr< MsgStream > m_log
Message streamer.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
virtual StatusCode createNullRef(const std::string &path)
Insert null marker for not existent transient object.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
std::set< std::string > m_badFiles
Set with bad files/tables.
StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
IAddressCreator implementation: Address creation.
const std::string & getDb(int which) const
Access database/file name from saved index.
const std::string & name() const override
Retrieve name of the service
const std::string & path() const
Access to path of object.
MsgStream & dec(MsgStream &log)
StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
Commit pending output.
IConverter * createConverter(long typ, const CLID &wanted, const ICnvFactory *fac) override
ConversionSvc overload: Create new Converter using factory.
const std::string & getCont(int which) const
Access container name from saved index.
MsgStream & log() const
Helper: Use message streamer.
std::vector< int > links
The links of the link manager.
const ValueType & value() const
bool patchStreamers(MsgStream &log)
static StatusCode setCompression(std::string_view compression)
Set the global compression level.
IoType
I/O Connection types.
long size() const
Retrieve number of link present.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
Gaudi::Property< int > m_splitLevel
unsigned int CLID
Class ID definition.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
const long ROOT_StorageType
virtual IRegistry * registry() const =0
Update branch name.
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Gaudi::Property< std::string > m_ioPerfStats
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
int makeLink(std::string_view p)
Convert path string to path index.
virtual StatusCode i__createRep(DataObject *pObj, IOpaqueAddress *&refpAddr)
Convert the transient object to the requested persistent representation.
StatusCode initialize() override
Initialize the service.
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
TClass * m_classDO
TClass pointer to DataObject class.
TYPE * get() const
Get interface pointer.
virtual StatusCode i__createObj(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create transient object from persistent data.
int loadRefs(std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
std::pair< int, unsigned long > save(std::string_view section, std::string_view cnt, TClass *cl, void *pObj, int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.
TClass * m_classRefs
TClass pointer to reference class.
StatusCode finalize() override
stop the service.
virtual const id_type & identifier() const =0
Full identifier (or key)
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
const std::string & fid() const
Access file id.
std::string m_currSection
Property: ROOT section name.
Gaudi::Property< int > m_approxEventsPerBasket
int loadObj(std::string_view section, std::string_view cnt, unsigned long entry, DataObject *&pObj)
Load object.
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
Gaudi::Property< std::string > m_recordName
constexpr static const auto FAILURE
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
LinkManager * linkMgr()
Retrieve Link manager.
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
virtual StatusCode createNullRep(const std::string &path)
Insert null marker for not existent transient object.
long addLink(const std::string &path, const DataObject *pObject)
Add link by object reference and path.
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.
IRegistry * registry() const
Get pointer to Registry.
std::shared_ptr< RootConnectionSetup > m_setup
Setup structure (ref-counted) and passed to data connections.
MSG::Level level() const
Retrieve output level.
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
const Link * link(long id) const
Retrieve symbolic link identified by ID.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator
Gaudi::Property< std::string > m_compression