CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EDConsumerBase.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWCore/Framework
4 // Class : EDConsumerBase
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones
10 // Created: Tue, 02 Apr 2013 21:36:06 GMT
11 // $Id: EDConsumerBase.cc,v 1.6 2013/06/07 17:58:32 chrjones Exp $
12 //
13 
14 // system include files
15 #include <cassert>
16 #include <utility>
17 
18 // user include files
24 
25 using namespace edm;
26 
27 //
28 // constants, enums and typedefs
29 //
30 
31 //
32 // static data member definitions
33 //
34 
35 //
36 // constructors and destructor
37 //
38 //EDConsumerBase::EDConsumerBase()
39 //{
40 //}
41 
42 // EDConsumerBase::EDConsumerBase(const EDConsumerBase& rhs)
43 // {
44 // // do actual copying here;
45 // }
46 
48 {
49 }
50 
51 //
52 // assignment operators
53 //
54 // const EDConsumerBase& EDConsumerBase::operator=(const EDConsumerBase& rhs)
55 // {
56 // //An exception safe implementation is
57 // EDConsumerBase temp(rhs);
58 // swap(rhs);
59 //
60 // return *this;
61 // }
62 
63 //
64 // member functions
65 //
68  ConsumesCollector c{this};
69  return std::move(c);
70 }
71 
72 
73 unsigned int
74 EDConsumerBase::recordConsumes(BranchType iBranch, TypeToGet const& iType, edm::InputTag const& iTag, bool iAlwaysGets) {
75  unsigned int index =m_tokenInfo.size();
76 
77  const size_t labelSize = iTag.label().size();
78  const size_t productInstanceSize = iTag.instance().size();
79  unsigned int labelStart = m_tokenLabels.size();
80  unsigned short delta1 = labelSize+1;
81  unsigned short delta2 = labelSize+2+productInstanceSize;
82  m_tokenInfo.emplace_back(TokenLookupInfo{iType.type(),ProductHolderIndexInvalid,iBranch},
83  iAlwaysGets,
84  LabelPlacement{labelStart,delta1,delta2},
85  iType.kind());
86 
87  bool skipCurrentProcess = iTag.willSkipCurrentProcess();
88 
89  const size_t additionalSize =
90  skipCurrentProcess ?
91  labelSize+productInstanceSize+3 :
92  labelSize+productInstanceSize+iTag.process().size()+3;
93 
94  m_tokenLabels.reserve(m_tokenLabels.size()+additionalSize);
95  {
96  const std::string& m =iTag.label();
97  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
98  m_tokenLabels.push_back('\0');
99  }
100  {
101  const std::string& m =iTag.instance();
102  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
103  m_tokenLabels.push_back('\0');
104  }
105  {
106  if (!skipCurrentProcess) {
107  const std::string& m =iTag.process();
108  m_tokenLabels.insert(m_tokenLabels.end(),m.begin(),m.end());
109  m_tokenLabels.push_back('\0');
110  } else {
111  m_tokenLabels.push_back('\0');
112  }
113  }
114  return index;
115 }
116 
117 void
119  ProductHolderIndexHelper const& iHelper)
120 {
121  {
122  auto itKind = m_tokenInfo.begin<kKind>();
123  auto itLabels = m_tokenInfo.begin<kLabels>();
124  for(auto itInfo = m_tokenInfo.begin<kLookupInfo>(),itEnd = m_tokenInfo.end<kLookupInfo>();
125  itInfo != itEnd; ++itInfo,++itKind,++itLabels) {
126  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
127  const char* moduleLabel = &(m_tokenLabels[labelStart]);
128  itInfo->m_index = iHelper.index(*itKind,
129  itInfo->m_type,
130  moduleLabel,
131  moduleLabel+itLabels->m_deltaToProductInstance,
132  moduleLabel+itLabels->m_deltaToProcessName);
133  }
134  }
135 
136  //now add resolved requests to get many to the end of our list
137  // a get many will have an empty module label
138  for(size_t i=0, iEnd = m_tokenInfo.size(); i!=iEnd;++i) {
139  //need to copy since pointer could be invalidated by emplace_back
140  auto const info = m_tokenInfo.get<kLookupInfo>(i);
141  if(info.m_branchType == iBranchType &&
142  info.m_index == ProductHolderIndexInvalid &&
143  m_tokenLabels[m_tokenInfo.get<kLabels>(i).m_startOfModuleLabel]=='\0') {
144  //find all matching types
145  const auto kind=m_tokenInfo.get<kKind>(i);
146  auto matches = iHelper.relatedIndexes(kind,info.m_type);
147 
148  //NOTE: This could be changed to contain the true labels for what is being
149  // requested but for now I want to remember these are part of a get many
151  bool alwaysGet = m_tokenInfo.get<kAlwaysGets>(i);
152  for(unsigned int j=0;j!=matches.numberOfMatches();++j) {
153  //only keep the ones that are for a specific data item and not a collection
154  if(matches.isFullyResolved(j)) {
155  auto index =matches.index(j);
156  m_tokenInfo.emplace_back(TokenLookupInfo{info.m_type,index,info.m_branchType},
157  alwaysGet,
158  labels,
159  kind);
160  }
161  }
162  }
163  }
164  m_tokenInfo.shrink_to_fit();
165 }
166 
167 
168 //
169 // const member functions
170 //
172 EDConsumerBase::indexFrom(EDGetToken iToken, BranchType iBranch, TypeID const& iType) const
173 {
174  if(unlikely(iToken.index()>=m_tokenInfo.size())) {
175  throwBadToken(iType,iToken);
176  }
177  const auto& info = m_tokenInfo.get<kLookupInfo>(iToken.index());
178  if (likely(iBranch == info.m_branchType)) {
179  if (likely(iType == info.m_type)) {
180  return info.m_index;
181  } else {
182  throwTypeMismatch(iType, iToken);
183  }
184  } else {
185  throwBranchMismatch(iBranch,iToken);
186  }
188 }
189 
190 void
191 EDConsumerBase::itemsToGet(BranchType iBranch, std::vector<ProductHolderIndex>& oIndices) const
192 {
193  //how many are we adding?
194  unsigned int count=0;
195  {
196  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
197  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
198  itEnd = m_tokenInfo.end<kLookupInfo>();
199  it != itEnd; ++it,++itAlwaysGet) {
200  if(iBranch==it->m_branchType) {
201  if (it->m_index != ProductHolderIndexInvalid) {
202  if(*itAlwaysGet) {
203  ++count;
204  }
205  }
206  }
207  }
208  }
209  oIndices.reserve(oIndices.size()+count);
210  {
211  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
212  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
213  itEnd = m_tokenInfo.end<kLookupInfo>();
214  it != itEnd; ++it,++itAlwaysGet) {
215  if(iBranch==it->m_branchType) {
216  if (it->m_index != ProductHolderIndexInvalid) {
217  if(*itAlwaysGet) {
218  oIndices.push_back(it->m_index);
219  }
220  }
221  }
222  }
223  }
224 }
225 
226 void
227 EDConsumerBase::itemsMayGet(BranchType iBranch, std::vector<ProductHolderIndex>& oIndices) const
228 {
229  //how many are we adding?
230  unsigned int count=0;
231  {
232  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
233  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
234  itEnd = m_tokenInfo.end<kLookupInfo>();
235  it != itEnd; ++it,++itAlwaysGet) {
236  if(iBranch==it->m_branchType) {
237  if (it->m_index != ProductHolderIndexInvalid) {
238  if(not *itAlwaysGet) {
239  ++count;
240  }
241  }
242  }
243  }
244  }
245  oIndices.reserve(oIndices.size()+count);
246  {
247  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
248  for(auto it = m_tokenInfo.begin<kLookupInfo>(),
249  itEnd = m_tokenInfo.end<kLookupInfo>();
250  it != itEnd; ++it,++itAlwaysGet) {
251  if(iBranch==it->m_branchType) {
252  if (it->m_index != ProductHolderIndexInvalid) {
253  if(not *itAlwaysGet) {
254  oIndices.push_back(it->m_index);
255  }
256  }
257  }
258  }
259  }
260 }
261 
262 void
264 {
265  unsigned int index = iToken.index();
266  auto labels = m_tokenInfo.get<kLabels>(index);
267  unsigned int start = labels.m_startOfModuleLabel;
268  oLabels.module = &(m_tokenLabels[start]);
269  oLabels.productInstance = oLabels.module+labels.m_deltaToProductInstance;
270  oLabels.process = oLabels.module+labels.m_deltaToProcessName;
271 }
272 
273 
274 void
276 {
277  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.";
278 }
279 void
281  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.";
282 }
283 
284 void
286 {
287  if(iToken.isUnitialized()) {
288  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.";
289  }
290  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.";
291 }
292 
293 
294 //
295 // static member functions
296 //
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
int i
Definition: DBlmapReader.cc:9
void itemsMayGet(BranchType, std::vector< ProductHolderIndex > &) const
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
KindOfType kind() const
Definition: TypeToGet.h:46
ProductHolderIndex indexFrom(EDGetToken, BranchType, TypeID const &) const
void updateLookup(BranchType iBranchType, ProductHolderIndexHelper const &)
ProductHolderIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
void throwTypeMismatch(edm::TypeID const &, EDGetToken) const
void itemsToGet(BranchType, std::vector< ProductHolderIndex > &) const
void throwBadToken(edm::TypeID const &iType, EDGetToken iToken) const
unsigned int ProductHolderIndex
edm::SoATuple< TokenLookupInfo, bool, LabelPlacement, edm::KindOfType > m_tokenInfo
BranchType
Definition: BranchType.h:11
unsigned int recordConsumes(BranchType iBranch, TypeToGet const &iType, edm::InputTag const &iTag, bool iAlwaysGets)
#define unlikely(x)
Definition: Likely.h:21
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
int j
Definition: DBlmapReader.cc:9
void throwBranchMismatch(BranchType, EDGetToken) const
std::vector< char > m_tokenLabels
bool willSkipCurrentProcess() const
Definition: InputTag.h:48
std::string const & BranchTypeToString(BranchType const &branchType)
Definition: BranchType.cc:98
bool isUnitialized() const
Definition: EDGetToken.h:49
void labelsForToken(EDGetToken iToken, Labels &oLabels) const
std::string const & label() const
Definition: InputTag.h:42
std::string const & process() const
Definition: InputTag.h:46
#define likely(x)
Definition: Likely.h:20
TypeID const & type() const
Definition: TypeToGet.h:45
std::string const & className() const
Definition: TypeID.cc:40
std::string const & instance() const
Definition: InputTag.h:43
unsigned int index() const
Definition: EDGetToken.h:47