File indexing completed on 2025-12-16 10:31:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012
0013
0014 #include <Gaudi/Property.h>
0015 #include <GaudiKernel/ClassID.h>
0016 #include <GaudiKernel/IIncidentSvc.h>
0017 #include <GaudiKernel/SmartIF.h>
0018 #include <GaudiUtils/IIODataManager.h>
0019 #include <map>
0020 #include <set>
0021 #include <string>
0022 #include <string_view>
0023 #include <vector>
0024
0025 #include <RootCnv/RootRefs.h>
0026 #include <TFile.h>
0027 #include <TTreePerfStats.h>
0028
0029
0030 class TTree;
0031 class TClass;
0032 class TBranch;
0033
0034 class MsgStream;
0035 class IRegistry;
0036 class DataObject;
0037 class IIncidentSvc;
0038
0039
0040
0041
0042 namespace Gaudi {
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 class GAUDI_API RootConnectionSetup final {
0055 private:
0056
0057 std::unique_ptr<MsgStream> m_msgSvc;
0058
0059 SmartIF<IIncidentSvc> m_incidentSvc = nullptr;
0060
0061 public:
0062
0063 typedef std::vector<std::string> StringVec;
0064
0065
0066 StringVec cacheBranches;
0067
0068 StringVec vetoBranches;
0069
0070 std::string loadSection;
0071
0072 int cacheSize{ 0 };
0073
0074 int learnEntries{ 0 };
0075
0076 Gaudi::Property<bool> produceReproducibleFiles{ "ProduceReproducibleFiles", true,
0077 "configure output files to be more reproducible" };
0078
0079 Gaudi::Property<bool> root630ForwardCompatibility{
0080 "ROOT630ForwardCompatibility", false,
0081 "When opening a file for CREATE or RECREATE, enable ROOT 6.30 forward compatibility "
0082 "(i.e. write a file that is readable with ROOT 6.24). Requires ROOT >= 6.30.06, see "
0083 "<https://github.com/root-project/root/issues/14793>." };
0084
0085
0086 RootConnectionSetup() = default;
0087
0088
0089 static StatusCode setCompression( std::string_view compression );
0090
0091 static int compression();
0092
0093
0094 void setMessageSvc( MsgStream* m );
0095
0096 MsgStream& msgSvc() const { return *m_msgSvc; }
0097
0098
0099 void setIncidentSvc( IIncidentSvc* m );
0100
0101 IIncidentSvc* incidentSvc() const { return m_incidentSvc.get(); }
0102 };
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 class GAUDI_API RootDataConnection : virtual public Gaudi::IDataConnection {
0113 public:
0114 enum class Status : StatusCode::code_t { ROOT_READ_ERROR = 0x2, ROOT_OPEN_ERROR = 0x4 };
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 struct ContainerSection {
0127
0128 ContainerSection() : start( -1 ), length( 0 ) {}
0129
0130 ContainerSection( int s, int l ) : start( s ), length( l ) {}
0131
0132 ContainerSection( const ContainerSection& s ) : start( s.start ), length( s.length ) {}
0133
0134 ContainerSection& operator=( const ContainerSection& s ) {
0135 if ( this != &s ) {
0136 start = s.start;
0137 length = s.length;
0138 }
0139 return *this;
0140 }
0141
0142 int start;
0143
0144 int length;
0145 };
0146
0147
0148 typedef std::vector<std::string> StringVec;
0149
0150 typedef std::vector<std::pair<std::string, std::string>> ParamMap;
0151
0152 typedef std::map<std::string, TTree*, std::less<>> Sections;
0153
0154 typedef std::vector<ContainerSection> ContainerSections;
0155
0156 typedef std::map<std::string, ContainerSections, std::less<>> MergeSections;
0157
0158 typedef std::vector<RootRef> LinkSections;
0159
0160 typedef std::set<const IInterface*> Clients;
0161
0162
0163 MsgStream& msgSvc() const { return m_setup->msgSvc(); }
0164 IIncidentSvc* incidentSvc() const { return m_setup->incidentSvc(); }
0165
0166 protected:
0167
0168 std::shared_ptr<RootConnectionSetup> m_setup;
0169
0170 std::unique_ptr<TTreePerfStats> m_statistics;
0171
0172 std::unique_ptr<TFile> m_file;
0173
0174 TTree* m_refs = nullptr;
0175
0176 Sections m_sections;
0177
0178 StringVec m_dbs;
0179
0180 StringVec m_conts;
0181
0182 StringVec m_links;
0183
0184 StringVec m_mergeFIDs;
0185
0186 ParamMap m_params;
0187
0188 MergeSections m_mergeSects;
0189
0190 LinkSections m_linkSects;
0191
0192 Clients m_clients;
0193
0194 std::string m_empty;
0195
0196
0197 const std::string& empty() const;
0198
0199
0200 StatusCode saveRefs();
0201
0202 public:
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 class Tool {
0213 protected:
0214 typedef RootDataConnection::StringVec StringVec;
0215 typedef RootDataConnection::ParamMap ParamMap;
0216 typedef RootDataConnection::Sections Sections;
0217 typedef RootDataConnection::MergeSections MergeSections;
0218 typedef RootDataConnection::LinkSections LinkSections;
0219 typedef RootDataConnection::ContainerSection ContainerSection;
0220 typedef RootDataConnection::ContainerSections ContainerSections;
0221
0222
0223 RootDataConnection* c;
0224
0225 public:
0226 TTree* refs() const { return c->m_refs; }
0227 StringVec& dbs() const { return c->m_dbs; }
0228 StringVec& conts() const { return c->m_conts; }
0229 StringVec& links() const { return c->m_links; }
0230 ParamMap& params() const { return c->m_params; }
0231 MsgStream& msgSvc() const { return c->msgSvc(); }
0232 IIncidentSvc* incidentSvc() const { return c->incidentSvc(); }
0233 const std::string& name() const { return c->m_name; }
0234 Sections& sections() const { return c->m_sections; }
0235 LinkSections& linkSections() const { return c->m_linkSects; }
0236 MergeSections& mergeSections() const { return c->m_mergeSects; }
0237
0238
0239 virtual ~Tool() = default;
0240
0241 virtual TBranch* getBranch( std::string_view section, std::string_view n ) = 0;
0242
0243 virtual RootRef poolRef( size_t ) const { return RootRef(); }
0244
0245
0246 virtual StatusCode readRefs() = 0;
0247
0248 virtual StatusCode saveRefs() = 0;
0249
0250 virtual int loadRefs( std::string_view section, std::string_view cnt, unsigned long entry,
0251 RootObjectRefs& refs ) = 0;
0252 };
0253 std::unique_ptr<Tool> m_tool;
0254 friend class Tool;
0255
0256
0257 Tool* makeTool();
0258
0259 public:
0260
0261 RootDataConnection( const IInterface* own, std::string_view nam, std::shared_ptr<RootConnectionSetup> setup );
0262
0263
0264 TFile* file() const { return m_file.get(); }
0265
0266 bool isConnected() const override { return bool( m_file ); }
0267
0268 bool isWritable() const { return m_file && m_file->IsWritable(); }
0269
0270 Tool* tool() const { return m_tool.get(); }
0271
0272 const MergeSections& mergeSections() const { return m_mergeSects; }
0273
0274 const StringVec& mergeFIDs() const { return m_mergeFIDs; }
0275
0276
0277 void addClient( const IInterface* client );
0278
0279 size_t removeClient( const IInterface* client );
0280
0281 bool lookupClient( const IInterface* client ) const;
0282
0283
0284 void badWriteError( std::string_view msg ) const;
0285
0286
0287 std::pair<const RootRef*, const ContainerSection*> getMergeSection( std::string_view container, int entry ) const;
0288
0289
0290 void enableStatistics( std::string_view section );
0291
0292 void saveStatistics( std::string_view statisticsFile );
0293
0294
0295 int loadObj( std::string_view section, std::string_view cnt, unsigned long entry, DataObject*& pObj );
0296
0297
0298 int loadRefs( std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs& refs );
0299
0300
0301 std::pair<int, unsigned long> saveObj( std::string_view section, std::string_view cnt, TClass* cl, DataObject* pObj,
0302 int minBufferSize, int maxBufferSize, int approxEventsPerBasket,
0303 int split_lvl, bool fill_missing = false );
0304
0305 std::pair<int, unsigned long> save( std::string_view section, std::string_view cnt, TClass* cl, void* pObj,
0306 int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl,
0307 bool fill_missing = false );
0308
0309
0310 StatusCode connectRead() override;
0311
0312 StatusCode connectWrite( IoType typ ) override;
0313
0314 StatusCode disconnect() override;
0315
0316 StatusCode read( void* const, size_t ) override { return StatusCode::FAILURE; }
0317
0318 StatusCode write( const void*, int ) override { return StatusCode::FAILURE; }
0319
0320 long long int seek( long long int, int ) override { return -1; }
0321
0322
0323 TTree* getSection( std::string_view sect, bool create = false );
0324
0325
0326 TBranch* getBranch( std::string_view section, std::string_view branch_name ) {
0327 return m_tool->getBranch( section, branch_name );
0328 }
0329
0330 TBranch* getBranch( std::string_view section, std::string_view branch_name, TClass* cl, void* ptr, int buff_siz,
0331 int split_lvl );
0332
0333
0334 void makeRef( const IRegistry& pA, RootRef& ref );
0335
0336 void makeRef( std::string_view name, long clid, int tech, std::string_view db, std::string_view cnt, int entry,
0337 RootRef& ref );
0338
0339
0340 int makeLink( std::string_view p );
0341
0342
0343 const std::string& getDb( int which ) const;
0344
0345
0346 const std::string& getCont( int which ) const {
0347 return ( which >= 0 ) && ( size_t( which ) < m_conts.size() ) ? *( m_conts.begin() + which ) : empty();
0348 }
0349
0350
0351 const std::string& getLink( int which ) const {
0352 return ( which >= 0 ) && ( size_t( which ) < m_links.size() ) ? *( m_links.begin() + which ) : empty();
0353 }
0354 };
0355 }
0356
0357 STATUSCODE_ENUM_DECL( Gaudi::RootDataConnection::Status )