CMS 3D CMS Logo

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