CMS 3D CMS Logo

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