The Gaudi Framework  v33r1 (b1225454)
PoolTool.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include "RootCnv/PoolClasses.h"
12 #include <algorithm>
13 /*
14  * Gaudi namespace declaration
15  */
16 namespace Gaudi {
17 
27  class PoolTool : virtual public RootDataConnection::Tool {
30 
31  public:
33  PoolTool( RootDataConnection* con ) { c = con; }
34 
36  string _treeName( std::string_view sr ) {
37  std::string t{sr};
38  std::replace( begin( t ), end( t ), '/', '_' );
39  return t;
40  }
41 
42  RootRef poolRef( size_t i ) const override { return m_poolLinks[i]; }
43 
45  int loadRefs( std::string_view /* section */, std::string_view cnt, unsigned long entry,
46  RootObjectRefs& refs ) override {
47  auto ti = sections().find( cnt );
48  TTree* t = ( ti != sections().end() ? ti->second : nullptr );
49  if ( !t ) { t = (TTree*)c->file()->Get( _treeName( cnt ).c_str() ); }
50  if ( t ) {
51  TBranch* b1 = t->GetBranch( "Links" );
52  TBranch* b2 = t->GetBranch( "Refs" );
53  MsgStream& msg = msgSvc();
54  if ( b1 && b2 ) {
55  LinkManager lm, *plm = &lm;
56  PoolDbLinkManager mgr, *pmgr = &mgr;
57  b1->SetAutoDelete( kFALSE );
58  b2->SetAutoDelete( kFALSE );
59  b1->SetAddress( &plm );
60  b2->SetAddress( &pmgr );
61  int nb1 = b1->GetEvent( entry );
62  int nb2 = b2->GetEvent( entry );
63  if ( nb1 > 1 && nb2 > 1 ) {
64  size_t ref_size = mgr.references().size();
65  refs.refs.resize( ref_size );
66  msg << MSG::VERBOSE;
67  for ( size_t j = 0; j < ref_size; ++j ) {
68  const pair<int, int>& oid = mgr.references()[j]->m_oid;
69  string loc = mgr.links()[j].substr( 1 );
70  RootRef& r = refs.refs[j];
71  if ( oid.first >= 0 ) {
72  r = m_poolLinks[oid.first];
73  r.entry = oid.second;
74  r.link = c->makeLink( loc );
75  msg << "Add leaf:" << oid.first << "->" << loc << " from " << c->getDb( r.dbase ) << "#"
76  << c->getCont( r.container ) << " Link:" << c->getLink( r.link ) << " CLID:" << hex << r.clid
77  << " Typ:" << hex << int( r.svc ) << " Ent:" << dec << r.entry << endl;
78  }
79  }
80  for ( int i = 0, n = lm.size(); i < n; ++i ) {
81  LinkManager::Link* lnk = lm.link( i );
82  int link_id = c->makeLink( lnk->path() );
83  msg << "Add Link:" << lnk->path() << endl;
84  refs.links.push_back( link_id );
85  }
86  return nb1 + nb2;
87  }
88  }
89  msg << MSG::ERROR << "Failed to access POOL Ref/Link branches:" << cnt << " [" << _treeName( cnt ) << "]"
90  << endmsg;
91  t->Print();
92  }
93  return -1;
94  }
95 
97  TBranch* getBranch( std::string_view /* section */, std::string_view branch_name ) override {
98  auto ti = sections().find( branch_name );
99  TTree* t = ( ti != sections().end() ? ti->second : nullptr );
100  if ( t ) { return (TBranch*)t->GetListOfBranches()->At( 0 ); }
101  string tname = _treeName( branch_name );
102  t = (TTree*)c->file()->Get( tname.c_str() ); // c->getSection(tname);
103  if ( t ) {
104  TBranch* b = (TBranch*)t->GetListOfBranches()->At( 0 );
105  if ( b ) {
106  sections()[std::string{branch_name}] = t;
107  return b;
108  }
109  msgSvc() << MSG::ERROR << "Failed to access POOL branch:" << branch_name << " [" << tname << "]" << endmsg;
110  t->Print();
111  }
112  return nullptr;
113  }
114 
116  StatusCode saveRefs() override { return StatusCode::FAILURE; }
117 
119  StatusCode readRefs() override {
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 } // namespace Gaudi
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:34
constexpr double sr
StatusCode saveRefs() override
Save references section when closing data file (NOT SUPPORTED)
Definition: PoolTool.h:116
int makeLink(std::string_view p)
Convert path string to path index.
std::vector< Gaudi::RootRef > m_poolLinks
Image of the POOL ##Links table.
Definition: PoolTool.h:29
MsgStream & dec(MsgStream &log)
Definition: MsgStream.h:277
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
T end(T... args)
const std::string & getDb(int which) const
Access database/file name from saved index.
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:281
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject.
Definition: extractEvt.C:81
T resize(T... args)
STL class.
int loadRefs(std::string_view, std::string_view cnt, unsigned long entry, RootObjectRefs &refs) override
Load references object from file.
Definition: PoolTool.h:45
int dbase
Data members to define object location in the persistent world.
Definition: extractEvt.C:46
Persistent reference object.
Definition: extractEvt.C:44
const std::string & getCont(int which) const
Access container name from saved index.
PoolTool(RootDataConnection *con)
Standard constructor.
Definition: PoolTool.h:33
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:61
const std::string & getLink(int which) const
Access link name from saved index.
def end
Definition: IOTest.py:123
T find(T... args)
T size(T... args)
RootRef poolRef(size_t i) const override
Internal overload to facilitate the access to POOL files.
Definition: PoolTool.h:42
TBranch * getBranch(std::string_view, std::string_view branch_name) override
Access data branch by name: Get existing branch in read only mode.
Definition: PoolTool.h:97
constexpr static const auto FAILURE
Definition: StatusCode.h:101
RootDataConnection * c
Pointer to containing data connection object.
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
TFile * file() const
Direct access to TFile structure.
StatusCode readRefs() override
Internal helper to read reference tables ##Params and ##Links.
Definition: PoolTool.h:119
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Concrete implementation of the IDataConnection interface to access ROOT files.
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
string _treeName(std::string_view sr)
Convert TES object identifier to ROOT tree name.
Definition: PoolTool.h:36
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
T emplace_back(T... args)