Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-11 22:29:29

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 addTransformProduct(std::shared_ptr<BranchDescription const> bd);
0233     void addAliasedProduct(std::shared_ptr<BranchDescription const> bd);
0234     void addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd);
0235     void addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd);
0236     void addParentProcessProduct(std::shared_ptr<BranchDescription const> bd);
0237 
0238     WrapperBase const* getIt(ProductID const&) const override;
0239     std::optional<std::tuple<WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0240                                                                                   unsigned int) const override;
0241     void getThinnedProducts(ProductID const&,
0242                             std::vector<WrapperBase const*>&,
0243                             std::vector<unsigned int>&) const override;
0244     OptionalThinnedKey getThinnedKeyFrom(ProductID const& parent,
0245                                          unsigned int key,
0246                                          ProductID const& thinned) const override;
0247 
0248     void findProducts(std::vector<ProductResolverBase const*> const& holders,
0249                       TypeID const& typeID,
0250                       BasicHandleVec& results,
0251                       SharedResourcesAcquirer* sra,
0252                       ModuleCallingContext const* mcc) const;
0253 
0254     ProductData const* findProductByLabel(KindOfType kindOfType,
0255                                           TypeID const& typeID,
0256                                           InputTag const& inputTag,
0257                                           EDConsumerBase const* consumer,
0258                                           SharedResourcesAcquirer* sra,
0259                                           ModuleCallingContext const* mcc) const;
0260 
0261     ProductData const* findProductByLabel(KindOfType kindOfType,
0262                                           TypeID const& typeID,
0263                                           std::string const& label,
0264                                           std::string const& instance,
0265                                           std::string const& process,
0266                                           EDConsumerBase const* consumer,
0267                                           SharedResourcesAcquirer* sra,
0268                                           ModuleCallingContext const* mcc) const;
0269 
0270     void put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* productResolver) const;
0271 
0272     std::shared_ptr<ProcessHistory const> processHistoryPtr_;
0273 
0274     ProcessHistoryID processHistoryID_;
0275     ProcessHistoryID processHistoryIDBeforeConfig_;
0276 
0277     ProcessConfiguration const* processConfiguration_;
0278 
0279     // A vector of product holders.
0280     ProductResolverCollection productResolvers_;  // products and provenances are persistent
0281 
0282     // Pointer to the product registry. There is one entry in the registry
0283     // for each EDProduct in the event.
0284     std::shared_ptr<ProductRegistry const> preg_;
0285     std::shared_ptr<ProductResolverIndexHelper const> productLookup_;
0286 
0287     std::vector<unsigned int> lookupProcessOrder_;
0288     ProcessHistoryID orderProcessHistoryID_;
0289 
0290     // Pointer to the 'source' that will be used to obtain EDProducts
0291     // from the persistent store. This 'source' is owned by the input source.
0292     DelayedReader* reader_;
0293 
0294     BranchType branchType_;
0295 
0296     // In use cases where the new process should not be appended to
0297     // input ProcessHistory, the following pointer should be null.
0298     // The Principal does not own this object.
0299     edm::propagate_const<HistoryAppender*> historyAppender_;
0300 
0301     CacheIdentifier_t cacheIdentifier_;
0302   };
0303 
0304   template <typename PROD>
0305   inline std::shared_ptr<Wrapper<PROD> const> getProductByTag(Principal const& ep,
0306                                                               InputTag const& tag,
0307                                                               ModuleCallingContext const* mcc) {
0308     TypeID tid = TypeID(typeid(PROD));
0309     ProductData const* result = ep.findProductByTag(tid, tag, mcc);
0310     if (result == nullptr) {
0311       return std::shared_ptr<Wrapper<PROD> const>();
0312     }
0313 
0314     if (!(result->wrapper()->dynamicTypeInfo() == typeid(PROD))) {
0315       handleimpl::throwConvertTypeError(typeid(PROD), result->wrapper()->dynamicTypeInfo());
0316     }
0317     return std::static_pointer_cast<Wrapper<PROD> const>(result->sharedConstWrapper());
0318   }
0319 }  // namespace edm
0320 #endif