Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TTreeReaderValueFast.hxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Brian Bockelman, 2017-06-13
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TTreeReaderValueFast
13 #define ROOT_TTreeReaderValueFast
14 
15 
16 ////////////////////////////////////////////////////////////////////////////
17 // //
18 // TTreeReaderValueFast //
19 // //
20 // A simple interface for reading data from trees or chains. //
21 // //
22 // //
23 ////////////////////////////////////////////////////////////////////////////
24 
25 #include "ROOT/TTreeReaderFast.hxx"
26 
27 #include "TBranch.h"
28 #include "TBufferFile.h"
29 
30 #include <type_traits>
31 
32 class TBranch;
33 
34 namespace ROOT {
35 namespace Experimental {
36 namespace Internal {
37 
38 /* All the common code shared by the fast reader templates.
39  */
40 class TTreeReaderValueFastBase {
41  public:
42  TTreeReaderValueFastBase(const TTreeReaderValueFastBase&) = delete;
43 
44  ROOT::Internal::TTreeReaderValueBase::ESetupStatus GetSetupStatus() const { return fSetupStatus; }
45  virtual ROOT::Internal::TTreeReaderValueBase::EReadStatus GetReadStatus() const { return fReadStatus; }
46 
47  //////////////////////////////////////////////////////////////////////////////
48  /// Construct a tree value reader and register it with the reader object.
49  TTreeReaderValueFastBase(TTreeReaderFast* reader, const std::string &branchName) :
50  fBranchName(branchName),
51  fLeafName(branchName), // TODO: only support single-leaf branches for now.
52  fTreeReader(reader),
53  fBuffer(TBuffer::kWrite, 32*1024),
54  fEvtIndex(reader->GetIndexRef())
55  {
56  if (fTreeReader) fTreeReader->RegisterValueReader(this);
57  }
58 
59  Int_t GetEvents(Long64_t eventNum) {
60  //printf("Getting events starting at %lld. Current remaining is %d events with base %lld.\n", eventNum, fRemaining, fEventBase);
61  if (fEventBase >= 0 && (fRemaining + fEventBase > eventNum)) {
62  Int_t adjust = (eventNum - fEventBase);
63  if (R__unlikely(Adjust(adjust) < 0)) {
64  //printf("Failed to adjust offset to mid-buffer.\n");
65  return -1;
66  }
67  fRemaining -= adjust;
68  } else {
69  fRemaining = fBranch->GetBulkRead().GetEntriesSerialized(eventNum, fBuffer);
70  if (R__unlikely(fRemaining < 0)) {
71  fReadStatus = ROOT::Internal::TTreeReaderValueBase::kReadError;
72  //printf("Failed to retrieve entries from the branch.\n");
73  return -1;
74  }
75  }
76  fEventBase = eventNum;
77  //printf("After getting events, the base is %lld with %d remaining.\n", fEventBase, fRemaining);
78  fReadStatus = ROOT::Internal::TTreeReaderValueBase::kReadSuccess;
79  return fRemaining;
80  }
81 
82  virtual const char *GetTypeName() {return "{UNDETERMINED}";}
83 
84 
85  protected:
86 
87  // Adjust the current buffer offset forward N events.
88  virtual Int_t Adjust(Int_t eventCount) {
89  Int_t bufOffset = fBuffer.Length();
90  fBuffer.SetBufferOffset(bufOffset + eventCount*GetSize());
91  return 0;
92  }
93  virtual UInt_t GetSize() = 0;
94 
95  void MarkTreeReaderUnavailable() {
96  fTreeReader = nullptr;
97  }
98 
99  // Create the linkage between the TTreeReader's current tree and this ReaderValue
100  // object. After CreateProxy() is invoked, if fSetupStatus doesn't indicate an
101  // error, then we are pointing toward a valid TLeaf in the current tree
102  void CreateProxy();
103 
104  virtual ~TTreeReaderValueFastBase();
105 
106  // Returns the name of the branch type; will be used when the TBranch version to
107  // detect between the compile-time and runtime type names.
108  virtual const char *BranchTypeName() = 0;
109 
110  std::string fBranchName; // Name of the branch we should read from.
111  std::string fLeafName; // The branch's leaf we should read from. NOTE: currently only support single-leaf branches.
112  TTreeReaderFast *fTreeReader{nullptr}; // Reader we belong to
113  TBranch * fBranch{nullptr}; // Actual branch object we are reading.
114  TLeaf * fLeaf{nullptr}; // Actual leaf we are reading.
115  TBufferFile fBuffer; // Buffer object holding the current events.
116  Int_t fRemaining{0}; // Number of events remaining in the buffer.
117  Int_t &fEvtIndex; // Current event index.
118  Long64_t fLastChainOffset{-1}; // Current chain in the TTree we are pointed at.
119  Long64_t fEventBase{-1}; // Event number of the current buffer position.
120 
121  ROOT::Internal::TTreeReaderValueBase::ESetupStatus fSetupStatus{ROOT::Internal::TTreeReaderValueBase::kSetupNotSetup}; // setup status of this data access
122  ROOT::Internal::TTreeReaderValueBase::EReadStatus fReadStatus{ROOT::Internal::TTreeReaderValueBase::kReadNothingYet}; // read status of this data access
123 
124  friend class ROOT::Experimental::TTreeReaderFast;
125 };
126 
127 } // Internal
128 
129 template <typename T>
130 class TTreeReaderValueFast final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
131 
132  public:
133  TTreeReaderValueFast(TTreeReaderFast* reader, const std::string &branchname) : ROOT::Experimental::Internal::TTreeReaderValueFastBase(reader, branchname) {}
134 
135  T* Get() {
136  return Deserialize(reinterpret_cast<char *>(reinterpret_cast<T*>(fBuffer.GetCurrent()) + fEvtIndex));
137  }
138  T* operator->() { return Get(); }
139  T& operator*() { return *Get(); }
140 
141  protected:
142  T* Deserialize(char *) {return nullptr;}
143 
144  virtual const char *GetTypeName() override {return "{INCOMPLETE}";}
145  virtual UInt_t GetSize() override {return sizeof(T);}
146 };
147 
148 template<>
149 class TTreeReaderValueFast<float> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
150 
151  public:
152 
153  TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
154  TTreeReaderValueFastBase(&tr, branchname) {}
155 
156  float* Get() {
157  return Deserialize(reinterpret_cast<char *>(reinterpret_cast<float*>(fBuffer.GetCurrent()) + fEvtIndex));
158  }
159  float* operator->() { return Get(); }
160  float& operator*() { return *Get(); }
161 
162  protected:
163  virtual const char *GetTypeName() override {return "float";}
164  virtual const char *BranchTypeName() override {return "float";}
165  virtual UInt_t GetSize() override {return sizeof(float);}
166  float * Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
167 
168  float fTmp;
169 };
170 
171 template <>
172 class TTreeReaderValueFast<double> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
173 
174  public:
175 
176  TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
177  TTreeReaderValueFastBase(&tr, branchname) {}
178 
179  // TODO: why isn't template specialization working here?
180  double* Get() {
181  //printf("Double: Attempting to deserialize buffer %p from index %d.\n", fBuffer.GetCurrent(), fEvtIndex);
182  return Deserialize(reinterpret_cast<char *>(reinterpret_cast<double*>(fBuffer.GetCurrent()) + fEvtIndex));
183  }
184  double* operator->() { return Get(); }
185  double& operator*() { return *Get(); }
186 
187  protected:
188  virtual const char *GetTypeName() override {return "double";}
189  virtual const char *BranchTypeName() override {return "double";}
190  virtual UInt_t GetSize() override {return sizeof(double);}
191  double* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
192 
193  double fTmp;
194 };
195 
196 template <>
197 class TTreeReaderValueFast<Int_t> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
198 
199  public:
200 
201  TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
202  TTreeReaderValueFastBase(&tr, branchname) {}
203 
204  Int_t* Get() {
205  return Deserialize(reinterpret_cast<char *>(reinterpret_cast<Int_t*>(fBuffer.GetCurrent()) + fEvtIndex));
206  }
207  Int_t* operator->() { return Get(); }
208  Int_t& operator*() { return *Get(); }
209 
210  protected:
211  virtual const char *GetTypeName() override {return "integer";}
212  virtual const char *BranchTypeName() override {return "integer";}
213  virtual UInt_t GetSize() override {return sizeof(Int_t);}
214  Int_t* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
215 
216  Int_t fTmp;
217 };
218 
219 template <>
220 class TTreeReaderValueFast<UInt_t> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
221 
222  public:
223 
224  TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
225  TTreeReaderValueFastBase(&tr, branchname) {}
226 
227  UInt_t* Get() {
228  return Deserialize(reinterpret_cast<char *>(reinterpret_cast<UInt_t*>(fBuffer.GetCurrent()) + fEvtIndex));
229  }
230  UInt_t* operator->() { return Get(); }
231  UInt_t& operator*() { return *Get(); }
232 
233  protected:
234  virtual const char *GetTypeName() override {return "unsigned integer";}
235  virtual const char *BranchTypeName() override {return "unsigned integer";}
236  virtual UInt_t GetSize() override {return sizeof(UInt_t);}
237  UInt_t* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
238 
239  UInt_t fTmp;
240 };
241 
242 template <>
243 class TTreeReaderValueFast<Bool_t> final : public ROOT::Experimental::Internal::TTreeReaderValueFastBase {
244 
245  public:
246 
247  TTreeReaderValueFast(TTreeReaderFast& tr, const std::string &branchname) :
248  TTreeReaderValueFastBase(&tr, branchname) {}
249 
250  Bool_t* Get() {
251  return Deserialize(reinterpret_cast<char *>(reinterpret_cast<Bool_t*>(fBuffer.GetCurrent()) + fEvtIndex));
252  }
253  Bool_t* operator->() { return Get(); }
254  Bool_t& operator*() { return *Get(); }
255 
256  protected:
257  virtual const char *GetTypeName() override {return "unsigned integer";}
258  virtual const char *BranchTypeName() override {return "unsigned integer";}
259  virtual UInt_t GetSize() override {return sizeof(Bool_t);}
260  Bool_t* Deserialize(char *input) {frombuf(input, &fTmp); return &fTmp;}
261 
262  Bool_t fTmp;
263 };
264 
265 } // Experimental
266 } // ROOT
267 
268 #endif // ROOT_TTreeReaderValueFast