Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TTreeCache.h
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Rene Brun 04/06/2006
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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_TTreeCache
13 #define ROOT_TTreeCache
14 
15 
16 //////////////////////////////////////////////////////////////////////////
17 // //
18 // TTreeCache //
19 // //
20 // Specialization of TFileCacheRead for a TTree //
21 // //
22 //////////////////////////////////////////////////////////////////////////
23 
24 #include "TFileCacheRead.h"
25 
26 #include <cstdint>
27 #include <memory>
28 #include <utility>
29 #include <vector>
30 
31 class TTree;
32 class TBranch;
33 class TObjArray;
34 
35 class TTreeCache : public TFileCacheRead {
36 
37 public:
38  enum EPrefillType { kNoPrefill, kAllBranches };
39 
40 protected:
41  Long64_t fEntryMin{0}; ///<! first entry in the cache
42  Long64_t fEntryMax{1}; ///<! last entry in the cache
43  Long64_t fEntryCurrent{-1}; ///<! current lowest entry number in the cache
44  Long64_t fEntryNext{-1}; ///<! next entry number where cache must be filled
45  Long64_t fCurrentClusterStart{-1}; ///<! Start of the cluster(s) where the current content was picked out
46  Long64_t fNextClusterStart{-1}; ///<! End+1 of the cluster(s) where the current content was picked out
47  Int_t fNbranches{0}; ///<! Number of branches in the cache
48  Int_t fNReadOk{0}; ///< Number of blocks read and found in the cache
49  Int_t fNMissReadOk{0}; ///< Number of blocks read, not found in the primary cache, and found in the secondary cache.
50  Int_t fNReadMiss{0}; ///< Number of blocks read and not found in the cache
51  Int_t fNMissReadMiss{0}; ///< Number of blocks read and not found in either cache.
52  Int_t fNReadPref{0}; ///< Number of blocks that were prefetched
53  Int_t fNMissReadPref{0}; ///< Number of blocks read into the secondary ("miss") cache.
54  TObjArray *fBranches{nullptr}; ///<! List of branches to be stored in the cache
55  TList *fBrNames{nullptr}; ///<! list of branch names in the cache
56  TTree *fTree{nullptr}; ///<! pointer to the current Tree
57  Bool_t fIsLearning{kTRUE}; ///<! true if cache is in learning mode
58  Bool_t fIsManual{kFALSE}; ///<! true if cache is StopLearningPhase was used
59  Bool_t fFirstBuffer{kTRUE}; ///<! true if first buffer is used for prefetching
60  Bool_t fOneTime{kFALSE}; ///<! used in the learning phase
61  Bool_t fReverseRead{kFALSE}; ///<! reading in reverse mode
62  Int_t fFillTimes{0}; ///<! how many times we can fill the current buffer
63  Bool_t fFirstTime{kTRUE}; ///<! save the fact that we processes the first entry
64  Long64_t fFirstEntry{-1}; ///<! save the value of the first entry
65  Bool_t fReadDirectionSet{kFALSE}; ///<! read direction established
66  Bool_t fEnabled{kTRUE}; ///<! cache enabled for cached reading
67  EPrefillType fPrefillType; ///< Whether a pre-filling is enabled (and if applicable which type)
68  static Int_t fgLearnEntries; ///< number of entries used for learning mode
69  Bool_t fAutoCreated{kFALSE}; ///<! true if cache was automatically created
70 
71  Bool_t fLearnPrefilling{kFALSE}; ///<! true if we are in the process of executing LearnPrefill
72 
73  // These members hold cached data for missed branches when miss optimization
74  // is enabled. Pointers are only initialized if the miss cache is enabled.
75  Bool_t fOptimizeMisses{kFALSE}; ///<! true if we should optimize cache misses.
76  Long64_t fFirstMiss{-1}; ///<! set to the event # of the first miss.
77  Long64_t fLastMiss{-1}; ///<! set to the event # of the last miss.
78 
79  // Representation of a positioned buffer IO.
80  // {0,0} designates the uninitialized - or invalid - buffer.
81  struct IOPos {
82  IOPos(Long64_t pos, Int_t len) : fPos(pos), fLen(len) {}
83 
84  Long64_t fPos{0}; //! Position in file of cache entry.
85  Int_t fLen{0}; //! Length of cache entry.
86  };
87 
88  struct MissCache {
89  struct Entry {
90  Entry(IOPos io) : fIO(io) {}
91 
92  IOPos fIO;
93  ULong64_t fIndex{0}; ///<! Location in fData corresponding to this entry.
94  friend bool operator<(const Entry &a, const Entry &b) { return a.fIO.fPos < b.fIO.fPos; }
95  };
96  std::vector<Entry> fEntries; ///<! Description of buffers in the miss cache.
97  std::vector<TBranch *> fBranches; ///<! list of branches that we read on misses.
98  std::vector<char> fData; ///<! Actual data in the cache.
99 
100  void clear()
101  {
102  fEntries.clear();
103  fBranches.clear();
104  fData.clear();
105  }
106  };
107 
108  std::unique_ptr<MissCache> fMissCache; ///<! Cache contents for misses
109 
110 private:
111  TTreeCache(const TTreeCache &) = delete; ///< this class cannot be copied
112  TTreeCache &operator=(const TTreeCache &) = delete;
113 
114  // These are all functions related to the "miss cache": this attempts to
115  // optimize ROOT's behavior when the TTreeCache has a cache miss. In this
116  // case, we try to read several branches for the event with the miss.
117  //
118  // The miss cache is more CPU-intensive than the rest of the TTreeCache code;
119  // for local work (i.e., laptop with SSD), this CPU cost may outweight the
120  // benefit.
121  Bool_t CheckMissCache(char *buf, Long64_t pos,
122  int len); ///< Check the miss cache for a particular buffer, fetching if deemed necessary.
123  Bool_t FillMissCache(); ///< Fill the miss cache from the current set of active branches.
124  Bool_t CalculateMissCache(); ///< Calculate the appropriate miss cache to fetch; helper function for FillMissCache
125  IOPos FindBranchBasketPos(TBranch &, Long64_t entry); ///< Given a branch and an entry, determine the file location
126  ///< (offset / size) of the corresponding basket.
127  TBranch *CalculateMissEntries(Long64_t, int, bool); ///< Given an file read, try to determine the corresponding branch.
128  Bool_t ProcessMiss(Long64_t pos, int len); ///<! Given a file read not in the miss cache, handle (possibly) loading the data.
129 
130 public:
131 
132  TTreeCache();
133  TTreeCache(TTree *tree, Int_t buffersize=0);
134  virtual ~TTreeCache();
135  virtual Int_t AddBranch(TBranch *b, Bool_t subgbranches = kFALSE);
136  virtual Int_t AddBranch(const char *branch, Bool_t subbranches = kFALSE);
137  virtual Int_t DropBranch(TBranch *b, Bool_t subbranches = kFALSE);
138  virtual Int_t DropBranch(const char *branch, Bool_t subbranches = kFALSE);
139  virtual void Disable() {fEnabled = kFALSE;}
140  virtual void Enable() {fEnabled = kTRUE;}
141  Bool_t GetOptimizeMisses() const { return fOptimizeMisses; }
142  const TObjArray *GetCachedBranches() const { return fBranches; }
143  EPrefillType GetConfiguredPrefillType() const;
144  Double_t GetEfficiency() const;
145  Double_t GetEfficiencyRel() const;
146  virtual Int_t GetEntryMin() const {return fEntryMin;}
147  virtual Int_t GetEntryMax() const {return fEntryMax;}
148  static Int_t GetLearnEntries();
149  virtual EPrefillType GetLearnPrefill() const {return fPrefillType;}
150  Double_t GetMissEfficiency() const;
151  Double_t GetMissEfficiencyRel() const;
152  TTree *GetTree() const {return fTree;}
153  Bool_t IsAutoCreated() const {return fAutoCreated;}
154  virtual Bool_t IsEnabled() const {return fEnabled;}
155  virtual Bool_t IsLearning() const {return fIsLearning;}
156 
157  virtual Bool_t FillBuffer();
158  virtual Int_t LearnBranch(TBranch *b, Bool_t subgbranches = kFALSE);
159  virtual void LearnPrefill();
160 
161  virtual void Print(Option_t *option="") const;
162  virtual Int_t ReadBuffer(char *buf, Long64_t pos, Int_t len);
163  virtual Int_t ReadBufferNormal(char *buf, Long64_t pos, Int_t len);
164  virtual Int_t ReadBufferPrefetch(char *buf, Long64_t pos, Int_t len);
165  virtual void ResetCache();
166  void ResetMissCache(); // Reset the miss cache.
167  void SetAutoCreated(Bool_t val) {fAutoCreated = val;}
168  virtual Int_t SetBufferSize(Int_t buffersize);
169  virtual void SetEntryRange(Long64_t emin, Long64_t emax);
170  virtual void SetFile(TFile *file, TFile::ECacheAction action=TFile::kDisconnect);
171  virtual void SetLearnPrefill(EPrefillType type = kNoPrefill);
172  static void SetLearnEntries(Int_t n = 10);
173  void SetOptimizeMisses(Bool_t opt);
174  void StartLearningPhase();
175  virtual void StopLearningPhase();
176  virtual void UpdateBranches(TTree *tree);
177 
178  ClassDef(TTreeCache,3) //Specialization of TFileCacheRead for a TTree
179 };
180 
181 #endif