CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/FWCore/Framework/interface/Group.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_Group_h
00002 #define FWCore_Framework_Group_h
00003 
00004 /*----------------------------------------------------------------------
00005 
00006 Group: A collection of information related to a single EDProduct. This
00007 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/ConstBranchDescription.h"
00015 #include "DataFormats/Provenance/interface/Provenance.h"
00016 #include "FWCore/Utilities/interface/TypeID.h"
00017 
00018 #include "boost/shared_ptr.hpp"
00019 #include "boost/utility.hpp"
00020 
00021 #include <string>
00022 
00023 namespace edm {
00024   class BranchMapper;
00025   class DelayedReader;
00026   class WrapperInterfaceBase;
00027 
00028   class Group : private boost::noncopyable {
00029   public:
00030     Group();
00031     virtual ~Group();
00032     void resetProductData() {
00033       productData().resetProductData();
00034       resetStatus();
00035     }
00036 
00037     void deleteProduct() {
00038       productData().resetProductData();
00039       setProductDeleted();
00040     }
00041     
00042     // product is not available (dropped or never created)
00043     bool productUnavailable() const {return productUnavailable_();}
00044 
00045     // provenance is currently available
00046     bool provenanceAvailable() const;
00047 
00048     // Scheduled for on demand production
00049     bool onDemand() const {return onDemand_();}
00050     
00051     // Product was deleted early in order to save memory
00052     bool productWasDeleted() const {return productWasDeleted_();}
00053 
00054     // Retrieves a shared pointer to the wrapped product.
00055     boost::shared_ptr<void const> product() const { return productData().wrapper_; }
00056 
00057     // Retrieves the wrapped product and type. (non-owning);
00058     WrapperHolder wrapper() const { return WrapperHolder(productData().wrapper_.get(), productData().getInterface()); }
00059 
00060     // Retrieves pointer to the per event(lumi)(run) provenance.
00061     ProductProvenance* productProvenancePtr() const {
00062       return provenance()->productProvenance();
00063     }
00064 
00065     // Sets the the per event(lumi)(run) provenance.
00066     void setProductProvenance(ProductProvenance const& prov) const;
00067 
00068     // Retrieves a reference to the event independent provenance.
00069     ConstBranchDescription const& branchDescription() const {return *productData().branchDescription();}
00070 
00071     // Sets the pointer to the event independent provenance.
00072     void resetBranchDescription(boost::shared_ptr<ConstBranchDescription> bd) {productData().resetBranchDescription(bd);}
00073 
00074     // Retrieves a reference to the module label.
00075     std::string const& moduleLabel() const {return branchDescription().moduleLabel();}
00076 
00077     // Retrieves a reference to the product instance name
00078     std::string const& productInstanceName() const {return branchDescription().productInstanceName();}
00079 
00080     // Retrieves a reference to the process name
00081     std::string const& processName() const {return branchDescription().processName();}
00082 
00083     // Retrieves pointer to a class containing both the event independent and the per even provenance.
00084     Provenance* provenance() const;
00085 
00086     // Initializes the event independent portion of the provenance, plus the process history ID, the product ID, and the mapper.
00087     void setProvenance(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid, ProductID const& pid);
00088 
00089     // Initializes the event independent portion of the provenance, plus the process history ID and the mapper.
00090     void setProvenance(boost::shared_ptr<BranchMapper> mapper, ProcessHistoryID const& phid);
00091 
00092     // Initializes the process history ID.
00093     void setProcessHistoryID(ProcessHistoryID const& phid);
00094 
00095     // Write the group to the stream.
00096     void write(std::ostream& os) const;
00097 
00098     // Return the type of the product stored in this Group.
00099     // We are relying on the fact that Type instances are small, and
00100     // so we are free to copy them at will.
00101     TypeID productType() const;
00102 
00103     // Retrieves the product ID of the product.
00104     ProductID const& productID() const {return productData().prov_.productID();}
00105 
00106     // Puts the product and its per event(lumi)(run) provenance into the Group.
00107     void putProduct(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance) {
00108       putProduct_(edp, productProvenance);
00109     }
00110 
00111     // Puts the product into the Group.
00112     void putProduct(WrapperOwningHolder const& edp) const {
00113       putProduct_(edp);
00114     }
00115 
00116     // This returns true if it will be put, false if it will be merged
00117     bool putOrMergeProduct() const {
00118       return putOrMergeProduct_();
00119     }
00120 
00121     // merges the product with the pre-existing product
00122     void mergeProduct(WrapperOwningHolder const& edp, ProductProvenance& productProvenance) {
00123       mergeProduct_(edp, productProvenance);
00124     }
00125 
00126     void mergeProduct(WrapperOwningHolder const& edp) const {
00127       mergeProduct_(edp);
00128     }
00129 
00130     // Merges two instances of the product.
00131     void mergeTheProduct(WrapperOwningHolder const& edp) const;
00132 
00133     void reallyCheckType(WrapperOwningHolder const& prod) const;
00134 
00135     void checkType(WrapperOwningHolder const& prod) const {
00136       checkType_(prod);
00137     }
00138 
00139     void swap(Group& rhs) {swap_(rhs);}
00140 
00141     virtual ProductData const& productData() const = 0;
00142 
00143     virtual ProductData& productData() = 0;
00144 
00145   private:
00146     virtual void swap_(Group& rhs) = 0;
00147     virtual bool onDemand_() const = 0;
00148     virtual bool productUnavailable_() const = 0;
00149     virtual bool productWasDeleted_() const = 0;
00150     virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance) = 0;
00151     virtual void putProduct_(WrapperOwningHolder const& edp) const = 0;
00152     virtual void mergeProduct_(WrapperOwningHolder const&  edp, ProductProvenance& productProvenance) = 0;
00153     virtual void mergeProduct_(WrapperOwningHolder const& edp) const = 0;
00154     virtual bool putOrMergeProduct_() const = 0;
00155     virtual void checkType_(WrapperOwningHolder const& prod) const = 0;
00156     virtual void resetStatus() = 0;
00157     virtual void setProductDeleted() =0;
00158   };
00159 
00160   inline
00161   std::ostream&
00162   operator<<(std::ostream& os, Group const& g) {
00163     g.write(os);
00164     return os;
00165   }
00166 
00167   class InputGroup : public Group {
00168     public:
00169       explicit InputGroup(boost::shared_ptr<ConstBranchDescription> bd) :
00170         Group(), productData_(bd), productIsUnavailable_(false),
00171         productHasBeenDeleted_(false) {}
00172       virtual ~InputGroup();
00173 
00174       // The following is const because we can add an EDProduct to the
00175       // cache after creation of the Group, without changing the meaning
00176       // of the Group.
00177       void setProduct(WrapperOwningHolder const& prod) const;
00178       bool productIsUnavailable() const {return productIsUnavailable_;}
00179       void setProductUnavailable() const {productIsUnavailable_ = true;}
00180 
00181     private:
00182       virtual void swap_(Group& rhs) {
00183         InputGroup& other = dynamic_cast<InputGroup&>(rhs);
00184         edm::swap(productData_, other.productData_);
00185         std::swap(productIsUnavailable_, other.productIsUnavailable_);
00186       }
00187       virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance);
00188       virtual void putProduct_(WrapperOwningHolder const& edp) const;
00189       virtual void mergeProduct_(WrapperOwningHolder const& edp, ProductProvenance& productProvenance);
00190       virtual void mergeProduct_(WrapperOwningHolder const& edp) const;
00191       virtual bool putOrMergeProduct_() const;
00192       virtual void checkType_(WrapperOwningHolder const&) const {}
00193       virtual void resetStatus() {productIsUnavailable_ = false;
00194         productHasBeenDeleted_=false;}
00195       virtual bool onDemand_() const {return false;}
00196       virtual bool productUnavailable_() const;
00197       virtual bool productWasDeleted_() const {return productHasBeenDeleted_;}
00198       virtual ProductData const& productData() const {return productData_;}
00199       virtual ProductData& productData() {return productData_;}
00200       virtual void setProductDeleted() {productHasBeenDeleted_=true;}
00201 
00202       ProductData productData_;
00203       mutable bool productIsUnavailable_;
00204       mutable bool productHasBeenDeleted_;
00205   };
00206 
00207   // Free swap function
00208   inline void swap(InputGroup& a, InputGroup& b) {
00209     a.swap(b);
00210   }
00211 
00212   class ProducedGroup : public Group {
00213     protected:
00214     enum GroupStatus {
00215       Present = 0,
00216       NotRun = 3,
00217       NotCompleted = 4,
00218       NotPut = 5,
00219       UnscheduledNotRun = 6,
00220       ProductDeleted =7,
00221       Uninitialized = 0xff
00222     };
00223     public:
00224       ProducedGroup() : Group() {}
00225       virtual ~ProducedGroup();
00226       void producerStarted();
00227       void producerCompleted();
00228       GroupStatus& status() const {return status_();}
00229     private:
00230       virtual void putProduct_(WrapperOwningHolder const& edp, ProductProvenance const& productProvenance);
00231       virtual void putProduct_(WrapperOwningHolder const& edp) const;
00232       virtual void mergeProduct_(WrapperOwningHolder const& edp, ProductProvenance& productProvenance);
00233       virtual void mergeProduct_(WrapperOwningHolder const& edp) const;
00234       virtual bool putOrMergeProduct_() const;
00235       virtual void checkType_(WrapperOwningHolder const& prod) const {
00236         reallyCheckType(prod);
00237       }
00238       virtual GroupStatus& status_() const = 0;
00239       virtual bool productUnavailable_() const;
00240       virtual bool productWasDeleted_() const;
00241       virtual void setProductDeleted();
00242  
00243   };
00244 
00245   class ScheduledGroup : public ProducedGroup {
00246     public:
00247       explicit ScheduledGroup(boost::shared_ptr<ConstBranchDescription> bd) : ProducedGroup(), productData_(bd), theStatus_(NotRun) {}
00248       virtual ~ScheduledGroup();
00249     private:
00250       virtual void swap_(Group& rhs) {
00251         ScheduledGroup& other = dynamic_cast<ScheduledGroup&>(rhs);
00252         edm::swap(productData_, other.productData_);
00253         std::swap(theStatus_, other.theStatus_);
00254       }
00255       virtual void resetStatus() {theStatus_ = NotRun;}
00256       virtual bool onDemand_() const {return false;}
00257       virtual ProductData const& productData() const {return productData_;}
00258       virtual ProductData& productData() {return productData_;}
00259       virtual GroupStatus& status_() const {return theStatus_;}
00260       ProductData productData_;
00261       mutable GroupStatus theStatus_;
00262   };
00263 
00264   // Free swap function
00265   inline void swap(ScheduledGroup& a, ScheduledGroup& b) {
00266     a.swap(b);
00267   }
00268 
00269   class UnscheduledGroup : public ProducedGroup {
00270     public:
00271       explicit UnscheduledGroup(boost::shared_ptr<ConstBranchDescription> bd) : ProducedGroup(), productData_(bd), theStatus_(UnscheduledNotRun) {}
00272       virtual ~UnscheduledGroup();
00273     private:
00274       virtual void swap_(Group& rhs) {
00275         UnscheduledGroup& other = dynamic_cast<UnscheduledGroup&>(rhs);
00276         edm::swap(productData_, other.productData_);
00277         std::swap(theStatus_, other.theStatus_);
00278       }
00279       virtual void resetStatus() {theStatus_ = UnscheduledNotRun;}
00280       virtual bool onDemand_() const {return status() == UnscheduledNotRun;}
00281       virtual ProductData const& productData() const {return productData_;}
00282       virtual ProductData& productData() {return productData_;}
00283       virtual GroupStatus& status_() const {return theStatus_;}
00284       ProductData productData_;
00285       mutable GroupStatus theStatus_;
00286   };
00287 
00288   // Free swap function
00289   inline void swap(UnscheduledGroup& a, UnscheduledGroup& b) {
00290     a.swap(b);
00291   }
00292 
00293   class SourceGroup : public ProducedGroup {
00294     public:
00295       explicit SourceGroup(boost::shared_ptr<ConstBranchDescription> bd) : ProducedGroup(), productData_(bd), theStatus_(NotPut) {}
00296       virtual ~SourceGroup();
00297     private:
00298       virtual void swap_(Group& rhs) {
00299         SourceGroup& other = dynamic_cast<SourceGroup&>(rhs);
00300         edm::swap(productData_, other.productData_);
00301         std::swap(theStatus_, other.theStatus_);
00302       }
00303       virtual void resetStatus() {theStatus_ = NotPut;}
00304       virtual bool onDemand_() const {return false;}
00305       virtual ProductData const& productData() const {return productData_;}
00306       virtual ProductData& productData() {return productData_;}
00307       virtual GroupStatus& status_() const {return theStatus_;}
00308       ProductData productData_;
00309       mutable GroupStatus theStatus_;
00310   };
00311 
00312   // Free swap function
00313   inline void swap(SourceGroup& a, SourceGroup& b) {
00314     a.swap(b);
00315   }
00316 }
00317 
00318 #endif