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 58 static bool match_wild(
const char *str,
const char *pat) {
66 for (s = str, p = pat; *
s; ++
s, ++p) {
69 if (*s ==
'.')
goto starCheck;
74 do { ++pat; }
while (*pat ==
'*');
75 if (!*pat)
return true;
78 if ( table[*s] != table[*p] )
83 while (*p ==
'*') ++p;
87 if (!star)
return false;
94 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0) 95 int res = 0,
level = ROOT::CompressionSettings(ROOT::kLZMA,6);
96 auto idx = compression.
find(
':');
97 if ( idx != string::npos ) {
98 string alg = compression.
substr(0,idx);
99 ROOT::ECompressionAlgorithm alg_code = ROOT::kUseGlobalSetting;
100 if ( strcasecmp(alg.
c_str(),
"ZLIB") == 0 )
101 alg_code = ROOT::kZLIB;
102 else if ( strcasecmp(alg.
c_str(),
"LZMA") == 0 )
103 alg_code = ROOT::kLZMA;
105 throw runtime_error(
"ERROR: request to set unknown ROOT compression algorithm:"+alg);
106 res = ::sscanf(compression.
c_str()+idx+1,
"%d",&
level);
108 s_compressionLevel = ROOT::CompressionSettings(alg_code,
level);
111 throw runtime_error(
"ERROR: request to set unknown ROOT compression level:"+compression.
substr(idx+1));
114 s_compressionLevel =
level;
117 throw runtime_error(
"ERROR: request to set unknown ROOT compression mechanism:"+compression);
119 if ( !compression.
empty() ) {}
126 return s_compressionLevel;
137 m_incidentSvc.reset(s);
145 if ( fname.
length() == 36 && fname[8]==
'-'&&fname[13]==
'-'&&fname[18]==
'-'&&fname[23]==
'-' ) {
180 if ( !statisticsFile.
empty() )
205 #ifdef __POOL_COMPATIBILITY 206 else if (
m_file->Get(
"##Links") != nullptr )
229 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0) 243 if ( elem.first ==
"FID" ) {
245 if ( elem.second !=
m_fid ) {
246 msgSvc() << MSG::DEBUG <<
"Check FID param:" << elem.second <<
endmsg;
253 if ( !need_fid && fid !=
m_fid ) {
258 msgSvc() << MSG::DEBUG <<
"Using FID " <<
m_fid <<
" from params table...." <<
endmsg 271 m_refs =
new TTree(
"Refs",
"Root reference data");
283 m_refs =
new TTree(
"Refs",
"Root reference data");
299 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0) 309 m_refs =
new TTree(
"Refs",
"Root reference data");
325 if ( !
m_file->IsZombie() ) {
326 if (
m_file->IsWritable() ) {
335 if ( i.second->Write() < 0 )
badWriteError(
"Write section:"+i.first);
336 msgSvc() <<
"Disconnect section " << i.first <<
" " << i.second->GetName() <<
endmsg;
359 if ( !t && create ) {
361 t =
new TTree(section.
c_str(),
"Root data for Gaudi");
364 int cacheSize =
m_setup->cacheSize;
368 if ( section ==
m_setup->loadSection && cacheSize>-2 ) {
370 int learnEntries =
m_setup->learnEntries;
371 t->SetCacheSize(cacheSize);
372 t->SetCacheLearnEntries(learnEntries);
375 msg <<
"Tree:" << section <<
"Setting up tree cache:" << cacheSize <<
endmsg;
380 msg <<
"Tree:" << section <<
" Setting up tree cache:" << cacheSize <<
" Add all branches." <<
endmsg;
381 msg <<
"Tree:" << section <<
" Learn for " << learnEntries <<
" entries." <<
endmsg;
384 msg <<
"Adding (default) all branches to tree cache." <<
endmsg;
385 t->AddBranchToCache(
"*",kTRUE);
387 if ( cB.
size()==1 && cB[0]==
"*" ) {
388 msg <<
"Adding all branches to tree cache according to option \"CacheBranches\"." <<
endmsg;
389 t->AddBranchToCache(
"*",kTRUE);
392 for(TIter it(t->GetListOfBranches()); it.Next(); ) {
393 const char*
n = ((TNamed*)(*it))->GetName();
394 bool add =
false, veto =
false;
395 for(
const auto& i : cB ) {
396 if ( !match_wild(n,(i).c_str()) )
continue;
400 for(
auto i=vB.
cbegin(); !add && i!=vB.
cend();++i) {
401 if ( !match_wild(n,(*i).c_str()) )
continue;
405 if ( add && !veto ) {
406 msg <<
"Add " << n <<
" to branch cache." <<
endmsg;
407 t->AddBranchToCache(n,kTRUE);
410 msg <<
"Do not cache branch " << n <<
endmsg;
424 string n = branch_name;
426 [](
const char c) {
return !
isalnum(c); },
430 TBranch* b = t->GetBranch(n.c_str());
431 if ( !b && cl &&
m_file->IsWritable() ) {
432 b = t->Branch(n.c_str(),cl->GetName(),(
void*)(ptr ? &ptr :
nullptr),buff_siz,split_lvl);
434 if ( !b ) b = t->GetBranch(branch_name.
c_str());
435 if ( b ) b->SetAutoDelete(kFALSE);
449 if ( (which>=0) && (
size_t(which)<
m_dbs.
size()) ) {
464 DataObjectPush push(pObj);
465 return save(section,cnt,cl,pObj,buff_siz,split_lvl,fill);
472 TBranch* b =
getBranch(section, cnt, cl, pObj ? &pObj :
nullptr, buff_siz, split_lvl);
474 Long64_t
evt = b->GetEntries();
477 if ( fill_missing ) {
478 Long64_t num, nevt = b->GetTree()->GetEntries();
480 b->SetAddress(
nullptr);
482 while( num > 0 ) { b->Fill(); --num; }
484 <<
" / Tree: " << nevt <<
" / Branch: " << b->GetEntries()+1
485 <<
" NULL entries to:" << cnt <<
endmsg;
486 evt = b->GetEntries();
489 b->SetAddress(&pObj);
490 return {b->Fill(),evt};
502 TClass* cl = gROOT->GetClass(b->GetClassName(),kTRUE);
507 DataObjectPush push(pObj);
508 b->SetAddress(&pObj);
509 if ( section ==
m_setup->loadSection ) {
510 TTree* t = b->GetTree();
511 if ( Long64_t(entry) != t->GetReadEntry() ) {
512 t->LoadTree(Long64_t(entry));
515 nb = b->GetEntry(entry);
517 if (
msgSvc().isActive() ) {
518 msgSvc() <<
"Load [" << entry <<
"] --> " << section
519 <<
":" << cnt <<
" " << nb <<
" bytes." 523 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0) 530 else if ( nb == 0 && pObj->
clID() == CLID_DataObject) {
531 TFile* f = b->GetFile();
532 int vsn = f->GetVersion();
538 else if ( vsn>1000000 && (vsn%1000000)<52400 ) {
559 int nbytes =
m_tool->loadRefs(section,cnt,entry,refs);
560 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0) 583 for(
auto j=s.
cbegin(); j != s.
cend(); ++j,++cnt) {
589 <<
" [" << entry <<
"]" <<
endmsg 598 <<
" [" << entry <<
"]" <<
endmsg 600 return {
nullptr,
nullptr };
612 if ( db ==
m_fid ) db = s_local;
624 if ( !cnt.
empty() ) {
632 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.
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.
unsigned long getCode() const
Get the status code by value.
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.
bool isSuccess() const
Test for a status code of SUCCESS.
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.
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.
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.
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.
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.
Base class for all Incidents (computing events).
MsgStream & msgSvc() const
Allow access to printer service.
static long setCompression(const std::string &compression)
Set the global compression level.
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.
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.