CMS 3D CMS Logo

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