26 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) 27 #include "Compression.h" 28 static int s_compressionLevel = ROOT::CompressionSettings( ROOT::kLZMA, 4 );
30 static int s_compressionLevel = 1;
37 using namespace Gaudi;
39 typedef const string&
CSTR;
41 static const string s_empty;
42 static const string s_local =
"<localDB>";
44 #ifdef __POOL_COMPATIBILITY 59 const char*
name()
const override {
return "RootDataConnection"; }
65 switch ( static_cast<RootDataConnection::Status>( code ) ) {
66 case RootDataConnection::Status::ROOT_READ_ERROR:
67 return "ROOT_READ_ERROR";
68 case RootDataConnection::Status::ROOT_OPEN_ERROR:
69 return "ROOT_OPEN_ERROR";
79 static bool match_wild(
const char* str,
const char* pat )
88 for ( s = str, p = pat; *
s; ++
s, ++p ) {
91 if ( *s ==
'.' )
goto starCheck;
98 }
while ( *pat ==
'*' );
99 if ( !*pat )
return true;
102 if ( table[*s] != table[*p] )
goto starCheck;
106 while ( *p ==
'*' ) ++p;
110 if ( !star )
return false;
118 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) 119 int res = 0,
level = ROOT::CompressionSettings( ROOT::kLZMA, 6 );
120 auto idx = compression.
find(
':' );
121 if ( idx != string::npos ) {
122 string alg = compression.
substr( 0, idx );
123 ROOT::ECompressionAlgorithm alg_code = ROOT::kUseGlobalSetting;
124 if ( strcasecmp( alg.
c_str(),
"ZLIB" ) == 0 )
125 alg_code = ROOT::kZLIB;
126 else if ( strcasecmp( alg.
c_str(),
"LZMA" ) == 0 )
127 alg_code = ROOT::kLZMA;
129 throw runtime_error(
"ERROR: request to set unknown ROOT compression algorithm:" + alg );
130 res = ::sscanf( compression.
c_str() + idx + 1,
"%d", &
level );
132 s_compressionLevel = ROOT::CompressionSettings( alg_code,
level );
135 throw runtime_error(
"ERROR: request to set unknown ROOT compression level:" + compression.
substr( idx + 1 ) );
137 s_compressionLevel =
level;
140 throw runtime_error(
"ERROR: request to set unknown ROOT compression mechanism:" + compression );
142 if ( !compression.
empty() ) {
163 if ( fname.
length() == 36 && fname[8] ==
'-' && fname[13] ==
'-' && fname[18] ==
'-' && fname[23] ==
'-' ) {
225 #ifdef __POOL_COMPATIBILITY 226 else if (
m_file->Get(
"##Links" ) != nullptr )
250 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) 251 if ( sc == Status::ROOT_READ_ERROR ) {
264 if ( elem.first ==
"FID" ) {
266 if ( elem.second !=
m_fid ) {
267 msgSvc() << MSG::DEBUG <<
"Check FID param:" << elem.second <<
endmsg;
274 if ( !need_fid && fid !=
m_fid ) {
279 msgSvc() << MSG::DEBUG <<
"Using FID " <<
m_fid <<
" from params table...." <<
endmsg <<
"for PFN:" <<
m_pfn 293 m_refs =
new TTree(
"Refs",
"Root reference data" );
305 m_refs =
new TTree(
"Refs",
"Root reference data" );
320 if ( sc == Status::ROOT_READ_ERROR ) {
321 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) 330 TDirectory::TContext ctxt(
m_file.
get() );
331 m_refs =
new TTree(
"Refs",
"Root reference data" );
348 if ( !
m_file->IsZombie() ) {
349 if (
m_file->IsWritable() ) {
351 TDirectory::TContext ctxt(
m_file.
get() );
358 if ( i.second->Write() < 0 )
badWriteError(
"Write section:" + i.first );
359 msgSvc() <<
"Disconnect section " << i.first <<
" " << i.second->GetName() <<
endmsg;
383 if ( !t && create ) {
384 TDirectory::TContext ctxt(
m_file.
get() );
385 t =
new TTree( section.
c_str(),
"Root data for Gaudi" );
388 int cacheSize =
m_setup->cacheSize;
392 if ( section ==
m_setup->loadSection && cacheSize > -2 ) {
394 int learnEntries =
m_setup->learnEntries;
395 t->SetCacheSize( cacheSize );
396 t->SetCacheLearnEntries( learnEntries );
399 msg <<
"Tree:" << section <<
"Setting up tree cache:" << cacheSize <<
endmsg;
403 msg <<
"Tree:" << section <<
" Setting up tree cache:" << cacheSize <<
" Add all branches." <<
endmsg;
404 msg <<
"Tree:" << section <<
" Learn for " << learnEntries <<
" entries." <<
endmsg;
407 msg <<
"Adding (default) all branches to tree cache." <<
endmsg;
408 t->AddBranchToCache(
"*", kTRUE );
410 if ( cB.
size() == 1 && cB[0] ==
"*" ) {
411 msg <<
"Adding all branches to tree cache according to option \"CacheBranches\"." <<
endmsg;
412 t->AddBranchToCache(
"*", kTRUE );
414 for ( TIter it( t->GetListOfBranches() ); it.Next(); ) {
415 const char*
n = ( (TNamed*)( *it ) )->GetName();
416 bool add =
false, veto =
false;
417 for (
const auto& i : cB ) {
418 if ( !match_wild( n, ( i ).c_str() ) )
continue;
422 for (
auto i = vB.
cbegin(); !add && i != vB.
cend(); ++i ) {
423 if ( !match_wild( n, ( *i ).c_str() ) )
continue;
427 if ( add && !veto ) {
428 msg <<
"Add " << n <<
" to branch cache." <<
endmsg;
429 t->AddBranchToCache( n, kTRUE );
431 msg <<
"Do not cache branch " << n <<
endmsg;
447 string n = branch_name;
451 TBranch* b = t->GetBranch( n.c_str() );
452 if ( !b && cl &&
m_file->IsWritable() ) {
453 b = t->Branch( n.c_str(), cl->GetName(), (
void*)( ptr ? &ptr :
nullptr ), buff_siz, split_lvl );
455 if ( !b ) b = t->GetBranch( branch_name.
c_str() );
456 if ( b ) b->SetAutoDelete( kFALSE );
472 if ( ( which >= 0 ) && (
size_t( which ) <
m_dbs.
size() ) ) {
484 int buff_siz,
int split_lvl,
bool fill )
486 DataObjectPush push( pObj );
487 return save( section, cnt, cl, pObj, buff_siz, split_lvl, fill );
492 int split_lvl,
bool fill_missing )
495 TBranch* b =
getBranch( section, cnt, cl, pObj ? &pObj :
nullptr, buff_siz, split_lvl );
497 Long64_t
evt = b->GetEntries();
500 if ( fill_missing ) {
501 Long64_t num, nevt = b->GetTree()->GetEntries();
503 b->SetAddress(
nullptr );
509 msgSvc() <<
MSG::DEBUG <<
"Added " << long( nevt - evt ) <<
" / Tree: " << nevt
510 <<
" / Branch: " << b->GetEntries() + 1 <<
" NULL entries to:" << cnt <<
endmsg;
511 evt = b->GetEntries();
514 b->SetAddress( &pObj );
515 return {b->Fill(), evt};
528 TClass* cl = gROOT->GetClass( b->GetClassName(), kTRUE );
533 DataObjectPush push( pObj );
534 b->SetAddress( &pObj );
535 if ( section ==
m_setup->loadSection ) {
536 TTree* t = b->GetTree();
537 if ( Long64_t( entry ) != t->GetReadEntry() ) {
538 t->LoadTree( Long64_t( entry ) );
541 nb = b->GetEntry( entry );
543 if (
msgSvc().isActive() ) {
544 msgSvc() <<
"Load [" << entry <<
"] --> " << section <<
":" << cnt <<
" " << nb <<
" bytes." <<
endmsg;
547 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) 553 }
else if ( nb == 0 && pObj->
clID() == CLID_DataObject ) {
554 TFile* f = b->GetFile();
555 int vsn = f->GetVersion();
560 }
else if ( vsn > 1000000 && ( vsn % 1000000 ) < 52400 ) {
581 int nbytes =
m_tool->loadRefs( section, cnt, entry, refs );
582 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 ) 606 for (
auto j = s.
cbegin(); j != s.
cend(); ++j, ++cnt ) {
619 msgSvc() <<
MSG::DEBUG <<
"Return INVALID MergeSection for:" << container <<
" [" << entry <<
"]" <<
endmsg 621 return {
nullptr,
nullptr};
635 if ( db ==
m_fid ) db = s_local;
646 if ( !cnt.
empty() ) {
653 if ( !name.
empty() ) {
void addClient(const IInterface *client)
Add new client to this data source.
bool lookupClient(const IInterface *client) const
Lookup client for this data source.
constexpr static const auto FAILURE
MergeSections m_mergeSects
Database section map for merged files.
Definition of the MsgStream class used to transmit messages.
virtual const CLID & clID() const =0
Retrieve class information from link.
const std::string & fid() const
Access file id.
std::unique_ptr< Tool > m_tool
std::string m_name
Connection name/identifier.
IoType
I/O Connection types.
std::pair< int, unsigned long > saveObj(const std::string §ion, const std::string &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.
void saveStatistics(const std::string &statisticsFile)
Save TTree access statistics if required.
const std::string & getDb(int which) const
Access database/file name from saved index.
std::string m_fid
File ID of the connection.
The category assigned to a StatusCode.
std::unique_ptr< TTreePerfStats > m_statistics
I/O read statistics from TTree.
int loadObj(const std::string §ion, const std::string &cnt, unsigned long entry, DataObject *&pObj)
Load object.
static int compression()
Access to global compression level.
Clients m_clients
Client list.
int length
The length of the section.
TTree * getSection(const std::string §, bool create=false)
Access TTree section from section name. The section is created if required.
int start
The start entry of the section.
size_t removeClient(const IInterface *client)
Remove client from this data source.
bool isActive() const
Accessor: is MsgStream active.
GAUDI_API void fill(AIDA::IHistogram1D *histo, const double value, const double weight=1.0)
simple function to fill AIDA::IHistogram1D objects
RootDataConnection(const IInterface *own, const std::string &nam, std::shared_ptr< RootConnectionSetup > setup)
Standard constructor.
virtual const name_type & name() const =0
Name of the directory (or key)
void setMessageSvc(MsgStream *m)
Set message service reference.
StatusCode connectWrite(IoType typ) override
Open data stream in write mode.
virtual const std::string * par() const =0
Retrieve String parameters.
static StatusCode setCompression(const std::string &compression)
Set the global compression level.
const std::string & pfn() const
Access physical file name.
int loadRefs(const std::string §ion, const std::string &cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
StringVec m_links
Map containing internal links names.
ParamMap m_params
Parameter map for file parameters.
const long POOL_ROOTKEY_StorageType
StringVec m_mergeFIDs
Map containing merge FIDs.
std::string m_pfn
Physical file name of the connection.
int dbase
Data members to define object location in the persistent world.
Persistent reference object.
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
const std::string & name() const
Connection name.
#define STATUSCODE_ENUM_IMPL(...)
Assign a category to the StatusCode enum declared with STATUSCODE_ENUM_DECL( ENUM ) ...
This class is used for returning status codes from appropriate routines.
void clear(STATE_TYPE _i=std::ios_base::failbit)
Definition of the basic interface.
static const Category & default_category() noexcept
Default Gaudi StatusCode category.
TBranch * getBranch(const std::string §ion, const std::string &branch_name)
Access data branch by name: Get existing branch in read only mode.
void makeRef(IRegistry *pA, RootRef &ref)
Create reference object from registry entry.
StringVec m_conts
Map containing external container names.
const std::string & empty() const
Empty string reference.
Sections m_sections
Tree sections in TFile.
std::pair< const RootRef *, const ContainerSection * > getMergeSection(const std::string &container, int entry) const
Access link section for single container and entry.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
const long ROOT_StorageType
virtual long svcType() const =0
Retrieve service type.
const long POOL_ROOT_StorageType
Tool * makeTool()
Create file access tool to encapsulate POOL compatibiliy.
constexpr static const auto SUCCESS
std::pair< int, unsigned long > save(const std::string §ion, const std::string &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.
StatusCode connectRead() override
Open data stream in read mode.
ABC describing basic data connection.
int makeLink(const std::string &p)
Convert path string to path index.
const long POOL_ROOTTREE_StorageType
std::shared_ptr< RootConnectionSetup > m_setup
Reference to the setup structure.
LinkSections m_linkSects
Database link sections.
void resetAge()
Reset age.
const StatusCode & ignore() const
Ignore/check StatusCode.
Base class for all Incidents (computing events).
MsgStream & msgSvc() const
Allow access to printer service.
std::unique_ptr< TFile > m_file
Reference to ROOT file.
Opaque address interface definition.
StringVec m_dbs
Map containing external database file names (fids)
StatusCode disconnect() override
Release data stream and release implementation dependent resources.
void setIncidentSvc(IIncidentSvc *m)
Set incident service reference.
void enableStatistics(const std::string §ion)
Enable TTreePerStats.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
A DataObject is the base class of any identifiable object on any data store.
TTree * m_refs
Pointer to the reference tree.
virtual std::string message(code_t code) const
Description for code within this category.
Helper functions to set/get the application return code.
Internal helper class, which described a TBranch section in a ROOT file.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
The interface implemented by the IncidentSvc service.
void badWriteError(const std::string &msg) const
Error handler when bad write statements occur.
unsigned long code_t
type of StatusCode value