CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DataFormats/Provenance/interface/ProductRegistry.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Provenance_ProductRegistry_h
00002 #define DataFormats_Provenance_ProductRegistry_h
00003 
00011 #include "DataFormats/Provenance/interface/BranchDescription.h"
00012 #include "DataFormats/Provenance/interface/BranchKey.h"
00013 #include "DataFormats/Provenance/interface/BranchListIndex.h"
00014 #include "DataFormats/Provenance/interface/BranchType.h"
00015 #include "DataFormats/Provenance/interface/ConstBranchDescription.h"
00016 #include "FWCore/Utilities/interface/ProductHolderIndex.h"
00017 
00018 #include "boost/array.hpp"
00019 #include "boost/shared_ptr.hpp"
00020 
00021 #include <iosfwd>
00022 #include <map>
00023 #include <string>
00024 #include <vector>
00025 
00026 namespace edm {
00027   class ProductHolderIndexHelper;
00028 
00029   class ProductRegistry {
00030 
00031   public:
00032     typedef std::map<BranchKey, BranchDescription> ProductList;
00033 
00034     ProductRegistry();
00035 
00036     // A constructor from the persistent data memebers from another product registry.
00037     // saves time by not copying the transient components.
00038     // The constructed registry will be frozen by default.
00039     explicit ProductRegistry(ProductList const& productList, bool toBeFrozen = true);
00040 
00041     virtual ~ProductRegistry() {}
00042 
00043     typedef std::map<BranchKey, ConstBranchDescription> ConstProductList;
00044 
00045     void addProduct(BranchDescription const& productdesc, bool iFromListener = false);
00046 
00047     void addLabelAlias(BranchDescription const& productdesc, std::string const& labelAlias, std::string const& instanceAlias);
00048 
00049     void copyProduct(BranchDescription const& productdesc);
00050 
00051     void setFrozen(bool initializeLookupInfo = true) const;
00052 
00053     std::string merge(ProductRegistry const& other,
00054         std::string const& fileName,
00055         BranchDescription::MatchMode parametersMustMatch = BranchDescription::Permissive,
00056         BranchDescription::MatchMode branchesMustMatch = BranchDescription::Permissive);
00057 
00058     void updateFromInput(ProductList const& other);
00059 
00060     void updateFromInput(std::vector<BranchDescription> const& other);
00061 
00062     ProductList const& productList() const {
00063       //throwIfNotFrozen();
00064       return productList_;
00065     }
00066 
00067     ProductList& productListUpdator() {
00068       throwIfFrozen();
00069       return productList_;
00070     }
00071 
00072     // Return all the branch names currently known to *this.  This
00073     // does a return-by-value of the vector so that it may be used in
00074     // a colon-initialization list.
00075     std::vector<std::string> allBranchNames() const;
00076 
00077     // Return pointers to (const) BranchDescriptions for all the
00078     // BranchDescriptions known to *this.  This does a
00079     // return-by-value of the vector so that it may be used in a
00080     // colon-initialization list.
00081     std::vector<BranchDescription const*> allBranchDescriptions() const;
00082 
00083     //NOTE: this is not const since we only want items that have non-const access to this class to be
00084     // able to call this internal iteration
00085     template<typename T>
00086     void callForEachBranch(T const& iFunc)  {
00087       //NOTE: If implementation changes from a map, need to check that iterators are still valid
00088       // after an insert with the new container, else need to copy the container and iterate over the copy
00089       for(ProductRegistry::ProductList::const_iterator itEntry = productList_.begin(),
00090           itEntryEnd = productList_.end();
00091           itEntry != itEntryEnd; ++itEntry) {
00092         iFunc(itEntry->second);
00093       }
00094     }
00095     ProductList::size_type size() const {return productList_.size();}
00096 
00097     void print(std::ostream& os) const;
00098 
00099     bool anyProducts(BranchType const brType) const;
00100 
00101     ConstProductList& constProductList() const {
00102        //throwIfNotFrozen();
00103        return transient_.constProductList_;
00104     }
00105 
00106     boost::shared_ptr<ProductHolderIndexHelper> const& productLookup(BranchType branchType) const;
00107 
00108     // returns the appropriate ProductHolderIndex else ProductHolderIndexInvalid if no BranchID is available
00109     ProductHolderIndex indexFrom(BranchID const& iID) const;
00110 
00111     bool productProduced(BranchType branchType) const {return transient_.productProduced_[branchType];}
00112     bool anyProductProduced() const {return transient_.anyProductProduced_;}
00113     BranchListIndex producedBranchListIndex() const {return transient_.producedBranchListIndex_;}
00114 
00115     void setProducedBranchListIndex(BranchListIndex blix) const {
00116       transient_.producedBranchListIndex_ = blix;
00117     }
00118 
00119     std::vector<std::string>& missingDictionaries() const {
00120       return transient_.missingDictionaries_;
00121     }
00122 
00123     ProductHolderIndex const& getNextIndexValue(BranchType branchType) const;
00124 
00125     void initializeTransients() const {transient_.reset();}
00126 
00127     struct Transients {
00128       Transients();
00129       void reset();
00130       bool frozen_;
00131       ConstProductList constProductList_;
00132       // Is at least one (run), (lumi), (event) product produced this process?
00133       boost::array<bool, NumBranchTypes> productProduced_;
00134       bool anyProductProduced_;
00135 
00136       boost::shared_ptr<ProductHolderIndexHelper> eventProductLookup_;
00137       boost::shared_ptr<ProductHolderIndexHelper> lumiProductLookup_;
00138       boost::shared_ptr<ProductHolderIndexHelper> runProductLookup_;
00139 
00140       ProductHolderIndex eventNextIndexValue_;
00141       ProductHolderIndex lumiNextIndexValue_;
00142       ProductHolderIndex runNextIndexValue_;
00143 
00144       std::map<BranchID, ProductHolderIndex> branchIDToIndex_;
00145 
00146       BranchListIndex producedBranchListIndex_;
00147 
00148       std::vector<std::string> missingDictionaries_;
00149     };
00150 
00151   private:
00152     void setProductProduced(BranchType branchType) const {
00153       transient_.productProduced_[branchType] = true;
00154       transient_.anyProductProduced_ = true;
00155     }
00156 
00157     bool& frozen() const {return transient_.frozen_;}
00158 
00159     void updateConstProductRegistry();
00160     void initializeLookupTables() const;
00161     virtual void addCalled(BranchDescription const&, bool iFromListener);
00162     void throwIfNotFrozen() const;
00163     void throwIfFrozen() const;
00164 
00165     ProductHolderIndex& nextIndexValue(BranchType branchType) const;
00166 
00167     ProductList productList_;
00168     mutable Transients transient_;
00169   };
00170 
00171   inline
00172   bool
00173   operator==(ProductRegistry const& a, ProductRegistry const& b) {
00174     return a.productList() == b.productList();
00175   }
00176 
00177   inline
00178   bool
00179   operator!=(ProductRegistry const& a, ProductRegistry const& b) {
00180     return !(a == b);
00181   }
00182 
00183   inline
00184   std::ostream&
00185   operator<<(std::ostream& os, ProductRegistry const& pr) {
00186     pr.print(os);
00187     return os;
00188   }
00189 
00190 } // edm
00191 
00192 #endif