Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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::vector<std::shared_ptr<ProductResolverBase>>&& resolvers,
0071               ProcessConfiguration const& pc,
0072               BranchType bt,
0073               HistoryAppender* historyAppender);
0074 
0075     ~Principal() override;
0076 
0077     //This should only be called when this Principal is not being actively used
0078     void possiblyUpdateAfterAddition(std::shared_ptr<ProductRegistry const>);
0079 
0080     void fillPrincipal(DelayedReader* reader);
0081     void fillPrincipal(ProcessHistoryID const& hist, ProcessHistory const* phr, DelayedReader* reader);
0082     void fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader);
0083 
0084     void clearPrincipal();
0085 
0086     void setupUnscheduled(UnscheduledConfigurator const&);
0087 
0088     void deleteProduct(BranchID const& id) const;
0089 
0090     EDProductGetter const* prodGetter() const { return this; }
0091 
0092     // Return a BasicHandle to the product which:
0093     //   1. matches the given label, instance, and process
0094     //   (if process if empty gets the match from the most recent process)
0095     //   2. If kindOfType is PRODUCT, then the type of the product matches typeID
0096     //   3. If kindOfType is ELEMENT
0097     //      a.  the product is a sequence,
0098     //      b.  the sequence has the nested type 'value_type'
0099     //      c.  typeID is the same as or a public base of
0100     //      this value_type,
0101 
0102     BasicHandle getByLabel(KindOfType kindOfType,
0103                            TypeID const& typeID,
0104                            InputTag const& inputTag,
0105                            EDConsumerBase const* consumes,
0106                            SharedResourcesAcquirer* sra,
0107                            ModuleCallingContext const* mcc) const;
0108 
0109     BasicHandle getByLabel(KindOfType kindOfType,
0110                            TypeID const& typeID,
0111                            std::string const& label,
0112                            std::string const& instance,
0113                            std::string const& process,
0114                            EDConsumerBase const* consumes,
0115                            SharedResourcesAcquirer* sra,
0116                            ModuleCallingContext const* mcc) const;
0117 
0118     BasicHandle getByToken(KindOfType kindOfType,
0119                            TypeID const& typeID,
0120                            ProductResolverIndex index,
0121                            bool skipCurrentProcess,
0122                            bool& ambiguous,
0123                            SharedResourcesAcquirer* sra,
0124                            ModuleCallingContext const* mcc) const;
0125 
0126     void prefetchAsync(WaitingTaskHolder waitTask,
0127                        ProductResolverIndex index,
0128                        bool skipCurrentProcess,
0129                        ServiceToken const& token,
0130                        ModuleCallingContext const* mcc) const;
0131 
0132     ProcessHistory const& processHistory() const { return *processHistoryPtr_; }
0133 
0134     ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
0135 
0136     ProcessConfiguration const& processConfiguration() const { return *processConfiguration_; }
0137 
0138     ProductRegistry const& productRegistry() const { return *preg_; }
0139     std::vector<ProductDescription const*> productDescriptions() const;
0140 
0141     ProductResolverIndexHelper const& productLookup() const { return *productLookup_; }
0142 
0143     // merge Principals containing different products.
0144     void recombine(Principal& other, std::vector<BranchID> const& bids);
0145 
0146     ProductResolverBase* getModifiableProductResolver(BranchID const& oid) {
0147       return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getProductResolver(oid));
0148     }
0149 
0150     size_t size() const;
0151 
0152     // These iterators skip over any null shared pointers
0153     const_iterator begin() const {
0154       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.begin(), productResolvers_.end());
0155     }
0156     const_iterator end() const {
0157       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.end(), productResolvers_.end());
0158     }
0159 
0160     iterator begin() {
0161       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.begin(), productResolvers_.end());
0162     }
0163     iterator end() {
0164       return boost::make_filter_iterator<FilledProductPtr>(productResolvers_.end(), productResolvers_.end());
0165     }
0166 
0167     Provenance const& getProvenance(BranchID const& bid) const;
0168     StableProvenance const& getStableProvenance(BranchID const& bid) const;
0169 
0170     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
0171 
0172     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0173 
0174     BranchType const& branchType() const { return branchType_; }
0175 
0176     //This will never return 0 so you can use 0 to mean unset
0177     typedef unsigned long CacheIdentifier_t;
0178     CacheIdentifier_t cacheIdentifier() const { return cacheIdentifier_; }
0179 
0180     DelayedReader* reader() const { return reader_; }
0181 
0182     ConstProductResolverPtr getProductResolver(BranchID const& oid) const;
0183 
0184     ProductData const* findProductByTag(TypeID const& typeID,
0185                                         InputTag const& tag,
0186                                         ModuleCallingContext const* mcc) const;
0187 
0188     void readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata = nullptr);
0189 
0190     std::vector<unsigned int> const& lookupProcessOrder() const noexcept { return lookupProcessOrder_; }
0191 
0192     ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const& oid) const noexcept;
0193 
0194     virtual unsigned int processBlockIndex(std::string const& processName) const;
0195 
0196   protected:
0197     // ----- Add a new ProductResolver
0198     // *this takes ownership of the ProductResolver, which in turn owns its
0199     // data.
0200     void addProduct_(std::unique_ptr<ProductResolverBase> phb);
0201     void addProductOrThrow(std::unique_ptr<ProductResolverBase> phb);
0202     ProductResolverBase* getExistingProduct(BranchID const& branchID);
0203     ProductResolverBase const* getExistingProduct(BranchID const& branchID) const;
0204     ProductResolverBase const* getExistingProduct(ProductResolverBase const& phb) const;
0205 
0206     void put_(ProductDescription const& bd, std::unique_ptr<WrapperBase> edp) const;
0207 
0208     //F must take an argument of type ProductResolverBase*
0209     template <typename F>
0210     void applyToResolvers(F iFunc) {
0211       for (auto& resolver : productResolvers_) {
0212         iFunc(resolver.get());
0213       }
0214     }
0215 
0216   private:
0217     void adjustIndexesAfterProductRegistryAddition();
0218 
0219     //called by adjustIndexesAfterProductRegistryAddition only if an index actually changed
0220     virtual void changedIndexes_() {}
0221 
0222     //called by adjustIndexesAfterProductRegistryAddition
0223     void addDroppedProduct(ProductDescription const& bd);
0224 
0225     WrapperBase const* getIt(ProductID const&) const override;
0226     std::optional<std::tuple<WrapperBase const*, unsigned int>> getThinnedProduct(ProductID const&,
0227                                                                                   unsigned int) const override;
0228     void getThinnedProducts(ProductID const&,
0229                             std::vector<WrapperBase const*>&,
0230                             std::vector<unsigned int>&) const override;
0231     OptionalThinnedKey getThinnedKeyFrom(ProductID const& parent,
0232                                          unsigned int key,
0233                                          ProductID const& thinned) const override;
0234 
0235     ProductData const* findProductByLabel(KindOfType kindOfType,
0236                                           TypeID const& typeID,
0237                                           InputTag const& inputTag,
0238                                           EDConsumerBase const* consumer,
0239                                           SharedResourcesAcquirer* sra,
0240                                           ModuleCallingContext const* mcc) const;
0241 
0242     ProductData const* findProductByLabel(KindOfType kindOfType,
0243                                           TypeID const& typeID,
0244                                           std::string const& label,
0245                                           std::string const& instance,
0246                                           std::string const& process,
0247                                           EDConsumerBase const* consumer,
0248                                           SharedResourcesAcquirer* sra,
0249                                           ModuleCallingContext const* mcc) const;
0250 
0251     void put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* productResolver) const;
0252 
0253     std::shared_ptr<ProcessHistory const> processHistoryPtr_;
0254 
0255     ProcessHistoryID processHistoryID_;
0256     ProcessHistoryID processHistoryIDBeforeConfig_;
0257 
0258     ProcessConfiguration const* processConfiguration_;
0259 
0260     // A vector of product holders.
0261     ProductResolverCollection productResolvers_;  // products and provenances are persistent
0262 
0263     // Pointer to the product registry. There is one entry in the registry
0264     // for each EDProduct in the event.
0265     std::shared_ptr<ProductRegistry const> preg_;
0266     std::shared_ptr<ProductResolverIndexHelper const> productLookup_;
0267 
0268     std::vector<unsigned int> lookupProcessOrder_;
0269     ProcessHistoryID orderProcessHistoryID_;
0270 
0271     // Pointer to the 'source' that will be used to obtain EDProducts
0272     // from the persistent store. This 'source' is owned by the input source.
0273     DelayedReader* reader_;
0274 
0275     BranchType branchType_;
0276 
0277     // In use cases where the new process should not be appended to
0278     // input ProcessHistory, the following pointer should be null.
0279     // The Principal does not own this object.
0280     edm::propagate_const<HistoryAppender*> historyAppender_;
0281 
0282     CacheIdentifier_t cacheIdentifier_;
0283   };
0284 
0285   template <typename PROD>
0286   inline std::shared_ptr<Wrapper<PROD> const> getProductByTag(Principal const& ep,
0287                                                               InputTag const& tag,
0288                                                               ModuleCallingContext const* mcc) {
0289     TypeID tid = TypeID(typeid(PROD));
0290     ProductData const* result = ep.findProductByTag(tid, tag, mcc);
0291     if (result == nullptr) {
0292       return std::shared_ptr<Wrapper<PROD> const>();
0293     }
0294 
0295     if (!(result->wrapper()->dynamicTypeInfo() == typeid(PROD))) {
0296       handleimpl::throwConvertTypeError(typeid(PROD), result->wrapper()->dynamicTypeInfo());
0297     }
0298     return std::static_pointer_cast<Wrapper<PROD> const>(result->sharedConstWrapper());
0299   }
0300 }  // namespace edm
0301 #endif