CMS 3D CMS Logo

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