CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/FWCore/Framework/interface/Principal.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_Principal_h
00002 #define FWCore_Framework_Principal_h
00003 
00004 /*----------------------------------------------------------------------
00005 
00006 Principal: This is the implementation of the classes responsible
00007 for management of EDProducts. It is not seen by reconstruction code.
00008 
00009 The major internal component of the Principal is the Group, which
00010 contains an EDProduct and its associated Provenance, along with
00011 ancillary transient information regarding the two. Groups are handled
00012 through shared pointers.
00013 
00014 The Principal returns BasicHandle, rather than a shared
00015 pointer to a Group, when queried.
00016 
00017 (Historical note: prior to April 2007 this class was named DataBlockImpl)
00018 
00019 ----------------------------------------------------------------------*/
00020 #include "DataFormats/Common/interface/BasicHandle.h"
00021 #include "DataFormats/Common/interface/ConvertHandle.h"
00022 #include "DataFormats/Common/interface/EDProductGetter.h"
00023 #include "DataFormats/Common/interface/OutputHandle.h"
00024 #include "DataFormats/Common/interface/Wrapper.h"
00025 #include "DataFormats/Common/interface/WrapperHolder.h"
00026 #include "DataFormats/Common/interface/WrapperOwningHolder.h"
00027 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00028 #include "DataFormats/Provenance/interface/ProductTransientIndex.h"
00029 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
00030 #include "DataFormats/Provenance/interface/TransientProductLookupMap.h"
00031 #include "FWCore/Framework/interface/Frameworkfwd.h"
00032 #include "FWCore/Framework/interface/Group.h"
00033 #include "FWCore/Utilities/interface/InputTag.h"
00034 
00035 #include "boost/iterator/filter_iterator.hpp"
00036 #include "boost/shared_ptr.hpp"
00037 
00038 #include <map>
00039 #include <memory>
00040 #include <set>
00041 #include <string>
00042 #include <vector>
00043 
00044 namespace edm {
00045 
00046    class HistoryAppender;
00047 
00048    struct FilledGroupPtr {
00049       bool operator()(boost::shared_ptr<Group> const& iObj) { return bool(iObj);}
00050    };
00051 
00052   class Principal : public EDProductGetter {
00053   public:
00054     typedef std::vector<boost::shared_ptr<Group> > GroupCollection;
00055     typedef boost::filter_iterator<FilledGroupPtr, GroupCollection::const_iterator> const_iterator;
00056     typedef ProcessHistory::const_iterator ProcessNameConstIterator;
00057     typedef Group const* ConstGroupPtr;
00058     typedef std::vector<BasicHandle> BasicHandleVec;
00059     typedef GroupCollection::size_type      size_type;
00060 
00061     typedef boost::shared_ptr<Group> SharedGroupPtr;
00062     typedef std::string ProcessName;
00063 
00064     Principal(boost::shared_ptr<ProductRegistry const> reg,
00065               ProcessConfiguration const& pc,
00066               BranchType bt,
00067               HistoryAppender* historyAppender);
00068 
00069     virtual ~Principal();
00070 
00071     bool adjustToNewProductRegistry(ProductRegistry const& reg);
00072 
00073     void adjustIndexesAfterProductRegistryAddition();
00074 
00075     void addGroupScheduled(boost::shared_ptr<ConstBranchDescription> bd);
00076 
00077     void addGroupSource(boost::shared_ptr<ConstBranchDescription> bd);
00078 
00079     void addGroupInput(boost::shared_ptr<ConstBranchDescription> bd);
00080 
00081     void addOnDemandGroup(boost::shared_ptr<ConstBranchDescription> bd);
00082 
00083     void addGroupAliased(boost::shared_ptr<ConstBranchDescription> bd);
00084 
00085     void fillPrincipal(ProcessHistoryID const& hist, DelayedReader* reader);
00086 
00087     void clearPrincipal();
00088 
00089     void deleteProduct(BranchID const& id);
00090     
00091     EDProductGetter const* prodGetter() const {return this;}
00092 
00093     OutputHandle getForOutput(BranchID const& bid, bool getProd) const;
00094 
00095     BasicHandle  getByLabel(TypeID const& tid,
00096                             std::string const& label,
00097                             std::string const& productInstanceName,
00098                             std::string const& processName,
00099                             size_t& cachedOffset,
00100                             int& fillCount) const;
00101 
00102     void getManyByType(TypeID const& tid,
00103                  BasicHandleVec& results) const;
00104 
00105     // Return a BasicHandle to the product which:
00106     //   1. is a sequence,
00107     //   2. and has the nested type 'value_type'
00108     //   3. and for which typeID is the same as or a public base of
00109     //      this value_type,
00110     //   4. and which matches the given label, instance, and process
00111     size_t getMatchingSequence(TypeID const& typeID,
00112                                std::string const& moduleLabel,
00113                                std::string const& productInstanceName,
00114                                std::string const& processName,
00115                                BasicHandle& result) const;
00116 
00117     ProcessHistory const& processHistory() const {
00118       return *processHistoryPtr_;
00119     }
00120 
00121     ProcessHistoryID const& processHistoryID() const {
00122       return processHistoryID_;
00123     }
00124 
00125     ProcessConfiguration const& processConfiguration() const {return *processConfiguration_;}
00126 
00127     ProductRegistry const& productRegistry() const {return *preg_;}
00128 
00129     // merge Principals containing different groups.
00130     void recombine(Principal& other, std::vector<BranchID> const& bids);
00131 
00132     size_t size() const;
00133 
00134     // These iterators skip over any null shared pointers
00135     const_iterator begin() const {return boost::make_filter_iterator<FilledGroupPtr>(groups_.begin(), groups_.end());}
00136     const_iterator end() const {return  boost::make_filter_iterator<FilledGroupPtr>(groups_.end(), groups_.end());}
00137 
00138     Provenance getProvenance(BranchID const& bid) const;
00139 
00140     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
00141 
00142     BranchType const& branchType() const {return branchType_;}
00143 
00144     DelayedReader* reader() const {return reader_;}
00145 
00146     void maybeFlushCache(TypeID const& tid, InputTag const& tag) const;
00147 
00148     ConstGroupPtr getGroup(BranchID const& oid,
00149                            bool resolveProd,
00150                            bool fillOnDemand) const;
00151 
00152     ProductData const* findGroupByTag(TypeID const& typeID, InputTag const& tag) const;
00153 
00154   protected:
00155 
00156     // ----- Add a new Group
00157     // *this takes ownership of the Group, which in turn owns its
00158     // data.
00159     void addGroup_(std::auto_ptr<Group> g);
00160     void addGroupOrThrow(std::auto_ptr<Group> g);
00161     Group* getExistingGroup(BranchID const& branchID);
00162     Group* getExistingGroup(Group const& g);
00163 
00164     ConstGroupPtr getGroupByIndex(ProductTransientIndex const& oid,
00165                                   bool resolveProd,
00166                                   bool fillOnDemand) const;
00167 
00168     // Make my DelayedReader get the EDProduct for a Group or
00169     // trigger unscheduled execution if required.  The Group is
00170     // a cache, and so can be modified through the const reference.
00171     // We do not change the *number* of groups through this call, and so
00172     // *this is const.
00173     void resolveProduct(Group const& g, bool fillOnDemand) const {resolveProduct_(g, fillOnDemand);}
00174 
00175     // throws if the pointed to product is already in the Principal.
00176     void checkUniquenessAndType(WrapperOwningHolder const& prod, Group const* group) const;
00177 
00178     void putOrMerge(WrapperOwningHolder const& prod, Group const* group) const;
00179 
00180     void putOrMerge(WrapperOwningHolder const& prod, ProductProvenance& prov, Group* group);
00181 
00182   private:
00183     virtual WrapperHolder getIt(ProductID const&) const;
00184 
00185     virtual bool unscheduledFill(std::string const& moduleLabel) const = 0;
00186 
00187     // Used for indices to find groups by type and process
00188     typedef TransientProductLookupMap TypeLookup;
00189 
00190     size_t findGroup(TypeID const& typeID,
00191                      TypeLookup const& typeLookup,
00192                      std::string const& moduleLabel,
00193                      std::string const& productInstanceName,
00194                      std::string const& processName,
00195                      BasicHandle& result) const;
00196 
00197     ProductData const* findGroupByLabel(TypeID const& typeID,
00198                                         TypeLookup const& typeLookup,
00199                                         std::string const& moduleLabel,
00200                                         std::string const& productInstanceName,
00201                                         std::string const& processName,
00202                                         size_t& cachedOffset,
00203                                         int& fillCount) const;
00204 
00205     size_t findGroups(TypeID const& typeID,
00206                       TypeLookup const& typeLookup,
00207                       BasicHandleVec& results) const;
00208 
00209     // defaults to no-op unless overridden in derived class.
00210     virtual void resolveProduct_(Group const&, bool /*fillOnDemand*/) const {}
00211 
00212     ProcessHistory const* processHistoryPtr_;
00213 
00214     ProcessHistoryID processHistoryID_;
00215 
00216     ProcessConfiguration const* processConfiguration_;
00217 
00218     // A vector of groups.
00219     GroupCollection groups_; // products and provenances are persistent
00220 
00221     // Pointer to the product registry. There is one entry in the registry
00222     // for each EDProduct in the event.
00223     boost::shared_ptr<ProductRegistry const> preg_;
00224 
00225     // Pointer to the 'source' that will be used to obtain EDProducts
00226     // from the persistent store. This 'source' is owned by the input source.
00227     DelayedReader* reader_;
00228 
00229     // Used to check for duplicates.  The same product instance must not be in more than one group.
00230     mutable std::set<void const*> productPtrs_;
00231 
00232     BranchType branchType_;
00233 
00234     // In use cases where the new process should not be appended to
00235     // input ProcessHistory, the following pointer should be null.
00236     // The Principal does not own this object.
00237     HistoryAppender* historyAppender_;
00238 
00239     static const ProcessHistory emptyProcessHistory_;
00240   };
00241 
00242   template <typename PROD>
00243   inline
00244   boost::shared_ptr<Wrapper<PROD> const>
00245   getProductByTag(Principal const& ep, InputTag const& tag) {
00246     TypeID tid = TypeID(typeid(PROD));
00247     ep.maybeFlushCache(tid, tag);
00248     ProductData const* result = ep.findGroupByTag(tid, tag);
00249 
00250     if(result->getInterface() &&
00251        (!(result->getInterface()->dynamicTypeInfo() == typeid(PROD)))) {
00252       handleimpl::throwConvertTypeError(typeid(PROD), result->getInterface()->dynamicTypeInfo());
00253     }
00254     return boost::static_pointer_cast<Wrapper<PROD> const>(result->wrapper_);
00255   }
00256 }
00257 #endif