Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:54:30

0001 #ifndef DataFormats_Provenance_ProductRegistry_h
0002 #define DataFormats_Provenance_ProductRegistry_h
0003 
0004 /** \class edm::ProductRegistry
0005 
0006      \original author Stefano ARGIRO
0007      \current author Bill Tanenbaum
0008      \date 19 Jul 2005
0009 */
0010 
0011 #include "DataFormats/Provenance/interface/BranchDescription.h"
0012 #include "DataFormats/Provenance/interface/BranchKey.h"
0013 #include "DataFormats/Provenance/interface/BranchListIndex.h"
0014 #include "DataFormats/Provenance/interface/BranchType.h"
0015 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0016 #include "FWCore/Utilities/interface/ProductResolverIndex.h"
0017 #include "FWCore/Utilities/interface/get_underlying_safe.h"
0018 
0019 #include <array>
0020 #include <memory>
0021 
0022 #include <iosfwd>
0023 #include <map>
0024 #include <set>
0025 #include <string>
0026 #include <string_view>
0027 #include <tuple>
0028 #include <utility>
0029 #include <vector>
0030 
0031 namespace edm {
0032 
0033   class ProductResolverIndexHelper;
0034   class TypeID;
0035   class TypeWithDict;
0036 
0037   class ProductRegistry {
0038   public:
0039     typedef std::map<BranchKey, BranchDescription> ProductList;
0040 
0041     ProductRegistry();
0042 
0043     // A constructor from the persistent data members from another product registry.
0044     // saves time by not copying the transient components.
0045     // The constructed registry will be frozen by default.
0046     explicit ProductRegistry(ProductList const& productList, bool toBeFrozen = true);
0047 
0048     virtual ~ProductRegistry() {}
0049 
0050     typedef std::map<BranchKey, BranchDescription const> ConstProductList;
0051 
0052     void addProduct(BranchDescription const& productdesc, bool iFromListener = false);
0053 
0054     void addLabelAlias(BranchDescription const& productdesc,
0055                        std::string const& labelAlias,
0056                        std::string const& instanceAlias);
0057 
0058     void copyProduct(BranchDescription const& productdesc);
0059 
0060     void setFrozen(bool initializeLookupInfo = true);
0061 
0062     void setFrozen(std::set<TypeID> const& productTypesConsumed,
0063                    std::set<TypeID> const& elementTypesConsumed,
0064                    std::string const& processName);
0065 
0066     void setUnscheduledProducts(std::set<std::string> const& unscheduledLabels);
0067 
0068     std::string merge(ProductRegistry const& other,
0069                       std::string const& fileName,
0070                       BranchDescription::MatchMode branchesMustMatch = BranchDescription::Permissive);
0071 
0072     void updateFromInput(ProductList const& other);
0073 
0074     void updateFromInput(std::vector<BranchDescription> const& other);
0075 
0076     ProductList const& productList() const {
0077       //throwIfNotFrozen();
0078       return productList_;
0079     }
0080 
0081     ProductList& productListUpdator() {
0082       throwIfFrozen();
0083       return productList_;
0084     }
0085 
0086     // Return all the branch names currently known to *this.  This
0087     // does a return-by-value of the vector so that it may be used in
0088     // a colon-initialization list.
0089     std::vector<std::string> allBranchNames() const;
0090 
0091     // Return pointers to (const) BranchDescriptions for all the
0092     // BranchDescriptions known to *this.  This does a
0093     // return-by-value of the vector so that it may be used in a
0094     // colon-initialization list.
0095     std::vector<BranchDescription const*> allBranchDescriptions() const;
0096 
0097     //NOTE: this is not const since we only want items that have non-const access to this class to be
0098     // able to call this internal iteration
0099     template <typename T>
0100     void callForEachBranch(T const& iFunc) {
0101       //NOTE: If implementation changes from a map, need to check that iterators are still valid
0102       // after an insert with the new container, else need to copy the container and iterate over the copy
0103       for (ProductRegistry::ProductList::const_iterator itEntry = productList_.begin(), itEntryEnd = productList_.end();
0104            itEntry != itEntryEnd;
0105            ++itEntry) {
0106         iFunc(itEntry->second);
0107       }
0108     }
0109     ProductList::size_type size() const { return productList_.size(); }
0110 
0111     void print(std::ostream& os) const;
0112 
0113     bool anyProducts(BranchType const brType) const;
0114 
0115     std::shared_ptr<ProductResolverIndexHelper const> productLookup(BranchType branchType) const;
0116     std::shared_ptr<ProductResolverIndexHelper> productLookup(BranchType branchType);
0117 
0118     // returns the appropriate ProductResolverIndex else ProductResolverIndexInvalid if no BranchID is available
0119     ProductResolverIndex indexFrom(BranchID const& iID) const;
0120 
0121     bool productProduced(BranchType branchType) const { return transient_.productProduced_[branchType]; }
0122     bool anyProductProduced() const { return transient_.anyProductProduced_; }
0123 
0124     // Looks if a (type, moduleLabel, productInstanceName) is an alias to some other branch
0125     //
0126     // Can return multiple modules if kindOfType is ELEMENT_TYPE (i.e.
0127     // the product is consumed via edm::View) and there is ambiguity
0128     // (in which case actual Event::get() would eventually lead to an
0129     // exception). In that case all possible modules whose product
0130     // could be consumed are returned.
0131     std::vector<std::string> aliasToModules(KindOfType kindOfType,
0132                                             TypeID const& type,
0133                                             std::string_view moduleLabel,
0134                                             std::string_view productInstanceName) const;
0135 
0136     ProductResolverIndex const& getNextIndexValue(BranchType branchType) const;
0137 
0138     void initializeTransients() { transient_.reset(); }
0139 
0140     bool frozen() const { return transient_.frozen_; }
0141 
0142     struct Transients {
0143       Transients();
0144       void reset();
0145 
0146       bool frozen_;
0147       // Is at least one (run), (lumi), (event) persistent product produced this process?
0148       std::array<bool, NumBranchTypes> productProduced_;
0149       bool anyProductProduced_;
0150 
0151       std::array<edm::propagate_const<std::shared_ptr<ProductResolverIndexHelper>>, NumBranchTypes> productLookups_;
0152 
0153       std::array<ProductResolverIndex, NumBranchTypes> nextIndexValues_;
0154 
0155       std::map<BranchID, ProductResolverIndex> branchIDToIndex_;
0156 
0157       enum { kKind, kType, kModuleLabel, kProductInstanceName, kAliasForModuleLabel };
0158       using AliasToOriginalVector = std::vector<std::tuple<KindOfType, TypeID, std::string, std::string, std::string>>;
0159       AliasToOriginalVector aliasToOriginal_;
0160     };
0161 
0162   private:
0163     void setProductProduced(BranchType branchType) {
0164       transient_.productProduced_[branchType] = true;
0165       transient_.anyProductProduced_ = true;
0166     }
0167 
0168     void freezeIt(bool frozen = true) { transient_.frozen_ = frozen; }
0169 
0170     void initializeLookupTables(std::set<TypeID> const* productTypesConsumed,
0171                                 std::set<TypeID> const* elementTypesConsumed,
0172                                 std::string const* processName);
0173     void addElementTypesForAliases(std::set<TypeID> const* elementTypesConsumed,
0174                                    std::map<TypeID, TypeID> const& containedTypeMap,
0175                                    std::map<TypeID, std::vector<TypeWithDict>> const& containedTypeToBaseTypesMap);
0176 
0177     void checkDictionariesOfConsumedTypes(std::set<TypeID> const* productTypesConsumed,
0178                                           std::set<TypeID> const* elementTypesConsumed,
0179                                           std::map<TypeID, TypeID> const& containedTypeMap,
0180                                           std::map<TypeID, std::vector<TypeWithDict>>& containedTypeToBaseTypesMap);
0181 
0182     void checkForDuplicateProcessName(BranchDescription const& desc, std::string const* processName) const;
0183 
0184     virtual void addCalled(BranchDescription const&, bool iFromListener);
0185     void throwIfNotFrozen() const;
0186     void throwIfFrozen() const;
0187 
0188     ProductResolverIndex& nextIndexValue(BranchType branchType);
0189 
0190     ProductList productList_;
0191     Transients transient_;
0192   };
0193 
0194   inline bool operator==(ProductRegistry const& a, ProductRegistry const& b) {
0195     return a.productList() == b.productList();
0196   }
0197 
0198   inline bool operator!=(ProductRegistry const& a, ProductRegistry const& b) { return !(a == b); }
0199 
0200   inline std::ostream& operator<<(std::ostream& os, ProductRegistry const& pr) {
0201     pr.print(os);
0202     return os;
0203   }
0204 
0205 }  // namespace edm
0206 
0207 #endif