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>();
90 if ( !status.
isSuccess() ) {
return error(
"Failed to initialize ConversionSvc base class." ); }
99 if ( !
m_ioMgr )
return error(
"Unable to localize interface from service:IODataManager" );
101 if ( !
m_incidentSvc )
return error(
"Unable to localize interface from service:IncidentSvc" );
107 if ( !
m_classDO )
return error(
"Unable to load class description for DataObject" );
110 if ( !
m_classRefs )
return error(
"Unable to load class description for ObjectRefs" );
119 for (
auto& i : cons ) {
123 if (
pc->lookupClient(
this ) ) {
124 size_t num_clients =
pc->removeClient(
this );
125 if ( num_clients == 0 ) {
126 if (
m_ioMgr->disconnect(
pc ).isSuccess() ) {
127 log() <<
"Disconnected data IO:" <<
pc->fid() <<
" [" <<
pc->pfn() <<
"]" <<
endmsg;
138 m_setup->setIncidentSvc(
nullptr );
144 if ( wanted == CLID_StatisticsFile )
146 else if ( wanted == CLID_StatisticsDirectory )
148 else if ( wanted == CLID_RowWiseTuple )
150 else if ( wanted == CLID_ColumnWiseTuple )
162 TClass* cl = s_classesNames[cname];
163 if (
nullptr == cl ) {
164 cl = TClass::GetClass( cname.
c_str() );
166 s_classesNames[cname] = cl;
167 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 );
191 if ( ::strncasecmp( openMode.
c_str(),
"RECREATE", 3 ) == 0 )
193 else if ( ::strncasecmp( openMode.
c_str(),
"NEW", 1 ) == 0 )
195 else if ( ::strncasecmp( openMode.
c_str(),
"CREATE", 1 ) == 0 )
197 else if ( ::strncasecmp( openMode.
c_str(),
"UPDATE", 1 ) == 0 )
201 log() <<
MSG::ERROR <<
"The dataset " << dsn <<
" cannot be opened in mode " << openMode <<
". [Invalid mode]"
210 bool fire_incident =
false;
213 auto connection = std::make_unique<RootDataConnection>(
this, dataset,
m_setup );
216 :
m_ioMgr->connectRead(
false, connection.get() );
228 connection.release();
231 dataset, mode ==
IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
238 if ( !
pc->isConnected() )
239 if (
auto sc =
pc->connectRead(); !sc )
return sc;
242 pc->addClient(
this );
245 if ( fire_incident ) {
247 string fid =
pc->fid();
252 unsigned long ipar[2] = { (
unsigned long)( *con ), (
unsigned long)b->GetEntries() - 1 };
253 for (
int i = 0; i < b->GetEntries(); ++i ) {
255 if ( !
pc->mergeFIDs().empty() ) fid =
pc->mergeFIDs()[i];
259 <<
pc->fid() <<
"][" << i <<
"]" <<
endmsg;
274 for (
auto& i :
m_ioMgr->connections(
this ) ) {
277 if (
pc &&
pc->lookupClient(
this ) ) {
278 size_t num_client =
pc->removeClient(
this );
279 if ( num_client == 0 ) {
280 if (
m_ioMgr->disconnect(
pc ).isSuccess() ) {
281 log() <<
MSG::INFO <<
"Removed disconnected IO stream:" <<
pc->fid() <<
" [" <<
pc->pfn() <<
"]"
295 return error(
string(
"connectDatabase> Caught exception:" ) + e.
what() );
298 return error(
"connectDatabase> Unknown Fatal Exception for " + dataset );
312 Long64_t
evt = b->GetEntries();
313 TTree*
t = b->GetTree();
314 TObjArray* a =
t->GetListOfBranches();
315 Int_t nb = a->GetEntriesFast();
317 for ( Int_t i = 0; i < nb; ++i ) {
318 TBranch* br_ptr = (TBranch*)a->UncheckedAt( i );
319 Long64_t br_evt = br_ptr->GetEntries();
320 if ( br_evt <
evt ) {
321 Long64_t num =
evt - br_evt;
322 br_ptr->SetAddress(
nullptr );
329 <<
" Branch: " << br_ptr->GetEntries() <<
" RefNo: " << br_ptr->GetEntries() - 1
330 <<
" NULL entries to:" << br_ptr->GetName() <<
endmsg;
334 b->GetTree()->SetEntries(
evt );
339 return error(
"commitOutput> Failed to update entry numbers on " + dsn );
360 size_t len =
path.find(
'/', 1 );
361 string section =
path.substr( 1, len == string::npos ? string::npos : len - 1 );
370 size_t len =
path.find(
'/', 1 );
371 string section =
path.substr( 1, len == string::npos ? string::npos : len - 1 );
383 if ( !pObj )
return error(
"createRep> Current Database is invalid!" );
388 size_t len = p[1].
find(
'/', 1 );
389 string sect = p[1].
substr( 1, len == string::npos ? string::npos : len - 1 );
392 if ( ret.first > 1 || ( clid == CLID_DataObject && ret.first == 1 ) ) {
393 unsigned long ip[2] = { 0, ret.second };
397 return error(
"Failed to write object data for:" + p[1] );
409 StatusCode status = dataMgr->objectLeaves( pObj, leaves );
413 size_t len =
id.
find(
'/', 1 );
414 string sect =
id.substr( 1, len == string::npos ? string::npos : len - 1 );
416 for (
auto& i : leaves ) {
417 if ( i->address() ) {
419 ref.entry = i->address()->ipar()[1];
423 for (
int i = 0,
n = pLinks->
size(); i <
n; ++i ) {
430 if ( ret.first > 1 ) {
432 log() <<
MSG::DEBUG <<
"Writing object:" <<
id <<
" " << ret.first <<
" " <<
hex << ret.second <<
dec
447 const string*
par = pA->
par();
448 unsigned long* ipar =
const_cast<unsigned long*
>( pA->
ipar() );
451 ipar[0] = (
unsigned long)con;
453 size_t len =
par[1].find(
'/', 1 );
454 string section =
par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
456 int nb = con->
loadObj( section,
par[1], ipar[1], pObj );
457 if ( nb > 1 || ( nb == 1 && pObj->
clID() == CLID_DataObject ) ) {
463 string tag =
par[0] +
":" +
par[1];
466 return error(
"createObj> Cannot access the object:" + tag );
473 if ( !pA || !pObj )
return error(
"read> Cannot read object -- no valid object address present " );
475 const unsigned long* ipar = pA->
ipar();
479 const string*
par = pA->
par();
480 size_t len =
par[1].find(
'/', 1 );
481 string section =
par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
482 int nb = con->
loadRefs( section,
par[1], ipar[1], refs );
485 unsigned long nipar[2];
490 for (
auto&
r : refs.
refs ) {
491 npar[0] = con->
getDb(
r.dbase );
492 npar[1] = con->
getCont(
r.container );
501 <<
"#" << npar[2] <<
"[" <<
r.entry <<
"]" <<
endmsg;
502 sc = dataMgr->registerAddress( pA->
registry(), npar[2], nPA );
509 }
else if ( nb < 0 ) {
510 string tag =
par[0] +
":" +
par[1];
513 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.
long
(c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations # # This software i...
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.
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.
auto get(const Handle &handle, const Algo &, const EventContext &) -> decltype(details::deref(handle.get()))
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
Backward compatibility (.
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.
Header file for std:chrono::duration-based Counters.
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