Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TTreeReaderFast.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_TTreeReaderFast
13 #define ROOT_TTreeReaderFast
14 
15 
16 ////////////////////////////////////////////////////////////////////////////
17 // //
18 // TTreeReader //
19 // //
20 // A simple interface for reading trees or chains. //
21 // //
22 // //
23 ////////////////////////////////////////////////////////////////////////////
24 
25 #include "TTree.h"
26 #include "TTreeReader.h"
27 
28 #include <deque>
29 
30 // Forward decl's
31 namespace ROOT {
32 namespace Experimental {
33 namespace Internal {
34 class TTreeReaderValueFast;
35 class TTreeReaderValueFastBase;
36 } // Internal
37 
38 class TTreeReaderFast: public TObject {
39 public:
40 
41  // A simple iterator based on TTreeReader::Iterator_t; allows use of the
42  // TTreeReaderFast.
43  //
44  // NOTE that an increment may invalidate previous copies of the iterator.
45  class Iterator_t:
46  public std::iterator<std::input_iterator_tag, const Long64_t, Long64_t> {
47  private:
48  Int_t *fIdx{nullptr}; ///< Current offset inside this cluster.
49  Int_t fCount{0}; ///< Number of entries inside this cluster.
50  Long64_t fEntry{-1}; ///< Entry number of the tree referenced by this iterator; -1 is invalid.
51  TTreeReaderFast *fReader{nullptr}; ///< The reader we select the entries on.
52 
53  /// Whether the iterator points to a valid entry.
54  bool IsValid() const { return fEntry >= 0; }
55 
56  public:
57  /// Default-initialize the iterator as "past the end".
58  Iterator_t() {}
59 
60  /// Initialize the iterator with the reader it steers and a
61  /// tree entry number; -1 is invalid.
62  Iterator_t(TTreeReaderFast& reader, Long64_t first):
63  fIdx(&(reader.fEvtIndex)), fEntry(first), fReader(&reader)
64  {
65  //printf("Initializing new iterator; start of %lld, proceed for %lld events.\n", first, count);
66  fCount = fReader->GetNextRange(fEntry);
67  *fIdx = 0;
68  }
69 
70  /// Compare two iterators for equality.
71  bool operator==(const Iterator_t& lhs) const {
72  // From C++14: value initialized (past-end) it compare equal.
73  if (R__unlikely(!IsValid() && !lhs.IsValid())) {return true;}
74  return R__unlikely(fEntry == lhs.fEntry && fReader == lhs.fReader);
75  }
76 
77  /// Compare two iterators for inequality.
78  bool operator!=(const Iterator_t& lhs) const {
79  return !(*this == lhs);
80  }
81 
82  /// Increment the iterator (postfix i++).
83  Iterator_t operator++(int) {
84  Iterator_t ret = *this;
85  this->operator++();
86  return ret;
87  }
88 
89  /// Increment the iterator (prefix ++i).
90  Iterator_t& operator++() {
91  (*fIdx)++;
92  if (R__unlikely(*fIdx == fCount)) {
93  //printf("Hit end-of-basket of %d events. Get next entry.\n", fCount);
94  fEntry += fCount;
95  *fIdx = 0;
96  fCount = fReader->GetNextRange(fEntry);
97  //printf("This chunk has %d events.\n", fCount);
98  if (R__unlikely(!fCount || (fCount < 0))) {
99  fEntry = -1;
100  fReader->fEntryStatus = TTreeReader::kEntryBadReader;
101  }
102  }
103  return *this;
104  }
105 
106  /// Set the entry number in the reader and return it.
107  Long64_t operator*() {
108  return fEntry + *fIdx;
109  }
110 
111  Long64_t operator*() const {
112  return **const_cast<Iterator_t*>(this);
113  }
114  };
115 
116  typedef Iterator_t iterator;
117 
118  TTreeReaderFast():
119  fTree(nullptr),
120  fEntryStatus(TTreeReader::kEntryNoTree),
121  fLastEntry(-1)
122  {}
123 
124  TTreeReaderFast(TTree* tree);
125  TTreeReaderFast(const char* keyname, TDirectory* dir = NULL );
126 
127  ~TTreeReaderFast();
128 
129  TTreeReader::EEntryStatus SetEntriesRange(Long64_t first, Long64_t last);
130 
131  TTreeReader::EEntryStatus GetEntryStatus() const { return fEntryStatus; }
132 
133  TTree* GetTree() const { return fTree; }
134 
135  TTreeReader::EEntryStatus SetEntry(Long64_t);
136 
137  /// Return an iterator to the 0th TTree entry.
138  Iterator_t begin() {
139  return Iterator_t(*this, 0);
140  }
141  Iterator_t end() const { return Iterator_t(); }
142 
143 protected:
144 
145  // Returns a reference to the current event index in the various value buffers.
146  Int_t &GetIndexRef() {return fEvtIndex;}
147 
148  void RegisterValueReader(ROOT::Experimental::Internal::TTreeReaderValueFastBase* reader);
149  void DeregisterValueReader(ROOT::Experimental::Internal::TTreeReaderValueFastBase* reader);
150 
151 private:
152 
153  Int_t GetNextRange(Int_t);
154  void Initialize();
155 
156  TTree* fTree{nullptr}; ///< tree that's read
157  TDirectory* fDirectory{nullptr}; ///< directory (or current file for chains)
158  ROOT::Internal::TBranchProxyDirector* fDirector{nullptr}; ///< proxying director, owned
159  TTreeReader::EEntryStatus fEntryStatus{TTreeReader::kEntryNotLoaded}; ///< status of most recent read request
160  std::deque<ROOT::Experimental::Internal::TTreeReaderValueFastBase*> fValues; ///< readers that use our director
161 
162  Int_t fEvtIndex{-1};
163  Long64_t fBaseEvent{-1};
164  Long64_t fLastEntry{-1};
165 
166  friend class ROOT::Experimental::Internal::TTreeReaderValueFastBase;
167 
168  ClassDef(TTreeReaderFast, 0); // A simple interface to read trees via bulk I/O
169 };
170 
171 } // Experimental
172 } // ROOT
173 #endif // defined TTreeReaderFast