CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/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 <memory>
00012 #include <string>
00013 
00014 #include "boost/shared_ptr.hpp"
00015 #include "boost/utility.hpp"
00016 
00017 #include "Reflex/Type.h"
00018 
00019 #include "DataFormats/Common/interface/EDProduct.h"
00020 #include "DataFormats/Provenance/interface/ConstBranchDescription.h"
00021 #include "DataFormats/Provenance/interface/Provenance.h"
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     // Return true if this group's product is a sequence, and if the
00122     // sequence has a 'value_type' that 'matches' the given type.
00123     // 'Matches' in this context means the sequence's value_type is
00124     // either the same as the given type, or has the given type as a
00125     // public base type.
00126     bool isMatchingSequence(Reflex::Type const& wanted) const;
00127 
00128     // Retrieves the product ID of the product.
00129     ProductID const& productID() const {return groupData().prov_.productID();};
00130 
00131     // Puts the product and its per event(lumi)(run) provenance into the Group.
00132     void putProduct(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance) {
00133       putProduct_(edp, productProvenance);
00134     }
00135     void putProduct(std::auto_ptr<EDProduct> edp, std::auto_ptr<ProductProvenance> productProvenance) {
00136       putProduct_(edp, boost::shared_ptr<ProductProvenance>(productProvenance.release()));
00137     }
00138 
00139     // Puts the product into the Group.
00140     void putProduct(std::auto_ptr<EDProduct> edp) const {
00141       putProduct_(edp);
00142     }
00143 
00144     // This returns true if it will be put, false if it will be merged
00145     bool putOrMergeProduct() const {
00146       return putOrMergeProduct_();
00147     }
00148 
00149     // merges the product with the pre-existing product
00150     void mergeProduct(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance) {
00151       mergeProduct_(edp, productProvenance);
00152     }
00153     void mergeProduct(std::auto_ptr<EDProduct> edp, std::auto_ptr<ProductProvenance> productProvenance) {
00154       mergeProduct_(edp, boost::shared_ptr<ProductProvenance>(productProvenance.release()));
00155     }
00156 
00157     void mergeProduct(std::auto_ptr<EDProduct> edp) const {
00158       mergeProduct_(edp);
00159     }
00160 
00161     // Merges two instances of the product.
00162     void mergeTheProduct(std::auto_ptr<EDProduct> edp) const;
00163 
00164     void checkType(EDProduct const& prod) const {
00165       checkType_(prod);
00166     }
00167 
00168     void swap(Group& rhs) {swap_(rhs);}
00169 
00170     virtual GroupData const& groupData() const = 0;
00171 
00172     virtual GroupData& groupData() = 0;
00173 
00174   private:
00175     virtual void swap_(Group& rhs) = 0;
00176     virtual bool onDemand_() const = 0;
00177     virtual bool productUnavailable_() const = 0;
00178     virtual void putProduct_(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance) = 0;
00179     virtual void putProduct_(std::auto_ptr<EDProduct> edp) const = 0;
00180     virtual void mergeProduct_(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance) = 0;
00181     virtual void mergeProduct_(std::auto_ptr<EDProduct> edp) const = 0;
00182     virtual bool putOrMergeProduct_() const = 0;
00183     virtual void checkType_(EDProduct const& prod) const = 0;
00184     virtual void resetStatus() = 0;
00185   };
00186 
00187   inline
00188   std::ostream&
00189   operator<<(std::ostream& os, Group const& g) {
00190     g.write(os);
00191     return os;
00192   }
00193 
00194   class InputGroup : public Group {
00195     public:
00196       explicit InputGroup(boost::shared_ptr<ConstBranchDescription> bd) :
00197         Group(), groupData_(bd), productIsUnavailable_(false) {}
00198       virtual ~InputGroup();
00199 
00200       // The following is const because we can add an EDProduct to the
00201       // cache after creation of the Group, without changing the meaning
00202       // of the Group.
00203       void setProduct(std::auto_ptr<EDProduct> prod) const;
00204       bool productIsUnavailable() const {return productIsUnavailable_;}
00205       void setProductUnavailable() const {productIsUnavailable_ = true;}
00206 
00207     private:
00208       virtual void swap_(Group& rhs) {
00209         InputGroup& other = dynamic_cast<InputGroup&>(rhs);
00210         edm::swap(groupData_, other.groupData_);
00211         std::swap(productIsUnavailable_, other.productIsUnavailable_);
00212       }
00213       virtual void putProduct_(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance);
00214       virtual void putProduct_(std::auto_ptr<EDProduct> edp) const;
00215       virtual void mergeProduct_(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance);
00216       virtual void mergeProduct_(std::auto_ptr<EDProduct> edp) const;
00217       virtual bool putOrMergeProduct_() const;
00218       virtual void checkType_(EDProduct const& prod) const {}
00219       virtual void resetStatus() {productIsUnavailable_ = false;}
00220       virtual bool onDemand_() const {return false;}
00221       virtual bool productUnavailable_() const;
00222       virtual GroupData const& groupData() const {return groupData_;}
00223       virtual GroupData& groupData() {return groupData_;}
00224       GroupData groupData_;
00225       mutable bool productIsUnavailable_;
00226   };
00227 
00228   // Free swap function
00229   inline void swap(InputGroup& a, InputGroup& b) {
00230     a.swap(b);
00231   }
00232 
00233   class ProducedGroup : public Group {
00234     protected:
00235     enum GroupStatus {
00236       Present = 0,
00237       NotRun = 3,
00238       NotCompleted = 4,
00239       NotPut = 5,
00240       UnscheduledNotRun = 6,
00241       Uninitialized = 0xff
00242     };
00243     public:
00244       ProducedGroup() : Group() {}
00245       virtual ~ProducedGroup();
00246       void producerStarted();
00247       void producerCompleted();
00248       GroupStatus const& status() const {return status_();}
00249       GroupStatus& status() {return status_();}
00250     private:
00251       virtual void putProduct_(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance);
00252       virtual void putProduct_(std::auto_ptr<EDProduct> edp) const;
00253       virtual void mergeProduct_(std::auto_ptr<EDProduct> edp, boost::shared_ptr<ProductProvenance> productProvenance);
00254       virtual void mergeProduct_(std::auto_ptr<EDProduct> edp) const;
00255       virtual bool putOrMergeProduct_() const;
00256       virtual void checkType_(EDProduct const& prod) const {
00257         groupData().checkType(prod);
00258       }
00259       virtual GroupStatus const& status_() const = 0;
00260       virtual GroupStatus& status_() = 0;
00261       virtual bool productUnavailable_() const;
00262   };
00263 
00264   class ScheduledGroup : public ProducedGroup {
00265     public:
00266       explicit ScheduledGroup(boost::shared_ptr<ConstBranchDescription> bd) : ProducedGroup(), groupData_(bd), theStatus_(NotRun) {}
00267       virtual ~ScheduledGroup();
00268     private:
00269       virtual void swap_(Group& rhs) {
00270         ScheduledGroup& other = dynamic_cast<ScheduledGroup&>(rhs);
00271         edm::swap(groupData_, other.groupData_);
00272         std::swap(theStatus_, other.theStatus_);
00273       }
00274       virtual void resetStatus() {theStatus_ = NotRun;}
00275       virtual bool onDemand_() const {return false;}
00276       virtual GroupData const& groupData() const {return groupData_;}
00277       virtual GroupData& groupData() {return groupData_;}
00278       virtual GroupStatus const& status_() const {return theStatus_;}
00279       virtual GroupStatus& status_() {return theStatus_;}
00280       GroupData groupData_;
00281       GroupStatus theStatus_;
00282   };
00283 
00284   // Free swap function
00285   inline void swap(ScheduledGroup& a, ScheduledGroup& b) {
00286     a.swap(b);
00287   }
00288 
00289   class UnscheduledGroup : public ProducedGroup {
00290     public:
00291       explicit UnscheduledGroup(boost::shared_ptr<ConstBranchDescription> bd) : ProducedGroup(), groupData_(bd), theStatus_(UnscheduledNotRun) {}
00292       virtual ~UnscheduledGroup();
00293     private:
00294       virtual void swap_(Group& rhs) {
00295         UnscheduledGroup& other = dynamic_cast<UnscheduledGroup&>(rhs);
00296         edm::swap(groupData_, other.groupData_);
00297         std::swap(theStatus_, other.theStatus_);
00298       }
00299       virtual void resetStatus() {theStatus_ = UnscheduledNotRun;}
00300       virtual bool onDemand_() const {return status() == UnscheduledNotRun;}
00301       virtual GroupData const& groupData() const {return groupData_;}
00302       virtual GroupData& groupData() {return groupData_;}
00303       virtual GroupStatus const& status_() const {return theStatus_;}
00304       virtual GroupStatus& status_() {return theStatus_;}
00305       GroupData groupData_;
00306       GroupStatus theStatus_;
00307   };
00308 
00309   // Free swap function
00310   inline void swap(UnscheduledGroup& a, UnscheduledGroup& b) {
00311     a.swap(b);
00312   }
00313 
00314   class SourceGroup : public ProducedGroup {
00315     public:
00316       explicit SourceGroup(boost::shared_ptr<ConstBranchDescription> bd) : ProducedGroup(), groupData_(bd), theStatus_(NotPut) {}
00317       virtual ~SourceGroup();
00318     private:
00319       virtual void swap_(Group& rhs) {
00320         SourceGroup& other = dynamic_cast<SourceGroup&>(rhs);
00321         edm::swap(groupData_, other.groupData_);
00322         std::swap(theStatus_, other.theStatus_);
00323       }
00324       virtual void resetStatus() {theStatus_ = NotPut;}
00325       virtual bool onDemand_() const {return false;}
00326       virtual GroupData const& groupData() const {return groupData_;}
00327       virtual GroupData& groupData() {return groupData_;}
00328       virtual GroupStatus const& status_() const {return theStatus_;}
00329       virtual GroupStatus& status_() {return theStatus_;}
00330       GroupData groupData_;
00331       GroupStatus theStatus_;
00332   };
00333 
00334   // Free swap function
00335   inline void swap(edm::SourceGroup& a, edm::SourceGroup& b) {
00336     a.swap(b);
00337   }
00338 }
00339 
00340 #endif