CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/FWCore/Framework/interface/Principal.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_Principal_h
00002 #define FWCore_Framework_Principal_h
00003 
00004 /*----------------------------------------------------------------------
00005 
00006 Principal: This is the implementation of the classes responsible
00007 for management of EDProducts. It is not seen by reconstruction code.
00008 
00009 The major internal component of the Principal is the ProductHolder, which
00010 contains an EDProduct and its associated Provenance, along with
00011 ancillary transient information regarding the two. ProductHolders are handled
00012 through shared pointers.
00013 
00014 The Principal returns BasicHandle, rather than a shared
00015 pointer to a ProductHolder, when queried.
00016 
00017 (Historical note: prior to April 2007 this class was named DataBlockImpl)
00018 
00019 ----------------------------------------------------------------------*/
00020 #include "DataFormats/Common/interface/BasicHandle.h"
00021 #include "DataFormats/Common/interface/ConvertHandle.h"
00022 #include "DataFormats/Common/interface/EDProductGetter.h"
00023 #include "DataFormats/Common/interface/OutputHandle.h"
00024 #include "DataFormats/Common/interface/Wrapper.h"
00025 #include "DataFormats/Common/interface/WrapperHolder.h"
00026 #include "DataFormats/Common/interface/WrapperOwningHolder.h"
00027 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00028 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
00029 #include "FWCore/Framework/interface/Frameworkfwd.h"
00030 #include "FWCore/Framework/interface/ProductHolder.h"
00031 #include "FWCore/Utilities/interface/InputTag.h"
00032 #include "FWCore/Utilities/interface/ProductKindOfType.h"
00033 
00034 #include "boost/iterator/filter_iterator.hpp"
00035 #include "boost/shared_ptr.hpp"
00036 
00037 #include <map>
00038 #include <memory>
00039 #include <set>
00040 #include <string>
00041 #include <vector>
00042 
00043 namespace edm {
00044 
00045   class HistoryAppender;
00046   class ProductHolderIndexHelper;
00047 
00048   struct FilledProductPtr {
00049     bool operator()(boost::shared_ptr<ProductHolderBase> const& iObj) { return bool(iObj);}
00050   };
00051 
00052   class Principal : public EDProductGetter {
00053   public:
00054     typedef std::vector<boost::shared_ptr<ProductHolderBase> > ProductHolderCollection;
00055     typedef boost::filter_iterator<FilledProductPtr, ProductHolderCollection::const_iterator> const_iterator;
00056     typedef ProcessHistory::const_iterator ProcessNameConstIterator;
00057     typedef ProductHolderBase const* ConstProductPtr;
00058     typedef std::vector<BasicHandle> BasicHandleVec;
00059     typedef ProductHolderCollection::size_type size_type;
00060 
00061     typedef boost::shared_ptr<ProductHolderBase> SharedProductPtr;
00062     typedef std::string ProcessName;
00063 
00064     Principal(boost::shared_ptr<ProductRegistry const> reg,
00065               boost::shared_ptr<ProductHolderIndexHelper const> productLookup,
00066               ProcessConfiguration const& pc,
00067               BranchType bt,
00068               HistoryAppender* historyAppender);
00069 
00070     virtual ~Principal();
00071 
00072     bool adjustToNewProductRegistry(ProductRegistry const& reg);
00073 
00074     void adjustIndexesAfterProductRegistryAddition();
00075 
00076     void addScheduledProduct(boost::shared_ptr<ConstBranchDescription> bd);
00077 
00078     void addSourceProduct(boost::shared_ptr<ConstBranchDescription> bd);
00079 
00080     void addInputProduct(boost::shared_ptr<ConstBranchDescription> bd);
00081 
00082     void addUnscheduledProduct(boost::shared_ptr<ConstBranchDescription> bd);
00083 
00084     void addAliasedProduct(boost::shared_ptr<ConstBranchDescription> bd);
00085 
00086     void fillPrincipal(ProcessHistoryID const& hist, DelayedReader* reader);
00087 
00088     void clearPrincipal();
00089 
00090     void deleteProduct(BranchID const& id);
00091     
00092     EDProductGetter const* prodGetter() const {return this;}
00093 
00094     OutputHandle getForOutput(BranchID const& bid, bool getProd) const;
00095 
00096     // Return a BasicHandle to the product which:
00097     //   1. matches the given label, instance, and process
00098     //   (if process if empty gets the match from the most recent process)
00099     //   2. If kindOfType is PRODUCT, then the type of the product matches typeID
00100     //   3. If kindOfType is ELEMENT
00101     //      a.  the product is a sequence,
00102     //      b.  the sequence has the nested type 'value_type'
00103     //      c.  typeID is the same as or a public base of
00104     //      this value_type,
00105 
00106     BasicHandle  getByLabel(KindOfType kindOfType,
00107                             TypeID const& typeID,
00108                             InputTag const& inputTag) const;
00109 
00110     BasicHandle  getByLabel(KindOfType kindOfType,
00111                             TypeID const& typeID,
00112                             std::string const& label,
00113                             std::string const& instance,
00114                             std::string const& process) const;
00115     
00116     BasicHandle getByToken(KindOfType kindOfType,
00117                            TypeID const& typeID,
00118                            ProductHolderIndex index,
00119                            bool skipCurrentProcess,
00120                            bool& ambiguous) const;
00121 
00122     void getManyByType(TypeID const& typeID,
00123                        BasicHandleVec& results) const;
00124 
00125     ProcessHistory const& processHistory() const {
00126       return *processHistoryPtr_;
00127     }
00128 
00129     ProcessHistoryID const& processHistoryID() const {
00130       return processHistoryID_;
00131     }
00132 
00133     ProcessConfiguration const& processConfiguration() const {return *processConfiguration_;}
00134 
00135     ProductRegistry const& productRegistry() const {return *preg_;}
00136 
00137     ProductHolderIndexHelper const& productLookup() const {return *productLookup_;}
00138 
00139     // merge Principals containing different products.
00140     void recombine(Principal& other, std::vector<BranchID> const& bids);
00141 
00142     size_t size() const;
00143 
00144     // These iterators skip over any null shared pointers
00145     const_iterator begin() const {return boost::make_filter_iterator<FilledProductPtr>(productHolders_.begin(), productHolders_.end());}
00146     const_iterator end() const {return  boost::make_filter_iterator<FilledProductPtr>(productHolders_.end(), productHolders_.end());}
00147 
00148     Provenance getProvenance(BranchID const& bid) const;
00149 
00150     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
00151 
00152     BranchType const& branchType() const {return branchType_;}
00153 
00154     DelayedReader* reader() const {return reader_;}
00155 
00156     ConstProductPtr getProductHolder(BranchID const& oid,
00157                                      bool resolveProd,
00158                                      bool fillOnDemand) const;
00159 
00160     ProductData const* findProductByTag(TypeID const& typeID, InputTag const& tag) const;
00161 
00162     // Make my DelayedReader get the EDProduct for a ProductHolder or
00163     // trigger unscheduled execution if required.  The ProductHolder is
00164     // a cache, and so can be modified through the const reference.
00165     // We do not change the *number* of products through this call, and so
00166     // *this is const.
00167     void resolveProduct(ProductHolderBase const& phb, bool fillOnDemand) const {resolveProduct_(phb, fillOnDemand);}
00168 
00169     virtual bool unscheduledFill(std::string const& moduleLabel) const = 0;
00170 
00171     std::vector<unsigned int> const& lookupProcessOrder() const { return lookupProcessOrder_; }
00172 
00173     ConstProductPtr getProductByIndex(ProductHolderIndex const& oid,
00174                                       bool resolveProd,
00175                                       bool fillOnDemand) const;
00176 
00177     bool isComplete() const {return isComplete_();}
00178 
00179   protected:
00180 
00181     // ----- Add a new ProductHolder
00182     // *this takes ownership of the ProductHolder, which in turn owns its
00183     // data.
00184     void addProduct_(std::auto_ptr<ProductHolderBase> phb);
00185     void addProductOrThrow(std::auto_ptr<ProductHolderBase> phb);
00186     ProductHolderBase* getExistingProduct(BranchID const& branchID);
00187     ProductHolderBase* getExistingProduct(ProductHolderBase const& phb);
00188 
00189     // throws if the pointed to product is already in the Principal.
00190     void checkUniquenessAndType(WrapperOwningHolder const& prod, ProductHolderBase const* productHolder) const;
00191 
00192     void putOrMerge(WrapperOwningHolder const& prod, ProductHolderBase const* productHolder) const;
00193 
00194     void putOrMerge(WrapperOwningHolder const& prod, ProductProvenance& prov, ProductHolderBase* productHolder);
00195 
00196   private:
00197     virtual WrapperHolder getIt(ProductID const&) const;
00198 
00199     void findProducts(std::vector<ProductHolderBase const*> const& holders,
00200                       TypeID const& typeID,
00201                       BasicHandleVec& results) const;
00202 
00203     ProductData const* findProductByLabel(KindOfType kindOfType,
00204                                           TypeID const& typeID,
00205                                           InputTag const& inputTag) const;
00206 
00207     ProductData const* findProductByLabel(KindOfType kindOfType,
00208                                           TypeID const& typeID,
00209                                           std::string const& label,
00210                                           std::string const& instance,
00211                                           std::string const& process) const;
00212 
00213     // defaults to no-op unless overridden in derived class.
00214     virtual void resolveProduct_(ProductHolderBase const&, bool /*fillOnDemand*/) const {}
00215 
00216     virtual bool isComplete_() const {return true;}
00217 
00218     ProcessHistory const* processHistoryPtr_;
00219 
00220     ProcessHistoryID processHistoryID_;
00221 
00222     ProcessConfiguration const* processConfiguration_;
00223 
00224     // A vector of product holders.
00225     ProductHolderCollection productHolders_; // products and provenances are persistent
00226 
00227     // Pointer to the product registry. There is one entry in the registry
00228     // for each EDProduct in the event.
00229     boost::shared_ptr<ProductRegistry const> preg_;
00230     boost::shared_ptr<ProductHolderIndexHelper const> productLookup_;
00231 
00232     std::vector<unsigned int> lookupProcessOrder_;
00233     ProcessHistoryID orderProcessHistoryID_;
00234 
00235     // Pointer to the 'source' that will be used to obtain EDProducts
00236     // from the persistent store. This 'source' is owned by the input source.
00237     DelayedReader* reader_;
00238 
00239     // Used to check for duplicates.  The same product instance must not be in more than one product holder
00240     mutable std::set<void const*> productPtrs_;
00241 
00242     BranchType branchType_;
00243 
00244     // In use cases where the new process should not be appended to
00245     // input ProcessHistory, the following pointer should be null.
00246     // The Principal does not own this object.
00247     HistoryAppender* historyAppender_;
00248 
00249     static const ProcessHistory emptyProcessHistory_;
00250   };
00251 
00252   template <typename PROD>
00253   inline
00254   boost::shared_ptr<Wrapper<PROD> const>
00255   getProductByTag(Principal const& ep, InputTag const& tag) {
00256     TypeID tid = TypeID(typeid(PROD));
00257     ProductData const* result = ep.findProductByTag(tid, tag);
00258 
00259     if(result->getInterface() &&
00260        (!(result->getInterface()->dynamicTypeInfo() == typeid(PROD)))) {
00261       handleimpl::throwConvertTypeError(typeid(PROD), result->getInterface()->dynamicTypeInfo());
00262     }
00263     return boost::static_pointer_cast<Wrapper<PROD> const>(result->wrapper_);
00264   }
00265 }
00266 #endif