CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/Framework/interface/ProductHolder.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_ProductHolder_h
00002 #define FWCore_Framework_ProductHolder_h
00003 
00004 /*----------------------------------------------------------------------
00005 
00006 ProductHolder: A collection of information related to a single EDProduct or
00007 a set of related EDProducts. This is the storage unit of such information.
00008 
00009 ----------------------------------------------------------------------*/
00010 
00011 #include "DataFormats/Common/interface/ProductData.h"
00012 #include "DataFormats/Common/interface/WrapperHolder.h"
00013 #include "DataFormats/Common/interface/WrapperOwningHolder.h"
00014 #include "DataFormats/Provenance/interface/BranchID.h"
00015 #include "DataFormats/Provenance/interface/ConstBranchDescription.h"
00016 #include "DataFormats/Provenance/interface/Provenance.h"
00017 #include "FWCore/Utilities/interface/ProductHolderIndex.h"
00018 #include "FWCore/Utilities/interface/TypeID.h"
00019 
00020 #include "boost/shared_ptr.hpp"
00021 
00022 #include <string>
00023 
00024 namespace edm {
00025   class BranchMapper;
00026   class DelayedReader;
00027   class Principal;
00028   class WrapperInterfaceBase;
00029 
00030   class ProductHolderBase {
00031   public:
00032 
00033     enum ResolveStatus { ProductFound, ProductNotFound, Ambiguous };
00034 
00035     ProductHolderBase();
00036     virtual ~ProductHolderBase();
00037 
00038     ProductHolderBase(ProductHolderBase const&) = delete; // Disallow copying and moving
00039     ProductHolderBase& operator=(ProductHolderBase const&) = delete; // Disallow copying and moving
00040 
00041     ProductData const& productData() const {
00042       return getProductData();
00043     }
00044 
00045     ProductData& productData() {
00046       return getProductData();
00047     }
00048 
00049     ProductData const* resolveProduct(ResolveStatus& resolveStatus, bool skipCurrentProcess) const {
00050       return resolveProduct_(resolveStatus, skipCurrentProcess);
00051     }
00052 
00053     void resetStatus () {
00054       resetStatus_();
00055     }
00056 
00057     void setProductDeleted () {
00058       setProductDeleted_();
00059     }
00060 
00061     void resetProductData() { resetProductData_(); }
00062 
00063     void deleteProduct() {
00064       getProductData().resetProductData();
00065       setProductDeleted_();
00066     }
00067     
00068     // product is not available (dropped or never created)
00069     bool productUnavailable() const {return productUnavailable_();}
00070 
00071     // provenance is currently available
00072     bool provenanceAvailable() const;
00073 
00074     // Scheduled for on demand production
00075     bool onDemand() const {return onDemand_();}
00076     
00077     // Product was deleted early in order to save memory
00078     bool productWasDeleted() const {return productWasDeleted_();}
00079 
00080     // Retrieves a shared pointer to the wrapped product.
00081     boost::shared_ptr<void const> product() const { return getProductData().wrapper_; }
00082 
00083     // Retrieves the wrapped product and type. (non-owning);
00084     WrapperHolder wrapper() const { return WrapperHolder(getProductData().wrapper_.get(), getProductData().getInterface()); }
00085 
00086     // Retrieves pointer to the per event(lumi)(run) provenance.
00087     ProductProvenance* productProvenancePtr() const { return productProvenancePtr_(); }
00088 
00089     // Sets the the per event(lumi)(run) provenance.
00090     void setProductProvenance(ProductProvenance const& prov) const;
00091 
00092     // Retrieves a reference to the event independent provenance.
00093     ConstBranchDescription const& branchDescription() const {return branchDescription_();}
00094 
00095     // Retrieves a reference to the event independent provenance.
00096     bool singleProduct() const {return singleProduct_();}
00097 
00098     void setPrincipal(Principal* principal) { setPrincipal_(principal); }
00099 
00100     // Sets the pointer to the event independent provenance.
00101     void resetBranchDescription(boost::shared_ptr<ConstBranchDescription> bd) {resetBranchDescription_(bd);}
00102 
00103     // Retrieves a reference to the module label.
00104     std::string const& moduleLabel() const {return branchDescription().moduleLabel();}
00105 
00106     // Same as moduleLabel except in the case of an AliasProductHolder, in which
00107     // case it resolves the module which actually produces the product and returns
00108     // its module label
00109     std::string const& resolvedModuleLabel() const {return resolvedModuleLabel_();}
00110 
00111     // Retrieves a reference to the product instance name
00112     std::string const& productInstanceName() const {return branchDescription().productInstanceName();}
00113 
00114     // Retrieves a reference to the process name
00115     std::string const& processName() const {return branchDescription().processName();}
00116 
00117     // Retrieves pointer to a class containing both the event independent and the per even provenance.
00118     Provenance* provenance() const;
00119 
00120     // Initializes the event independent portion of the provenance, plus the process history ID, the product ID, and the mapper.
00121     void setProvenance(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid) { setProvenance_(mapper, phid, pid); }
00122 
00123     // Initializes the process history ID.
00124     void setProcessHistoryID(ProcessHistoryID const& phid) { setProcessHistoryID_(phid); }
00125 
00126     // Write the product to the stream.
00127     void write(std::ostream& os) const;
00128 
00129     // Return the type of the product stored in this ProductHolder.
00130     // We are relying on the fact that Type instances are small, and
00131     // so we are free to copy them at will.
00132     TypeID productType() const;
00133 
00134     // Retrieves the product ID of the product.
00135     ProductID const& productID() const {return getProductData().prov_.productID();}
00136 
00137     // Puts the product and its per event(lumi)(run) provenance into the ProductHolder.
00138     void putProduct(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance) {
00139       putProduct_(edp, productProvenance);
00140     }
00141 
00142     // Puts the product into the ProductHolder.
00143     void putProduct(WrapperOwningHolder const& edp) const {
00144       putProduct_(edp);
00145     }
00146 
00147     // This returns true if it will be put, false if it will be merged
00148     bool putOrMergeProduct() const {
00149       return putOrMergeProduct_();
00150     }
00151 
00152     // merges the product with the pre-existing product
00153     void mergeProduct(WrapperOwningHolder const& edp, ProductProvenance& productProvenance) {
00154       mergeProduct_(edp, productProvenance);
00155     }
00156 
00157     void mergeProduct(WrapperOwningHolder const& edp) const {
00158       mergeProduct_(edp);
00159     }
00160 
00161     // Merges two instances of the product.
00162     void mergeTheProduct(WrapperOwningHolder const& edp) const;
00163 
00164     void reallyCheckType(WrapperOwningHolder const& prod) const;
00165 
00166     void checkType(WrapperOwningHolder const& prod) const {
00167       checkType_(prod);
00168     }
00169 
00170     void swap(ProductHolderBase& rhs) {swap_(rhs);}
00171 
00172     void throwProductDeletedException() const;
00173 
00174   private:
00175     virtual ProductData const& getProductData() const = 0;
00176     virtual ProductData& getProductData() = 0;
00177     virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const = 0;
00178     virtual void swap_(ProductHolderBase& rhs) = 0;
00179     virtual bool onDemand_() const = 0;
00180     virtual bool productUnavailable_() const = 0;
00181     virtual bool productWasDeleted_() const = 0;
00182     virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance) = 0;
00183     virtual void putProduct_(WrapperOwningHolder const& edp) const = 0;
00184     virtual void mergeProduct_(WrapperOwningHolder const&  edp, ProductProvenance& productProvenance) = 0;
00185     virtual void mergeProduct_(WrapperOwningHolder const& edp) const = 0;
00186     virtual bool putOrMergeProduct_() const = 0;
00187     virtual void checkType_(WrapperOwningHolder const& prod) const = 0;
00188     virtual void resetStatus_() = 0;
00189     virtual void setProductDeleted_() = 0;
00190     virtual ConstBranchDescription const& branchDescription_() const = 0;
00191     virtual void resetBranchDescription_(boost::shared_ptr<ConstBranchDescription> bd) = 0;
00192     virtual std::string const& resolvedModuleLabel_() const = 0;
00193     virtual void setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid) = 0;
00194     virtual void setProcessHistoryID_(ProcessHistoryID const& phid) = 0;
00195     virtual ProductProvenance* productProvenancePtr_() const = 0;
00196     virtual void resetProductData_() = 0;
00197     virtual bool singleProduct_() const = 0;
00198     virtual void setPrincipal_(Principal* principal) = 0;
00199   };
00200 
00201   inline
00202   std::ostream&
00203   operator<<(std::ostream& os, ProductHolderBase const& phb) {
00204     phb.write(os);
00205     return os;
00206   }
00207 
00208   class InputProductHolder : public ProductHolderBase {
00209     public:
00210     explicit InputProductHolder(boost::shared_ptr<ConstBranchDescription> bd, Principal* principal) :
00211         ProductHolderBase(), productData_(bd), productIsUnavailable_(false),
00212         productHasBeenDeleted_(false), principal_(principal) {}
00213       virtual ~InputProductHolder();
00214 
00215       // The following is const because we can add an EDProduct to the
00216       // cache after creation of the ProductHolder, without changing the meaning
00217       // of the ProductHolder.
00218       void setProduct(WrapperOwningHolder const& prod) const;
00219       bool productIsUnavailable() const {return productIsUnavailable_;}
00220       void setProductUnavailable() const {productIsUnavailable_ = true;}
00221 
00222     private:
00223       virtual void swap_(ProductHolderBase& rhs) {
00224         InputProductHolder& other = dynamic_cast<InputProductHolder&>(rhs);
00225         edm::swap(productData_, other.productData_);
00226         std::swap(productIsUnavailable_, other.productIsUnavailable_);
00227       }
00228       virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const;
00229       virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance);
00230       virtual void putProduct_(WrapperOwningHolder const& edp) const;
00231       virtual void mergeProduct_(WrapperOwningHolder const& edp, ProductProvenance& productProvenance);
00232       virtual void mergeProduct_(WrapperOwningHolder const& edp) const;
00233       virtual bool putOrMergeProduct_() const;
00234       virtual void checkType_(WrapperOwningHolder const&) const {}
00235       virtual void resetStatus_() {productIsUnavailable_ = false;
00236         productHasBeenDeleted_=false;}
00237       virtual bool onDemand_() const {return false;}
00238       virtual bool productUnavailable_() const;
00239       virtual bool productWasDeleted_() const {return productHasBeenDeleted_;}
00240       virtual ProductData const& getProductData() const {return productData_;}
00241       virtual ProductData& getProductData() {return productData_;}
00242       virtual void setProductDeleted_() {productHasBeenDeleted_ = true;}
00243       virtual ConstBranchDescription const& branchDescription_() const {return *productData().branchDescription();}
00244       virtual void resetBranchDescription_(boost::shared_ptr<ConstBranchDescription> bd) {productData().resetBranchDescription(bd);}
00245       virtual std::string const& resolvedModuleLabel_() const {return moduleLabel();}
00246       virtual void setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid);
00247       virtual void setProcessHistoryID_(ProcessHistoryID const& phid);
00248       virtual ProductProvenance* productProvenancePtr_() const;
00249       virtual void resetProductData_();
00250       virtual bool singleProduct_() const;
00251       virtual void setPrincipal_(Principal* principal);
00252 
00253       ProductData productData_;
00254       mutable bool productIsUnavailable_;
00255       mutable bool productHasBeenDeleted_;
00256       Principal* principal_;
00257   };
00258 
00259   // Free swap function
00260   inline void swap(InputProductHolder& a, InputProductHolder& b) {
00261     a.swap(b);
00262   }
00263 
00264   class ProducedProductHolder : public ProductHolderBase {
00265     public:
00266     enum ProductStatus {
00267       Present = 0,
00268       NotRun = 3,
00269       NotCompleted = 4,
00270       NotPut = 5,
00271       UnscheduledNotRun = 6,
00272       ProductDeleted =7,
00273       Uninitialized = 0xff
00274     };
00275       ProducedProductHolder() : ProductHolderBase() {}
00276       virtual ~ProducedProductHolder();
00277       void producerStarted();
00278       void producerCompleted();
00279       ProductStatus& status() const {return status_();}
00280     private:
00281       virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance);
00282       virtual void putProduct_(WrapperOwningHolder const& edp) const;
00283       virtual void mergeProduct_(WrapperOwningHolder const& edp, ProductProvenance& productProvenance);
00284       virtual void mergeProduct_(WrapperOwningHolder const& edp) const;
00285       virtual bool putOrMergeProduct_() const;
00286       virtual void checkType_(WrapperOwningHolder const& prod) const {
00287         reallyCheckType(prod);
00288       }
00289       virtual ProductStatus& status_() const = 0;
00290       virtual bool productUnavailable_() const;
00291       virtual bool productWasDeleted_() const;
00292       virtual void setProductDeleted_();
00293       virtual ConstBranchDescription const& branchDescription_() const {return *productData().branchDescription();}
00294       virtual void resetBranchDescription_(boost::shared_ptr<ConstBranchDescription> bd) {productData().resetBranchDescription(bd);}
00295       virtual std::string const& resolvedModuleLabel_() const {return moduleLabel();}
00296       virtual void setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid);
00297       virtual void setProcessHistoryID_(ProcessHistoryID const& phid);
00298       virtual ProductProvenance* productProvenancePtr_() const;
00299       virtual void resetProductData_();
00300       virtual bool singleProduct_() const;
00301       virtual void setPrincipal_(Principal* principal);
00302   };
00303 
00304   class ScheduledProductHolder : public ProducedProductHolder {
00305     public:
00306       explicit ScheduledProductHolder(boost::shared_ptr<ConstBranchDescription> bd) : ProducedProductHolder(), productData_(bd), theStatus_(NotRun) {}
00307       virtual ~ScheduledProductHolder();
00308     private:
00309       virtual void swap_(ProductHolderBase& rhs) {
00310         ScheduledProductHolder& other = dynamic_cast<ScheduledProductHolder&>(rhs);
00311         edm::swap(productData_, other.productData_);
00312         std::swap(theStatus_, other.theStatus_);
00313       }
00314       virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const;
00315       virtual void resetStatus_() {theStatus_ = NotRun;}
00316       virtual bool onDemand_() const {return false;}
00317       virtual ProductData const& getProductData() const {return productData_;}
00318       virtual ProductData& getProductData() {return productData_;}
00319       virtual ProductStatus& status_() const {return theStatus_;}
00320 
00321       ProductData productData_;
00322       mutable ProductStatus theStatus_;
00323   };
00324 
00325   // Free swap function
00326   inline void swap(ScheduledProductHolder& a, ScheduledProductHolder& b) {
00327     a.swap(b);
00328   }
00329 
00330   class UnscheduledProductHolder : public ProducedProductHolder {
00331     public:
00332       explicit UnscheduledProductHolder(boost::shared_ptr<ConstBranchDescription> bd, Principal* principal) :
00333         ProducedProductHolder(), productData_(bd), theStatus_(UnscheduledNotRun), principal_(principal) {}
00334       virtual ~UnscheduledProductHolder();
00335     private:
00336       virtual void swap_(ProductHolderBase& rhs) {
00337         UnscheduledProductHolder& other = dynamic_cast<UnscheduledProductHolder&>(rhs);
00338         edm::swap(productData_, other.productData_);
00339         std::swap(theStatus_, other.theStatus_);
00340       }
00341       virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const;
00342       virtual void resetStatus_() {theStatus_ = UnscheduledNotRun;}
00343       virtual bool onDemand_() const {return status() == UnscheduledNotRun;}
00344       virtual ProductData const& getProductData() const {return productData_;}
00345       virtual ProductData& getProductData() {return productData_;}
00346       virtual ProductStatus& status_() const {return theStatus_;}
00347 
00348       ProductData productData_;
00349       mutable ProductStatus theStatus_;
00350       Principal* principal_;
00351   };
00352 
00353   // Free swap function
00354   inline void swap(UnscheduledProductHolder& a, UnscheduledProductHolder& b) {
00355     a.swap(b);
00356   }
00357 
00358   class SourceProductHolder : public ProducedProductHolder {
00359     public:
00360       explicit SourceProductHolder(boost::shared_ptr<ConstBranchDescription> bd) : ProducedProductHolder(), productData_(bd), theStatus_(NotPut) {}
00361       virtual ~SourceProductHolder();
00362     private:
00363       virtual void swap_(ProductHolderBase& rhs) {
00364         SourceProductHolder& other = dynamic_cast<SourceProductHolder&>(rhs);
00365         edm::swap(productData_, other.productData_);
00366         std::swap(theStatus_, other.theStatus_);
00367       }
00368       virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const;
00369       virtual void resetStatus_() {theStatus_ = NotPut;}
00370       virtual bool onDemand_() const {return false;}
00371       virtual ProductData const& getProductData() const {return productData_;}
00372       virtual ProductData& getProductData() {return productData_;}
00373       virtual ProductStatus& status_() const {return theStatus_;}
00374 
00375       ProductData productData_;
00376       mutable ProductStatus theStatus_;
00377   };
00378 
00379   class AliasProductHolder : public ProductHolderBase {
00380     public:
00381       typedef ProducedProductHolder::ProductStatus ProductStatus;
00382       explicit AliasProductHolder(boost::shared_ptr<ConstBranchDescription> bd, ProducedProductHolder& realProduct) : ProductHolderBase(), realProduct_(realProduct), bd_(bd) {}
00383       virtual ~AliasProductHolder();
00384     private:
00385       virtual void swap_(ProductHolderBase& rhs) {
00386         AliasProductHolder& other = dynamic_cast<AliasProductHolder&>(rhs);
00387         realProduct_.swap(other.realProduct_);
00388         std::swap(bd_, other.bd_);
00389       }
00390       virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const {return realProduct_.resolveProduct(resolveStatus, skipCurrentProcess);}
00391       virtual bool onDemand_() const {return realProduct_.onDemand();}
00392       virtual ProductStatus& status_() const {return realProduct_.status();}
00393       virtual void resetStatus_() {realProduct_.resetStatus();}
00394       virtual bool productUnavailable_() const {return realProduct_.productUnavailable();}
00395       virtual bool productWasDeleted_() const {return realProduct_.productWasDeleted();}
00396       virtual void checkType_(WrapperOwningHolder const& prod) const {realProduct_.checkType(prod);}
00397       virtual ProductData const& getProductData() const {return realProduct_.productData();}
00398       virtual ProductData& getProductData() {return realProduct_.productData();}
00399       virtual void setProductDeleted_() {realProduct_.setProductDeleted();}
00400       virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance) {
00401         realProduct_.putProduct(edp, productProvenance);
00402       }
00403       virtual void putProduct_(WrapperOwningHolder const& edp) const {
00404         realProduct_.putProduct(edp);
00405       }
00406       virtual void mergeProduct_(WrapperOwningHolder const& edp, ProductProvenance& productProvenance) {
00407         realProduct_.mergeProduct(edp, productProvenance);
00408       }
00409       virtual void mergeProduct_(WrapperOwningHolder const& edp) const {
00410         realProduct_.mergeProduct(edp);
00411       }
00412       virtual bool putOrMergeProduct_() const {
00413         return realProduct_.putOrMergeProduct();
00414       }
00415       virtual ConstBranchDescription const& branchDescription_() const {return *bd_;}
00416       virtual void resetBranchDescription_(boost::shared_ptr<ConstBranchDescription> bd) {bd_ = bd;}
00417       virtual std::string const& resolvedModuleLabel_() const {return realProduct_.moduleLabel();}
00418       virtual void setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid);
00419       virtual void setProcessHistoryID_(ProcessHistoryID const& phid);
00420       virtual ProductProvenance* productProvenancePtr_() const;
00421       virtual void resetProductData_();
00422       virtual bool singleProduct_() const;
00423       virtual void setPrincipal_(Principal* principal);
00424 
00425       ProducedProductHolder& realProduct_;
00426       boost::shared_ptr<ConstBranchDescription> bd_;
00427   };
00428 
00429   class NoProcessProductHolder : public ProductHolderBase {
00430     public:
00431       typedef ProducedProductHolder::ProductStatus ProductStatus;
00432       NoProcessProductHolder(std::vector<ProductHolderIndex> const&  matchingHolders,
00433                              std::vector<bool> const& ambiguous,
00434                              Principal* principal);
00435       virtual ~NoProcessProductHolder();
00436     private:
00437       virtual ProductData const& getProductData() const;
00438       virtual ProductData& getProductData();
00439       virtual ProductData const* resolveProduct_(ResolveStatus& resolveStatus, bool skipCurrentProcess) const;
00440       virtual void swap_(ProductHolderBase& rhs);
00441       virtual bool onDemand_() const;
00442       virtual bool productUnavailable_() const;
00443       virtual bool productWasDeleted_() const;
00444       virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance);
00445       virtual void putProduct_(WrapperOwningHolder const& edp) const;
00446       virtual void mergeProduct_(WrapperOwningHolder const&  edp, ProductProvenance& productProvenance);
00447       virtual void mergeProduct_(WrapperOwningHolder const& edp) const;
00448       virtual bool putOrMergeProduct_() const;
00449       virtual void checkType_(WrapperOwningHolder const& prod) const;
00450       virtual void resetStatus_();
00451       virtual void setProductDeleted_();
00452       virtual ConstBranchDescription const& branchDescription_() const;
00453       virtual void resetBranchDescription_(boost::shared_ptr<ConstBranchDescription> bd);
00454       virtual std::string const& resolvedModuleLabel_() const {return moduleLabel();}
00455       virtual void setProvenance_(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid);
00456       virtual void setProcessHistoryID_(ProcessHistoryID const& phid);
00457       virtual ProductProvenance* productProvenancePtr_() const;
00458       virtual void resetProductData_();
00459       virtual bool singleProduct_() const;
00460       virtual void setPrincipal_(Principal* principal);
00461 
00462       std::vector<ProductHolderIndex> matchingHolders_;
00463       std::vector<bool> ambiguous_;
00464       Principal* principal_;
00465   };
00466 
00467   // Free swap function
00468   inline void swap(SourceProductHolder& a, SourceProductHolder& b) {
00469     a.swap(b);
00470   }
00471 }
00472 
00473 #endif