Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-23 15:57:36

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/ProductDescription.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   class SignallingProductRegistryFiller;
0033   class ProductResolverIndexHelper;
0034   class TypeID;
0035 
0036   class ProductRegistry {
0037   public:
0038     friend class SignallingProductRegistryFiller;
0039 
0040     typedef std::map<BranchKey, ProductDescription> ProductList;
0041 
0042     ProductRegistry() = default;
0043     ProductRegistry(const ProductRegistry&) = default;
0044     ProductRegistry(ProductRegistry&&) = default;
0045     ProductRegistry& operator=(ProductRegistry&&) = default;
0046     // A constructor from the persistent data members from another product registry.
0047     // saves time by not copying the transient components.
0048     // The constructed registry will be frozen by default.
0049     explicit ProductRegistry(ProductList const& productList, bool toBeFrozen = true);
0050 
0051     ~ProductRegistry() = default;
0052 
0053     typedef std::map<BranchKey, ProductDescription const> ConstProductList;
0054 
0055     void copyProduct(ProductDescription const& productdesc);
0056 
0057     void setFrozen(bool initializeLookupInfo = true);
0058 
0059     void setFrozen(std::set<TypeID> const& productTypesConsumed,
0060                    std::set<TypeID> const& elementTypesConsumed,
0061                    std::string const& processName);
0062 
0063     void setUnscheduledProducts(std::set<std::string> const& unscheduledLabels);
0064 
0065     std::string merge(ProductRegistry const& other,
0066                       std::string const& fileName,
0067                       ProductDescription::MatchMode branchesMustMatch = ProductDescription::Permissive);
0068 
0069     void updateFromInput(ProductList const& other);
0070 
0071     void updateFromInput(std::vector<ProductDescription> const& other);
0072 
0073     ProductList const& productList() const {
0074       //throwIfNotFrozen();
0075       return productList_;
0076     }
0077 
0078     ProductList& productListUpdator() {
0079       throwIfFrozen();
0080       return productList_;
0081     }
0082 
0083     // Return all the branch names currently known to *this.  This
0084     // does a return-by-value of the vector so that it may be used in
0085     // a colon-initialization list.
0086     std::vector<std::string> allBranchNames() const;
0087 
0088     // Return pointers to (const) ProductDescriptions for all the
0089     // ProductDescriptions known to *this.  This does a
0090     // return-by-value of the vector so that it may be used in a
0091     // colon-initialization list.
0092     std::vector<ProductDescription const*> allProductDescriptions() const;
0093 
0094     ProductList::size_type size() const { return productList_.size(); }
0095 
0096     //If the value differs between two versions of the main registry then
0097     // one must update any related meta data
0098     using CacheID = ProductList::size_type;
0099     CacheID cacheIdentifier() const { return size(); }
0100 
0101     void print(std::ostream& os) const;
0102 
0103     bool anyProducts(BranchType const brType) const;
0104 
0105     std::shared_ptr<ProductResolverIndexHelper const> productLookup(BranchType branchType) const;
0106 
0107     // returns the appropriate ProductResolverIndex else ProductResolverIndexInvalid if no BranchID is available
0108     ProductResolverIndex indexFrom(BranchID const& iID) const;
0109 
0110     bool productProduced(BranchType branchType) const { return transient_.productProduced_[branchType]; }
0111     bool anyProductProduced() const { return transient_.anyProductProduced_; }
0112 
0113     // Looks if a (type, moduleLabel, productInstanceName) is an alias to some other branch
0114     //
0115     // Can return multiple modules if kindOfType is ELEMENT_TYPE (i.e.
0116     // the product is consumed via edm::View) and there is ambiguity
0117     // (in which case actual Event::get() would eventually lead to an
0118     // exception). In that case all possible modules whose product
0119     // could be consumed are returned.
0120     std::vector<std::string> aliasToModules(KindOfType kindOfType,
0121                                             TypeID const& type,
0122                                             std::string_view moduleLabel,
0123                                             std::string_view productInstanceName) const;
0124 
0125     ProductResolverIndex const& getNextIndexValue(BranchType branchType) const;
0126 
0127     void initializeTransients() { transient_.reset(); }
0128 
0129     bool frozen() const { return transient_.frozen_; }
0130 
0131     struct Transients {
0132       Transients();
0133       void reset();
0134 
0135       bool frozen_;
0136       // Is at least one (run), (lumi), (event) persistent product produced this process?
0137       std::array<bool, NumBranchTypes> productProduced_;
0138       bool anyProductProduced_;
0139 
0140       std::array<std::shared_ptr<const ProductResolverIndexHelper>, NumBranchTypes> productLookups_;
0141 
0142       std::array<ProductResolverIndex, NumBranchTypes> nextIndexValues_;
0143 
0144       std::map<BranchID, ProductResolverIndex> branchIDToIndex_;
0145 
0146       enum { kKind, kType, kModuleLabel, kProductInstanceName, kAliasForModuleLabel };
0147       using AliasToOriginalVector = std::vector<std::tuple<KindOfType, TypeID, std::string, std::string, std::string>>;
0148       AliasToOriginalVector aliasToOriginal_;
0149     };
0150 
0151   private:
0152     //The following three routines are only called by SignallingProductRegistryFiller
0153     void addProduct_(ProductDescription const& productdesc);
0154 
0155     ProductDescription const& addLabelAlias_(ProductDescription const& productdesc,
0156                                              std::string const& labelAlias,
0157                                              std::string const& instanceAlias);
0158 
0159     // triggers callbacks for modules watching registration
0160     template <typename F>
0161     void addFromInput_(edm::ProductRegistry const& iReg, F&& iCallback) {
0162       throwIfFrozen();
0163       for (auto const& prod : iReg.productList_) {
0164         ProductList::iterator iter = productList_.find(prod.first);
0165         if (iter == productList_.end()) {
0166           productList_.insert(std::make_pair(prod.first, prod.second));
0167           iCallback(prod.second);
0168         } else {
0169           assert(combinable(iter->second, prod.second));
0170           iter->second.merge(prod.second);
0171         }
0172       }
0173     }
0174 
0175   private:
0176     void setProductProduced(BranchType branchType) {
0177       transient_.productProduced_[branchType] = true;
0178       transient_.anyProductProduced_ = true;
0179     }
0180 
0181     void freezeIt(bool frozen = true) { transient_.frozen_ = frozen; }
0182 
0183     void initializeLookupTables(std::set<TypeID> const* productTypesConsumed,
0184                                 std::set<TypeID> const* elementTypesConsumed,
0185                                 std::string const* processName);
0186     void addElementTypesForAliases(std::set<TypeID> const* elementTypesConsumed,
0187                                    std::map<TypeID, TypeID> const& containedTypeMap,
0188                                    std::map<TypeID, std::vector<TypeID>> const& containedTypeToBaseTypesMap);
0189 
0190     void checkDictionariesOfConsumedTypes(std::set<TypeID> const* productTypesConsumed,
0191                                           std::set<TypeID> const* elementTypesConsumed,
0192                                           std::map<TypeID, TypeID> const& containedTypeMap,
0193                                           std::map<TypeID, std::vector<TypeID>>& containedTypeToBaseTypesMap);
0194 
0195     void checkForDuplicateProcessName(ProductDescription const& desc, std::string const* processName) const;
0196 
0197     void throwIfNotFrozen() const;
0198     void throwIfFrozen() const;
0199 
0200     ProductResolverIndex& nextIndexValue(BranchType branchType);
0201 
0202     ProductList productList_;
0203     Transients transient_;
0204   };
0205 
0206   inline bool operator==(ProductRegistry const& a, ProductRegistry const& b) {
0207     return a.productList() == b.productList();
0208   }
0209 
0210   inline bool operator!=(ProductRegistry const& a, ProductRegistry const& b) { return !(a == b); }
0211 
0212   inline std::ostream& operator<<(std::ostream& os, ProductRegistry const& pr) {
0213     pr.print(os);
0214     return os;
0215   }
0216 
0217 }  // namespace edm
0218 
0219 #endif