Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:44:16

0001 #ifndef IOPool_Input_RootTree_h
0002 #define IOPool_Input_RootTree_h
0003 
0004 /*----------------------------------------------------------------------
0005 
0006 RootTree.h // used by ROOT input sources
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include "DataFormats/Provenance/interface/BranchDescription.h"
0011 #include "DataFormats/Provenance/interface/BranchID.h"
0012 #include "DataFormats/Provenance/interface/IndexIntoFile.h"
0013 #include "FWCore/Framework/interface/Frameworkfwd.h"
0014 #include "FWCore/ServiceRegistry/interface/ServiceRegistryfwd.h"
0015 #include "FWCore/Utilities/interface/BranchType.h"
0016 #include "FWCore/Utilities/interface/InputType.h"
0017 #include "FWCore/Utilities/interface/Signal.h"
0018 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0019 
0020 #include "Rtypes.h"
0021 #include "TBranch.h"
0022 
0023 #include <memory>
0024 #include <string>
0025 #include <vector>
0026 #include <unordered_set>
0027 #include <unordered_map>
0028 
0029 class TClass;
0030 class TTree;
0031 class TTreeCache;
0032 
0033 namespace edm {
0034   class RootDelayedReader;
0035   class InputFile;
0036 
0037   namespace roottree {
0038     unsigned int const defaultCacheSize = 20U * 1024 * 1024;
0039     unsigned int const defaultNonEventCacheSize = 1U * 1024 * 1024;
0040     unsigned int const defaultLearningEntries = 20U;
0041     unsigned int const defaultNonEventLearningEntries = 1U;
0042     using EntryNumber = IndexIntoFile::EntryNumber_t;
0043     struct BranchInfo {
0044       BranchInfo(BranchDescription const& prod)
0045           : branchDescription_(prod), productBranch_(nullptr), classCache_(nullptr), offsetToWrapperBase_(0) {}
0046       BranchDescription const branchDescription_;
0047       TBranch* productBranch_;
0048       //All access to a ROOT file is serialized
0049       CMS_SA_ALLOW mutable TClass* classCache_;
0050       CMS_SA_ALLOW mutable Int_t offsetToWrapperBase_;
0051     };
0052 
0053     class BranchMap {
0054     public:
0055       using Map = std::unordered_map<unsigned int, BranchInfo>;
0056 
0057       void reserve(Map::size_type iSize) { map_.reserve(iSize); }
0058       void insert(edm::BranchID const& iKey, BranchInfo const& iInfo) { map_.emplace(iKey.id(), iInfo); }
0059       BranchInfo const* find(BranchID const& iKey) const {
0060         auto itFound = map_.find(iKey.id());
0061         if (itFound == map_.end()) {
0062           return nullptr;
0063         }
0064         return &itFound->second;
0065       }
0066 
0067     private:
0068       Map map_;
0069     };
0070 
0071     Int_t getEntry(TBranch* branch, EntryNumber entryNumber);
0072     Int_t getEntry(TTree* tree, EntryNumber entryNumber);
0073     std::unique_ptr<TTreeCache> trainCache(TTree* tree,
0074                                            InputFile& file,
0075                                            unsigned int cacheSize,
0076                                            char const* branchNames);
0077   }  // namespace roottree
0078 
0079   class RootTree {
0080   public:
0081     using BranchMap = roottree::BranchMap;
0082     using EntryNumber = roottree::EntryNumber;
0083 
0084     RootTree(std::shared_ptr<InputFile> filePtr,
0085              BranchType const& branchType,
0086              unsigned int nIndexes,
0087              unsigned int learningEntries,
0088              bool enablePrefetching,
0089              InputType inputType);
0090 
0091     RootTree(std::shared_ptr<InputFile> filePtr,
0092              BranchType const& branchType,
0093              unsigned int nIndexes,
0094              unsigned int maxVirtualSize,
0095              unsigned int cacheSize,
0096              unsigned int learningEntries,
0097              bool enablePrefetching,
0098              InputType inputType);
0099 
0100     RootTree(std::shared_ptr<InputFile> filePtr,
0101              BranchType const& branchType,
0102              std::string const& processName,
0103              unsigned int nIndexes,
0104              unsigned int maxVirtualSize,
0105              unsigned int cacheSize,
0106              unsigned int learningEntries,
0107              bool enablePrefetching,
0108              InputType inputType);
0109 
0110     void init(std::string const& productTreeName, unsigned int maxVirtualSize, unsigned int cacheSize);
0111 
0112     ~RootTree();
0113 
0114     RootTree(RootTree const&) = delete;             // Disallow copying and moving
0115     RootTree& operator=(RootTree const&) = delete;  // Disallow copying and moving
0116 
0117     bool isValid() const;
0118     void numberOfBranchesToAdd(BranchMap::Map::size_type iSize) { branches_.reserve(iSize); }
0119     void addBranch(BranchDescription const& prod, std::string const& oldBranchName);
0120     void dropBranch(std::string const& oldBranchName);
0121     void getEntry(TBranch* branch, EntryNumber entry) const;
0122     void setPresence(BranchDescription& prod, std::string const& oldBranchName);
0123 
0124     bool next() { return ++entryNumber_ < entries_; }
0125     bool nextWithCache();
0126     bool current() const { return entryNumber_ < entries_ && entryNumber_ >= 0; }
0127     bool current(EntryNumber entry) const { return entry < entries_ && entry >= 0; }
0128     void rewind() { entryNumber_ = 0; }
0129     void rewindToInvalid() { entryNumber_ = IndexIntoFile::invalidEntry; }
0130     void close();
0131     bool skipEntries(unsigned int& offset);
0132     EntryNumber const& entryNumber() const { return entryNumber_; }
0133     EntryNumber const& entryNumberForIndex(unsigned int index) const;
0134     EntryNumber const& entries() const { return entries_; }
0135     void setEntryNumber(EntryNumber theEntryNumber);
0136     void insertEntryForIndex(unsigned int index);
0137     std::vector<std::string> const& branchNames() const { return branchNames_; }
0138     DelayedReader* rootDelayedReader() const;
0139     DelayedReader* resetAndGetRootDelayedReader() const;
0140     template <typename T>
0141     void fillAux(T*& pAux) {
0142       auxBranch_->SetAddress(&pAux);
0143       getEntry(auxBranch_, entryNumber_);
0144     }
0145 
0146     template <typename T>
0147     void fillBranchEntry(TBranch* branch, T*& pbuf) {
0148       branch->SetAddress(&pbuf);
0149       getEntry(branch, entryNumber_);
0150     }
0151 
0152     template <typename T>
0153     void fillBranchEntryMeta(TBranch* branch, EntryNumber entryNumber, T*& pbuf) {
0154       if (metaTree_ != nullptr) {
0155         // Metadata was in separate tree.  Not cached.
0156         branch->SetAddress(&pbuf);
0157         roottree::getEntry(branch, entryNumber);
0158       } else {
0159         fillBranchEntry<T>(branch, entryNumber, pbuf);
0160       }
0161     }
0162 
0163     template <typename T>
0164     void fillBranchEntry(TBranch* branch, EntryNumber entryNumber, T*& pbuf) {
0165       branch->SetAddress(&pbuf);
0166       getEntry(branch, entryNumber);
0167     }
0168 
0169     TTree const* tree() const { return tree_; }
0170     TTree* tree() { return tree_; }
0171     TTree const* metaTree() const { return metaTree_; }
0172     TTree* metaTree() { return metaTree_; }
0173     BranchMap const& branches() const;
0174 
0175     //For backwards compatibility
0176     TBranch* branchEntryInfoBranch() const { return branchEntryInfoBranch_; }
0177 
0178     inline TTreeCache* checkTriggerCache(TBranch* branch, EntryNumber entryNumber) const;
0179     TTreeCache* checkTriggerCacheImpl(TBranch* branch, EntryNumber entryNumber) const;
0180     inline TTreeCache* selectCache(TBranch* branch, EntryNumber entryNumber) const;
0181     void trainCache(char const* branchNames);
0182     void resetTraining() { trainNow_ = true; }
0183 
0184     BranchType branchType() const { return branchType_; }
0185     std::string const& processName() const { return processName_; }
0186 
0187     void setSignals(
0188         signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* preEventReadSource,
0189         signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* postEventReadSource);
0190 
0191   private:
0192     void setCacheSize(unsigned int cacheSize);
0193     void setTreeMaxVirtualSize(int treeMaxVirtualSize);
0194     void startTraining();
0195     void stopTraining();
0196 
0197     std::shared_ptr<InputFile> filePtr_;
0198     // We use bare pointers for pointers to some ROOT entities.
0199     // Root owns them and uses bare pointers internally.
0200     // Therefore,using smart pointers here will do no good.
0201     TTree* tree_ = nullptr;
0202     TTree* metaTree_ = nullptr;
0203     BranchType branchType_;
0204     std::string processName_;
0205     TBranch* auxBranch_ = nullptr;
0206     // We use a smart pointer to own the TTreeCache.
0207     // Unfortunately, ROOT owns it when attached to a TFile, but not after it is detached.
0208     // So, we make sure to it is detached before closing the TFile so there is no double delete.
0209     std::shared_ptr<TTreeCache> treeCache_;
0210     std::shared_ptr<TTreeCache> rawTreeCache_;
0211     //All access to a ROOT file is serialized
0212     CMS_SA_ALLOW mutable std::shared_ptr<TTreeCache> triggerTreeCache_;
0213     CMS_SA_ALLOW mutable std::shared_ptr<TTreeCache> rawTriggerTreeCache_;
0214     CMS_SA_ALLOW mutable std::unordered_set<TBranch*> trainedSet_;
0215     CMS_SA_ALLOW mutable std::unordered_set<TBranch*> triggerSet_;
0216     EntryNumber entries_ = 0;
0217     EntryNumber entryNumber_ = IndexIntoFile::invalidEntry;
0218     std::unique_ptr<std::vector<EntryNumber> > entryNumberForIndex_;
0219     std::vector<std::string> branchNames_;
0220     BranchMap branches_;
0221     bool trainNow_ = false;
0222     EntryNumber switchOverEntry_ = -1;
0223     CMS_SA_ALLOW mutable EntryNumber rawTriggerSwitchOverEntry_ = -1;
0224     CMS_SA_ALLOW mutable bool performedSwitchOver_ = false;
0225     unsigned int learningEntries_;
0226     unsigned int cacheSize_ = 0;
0227     unsigned long treeAutoFlush_ = 0;
0228     // Enable asynchronous I/O in ROOT (done in a separate thread).  Only takes
0229     // effect on the primary treeCache_; all other caches have this explicitly disabled.
0230     bool enablePrefetching_;
0231     bool enableTriggerCache_;
0232     std::unique_ptr<RootDelayedReader> rootDelayedReader_;
0233 
0234     TBranch* branchEntryInfoBranch_ = nullptr;  //backwards compatibility
0235     // below for backward compatibility
0236     TTree* infoTree_ = nullptr;  // backward compatibility
0237   };
0238 }  // namespace edm
0239 #endif