Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:05:02

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