00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <cassert>
00016 #include <utility>
00017
00018
00019 #include "FWCore/Framework/interface/EDConsumerBase.h"
00020 #include "FWCore/Framework/interface/ConsumesCollector.h"
00021 #include "FWCore/Utilities/interface/Likely.h"
00022 #include "FWCore/Utilities/interface/Exception.h"
00023 #include "DataFormats/Provenance/interface/ProductHolderIndexHelper.h"
00024
00025 using namespace edm;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 EDConsumerBase::~EDConsumerBase()
00048 {
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 ConsumesCollector
00067 EDConsumerBase::consumesCollector() {
00068 ConsumesCollector c{this};
00069 return std::move(c);
00070 }
00071
00072
00073 unsigned int
00074 EDConsumerBase::recordConsumes(BranchType iBranch, TypeToGet const& iType, edm::InputTag const& iTag, bool iAlwaysGets) {
00075 unsigned int index =m_tokenInfo.size();
00076
00077 const size_t labelSize = iTag.label().size();
00078 const size_t productInstanceSize = iTag.instance().size();
00079 unsigned int labelStart = m_tokenLabels.size();
00080 unsigned short delta1 = labelSize+1;
00081 unsigned short delta2 = labelSize+2+productInstanceSize;
00082 m_tokenInfo.emplace_back(TokenLookupInfo{iType.type(),ProductHolderIndexInvalid,iBranch},
00083 iAlwaysGets,
00084 LabelPlacement{labelStart,delta1,delta2},
00085 iType.kind());
00086
00087 bool skipCurrentProcess = iTag.willSkipCurrentProcess();
00088
00089 const size_t additionalSize =
00090 skipCurrentProcess ?
00091 labelSize+productInstanceSize+3 :
00092 labelSize+productInstanceSize+iTag.process().size()+3;
00093
00094 m_tokenLabels.reserve(m_tokenLabels.size()+additionalSize);
00095 {
00096 const std::string& m =iTag.label();
00097 m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
00098 m_tokenLabels.push_back('\0');
00099 }
00100 {
00101 const std::string& m =iTag.instance();
00102 m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
00103 m_tokenLabels.push_back('\0');
00104 }
00105 {
00106 if (!skipCurrentProcess) {
00107 const std::string& m =iTag.process();
00108 m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
00109 m_tokenLabels.push_back('\0');
00110 } else {
00111 m_tokenLabels.push_back('\0');
00112 }
00113 }
00114 return index;
00115 }
00116
00117 void
00118 EDConsumerBase::updateLookup(BranchType iBranchType,
00119 ProductHolderIndexHelper const& iHelper)
00120 {
00121 {
00122 auto itKind = m_tokenInfo.begin<kKind>();
00123 auto itLabels = m_tokenInfo.begin<kLabels>();
00124 for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
00125 itInfo != itEnd; ++itInfo,++itKind,++itLabels) {
00126 const unsigned int labelStart = itLabels->m_startOfModuleLabel;
00127 const char* moduleLabel = &(m_tokenLabels[labelStart]);
00128 itInfo->m_index = iHelper.index(*itKind,
00129 itInfo->m_type,
00130 moduleLabel,
00131 moduleLabel+itLabels->m_deltaToProductInstance,
00132 moduleLabel+itLabels->m_deltaToProcessName);
00133 }
00134 }
00135
00136
00137
00138 for(size_t i=0, iEnd = m_tokenInfo.size(); i!=iEnd;++i) {
00139
00140 auto const info = m_tokenInfo.get<kLookupInfo>(i);
00141 if(info.m_branchType == iBranchType &&
00142 info.m_index == ProductHolderIndexInvalid &&
00143 m_tokenLabels[m_tokenInfo.get<kLabels>(i).m_startOfModuleLabel]=='\0') {
00144
00145 const auto kind=m_tokenInfo.get<kKind>(i);
00146 auto matches = iHelper.relatedIndexes(kind,info.m_type);
00147
00148
00149
00150 const LabelPlacement labels= m_tokenInfo.get<kLabels>(i);
00151 bool alwaysGet = m_tokenInfo.get<kAlwaysGets>(i);
00152 for(unsigned int j=0;j!=matches.numberOfMatches();++j) {
00153
00154 if(matches.isFullyResolved(j)) {
00155 auto index =matches.index(j);
00156 m_tokenInfo.emplace_back(TokenLookupInfo{info.m_type,index,info.m_branchType},
00157 alwaysGet,
00158 labels,
00159 kind);
00160 }
00161 }
00162 }
00163 }
00164 m_tokenInfo.shrink_to_fit();
00165 }
00166
00167
00168
00169
00170
00171 ProductHolderIndex
00172 EDConsumerBase::indexFrom(EDGetToken iToken, BranchType iBranch, TypeID const& iType) const
00173 {
00174 if(unlikely(iToken.index()>=m_tokenInfo.size())) {
00175 throwBadToken(iType,iToken);
00176 }
00177 const auto& info = m_tokenInfo.get<kLookupInfo>(iToken.index());
00178 if (likely(iBranch == info.m_branchType)) {
00179 if (likely(iType == info.m_type)) {
00180 return info.m_index;
00181 } else {
00182 throwTypeMismatch(iType, iToken);
00183 }
00184 } else {
00185 throwBranchMismatch(iBranch,iToken);
00186 }
00187 return edm::ProductHolderIndexInvalid;
00188 }
00189
00190 void
00191 EDConsumerBase::itemsToGet(BranchType iBranch, std::vector<ProductHolderIndex>& oIndices) const
00192 {
00193
00194 unsigned int count=0;
00195 {
00196 auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
00197 for(auto it = m_tokenInfo.begin<kLookupInfo>(),
00198 itEnd = m_tokenInfo.end<kLookupInfo>();
00199 it != itEnd; ++it,++itAlwaysGet) {
00200 if(iBranch==it->m_branchType) {
00201 if (it->m_index != ProductHolderIndexInvalid) {
00202 if(*itAlwaysGet) {
00203 ++count;
00204 }
00205 }
00206 }
00207 }
00208 }
00209 oIndices.reserve(oIndices.size()+count);
00210 {
00211 auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
00212 for(auto it = m_tokenInfo.begin<kLookupInfo>(),
00213 itEnd = m_tokenInfo.end<kLookupInfo>();
00214 it != itEnd; ++it,++itAlwaysGet) {
00215 if(iBranch==it->m_branchType) {
00216 if (it->m_index != ProductHolderIndexInvalid) {
00217 if(*itAlwaysGet) {
00218 oIndices.push_back(it->m_index);
00219 }
00220 }
00221 }
00222 }
00223 }
00224 }
00225
00226 void
00227 EDConsumerBase::itemsMayGet(BranchType iBranch, std::vector<ProductHolderIndex>& oIndices) const
00228 {
00229
00230 unsigned int count=0;
00231 {
00232 auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
00233 for(auto it = m_tokenInfo.begin<kLookupInfo>(),
00234 itEnd = m_tokenInfo.end<kLookupInfo>();
00235 it != itEnd; ++it,++itAlwaysGet) {
00236 if(iBranch==it->m_branchType) {
00237 if (it->m_index != ProductHolderIndexInvalid) {
00238 if(not *itAlwaysGet) {
00239 ++count;
00240 }
00241 }
00242 }
00243 }
00244 }
00245 oIndices.reserve(oIndices.size()+count);
00246 {
00247 auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
00248 for(auto it = m_tokenInfo.begin<kLookupInfo>(),
00249 itEnd = m_tokenInfo.end<kLookupInfo>();
00250 it != itEnd; ++it,++itAlwaysGet) {
00251 if(iBranch==it->m_branchType) {
00252 if (it->m_index != ProductHolderIndexInvalid) {
00253 if(not *itAlwaysGet) {
00254 oIndices.push_back(it->m_index);
00255 }
00256 }
00257 }
00258 }
00259 }
00260 }
00261
00262 void
00263 EDConsumerBase::labelsForToken(EDGetToken iToken, Labels& oLabels) const
00264 {
00265 unsigned int index = iToken.index();
00266 auto labels = m_tokenInfo.get<kLabels>(index);
00267 unsigned int start = labels.m_startOfModuleLabel;
00268 oLabels.module = &(m_tokenLabels[start]);
00269 oLabels.productInstance = oLabels.module+labels.m_deltaToProductInstance;
00270 oLabels.process = oLabels.module+labels.m_deltaToProcessName;
00271 }
00272
00273
00274 void
00275 EDConsumerBase::throwTypeMismatch(edm::TypeID const& iType, EDGetToken iToken) const
00276 {
00277 throw cms::Exception("TypeMismatch")<<"A get using a EDGetToken used the C++ type '"<<iType.className()<<"' but the consumes call was for type '"<<m_tokenInfo.get<kLookupInfo>(iToken.index()).m_type.className()<<"'.\n Please modify either the consumes or get call so the types match.";
00278 }
00279 void
00280 EDConsumerBase::throwBranchMismatch(BranchType iBranch, EDGetToken iToken) const {
00281 throw cms::Exception("BranchTypeMismatch")<<"A get using a EDGetToken was done in "<<BranchTypeToString(iBranch)<<" but the consumes call was for "<<BranchTypeToString(m_tokenInfo.get<kLookupInfo>(iToken.index()).m_branchType)<<".\n Please modify the consumes call to use the correct branch type.";
00282 }
00283
00284 void
00285 EDConsumerBase::throwBadToken(edm::TypeID const& iType, EDGetToken iToken) const
00286 {
00287 if(iToken.isUnitialized()) {
00288 throw cms::Exception("BadToken")<<"A get using a EDGetToken with the C++ type '"<<iType.className()<<"' was made using an uninitialized token.\n Please check that the variable is being initialized from a 'consumes' call.";
00289 }
00290 throw cms::Exception("BadToken")<<"A get using a EDGetToken with the C++ type '"<<iType.className()<<"' was made using a token with a value "<<iToken.index()<<" which is beyond the range used by this module.\n Please check that the variable is being initialized from a 'consumes' call from this module.\n You can not share EDGetToken values between modules.";
00291 }
00292
00293
00294
00295
00296