Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-15 04:21:39

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     ProcessHistory const& processHistory() const { return *processHistoryPtr_; }
0135 
0136     ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
0137 
0138     ProcessConfiguration const& processConfiguration() const { return *processConfiguration_; }
0139 
0140     ProductRegistry const& productRegistry() const { return *preg_; }
0141 
0142     ProductResolverIndexHelper const& productLookup() const { return *productLookup_; }
0143 
0144     // merge Principals containing different products.
0145     void recombine(Principal& other, std::vector<BranchID> const& bids);
0146 
0147     ProductResolverBase* getModifiableProductResolver(BranchID const& oid) {
0148       return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getProductResolver(oid));
0149     }
0150 
0151     size_t size() const;
0152 
0153     // These iterators skip over any null shared pointers
0154     const_iterator begin() const {
0155       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.begin(), productResolvers_.end());
0156     }
0157     const_iterator end() const {
0158       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.end(), productResolvers_.end());
0159     }
0160 
0161     iterator begin() {
0162       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.begin(), productResolvers_.end());
0163     }
0164     iterator end() {
0165       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.end(), productResolvers_.end());
0166     }
0167 
0168     Provenance const& getProvenance(BranchID const& bid) const;
0169     StableProvenance const& getStableProvenance(BranchID const& bid) const;
0170 
0171     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
0172 
0173     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0174 
0175     BranchType const& branchType() const { return branchType_; }
0176 
0177     //This will never return 0 so you can use 0 to mean unset
0178     typedef unsigned long CacheIdentifier_t;
0179     CacheIdentifier_t cacheIdentifier() const { return cacheIdentifier_; }
0180 
0181     DelayedReader* reader() const { return reader_; }
0182 
0183     ConstProductResolverPtr getProductResolver(BranchID const& oid) const;
0184 
0185     ProductData const* findProductByTag(TypeID const& typeID,
0186                                         InputTag const& tag,
0187                                         ModuleCallingContext const* mcc) const;
0188 
0189     void readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata = nullptr);
0190 
0191     std::vector<unsigned int> const& lookupProcessOrder() const noexcept { return lookupProcessOrder_; }
0192 
0193     ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const& oid) const noexcept;
0194 
0195     virtual unsigned int processBlockIndex(std::string const& processName) const;
0196 
0197   protected:
0198     // ----- Add a new ProductResolver
0199     // *this takes ownership of the ProductResolver, which in turn owns its
0200     // data.
0201     void addProduct_(std::unique_ptr<ProductResolverBase> phb);
0202     void addProductOrThrow(std::unique_ptr<ProductResolverBase> phb);
0203     ProductResolverBase* getExistingProduct(BranchID const& branchID);
0204     ProductResolverBase const* getExistingProduct(BranchID const& branchID) const;
0205     ProductResolverBase const* getExistingProduct(ProductResolverBase const& phb) const;
0206 
0207     void put_(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const;
0208 
0209     //F must take an argument of type ProductResolverBase*
0210     template <typename F>
0211     void applyToResolvers(F iFunc) {
0212       for (auto& resolver : productResolvers_) {
0213         iFunc(resolver.get());
0214       }
0215     }
0216 
0217   private:
0218     //called by adjustIndexesAfterProductRegistryAddition only if an index actually changed
0219     virtual void changedIndexes_() {}
0220 
0221     void addScheduledProduct(std::shared_ptr<BranchDescription const> bd);
0222     void addSourceProduct(std::shared_ptr<BranchDescription const> bd);
0223     void addDelayedReaderInputProduct(std::shared_ptr<BranchDescription const> bd);
0224     void addPutOnReadInputProduct(std::shared_ptr<BranchDescription const> bd);
0225     void addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd);
0226     void addTransformProduct(std::shared_ptr<BranchDescription const> bd);
0227     void addAliasedProduct(std::shared_ptr<BranchDescription const> bd);
0228     void addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd);
0229     void addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd);
0230     void addParentProcessProduct(std::shared_ptr<BranchDescription const> bd);
0231 
0232     WrapperBase const* getIt(ProductID const&) const override;
0233     std::optional<std::tuple<WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0234                                                                                   unsigned int) const override;
0235     void getThinnedProducts(ProductID const&,
0236                             std::vector<WrapperBase const*>&,
0237                             std::vector<unsigned int>&) const override;
0238     OptionalThinnedKey getThinnedKeyFrom(ProductID const& parent,
0239                                          unsigned int key,
0240                                          ProductID const& thinned) const override;
0241 
0242     ProductData const* findProductByLabel(KindOfType kindOfType,
0243                                           TypeID const& typeID,
0244                                           InputTag const& inputTag,
0245                                           EDConsumerBase const* consumer,
0246                                           SharedResourcesAcquirer* sra,
0247                                           ModuleCallingContext const* mcc) const;
0248 
0249     ProductData const* findProductByLabel(KindOfType kindOfType,
0250                                           TypeID const& typeID,
0251                                           std::string const& label,
0252                                           std::string const& instance,
0253                                           std::string const& process,
0254                                           EDConsumerBase const* consumer,
0255                                           SharedResourcesAcquirer* sra,
0256                                           ModuleCallingContext const* mcc) const;
0257 
0258     void put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* productResolver) const;
0259 
0260     std::shared_ptr<ProcessHistory const> processHistoryPtr_;
0261 
0262     ProcessHistoryID processHistoryID_;
0263     ProcessHistoryID processHistoryIDBeforeConfig_;
0264 
0265     ProcessConfiguration const* processConfiguration_;
0266 
0267     // A vector of product holders.
0268     ProductResolverCollection productResolvers_;  // products and provenances are persistent
0269 
0270     // Pointer to the product registry. There is one entry in the registry
0271     // for each EDProduct in the event.
0272     std::shared_ptr<ProductRegistry const> preg_;
0273     std::shared_ptr<ProductResolverIndexHelper const> productLookup_;
0274 
0275     std::vector<unsigned int> lookupProcessOrder_;
0276     ProcessHistoryID orderProcessHistoryID_;
0277 
0278     // Pointer to the 'source' that will be used to obtain EDProducts
0279     // from the persistent store. This 'source' is owned by the input source.
0280     DelayedReader* reader_;
0281 
0282     BranchType branchType_;
0283 
0284     // In use cases where the new process should not be appended to
0285     // input ProcessHistory, the following pointer should be null.
0286     // The Principal does not own this object.
0287     edm::propagate_const<HistoryAppender*> historyAppender_;
0288 
0289     CacheIdentifier_t cacheIdentifier_;
0290   };
0291 
0292   template <typename PROD>
0293   inline std::shared_ptr<Wrapper<PROD> const> getProductByTag(Principal const& ep,
0294                                                               InputTag const& tag,
0295                                                               ModuleCallingContext const* mcc) {
0296     TypeID tid = TypeID(typeid(PROD));
0297     ProductData const* result = ep.findProductByTag(tid, tag, mcc);
0298     if (result == nullptr) {
0299       return std::shared_ptr<Wrapper<PROD> const>();
0300     }
0301 
0302     if (!(result->wrapper()->dynamicTypeInfo() == typeid(PROD))) {
0303       handleimpl::throwConvertTypeError(typeid(PROD), result->wrapper()->dynamicTypeInfo());
0304     }
0305     return std::static_pointer_cast<Wrapper<PROD> const>(result->sharedConstWrapper());
0306   }
0307 }  // namespace edm
0308 #endif