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