CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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/scoped_ptr.hpp"
00037 #include "boost/shared_ptr.hpp"
00038 
00039 #include <map>
00040 #include <memory>
00041 #include <set>
00042 #include <string>
00043 #include <vector>
00044 
00045 namespace edm {
00046    struct FilledGroupPtr {
00047       bool operator()(boost::shared_ptr<Group> const& iObj) { return bool(iObj);}
00048    };
00049 
00050   class Principal : public EDProductGetter {
00051   public:
00052     typedef std::vector<boost::shared_ptr<Group> > GroupCollection;
00053     typedef boost::filter_iterator<FilledGroupPtr, GroupCollection::const_iterator> const_iterator;
00054     typedef ProcessHistory::const_iterator ProcessNameConstIterator;
00055     typedef Group const* ConstGroupPtr;
00056     typedef std::vector<BasicHandle> BasicHandleVec;
00057     typedef GroupCollection::size_type      size_type;
00058 
00059     typedef boost::shared_ptr<Group> SharedGroupPtr;
00060     typedef std::string ProcessName;
00061 
00062     Principal(boost::shared_ptr<ProductRegistry const> reg,
00063               ProcessConfiguration const& pc,
00064               BranchType bt);
00065 
00066     virtual ~Principal();
00067 
00068     bool adjustToNewProductRegistry(ProductRegistry const& reg);
00069 
00070     void adjustIndexesAfterProductRegistryAddition();
00071 
00072     void addGroupScheduled(boost::shared_ptr<ConstBranchDescription> bd);
00073 
00074     void addGroupSource(boost::shared_ptr<ConstBranchDescription> bd);
00075 
00076     void addGroupInput(boost::shared_ptr<ConstBranchDescription> bd);
00077 
00078     void addOnDemandGroup(boost::shared_ptr<ConstBranchDescription> bd);
00079 
00080     void fillPrincipal(ProcessHistoryID const& hist, boost::shared_ptr<BranchMapper> mapper, DelayedReader* reader);
00081 
00082     void clearPrincipal();
00083 
00084     EDProductGetter const* prodGetter() const {return this;}
00085 
00086     OutputHandle getForOutput(BranchID const& bid, bool getProd) const;
00087 
00088     BasicHandle  getBySelector(TypeID const& tid,
00089                                SelectorBase const& s) const;
00090 
00091     BasicHandle  getByLabel(TypeID const& tid,
00092                             std::string const& label,
00093                             std::string const& productInstanceName,
00094                             std::string const& processName,
00095                             size_t& cachedOffset,
00096                             int& fillCount) const;
00097 
00098     void getMany(TypeID const& tid,
00099                  SelectorBase const&,
00100                  BasicHandleVec& results) const;
00101 
00102     BasicHandle  getByType(TypeID const& tid) const;
00103 
00104     void getManyByType(TypeID const& tid,
00105                  BasicHandleVec& results) const;
00106 
00107     // Return a BasicHandle to the product which:
00108     //   1. is a sequence,
00109     //   2. and has the nested type 'value_type'
00110     //   3. and for which typeID is the same as or a public base of
00111     //      this value_type,
00112     //   4. and which matches the given selector
00113     size_t getMatchingSequence(TypeID const& typeID,
00114                                SelectorBase const& selector,
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     boost::shared_ptr<BranchMapper> branchMapperPtr() const {return branchMapperPtr_;}
00145 
00146     DelayedReader* reader() const {return reader_;}
00147 
00148     void maybeFlushCache(TypeID const& tid, InputTag const& tag) const;
00149 
00150     ConstGroupPtr const getGroup(BranchID const& oid,
00151                                        bool resolveProd,
00152                                        bool fillOnDemand) const;
00153 
00154     ProductData const* findGroupByTag(TypeID const& typeID, InputTag const& tag) const;
00155 
00156   protected:
00157     ProcessHistory& processHistoryUpdate() {
00158       return *processHistoryPtr_;
00159     }
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 const 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     void setProcessHistory(Principal const& principal);
00188 
00189   private:
00190     virtual WrapperHolder getIt(ProductID const&) const;
00191 
00192     virtual bool unscheduledFill(std::string const& moduleLabel) const = 0;
00193 
00194     // Used for indices to find groups by type and process
00195     typedef TransientProductLookupMap TypeLookup;
00196 
00197     size_t findGroup(TypeID const& typeID,
00198                      TypeLookup const& typeLookup,
00199                      SelectorBase const& selector,
00200                      BasicHandle& result) const;
00201 
00202     ProductData const* findGroupByLabel(TypeID const& typeID,
00203                                         TypeLookup const& typeLookup,
00204                                         std::string const& moduleLabel,
00205                                         std::string const& productInstanceName,
00206                                         std::string const& processName,
00207                                         size_t& cachedOffset,
00208                                         int& fillCount) const;
00209 
00210     size_t findGroups(TypeID const& typeID,
00211                       TypeLookup const& typeLookup,
00212                       SelectorBase const& selector,
00213                       BasicHandleVec& results) const;
00214 
00215     // defaults to no-op unless overridden in derived class.
00216     virtual void resolveProduct_(Group const&, bool /*fillOnDemand*/) const {}
00217 
00218     boost::scoped_ptr<ProcessHistory> processHistoryPtr_;
00219 
00220     ProcessHistoryID processHistoryID_;
00221 
00222     ProcessConfiguration const* processConfiguration_;
00223 
00224     // A vector of groups.
00225     GroupCollection groups_; // products and provenances are persistent
00226 
00227     // Pointer to the product registry. There is one entry in the registry
00228     // for each EDProduct in the event.
00229     boost::shared_ptr<ProductRegistry const> preg_;
00230 
00231     // Pointer to the 'mapper' that will get provenance information
00232     // from the persistent store.
00233     boost::shared_ptr<BranchMapper> branchMapperPtr_;
00234 
00235     // Pointer to the 'source' that will be used to obtain EDProducts
00236     // from the persistent store. This 'source' is owned by the input source.
00237     DelayedReader* reader_;
00238 
00239     // Used to check for duplicates.  The same product instance must not be in more than one group.
00240     mutable std::set<void const*> productPtrs_;
00241 
00242     BranchType branchType_;
00243   };
00244 
00245   template <typename PROD>
00246   inline
00247   boost::shared_ptr<Wrapper<PROD> const>
00248   getProductByTag(Principal const& ep, InputTag const& tag) {
00249     TypeID tid = TypeID(typeid(PROD));
00250     ep.maybeFlushCache(tid, tag);
00251     ProductData const* result = ep.findGroupByTag(tid, tag);
00252 
00253     if(result->getInterface() &&
00254        (!(result->getInterface()->dynamicTypeInfo() == typeid(PROD)))) {
00255       handleimpl::throwConvertTypeError(typeid(PROD), result->getInterface()->dynamicTypeInfo());
00256     }
00257     return boost::static_pointer_cast<Wrapper<PROD> const>(result->wrapper_);
00258   }
00259 }
00260 #endif