00001 #ifndef FWCore_Framework_Principal_h
00002 #define FWCore_Framework_Principal_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00106
00107
00108
00109
00110
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
00130 void recombine(Principal& other, std::vector<BranchID> const& bids);
00131
00132 size_t size() const;
00133
00134
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
00157
00158
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
00169
00170
00171
00172
00173 void resolveProduct(Group const& g, bool fillOnDemand) const {resolveProduct_(g, fillOnDemand);}
00174
00175
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
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
00210 virtual void resolveProduct_(Group const&, bool ) const {}
00211
00212 ProcessHistory const* processHistoryPtr_;
00213
00214 ProcessHistoryID processHistoryID_;
00215
00216 ProcessConfiguration const* processConfiguration_;
00217
00218
00219 GroupCollection groups_;
00220
00221
00222
00223 boost::shared_ptr<ProductRegistry const> preg_;
00224
00225
00226
00227 DelayedReader* reader_;
00228
00229
00230 mutable std::set<void const*> productPtrs_;
00231
00232 BranchType branchType_;
00233
00234
00235
00236
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