CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/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 fillPrincipal(ProcessHistoryID const& hist, DelayedReader* reader);
00084 
00085     void clearPrincipal();
00086 
00087     void deleteProduct(BranchID const& id);
00088     
00089     EDProductGetter const* prodGetter() const {return this;}
00090 
00091     OutputHandle getForOutput(BranchID const& bid, bool getProd) const;
00092 
00093     BasicHandle  getBySelector(TypeID const& tid,
00094                                SelectorBase const& s) const;
00095 
00096     BasicHandle  getByLabel(TypeID const& tid,
00097                             std::string const& label,
00098                             std::string const& productInstanceName,
00099                             std::string const& processName,
00100                             size_t& cachedOffset,
00101                             int& fillCount) const;
00102 
00103     void getMany(TypeID const& tid,
00104                  SelectorBase const&,
00105                  BasicHandleVec& results) const;
00106 
00107     BasicHandle  getByType(TypeID const& tid) const;
00108 
00109     void getManyByType(TypeID const& tid,
00110                  BasicHandleVec& results) const;
00111 
00112     // Return a BasicHandle to the product which:
00113     //   1. is a sequence,
00114     //   2. and has the nested type 'value_type'
00115     //   3. and for which typeID is the same as or a public base of
00116     //      this value_type,
00117     //   4. and which matches the given selector
00118     size_t getMatchingSequence(TypeID const& typeID,
00119                                SelectorBase const& selector,
00120                                BasicHandle& result) const;
00121 
00122     ProcessHistory const& processHistory() const {
00123       return *processHistoryPtr_;
00124     }
00125 
00126     ProcessHistoryID const& processHistoryID() const {
00127       return processHistoryID_;
00128     }
00129 
00130     ProcessConfiguration const& processConfiguration() const {return *processConfiguration_;}
00131 
00132     ProductRegistry const& productRegistry() const {return *preg_;}
00133 
00134     // merge Principals containing different groups.
00135     void recombine(Principal& other, std::vector<BranchID> const& bids);
00136 
00137     size_t size() const;
00138 
00139     // These iterators skip over any null shared pointers
00140     const_iterator begin() const {return boost::make_filter_iterator<FilledGroupPtr>(groups_.begin(), groups_.end());}
00141     const_iterator end() const {return  boost::make_filter_iterator<FilledGroupPtr>(groups_.end(), groups_.end());}
00142 
00143     Provenance getProvenance(BranchID const& bid) const;
00144 
00145     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
00146 
00147     BranchType const& branchType() const {return branchType_;}
00148 
00149     DelayedReader* reader() const {return reader_;}
00150 
00151     void maybeFlushCache(TypeID const& tid, InputTag const& tag) const;
00152 
00153     ConstGroupPtr getGroup(BranchID const& oid,
00154                            bool resolveProd,
00155                            bool fillOnDemand) const;
00156 
00157     ProductData const* findGroupByTag(TypeID const& typeID, InputTag const& tag) const;
00158 
00159   protected:
00160 
00161     // ----- Add a new Group
00162     // *this takes ownership of the Group, which in turn owns its
00163     // data.
00164     void addGroup_(std::auto_ptr<Group> g);
00165     void addGroupOrThrow(std::auto_ptr<Group> g);
00166     Group* getExistingGroup(BranchID const& branchID);
00167     Group* getExistingGroup(Group const& g);
00168 
00169     ConstGroupPtr getGroupByIndex(ProductTransientIndex const& oid,
00170                                   bool resolveProd,
00171                                   bool fillOnDemand) const;
00172 
00173     // Make my DelayedReader get the EDProduct for a Group or
00174     // trigger unscheduled execution if required.  The Group is
00175     // a cache, and so can be modified through the const reference.
00176     // We do not change the *number* of groups through this call, and so
00177     // *this is const.
00178     void resolveProduct(Group const& g, bool fillOnDemand) const {resolveProduct_(g, fillOnDemand);}
00179 
00180     // throws if the pointed to product is already in the Principal.
00181     void checkUniquenessAndType(WrapperOwningHolder const& prod, Group const* group) const;
00182 
00183     void putOrMerge(WrapperOwningHolder const& prod, Group const* group) const;
00184 
00185     void putOrMerge(WrapperOwningHolder const& prod, ProductProvenance& prov, Group* group);
00186 
00187   private:
00188     virtual WrapperHolder getIt(ProductID const&) const;
00189 
00190     virtual bool unscheduledFill(std::string const& moduleLabel) const = 0;
00191 
00192     // Used for indices to find groups by type and process
00193     typedef TransientProductLookupMap TypeLookup;
00194 
00195     size_t findGroup(TypeID const& typeID,
00196                      TypeLookup const& typeLookup,
00197                      SelectorBase const& selector,
00198                      BasicHandle& result) const;
00199 
00200     ProductData const* findGroupByLabel(TypeID const& typeID,
00201                                         TypeLookup const& typeLookup,
00202                                         std::string const& moduleLabel,
00203                                         std::string const& productInstanceName,
00204                                         std::string const& processName,
00205                                         size_t& cachedOffset,
00206                                         int& fillCount) const;
00207 
00208     size_t findGroups(TypeID const& typeID,
00209                       TypeLookup const& typeLookup,
00210                       SelectorBase const& selector,
00211                       BasicHandleVec& results) const;
00212 
00213     // defaults to no-op unless overridden in derived class.
00214     virtual void resolveProduct_(Group const&, bool /*fillOnDemand*/) const {}
00215 
00216     ProcessHistory const* processHistoryPtr_;
00217 
00218     ProcessHistoryID processHistoryID_;
00219 
00220     ProcessConfiguration const* processConfiguration_;
00221 
00222     // A vector of groups.
00223     GroupCollection groups_; // products and provenances are persistent
00224 
00225     // Pointer to the product registry. There is one entry in the registry
00226     // for each EDProduct in the event.
00227     boost::shared_ptr<ProductRegistry const> preg_;
00228 
00229     // Pointer to the 'source' that will be used to obtain EDProducts
00230     // from the persistent store. This 'source' is owned by the input source.
00231     DelayedReader* reader_;
00232 
00233     // Used to check for duplicates.  The same product instance must not be in more than one group.
00234     mutable std::set<void const*> productPtrs_;
00235 
00236     BranchType branchType_;
00237 
00238     // In use cases where the new process should not be appended to
00239     // input ProcessHistory, the following pointer should be null.
00240     // The Principal does not own this object.
00241     HistoryAppender* historyAppender_;
00242 
00243     static ProcessHistory emptyProcessHistory_;
00244   };
00245 
00246   template <typename PROD>
00247   inline
00248   boost::shared_ptr<Wrapper<PROD> const>
00249   getProductByTag(Principal const& ep, InputTag const& tag) {
00250     TypeID tid = TypeID(typeid(PROD));
00251     ep.maybeFlushCache(tid, tag);
00252     ProductData const* result = ep.findGroupByTag(tid, tag);
00253 
00254     if(result->getInterface() &&
00255        (!(result->getInterface()->dynamicTypeInfo() == typeid(PROD)))) {
00256       handleimpl::throwConvertTypeError(typeid(PROD), result->getInterface()->dynamicTypeInfo());
00257     }
00258     return boost::static_pointer_cast<Wrapper<PROD> const>(result->wrapper_);
00259   }
00260 }
00261 #endif