Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-19 01:43:41

0001 #ifndef FWCore_Framework_Principal_h
0002 #define FWCore_Framework_Principal_h
0003 
0004 /*----------------------------------------------------------------------
0005 
0006 Principal: This is the implementation of the classes responsible
0007 for management of EDProducts. It is not seen by reconstruction code.
0008 
0009 The major internal component of the Principal is the ProductResolver, which
0010 contains an EDProduct and its associated Provenance, along with
0011 ancillary transient information regarding the two. ProductResolvers are handled
0012 through shared pointers.
0013 
0014 The Principal returns BasicHandle, rather than a shared
0015 pointer to a ProductResolver, when queried.
0016 
0017 (Historical note: prior to April 2007 this class was named DataBlockImpl)
0018 
0019 ----------------------------------------------------------------------*/
0020 #include "DataFormats/Common/interface/BasicHandle.h"
0021 #include "DataFormats/Common/interface/ConvertHandle.h"
0022 #include "DataFormats/Common/interface/WrapperBase.h"
0023 #include "DataFormats/Common/interface/EDProductGetter.h"
0024 #include "DataFormats/Common/interface/Wrapper.h"
0025 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0026 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
0027 #include "FWCore/Framework/interface/Frameworkfwd.h"
0028 #include "FWCore/Framework/interface/ProductResolverBase.h"
0029 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0030 #include "FWCore/Utilities/interface/InputTag.h"
0031 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0032 #include "FWCore/Utilities/interface/propagate_const.h"
0033 
0034 #include "boost/iterator/filter_iterator.hpp"
0035 
0036 #include <map>
0037 #include <memory>
0038 #include <set>
0039 #include <string>
0040 #include <vector>
0041 
0042 namespace edm {
0043 
0044   class HistoryAppender;
0045   class MergeableRunProductMetadata;
0046   class ModuleCallingContext;
0047   class ProductResolverIndexHelper;
0048   class EDConsumerBase;
0049   class SharedResourcesAcquirer;
0050   class UnscheduledConfigurator;
0051 
0052   struct FilledProductPtr {
0053     bool operator()(propagate_const<std::shared_ptr<ProductResolverBase>> const& iObj) { return bool(iObj); }
0054   };
0055 
0056   class Principal : public EDProductGetter {
0057   public:
0058     typedef std::vector<propagate_const<std::shared_ptr<ProductResolverBase>>> ProductResolverCollection;
0059     typedef boost::filter_iterator<FilledProductPtr, ProductResolverCollection::const_iterator> const_iterator;
0060     typedef boost::filter_iterator<FilledProductPtr, ProductResolverCollection::iterator> iterator;
0061     typedef ProcessHistory::const_iterator ProcessNameConstIterator;
0062     typedef ProductResolverBase const* ConstProductResolverPtr;
0063     typedef std::vector<BasicHandle> BasicHandleVec;
0064     typedef ProductResolverCollection::size_type size_type;
0065 
0066     typedef std::shared_ptr<ProductResolverBase> SharedProductPtr;
0067     typedef std::string ProcessName;
0068 
0069     Principal(std::shared_ptr<ProductRegistry const> reg,
0070               std::shared_ptr<ProductResolverIndexHelper const> productLookup,
0071               ProcessConfiguration const& pc,
0072               BranchType bt,
0073               HistoryAppender* historyAppender,
0074               bool isForPrimaryProcess = true);
0075 
0076     ~Principal() override;
0077 
0078     bool adjustToNewProductRegistry(ProductRegistry const& reg);
0079 
0080     void adjustIndexesAfterProductRegistryAddition();
0081 
0082     void fillPrincipal(DelayedReader* reader);
0083     void fillPrincipal(ProcessHistoryID const& hist, ProcessHistory const* phr, DelayedReader* reader);
0084     void fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader);
0085 
0086     void clearPrincipal();
0087 
0088     void setupUnscheduled(UnscheduledConfigurator const&);
0089 
0090     void deleteProduct(BranchID const& id) const;
0091 
0092     EDProductGetter const* prodGetter() const { return this; }
0093 
0094     // Return a BasicHandle to the product which:
0095     //   1. matches the given label, instance, and process
0096     //   (if process if empty gets the match from the most recent process)
0097     //   2. If kindOfType is PRODUCT, then the type of the product matches typeID
0098     //   3. If kindOfType is ELEMENT
0099     //      a.  the product is a sequence,
0100     //      b.  the sequence has the nested type 'value_type'
0101     //      c.  typeID is the same as or a public base of
0102     //      this value_type,
0103 
0104     BasicHandle getByLabel(KindOfType kindOfType,
0105                            TypeID const& typeID,
0106                            InputTag const& inputTag,
0107                            EDConsumerBase const* consumes,
0108                            SharedResourcesAcquirer* sra,
0109                            ModuleCallingContext const* mcc) const;
0110 
0111     BasicHandle getByLabel(KindOfType kindOfType,
0112                            TypeID const& typeID,
0113                            std::string const& label,
0114                            std::string const& instance,
0115                            std::string const& process,
0116                            EDConsumerBase const* consumes,
0117                            SharedResourcesAcquirer* sra,
0118                            ModuleCallingContext const* mcc) const;
0119 
0120     BasicHandle getByToken(KindOfType kindOfType,
0121                            TypeID const& typeID,
0122                            ProductResolverIndex index,
0123                            bool skipCurrentProcess,
0124                            bool& ambiguous,
0125                            SharedResourcesAcquirer* sra,
0126                            ModuleCallingContext const* mcc) const;
0127 
0128     void prefetchAsync(WaitingTaskHolder waitTask,
0129                        ProductResolverIndex index,
0130                        bool skipCurrentProcess,
0131                        ServiceToken const& token,
0132                        ModuleCallingContext const* mcc) const;
0133 
0134     void getManyByType(TypeID const& typeID,
0135                        BasicHandleVec& results,
0136                        EDConsumerBase const* consumes,
0137                        SharedResourcesAcquirer* sra,
0138                        ModuleCallingContext const* mcc) const;
0139 
0140     ProcessHistory const& processHistory() const { return *processHistoryPtr_; }
0141 
0142     ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
0143 
0144     ProcessConfiguration const& processConfiguration() const { return *processConfiguration_; }
0145 
0146     ProductRegistry const& productRegistry() const { return *preg_; }
0147 
0148     ProductResolverIndexHelper const& productLookup() const { return *productLookup_; }
0149 
0150     // merge Principals containing different products.
0151     void recombine(Principal& other, std::vector<BranchID> const& bids);
0152 
0153     ProductResolverBase* getModifiableProductResolver(BranchID const& oid) {
0154       return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getProductResolver(oid));
0155     }
0156 
0157     size_t size() const;
0158 
0159     // These iterators skip over any null shared pointers
0160     const_iterator begin() const {
0161       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.begin(), productResolvers_.end());
0162     }
0163     const_iterator end() const {
0164       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.end(), productResolvers_.end());
0165     }
0166 
0167     iterator begin() {
0168       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.begin(), productResolvers_.end());
0169     }
0170     iterator end() {
0171       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.end(), productResolvers_.end());
0172     }
0173 
0174     Provenance const& getProvenance(BranchID const& bid) const;
0175     StableProvenance const& getStableProvenance(BranchID const& bid) const;
0176 
0177     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
0178 
0179     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0180 
0181     BranchType const& branchType() const { return branchType_; }
0182 
0183     //This will never return 0 so you can use 0 to mean unset
0184     typedef unsigned long CacheIdentifier_t;
0185     CacheIdentifier_t cacheIdentifier() const { return cacheIdentifier_; }
0186 
0187     DelayedReader* reader() const { return reader_; }
0188 
0189     ConstProductResolverPtr getProductResolver(BranchID const& oid) const;
0190 
0191     ProductData const* findProductByTag(TypeID const& typeID,
0192                                         InputTag const& tag,
0193                                         ModuleCallingContext const* mcc) const;
0194 
0195     void readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata = nullptr);
0196 
0197     std::vector<unsigned int> const& lookupProcessOrder() const { return lookupProcessOrder_; }
0198 
0199     ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const& oid) const;
0200 
0201     virtual unsigned int processBlockIndex(std::string const& processName) const;
0202 
0203   protected:
0204     // ----- Add a new ProductResolver
0205     // *this takes ownership of the ProductResolver, which in turn owns its
0206     // data.
0207     void addProduct_(std::unique_ptr<ProductResolverBase> phb);
0208     void addProductOrThrow(std::unique_ptr<ProductResolverBase> phb);
0209     ProductResolverBase* getExistingProduct(BranchID const& branchID);
0210     ProductResolverBase const* getExistingProduct(BranchID const& branchID) const;
0211     ProductResolverBase const* getExistingProduct(ProductResolverBase const& phb) const;
0212 
0213     void put_(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const;
0214 
0215     //F must take an argument of type ProductResolverBase*
0216     template <typename F>
0217     void applyToResolvers(F iFunc) {
0218       for (auto& resolver : productResolvers_) {
0219         iFunc(resolver.get());
0220       }
0221     }
0222 
0223   private:
0224     //called by adjustIndexesAfterProductRegistryAddition only if an index actually changed
0225     virtual void changedIndexes_() {}
0226 
0227     void addScheduledProduct(std::shared_ptr<BranchDescription const> bd);
0228     void addSourceProduct(std::shared_ptr<BranchDescription const> bd);
0229     void addDelayedReaderInputProduct(std::shared_ptr<BranchDescription const> bd);
0230     void addPutOnReadInputProduct(std::shared_ptr<BranchDescription const> bd);
0231     void addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd);
0232     void addAliasedProduct(std::shared_ptr<BranchDescription const> bd);
0233     void addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd);
0234     void addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd);
0235     void addParentProcessProduct(std::shared_ptr<BranchDescription const> bd);
0236 
0237     WrapperBase const* getIt(ProductID const&) const override;
0238     std::optional<std::tuple<WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0239                                                                                   unsigned int) const override;
0240     void getThinnedProducts(ProductID const&,
0241                             std::vector<WrapperBase const*>&,
0242                             std::vector<unsigned int>&) const override;
0243     OptionalThinnedKey getThinnedKeyFrom(ProductID const& parent,
0244                                          unsigned int key,
0245                                          ProductID const& thinned) const override;
0246 
0247     void findProducts(std::vector<ProductResolverBase const*> const& holders,
0248                       TypeID const& typeID,
0249                       BasicHandleVec& results,
0250                       SharedResourcesAcquirer* sra,
0251                       ModuleCallingContext const* mcc) const;
0252 
0253     ProductData const* findProductByLabel(KindOfType kindOfType,
0254                                           TypeID const& typeID,
0255                                           InputTag const& inputTag,
0256                                           EDConsumerBase const* consumer,
0257                                           SharedResourcesAcquirer* sra,
0258                                           ModuleCallingContext const* mcc) const;
0259 
0260     ProductData const* findProductByLabel(KindOfType kindOfType,
0261                                           TypeID const& typeID,
0262                                           std::string const& label,
0263                                           std::string const& instance,
0264                                           std::string const& process,
0265                                           EDConsumerBase const* consumer,
0266                                           SharedResourcesAcquirer* sra,
0267                                           ModuleCallingContext const* mcc) const;
0268 
0269     void put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* productResolver) const;
0270 
0271     std::shared_ptr<ProcessHistory const> processHistoryPtr_;
0272 
0273     ProcessHistoryID processHistoryID_;
0274     ProcessHistoryID processHistoryIDBeforeConfig_;
0275 
0276     ProcessConfiguration const* processConfiguration_;
0277 
0278     // A vector of product holders.
0279     ProductResolverCollection productResolvers_;  // products and provenances are persistent
0280 
0281     // Pointer to the product registry. There is one entry in the registry
0282     // for each EDProduct in the event.
0283     std::shared_ptr<ProductRegistry const> preg_;
0284     std::shared_ptr<ProductResolverIndexHelper const> productLookup_;
0285 
0286     std::vector<unsigned int> lookupProcessOrder_;
0287     ProcessHistoryID orderProcessHistoryID_;
0288 
0289     // Pointer to the 'source' that will be used to obtain EDProducts
0290     // from the persistent store. This 'source' is owned by the input source.
0291     DelayedReader* reader_;
0292 
0293     BranchType branchType_;
0294 
0295     // In use cases where the new process should not be appended to
0296     // input ProcessHistory, the following pointer should be null.
0297     // The Principal does not own this object.
0298     edm::propagate_const<HistoryAppender*> historyAppender_;
0299 
0300     CacheIdentifier_t cacheIdentifier_;
0301   };
0302 
0303   template <typename PROD>
0304   inline std::shared_ptr<Wrapper<PROD> const> getProductByTag(Principal const& ep,
0305                                                               InputTag const& tag,
0306                                                               ModuleCallingContext const* mcc) {
0307     TypeID tid = TypeID(typeid(PROD));
0308     ProductData const* result = ep.findProductByTag(tid, tag, mcc);
0309     if (result == nullptr) {
0310       return std::shared_ptr<Wrapper<PROD> const>();
0311     }
0312 
0313     if (!(result->wrapper()->dynamicTypeInfo() == typeid(PROD))) {
0314       handleimpl::throwConvertTypeError(typeid(PROD), result->wrapper()->dynamicTypeInfo());
0315     }
0316     return std::static_pointer_cast<Wrapper<PROD> const>(result->sharedConstWrapper());
0317   }
0318 }  // namespace edm
0319 #endif