The Gaudi Framework  v30r3 (a5ef0a68)
PoolTool.h
Go to the documentation of this file.
1 #include "RootCnv/PoolClasses.h"
2 #include <algorithm>
3 /*
4 * Gaudi namespace declaration
5 */
6 namespace Gaudi
7 {
8 
18  class PoolTool : virtual public RootDataConnection::Tool
19  {
22 
23  public:
25  PoolTool( RootDataConnection* con ) { c = con; }
26 
28  string _treeName( boost::string_ref sr )
29  {
30  auto t = sr.to_string();
31  std::replace( begin( t ), end( t ), '/', '_' );
32  return t;
33  }
34 
35  RootRef poolRef( size_t i ) const override { return m_poolLinks[i]; }
36 
38  int loadRefs( boost::string_ref /* section */, boost::string_ref cnt, unsigned long entry,
39  RootObjectRefs& refs ) override
40  {
41  auto ti = sections().find( cnt );
42  TTree* t = ( ti != sections().end() ? ti->second : nullptr );
43  if ( !t ) {
44  t = (TTree*)c->file()->Get( _treeName( cnt ).c_str() );
45  }
46  if ( t ) {
47  TBranch* b1 = t->GetBranch( "Links" );
48  TBranch* b2 = t->GetBranch( "Refs" );
49  MsgStream& msg = msgSvc();
50  if ( b1 && b2 ) {
51  LinkManager lm, *plm = &lm;
52  PoolDbLinkManager mgr, *pmgr = &mgr;
53  b1->SetAutoDelete( kFALSE );
54  b2->SetAutoDelete( kFALSE );
55  b1->SetAddress( &plm );
56  b2->SetAddress( &pmgr );
57  int nb1 = b1->GetEvent( entry );
58  int nb2 = b2->GetEvent( entry );
59  if ( nb1 > 1 && nb2 > 1 ) {
60  size_t ref_size = mgr.references().size();
61  refs.refs.resize( ref_size );
62  msg << MSG::VERBOSE;
63  for ( size_t j = 0; j < ref_size; ++j ) {
64  const pair<int, int>& oid = mgr.references()[j]->m_oid;
65  string loc = mgr.links()[j].substr( 1 );
66  RootRef& r = refs.refs[j];
67  if ( oid.first >= 0 ) {
68  r = m_poolLinks[oid.first];
69  r.entry = oid.second;
70  r.link = c->makeLink( loc );
71  msg << "Add leaf:" << oid.first << "->" << loc << " from " << c->getDb( r.dbase ) << "#"
72  << c->getCont( r.container ) << " Link:" << c->getLink( r.link ) << " CLID:" << hex << r.clid
73  << " Typ:" << hex << int( r.svc ) << " Ent:" << dec << r.entry << endl;
74  }
75  }
76  for ( int i = 0, n = lm.size(); i < n; ++i ) {
77  LinkManager::Link* lnk = lm.link( i );
78  int link_id = c->makeLink( lnk->path() );
79  msg << "Add Link:" << lnk->path() << endl;
80  refs.links.push_back( link_id );
81  }
82  return nb1 + nb2;
83  }
84  }
85  msg << MSG::ERROR << "Failed to access POOL Ref/Link branches:" << cnt << " [" << _treeName( cnt ) << "]"
86  << endmsg;
87  t->Print();
88  }
89  return -1;
90  }
91 
93  TBranch* getBranch( boost::string_ref /* section */, boost::string_ref branch_name ) override
94  {
95  auto ti = sections().find( branch_name );
96  TTree* t = ( ti != sections().end() ? ti->second : nullptr );
97  if ( t ) {
98  return (TBranch*)t->GetListOfBranches()->At( 0 );
99  }
100  string tname = _treeName( branch_name );
101  t = (TTree*)c->file()->Get( tname.c_str() ); // c->getSection(tname);
102  if ( t ) {
103  TBranch* b = (TBranch*)t->GetListOfBranches()->At( 0 );
104  if ( b ) {
105  sections()[branch_name.to_string()] = t;
106  return b;
107  }
108  msgSvc() << MSG::ERROR << "Failed to access POOL branch:" << branch_name << " [" << tname << "]" << endmsg;
109  t->Print();
110  }
111  return nullptr;
112  }
113 
115  StatusCode saveRefs() override { return StatusCode::FAILURE; }
116 
118  StatusCode readRefs() override
119  {
120  int i;
121  char text[2048];
122  msgSvc() << MSG::VERBOSE;
123 
124  // First read ##Params
125  TTree* t = (TTree*)c->file()->Get( "##Params" );
126  if ( !t ) return StatusCode::FAILURE;
127  TBranch* b = t->GetBranch( "db_string" );
128  if ( !b ) return StatusCode::FAILURE;
129  for ( i = 0, b->SetAddress( text ); i < b->GetEntries(); ++i ) {
130  b->GetEvent( i );
131  char* id1 = strstr( text, "[NAME=" );
132  char* id2 = strstr( text, "[VALUE=" );
133  if ( id1 && id2 ) {
134  id1 += 6;
135  id2 += 7;
136  char* id11 = strstr( id1, "]" );
137  char* id22 = strstr( id2, "]" );
138  if ( id11 && id22 ) {
139  *id11 = 0;
140  *id22 = 0;
141  params().emplace_back( id1, id2 );
142  msgSvc() << "Param:" << id1 << "=" << id2 << "." << endmsg;
143  }
144  }
145  }
146 
147  // Read ##Links
148  t = (TTree*)c->file()->Get( "##Links" );
149  if ( !t ) return StatusCode::FAILURE;
150  b = t->GetBranch( "db_string" );
151  if ( !b ) return StatusCode::FAILURE;
152  m_poolLinks.resize( (size_t)b->GetEntries() + 2 ); // Take into account the ##Links and ##Shapes entry of POOL!
153  for ( i = 0, b->SetAddress( text ); i < b->GetEntries(); ++i ) {
154  b->GetEvent( i );
155  std::string db, container;
156  int clid = 1, technology = 0, ipar[2] = {-1, -1};
157  for ( char* p1 = (char*)text; p1; p1 = ::strchr( ++p1, '[' ) ) {
158  char* p2 = ::strchr( p1, '=' );
159  char* p3 = ::strchr( p1, ']' );
160  if ( p2 && p3 ) {
161  if (::strncmp( "[DB=", p1, 4 ) == 0 ) {
162  *p3 = 0;
163  db = p1 + 4;
164  } else if (::strncmp( "[CNT=", p1, 5 ) == 0 ) {
165  *p3 = 0;
166  container = p1 + 5;
167  } else if (::strncmp( "[OID=", p1, 5 ) == 0 ) {
168  *p3 = 0;
169  ::sscanf( p1 + 5, "%08X,%08X", (unsigned int*)&ipar[0], (unsigned int*)&ipar[1] );
170  } else if (::strncmp( "[CLID=", p1, 6 ) == 0 ) {
171  *p3 = 0;
172  ::sscanf( p1 + 6, "%08X", (unsigned int*)&clid );
173  } else if (::strncmp( "[TECH=", p1, 6 ) == 0 ) {
174  *p3 = 0;
175  ::sscanf( p1 + 6, "%08X", (unsigned int*)&technology );
176  } else {
177  *p3 = *p2 = 0;
178  }
179  *p3 = ']';
180  *p2 = '=';
181  }
182  }
183  c->makeRef( "", clid, technology, db, container, -1, m_poolLinks[i + 2] );
184  RootRef& r = m_poolLinks[i];
185  msgSvc() << "Add link[" << i << "]:" << db << container << " [" << r.dbase << "," << r.container << "] "
186  << " tech:" << hex << setw( 8 ) << r.svc << " CLID:" << setw( 8 ) << r.clid << dec << endmsg;
187  }
188  return StatusCode::SUCCESS;
189  }
190  };
191 }
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
constexpr double sr
StatusCode saveRefs() override
Save references section when closing data file (NOT SUPPORTED)
Definition: PoolTool.h:115
TFile * file() const
Direct access to TFile structure.
const std::string & getDb(int which) const
Access database/file name from saved index.
string _treeName(boost::string_ref sr)
Convert TES object identifier to ROOT tree name.
Definition: PoolTool.h:28
RootRef poolRef(size_t i) const override
Internal overload to facilitate the access to POOL files.
Definition: PoolTool.h:35
int makeLink(boost::string_ref p)
Convert path string to path index.
std::vector< Gaudi::RootRef > m_poolLinks
Image of the POOL ##Links table.
Definition: PoolTool.h:21
TBranch * getBranch(boost::string_ref, boost::string_ref branch_name) override
Access data branch by name: Get existing branch in read only mode.
Definition: PoolTool.h:93
MsgStream & dec(MsgStream &log)
Definition: MsgStream.h:299
const std::string & getLink(int which) const
Access link name from saved index.
T end(T...args)
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
Definition: RootRefs.h:64
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:304
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
Definition: RootRefs.h:60
T resize(T...args)
STL class.
int dbase
Data members to define object location in the persistent world.
Definition: RootRefs.h:33
Persistent reference object.
Definition: RootRefs.h:31
T push_back(T...args)
PoolTool(RootDataConnection *con)
Standard constructor.
Definition: PoolTool.h:25
T replace(T...args)
Helper class to facilitate an abstraction layer for reading POOL style files with this package...
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
int loadRefs(boost::string_ref, boost::string_ref cnt, unsigned long entry, RootObjectRefs &refs) override
Load references object from file.
Definition: PoolTool.h:38
const std::string & getCont(int which) const
Access container name from saved index.
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
std::vector< int > links
The links of the link manager.
Definition: RootRefs.h:62
T find(T...args)
T size(T...args)
RootDataConnection * c
Pointer to containing data connection object.
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
StatusCode readRefs() override
Internal helper to read reference tables ##Params and ##Links.
Definition: PoolTool.h:118
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Concrete implementation of the IDataConnection interface to access ROOT files.
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
T emplace_back(T...args)