CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules 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 //
12 
13 // system include files
14 #include <array>
15 #include <algorithm>
16 #include <cassert>
17 #include <cstring>
18 #include <set>
19 #include <utility>
20 
21 // user include files
33 
34 using namespace edm;
35 
36 namespace {
37  std::vector<char> makeEmptyTokenLabels() { return std::vector<char>{'\0'}; }
38 } // namespace
39 
41  : m_tokenLabels{makeEmptyTokenLabels()}, frozen_(false), containsCurrentProcessAlias_(false) {}
42 
44 
45 //
46 // member functions
47 //
49  ConsumesCollector c{this};
50  return c;
51 }
52 
53 static const edm::InputTag kWasEmpty("@EmptyLabel@");
54 
56  if (iTag.label().empty()) {
57  return kWasEmpty;
58  }
59  return iTag;
60 }
61 
63  TypeToGet const& iType,
64  edm::InputTag const& iTag,
65  bool iAlwaysGets) {
66  if (frozen_) {
67  throwConsumesCallAfterFrozen(iType, iTag);
68  }
69 
70  unsigned int index = m_tokenInfo.size();
71 
72  bool skipCurrentProcess = iTag.willSkipCurrentProcess();
73 
74  const size_t labelSize = iTag.label().size();
75  const size_t productInstanceSize = iTag.instance().size();
76  unsigned int labelStart = m_tokenLabels.size();
77  unsigned short delta1 = labelSize + 1;
78  unsigned short delta2 = labelSize + 2 + productInstanceSize;
79  m_tokenInfo.emplace_back(TokenLookupInfo{iType.type(), ProductResolverIndexInvalid, skipCurrentProcess, iBranch},
80  iAlwaysGets,
81  LabelPlacement{labelStart, delta1, delta2},
82  iType.kind());
83 
84  const size_t additionalSize = skipCurrentProcess ? labelSize + productInstanceSize + 3
85  : labelSize + productInstanceSize + iTag.process().size() + 3;
86 
87  m_tokenLabels.reserve(m_tokenLabels.size() + additionalSize);
88  {
89  const std::string& m = iTag.label();
90  m_tokenLabels.insert(m_tokenLabels.end(), m.begin(), m.end());
91  m_tokenLabels.push_back('\0');
92  }
93  {
94  const std::string& m = iTag.instance();
95  m_tokenLabels.insert(m_tokenLabels.end(), m.begin(), m.end());
96  m_tokenLabels.push_back('\0');
97  }
98  {
99  const std::string& m = iTag.process();
100  if (m == InputTag::kCurrentProcess) {
102  }
103  if (!skipCurrentProcess) {
104  m_tokenLabels.insert(m_tokenLabels.end(), m.begin(), m.end());
105  m_tokenLabels.push_back('\0');
106  } else {
107  m_tokenLabels.push_back('\0');
108  }
109  }
110  return index;
111 }
112 
114  ProductResolverIndexHelper const& iHelper,
115  bool iPrefetchMayGet) {
116  frozen_ = true;
118  {
119  auto itKind = m_tokenInfo.begin<kKind>();
120  auto itLabels = m_tokenInfo.begin<kLabels>();
121  for (auto itInfo = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); itInfo != itEnd;
122  ++itInfo, ++itKind, ++itLabels) {
123  if (itInfo->m_branchType == iBranchType) {
124  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
125  const char* moduleLabel = &(m_tokenLabels[labelStart]);
126  itInfo->m_index = ProductResolverIndexAndSkipBit(iHelper.index(*itKind,
127  itInfo->m_type,
128  moduleLabel,
129  moduleLabel + itLabels->m_deltaToProductInstance,
130  moduleLabel + itLabels->m_deltaToProcessName),
131  itInfo->m_index.skipCurrentProcess());
132  }
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 && info.m_index.productResolverIndex() == ProductResolverIndexInvalid &&
142  m_tokenLabels[m_tokenInfo.get<kLabels>(i).m_startOfModuleLabel] == '\0') {
143  //find all matching types
144  const auto kind = m_tokenInfo.get<kKind>(i);
145  auto matches = iHelper.relatedIndexes(kind, info.m_type);
146 
147  //NOTE: This could be changed to contain the true labels for what is being
148  // requested but for now I want to remember these are part of a get many
149  const LabelPlacement labels = m_tokenInfo.get<kLabels>(i);
150  bool alwaysGet = m_tokenInfo.get<kAlwaysGets>(i);
151  for (unsigned int j = 0; j != matches.numberOfMatches(); ++j) {
152  //only keep the ones that are for a specific data item and not a collection
153  if (matches.isFullyResolved(j)) {
154  auto index = matches.index(j);
155  m_tokenInfo.emplace_back(
156  TokenLookupInfo{info.m_type, index, info.m_index.skipCurrentProcess(), info.m_branchType},
157  alwaysGet,
158  labels,
159  kind);
160  }
161  }
162  }
163  }
164  m_tokenInfo.shrink_to_fit();
165 
166  itemsToGet(iBranchType, itemsToGetFromBranch_[iBranchType]);
167  if (iPrefetchMayGet) {
168  itemsMayGet(iBranchType, itemsToGetFromBranch_[iBranchType]);
169  }
170 }
171 
173  // temporarily unfreeze to allow late EventSetup consumes registration
174  frozen_ = false;
176  frozen_ = true;
177 
178  unsigned int index = 0;
179  for (auto it = m_esTokenInfo.begin<kESLookupInfo>(); it != m_esTokenInfo.end<kESLookupInfo>(); ++it, ++index) {
180  auto indexInRecord = iPI.indexInRecord(it->m_record, it->m_key);
182  const char* componentName = &(m_tokenLabels[it->m_startOfComponentName]);
183  if (*componentName) {
184  auto component = iPI.component(it->m_record, it->m_key);
185  if (component->label_.empty()) {
186  if (component->type_ != componentName) {
188  }
189  } else if (component->label_ != componentName) {
191  }
192  }
193  }
194  m_esTokenInfo.get<kESProxyIndex>(index) = indexInRecord;
195 
196  int negIndex = -1 * (index + 1);
197  for (auto& items : esItemsToGetFromTransition_) {
198  for (auto& itemIndex : items) {
199  if (itemIndex.value() == negIndex) {
200  itemIndex = indexInRecord;
201  esRecordsToGetFromTransition_[&items - &esItemsToGetFromTransition_.front()][&itemIndex - &items.front()] =
202  iPI.recordIndexFor(it->m_record);
203  negIndex = 1;
204  break;
205  }
206  }
207  if (negIndex > 0) {
208  break;
209  }
210  }
211  }
212 }
213 
215  eventsetup::EventSetupRecordKey const& iRecord,
217  edm::ESInputTag const& iTag) {
218  if (frozen_) {
219  throwESConsumesCallAfterFrozen(iRecord, iDataType, iTag);
220  }
221 
222  //m_tokenLabels first entry is a null. Since most ES data requests have
223  // empty labels we will assume we can reuse the first entry
224  unsigned int startOfComponentName = 0;
225  if (not iTag.module().empty()) {
226  startOfComponentName = m_tokenLabels.size();
227 
228  m_tokenLabels.reserve(m_tokenLabels.size() + iTag.module().size() + 1);
229  {
230  const std::string& m = iTag.module();
231  m_tokenLabels.insert(m_tokenLabels.end(), m.begin(), m.end());
232  m_tokenLabels.push_back('\0');
233  }
234  }
235 
236  auto index = static_cast<ESProxyIndex::Value_t>(m_esTokenInfo.size());
237  m_esTokenInfo.emplace_back(
238  ESTokenLookupInfo{iRecord, eventsetup::DataKey{iDataType, iTag.data().c_str()}, startOfComponentName},
239  ESProxyIndex{-1});
242  }
243  auto indexForToken = esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)].size();
244  esItemsToGetFromTransition_[static_cast<unsigned int>(iTrans)].emplace_back(-1 * (index + 1));
245  esRecordsToGetFromTransition_[static_cast<unsigned int>(iTrans)].emplace_back();
246  return ESTokenIndex{static_cast<ESTokenIndex::Value_t>(indexForToken)};
247 }
248 
249 //
250 // const member functions
251 //
253  BranchType iBranch,
254  TypeID const& iType) const {
255  if (UNLIKELY(iToken.index() >= m_tokenInfo.size())) {
256  throwBadToken(iType, iToken);
257  }
258  const auto& info = m_tokenInfo.get<kLookupInfo>(iToken.index());
259  if (LIKELY(iBranch == info.m_branchType)) {
260  if (LIKELY(iType == info.m_type)) {
261  return info.m_index;
262  } else {
263  throwTypeMismatch(iType, iToken);
264  }
265  } else {
266  throwBranchMismatch(iBranch, iToken);
267  }
269 }
270 
272  return m_tokenInfo.get<kLookupInfo>(iToken.index()).m_index;
273 }
274 
275 void EDConsumerBase::itemsToGet(BranchType iBranch, std::vector<ProductResolverIndexAndSkipBit>& oIndices) const {
276  //how many are we adding?
277  unsigned int count = 0;
278  {
279  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
280  for (auto it = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd;
281  ++it, ++itAlwaysGet) {
282  if (iBranch == it->m_branchType) {
283  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
284  if (*itAlwaysGet) {
285  ++count;
286  }
287  }
288  }
289  }
290  }
291  oIndices.reserve(oIndices.size() + count);
292  {
293  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
294  for (auto it = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd;
295  ++it, ++itAlwaysGet) {
296  if (iBranch == it->m_branchType) {
297  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
298  if (*itAlwaysGet) {
299  oIndices.push_back(it->m_index);
300  }
301  }
302  }
303  }
304  }
305 }
306 
307 void EDConsumerBase::itemsMayGet(BranchType iBranch, std::vector<ProductResolverIndexAndSkipBit>& oIndices) const {
308  //how many are we adding?
309  unsigned int count = 0;
310  {
311  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
312  for (auto it = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd;
313  ++it, ++itAlwaysGet) {
314  if (iBranch == it->m_branchType) {
315  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
316  if (not *itAlwaysGet) {
317  ++count;
318  }
319  }
320  }
321  }
322  }
323  oIndices.reserve(oIndices.size() + count);
324  {
325  auto itAlwaysGet = m_tokenInfo.begin<kAlwaysGets>();
326  for (auto it = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd;
327  ++it, ++itAlwaysGet) {
328  if (iBranch == it->m_branchType) {
329  if (it->m_index.productResolverIndex() != ProductResolverIndexInvalid) {
330  if (not *itAlwaysGet) {
331  oIndices.push_back(it->m_index);
332  }
333  }
334  }
335  }
336  }
337 }
338 
339 void EDConsumerBase::labelsForToken(EDGetToken iToken, Labels& oLabels) const {
340  unsigned int index = iToken.index();
341  auto labels = m_tokenInfo.get<kLabels>(index);
342  unsigned int start = labels.m_startOfModuleLabel;
343  oLabels.module = &(m_tokenLabels[start]);
344  oLabels.productInstance = oLabels.module + labels.m_deltaToProductInstance;
345  oLabels.process = oLabels.module + labels.m_deltaToProcessName;
346 }
347 
349  bool skipCurrentProcess,
350  BranchType iBranch) const {
351  for (auto it = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd; ++it) {
352  if (it->m_index.productResolverIndex() == iIndex and it->m_index.skipCurrentProcess() == skipCurrentProcess and
353  it->m_branchType == iBranch) {
354  return true;
355  }
356  }
357  return false;
358 }
359 
360 bool EDConsumerBase::registeredToConsumeMany(TypeID const& iType, BranchType iBranch) const {
361  for (auto it = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); it != itEnd; ++it) {
362  //consumesMany entries do not have their index resolved
363  if (it->m_index.productResolverIndex() == ProductResolverIndexInvalid and it->m_type == iType and
364  it->m_branchType == iBranch) {
365  return true;
366  }
367  }
368  return false;
369 }
370 
371 void EDConsumerBase::throwTypeMismatch(edm::TypeID const& iType, EDGetToken iToken) const {
372  throw cms::Exception("TypeMismatch") << "A get using a EDGetToken used the C++ type '" << iType.className()
373  << "' but the consumes call was for type '"
374  << m_tokenInfo.get<kLookupInfo>(iToken.index()).m_type.className()
375  << "'.\n Please modify either the consumes or get call so the types match.";
376 }
378  throw cms::Exception("BranchTypeMismatch")
379  << "A get using a EDGetToken was done in " << BranchTypeToString(iBranch) << " but the consumes call was for "
380  << BranchTypeToString(m_tokenInfo.get<kLookupInfo>(iToken.index()).m_branchType)
381  << ".\n Please modify the consumes call to use the correct branch type.";
382 }
383 
384 void EDConsumerBase::throwBadToken(edm::TypeID const& iType, EDGetToken iToken) const {
385  if (iToken.isUninitialized()) {
386  throw cms::Exception("BadToken") << "A get using a EDGetToken with the C++ type '" << iType.className()
387  << "' was made using an uninitialized token.\n Please check that the variable is "
388  "being initialized from a 'consumes' call.";
389  }
390  throw cms::Exception("BadToken")
391  << "A get using a EDGetToken with the C++ type '" << iType.className() << "' was made using a token with a value "
392  << iToken.index()
393  << " which is beyond the range used by this module.\n Please check that the variable is being initialized from a "
394  "'consumes' call from this module.\n You can not share EDGetToken values between modules.";
395 }
396 
398  throw cms::Exception("LogicError") << "A module declared it consumes a product after its constructor.\n"
399  << "This must be done in the contructor\n"
400  << "The product type was: " << typeToGet.type() << "\n"
401  << "and " << inputTag << "\n";
402 }
403 
406  edm::ESInputTag const& iTag) const {
407  throw cms::Exception("LogicError") << "A module declared it consumes an EventSetup product after its constructor.\n"
408  << "This must be done in the contructor\n"
409  << "The product type was: " << iDataType.name() << " in record "
410  << iRecord.type().name() << "\n"
411  << "and ESInputTag was " << iTag << "\n";
412 }
413 
415  throw cms::Exception("LogicError")
416  << "A module declared it consumes an EventSetup product during a ProcessBlock transition.\n"
417  << "EventSetup products can only be consumed in Event, Lumi, or Run transitions.\n";
418 }
419 
421 
422 namespace {
423  struct CharStarComp {
424  bool operator()(const char* iLHS, const char* iRHS) const { return strcmp(iLHS, iRHS) < 0; }
425  };
426 } // namespace
427 
428 namespace {
429  void insertFoundModuleLabel(edm::KindOfType consumedTypeKind,
430  edm::TypeID consumedType,
431  const char* consumedModuleLabel,
432  const char* consumedProductInstance,
433  std::vector<ModuleDescription const*>& modules,
434  std::set<std::string>& alreadyFound,
435  std::map<std::string, ModuleDescription const*> const& labelsToDesc,
436  ProductRegistry const& preg) {
437  // Convert from label string to module description, eliminate duplicates,
438  // then insert into the vector of modules
439  if (auto it = labelsToDesc.find(consumedModuleLabel); it != labelsToDesc.end()) {
440  if (alreadyFound.insert(consumedModuleLabel).second) {
441  modules.push_back(it->second);
442  }
443  return;
444  }
445  // Deal with EDAlias's by converting to the original module label first
446  if (auto aliasToModuleLabels =
447  preg.aliasToModules(consumedTypeKind, consumedType, consumedModuleLabel, consumedProductInstance);
448  not aliasToModuleLabels.empty()) {
449  bool foundInLabelsToDesc = false;
450  for (auto const& label : aliasToModuleLabels) {
451  if (auto it = labelsToDesc.find(label); it != labelsToDesc.end()) {
452  if (alreadyFound.insert(label).second) {
453  modules.push_back(it->second);
454  }
455  foundInLabelsToDesc = true;
456  } else {
457  if (label == "source") {
458  foundInLabelsToDesc = true;
459  }
460  }
461  }
462  if (foundInLabelsToDesc) {
463  return;
464  }
465  }
466  // Ignore the source products, we are only interested in module products.
467  // As far as I know, it should never be anything else so throw if something
468  // unknown gets passed in.
469  if (std::string_view(consumedModuleLabel) != "source") {
470  throw cms::Exception("EDConsumerBase", "insertFoundModuleLabel")
471  << "Couldn't find ModuleDescription for the consumed product type: '" << consumedType.className()
472  << "' module label: '" << consumedModuleLabel << "' product instance name: '" << consumedProductInstance
473  << "'";
474  }
475  }
476 } // namespace
477 
479  std::array<std::vector<ModuleDescription const*>*, NumBranchTypes>& modulesAll,
480  std::vector<ModuleProcessName>& modulesInPreviousProcesses,
481  ProductRegistry const& preg,
482  std::map<std::string, ModuleDescription const*> const& labelsToDesc,
483  std::string const& processName) const {
484  std::set<std::string> alreadyFound;
485 
486  auto modulesInPreviousProcessesEmplace = [&modulesInPreviousProcesses](std::string_view module,
487  std::string_view process) {
488  auto it = std::lower_bound(
489  modulesInPreviousProcesses.begin(), modulesInPreviousProcesses.end(), ModuleProcessName(module, process));
490  modulesInPreviousProcesses.emplace(it, module, process);
491  };
492 
493  auto itKind = m_tokenInfo.begin<kKind>();
494  auto itLabels = m_tokenInfo.begin<kLabels>();
495  for (auto itInfo = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); itInfo != itEnd;
496  ++itInfo, ++itKind, ++itLabels) {
497  ProductResolverIndexHelper const& helper = *preg.productLookup(itInfo->m_branchType);
498  std::vector<ModuleDescription const*>& modules = *modulesAll[itInfo->m_branchType];
499 
500  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
501  const char* const consumedModuleLabel = &(m_tokenLabels[labelStart]);
502  const char* const consumedProductInstance = consumedModuleLabel + itLabels->m_deltaToProductInstance;
503  const char* const consumedProcessName = consumedModuleLabel + itLabels->m_deltaToProcessName;
504 
505  if (not itInfo->m_index.skipCurrentProcess()) {
506  if (*consumedModuleLabel != '\0') { // not a consumesMany
507  if (*consumedProcessName != '\0') { // process name is specified in consumes call
508  if (helper.index(
509  *itKind, itInfo->m_type, consumedModuleLabel, consumedProductInstance, consumedProcessName) !=
511  if (processName == consumedProcessName) {
512  insertFoundModuleLabel(*itKind,
513  itInfo->m_type,
514  consumedModuleLabel,
515  consumedProductInstance,
516  modules,
517  alreadyFound,
518  labelsToDesc,
519  preg);
520  } else {
521  // Product explicitly from different process than the current process, so must refer to an earlier process (unless it ends up "not found")
522  modulesInPreviousProcessesEmplace(consumedModuleLabel, consumedProcessName);
523  }
524  }
525  } else { // process name was empty
526  auto matches = helper.relatedIndexes(*itKind, itInfo->m_type, consumedModuleLabel, consumedProductInstance);
527  for (unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
528  if (processName == matches.processName(j)) {
529  insertFoundModuleLabel(*itKind,
530  itInfo->m_type,
531  consumedModuleLabel,
532  consumedProductInstance,
533  modules,
534  alreadyFound,
535  labelsToDesc,
536  preg);
537  } else {
538  // Product did not match to current process, so must refer to an earlier process (unless it ends up "not found")
539  // Recall that empty process name means "in the latest process" that can change event-by-event
540  modulesInPreviousProcessesEmplace(consumedModuleLabel, matches.processName(j));
541  }
542  }
543  }
544  // consumesMany case
545  } else if (itInfo->m_index.productResolverIndex() == ProductResolverIndexInvalid) {
546  auto matches = helper.relatedIndexes(*itKind, itInfo->m_type);
547  for (unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
548  if (processName == matches.processName(j)) {
549  insertFoundModuleLabel(*itKind,
550  itInfo->m_type,
551  matches.moduleLabel(j),
552  matches.productInstanceName(j),
553  modules,
554  alreadyFound,
555  labelsToDesc,
556  preg);
557  } else {
558  modulesInPreviousProcessesEmplace(matches.moduleLabel(j), matches.processName(j));
559  }
560  }
561  }
562  } else {
563  // The skipCurrentProcess means the same as empty process name,
564  // except the current process is skipped. Therefore need to do
565  // the same matching as above. There is no consumesMany branch
566  // in this case.
567  auto matches = helper.relatedIndexes(*itKind, itInfo->m_type, consumedModuleLabel, consumedProductInstance);
568  for (unsigned int j = 0; j < matches.numberOfMatches(); ++j) {
569  if (processName != matches.processName(j)) {
570  modulesInPreviousProcessesEmplace(matches.moduleLabel(j), matches.processName(j));
571  }
572  }
573  }
574  }
575 }
576 
578  frozen_ = true;
579 
582 
583  auto newTokenLabels = makeEmptyTokenLabels();
584 
585  // first calculate the size of the new vector and reserve memory for it
586  std::vector<char>::size_type newSize = newTokenLabels.size();
587  std::string newProcessName;
588  for (auto iter = m_tokenInfo.begin<kLabels>(), itEnd = m_tokenInfo.end<kLabels>(); iter != itEnd; ++iter) {
589  newProcessName = &m_tokenLabels[iter->m_startOfModuleLabel + iter->m_deltaToProcessName];
590  if (newProcessName == InputTag::kCurrentProcess) {
591  newProcessName = processName;
592  }
593  newSize += (iter->m_deltaToProcessName + newProcessName.size() + 1);
594  }
595  newTokenLabels.reserve(newSize);
596 
597  unsigned int newStartOfModuleLabel = newTokenLabels.size();
598  for (auto iter = m_tokenInfo.begin<kLabels>(), itEnd = m_tokenInfo.end<kLabels>(); iter != itEnd; ++iter) {
599  unsigned int startOfModuleLabel = iter->m_startOfModuleLabel;
600  unsigned short deltaToProcessName = iter->m_deltaToProcessName;
601 
602  iter->m_startOfModuleLabel = newStartOfModuleLabel;
603 
604  newProcessName = &m_tokenLabels[startOfModuleLabel + deltaToProcessName];
605  if (newProcessName == InputTag::kCurrentProcess) {
606  newProcessName = processName;
607  }
608 
609  newStartOfModuleLabel += (deltaToProcessName + newProcessName.size() + 1);
610 
611  // Copy in both the module label and instance, they are the same
612  newTokenLabels.insert(newTokenLabels.end(),
613  m_tokenLabels.begin() + startOfModuleLabel,
614  m_tokenLabels.begin() + (startOfModuleLabel + deltaToProcessName));
615 
616  newTokenLabels.insert(newTokenLabels.end(), newProcessName.begin(), newProcessName.end());
617  newTokenLabels.push_back('\0');
618  }
619  m_tokenLabels = std::move(newTokenLabels);
620  }
621 }
622 
623 std::vector<ConsumesInfo> EDConsumerBase::consumesInfo() const {
624  // Use this to eliminate duplicate entries related
625  // to consumesMany items where only the type was specified
626  // and the there are multiple matches. In these cases the
627  // label, instance, and process will be empty.
628  std::set<edm::TypeID> alreadySeenTypes;
629 
630  std::vector<ConsumesInfo> result;
631  auto itAlways = m_tokenInfo.begin<kAlwaysGets>();
632  auto itKind = m_tokenInfo.begin<kKind>();
633  auto itLabels = m_tokenInfo.begin<kLabels>();
634  for (auto itInfo = m_tokenInfo.begin<kLookupInfo>(), itEnd = m_tokenInfo.end<kLookupInfo>(); itInfo != itEnd;
635  ++itInfo, ++itKind, ++itLabels, ++itAlways) {
636  const unsigned int labelStart = itLabels->m_startOfModuleLabel;
637  const char* consumedModuleLabel = &(m_tokenLabels[labelStart]);
638  const char* consumedInstance = consumedModuleLabel + itLabels->m_deltaToProductInstance;
639  const char* consumedProcessName = consumedModuleLabel + itLabels->m_deltaToProcessName;
640 
641  // consumesMany case
642  if (*consumedModuleLabel == '\0') {
643  if (!alreadySeenTypes.insert(itInfo->m_type).second) {
644  continue;
645  }
646  }
647 
648  // Just copy the information into the ConsumesInfo data structure
649  result.emplace_back(itInfo->m_type,
650  consumedModuleLabel,
651  consumedInstance,
652  consumedProcessName,
653  itInfo->m_branchType,
654  *itKind,
655  *itAlways,
656  itInfo->m_index.skipCurrentProcess());
657  }
658  return result;
659 }
660 
661 const char* EDConsumerBase::labelFor(ESTokenIndex iIndex) const {
662  return m_esTokenInfo.get<kESLookupInfo>(iIndex.value()).m_key.name().value();
663 }
size
Write out results.
edm::SoATuple< TokenLookupInfo, bool, LabelPlacement, edm::KindOfType > m_tokenInfo
Definition: start.py:1
ProductResolverIndexAndSkipBit uncheckedIndexFrom(EDGetToken) const
TypeID const & type() const
Definition: TypeToGet.h:42
static const TGPicture * info(bool iBackgroundIsBlack)
const char * labelFor(ESTokenIndex) const
constexpr unsigned int index() const noexcept
Definition: EDGetToken.h:50
Definition: helper.py:1
unsigned int ProductResolverIndex
virtual void doSelectInputProcessBlocks(ProductRegistry const &, ProcessBlockHelperBase const &)
std::string const & instance() const
Definition: InputTag.h:37
void updateLookup(BranchType iBranchType, ProductResolverIndexHelper const &, bool iPrefetchMayGet)
void throwESConsumesInProcessBlock() const
std::vector< std::string > aliasToModules(KindOfType kindOfType, TypeID const &type, std::string_view moduleLabel, std::string_view productInstanceName) const
constexpr Value_t value() const noexcept
Definition: ESIndices.h:70
void throwTypeMismatch(edm::TypeID const &, EDGetToken) const
void itemsToGet(BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
ProductResolverIndexAndSkipBit indexFrom(EDGetToken, BranchType, TypeID const &) const
#define LIKELY(x)
Definition: Likely.h:20
void modulesWhoseProductsAreConsumed(std::array< std::vector< ModuleDescription const *> *, NumBranchTypes > &modulesAll, std::vector< ModuleProcessName > &modulesInPreviousProcesses, ProductRegistry const &preg, std::map< std::string, ModuleDescription const *> const &labelsToDesc, std::string const &processName) const
std::string const & label() const
Definition: InputTag.h:36
KindOfType kind() const
Definition: TypeToGet.h:43
assert(be >=bs)
uint16_t size_type
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
const std::string & data() const
Definition: ESInputTag.h:104
BranchType
Definition: BranchType.h:11
char const * process
Definition: ProductLabels.h:7
unsigned int recordConsumes(BranchType iBranch, TypeToGet const &iType, edm::InputTag const &iTag, bool iAlwaysGets)
ESRecordIndex recordIndexFor(EventSetupRecordKey const &iRK) const noexcept
std::array< std::vector< ESProxyIndex >, static_cast< unsigned int >edm::Transition::NumberOfEventSetupTransitions)> esItemsToGetFromTransition_
char const * label
ESProxyIndex indexInRecord(EventSetupRecordKey const &iRK, DataKey const &iDK) const noexcept
If the index is not found, returns missingProxyIndex()
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
ProductResolverIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=nullptr) const
std::string const & BranchTypeToString(BranchType const &branchType)
Definition: BranchType.cc:93
Transition
Definition: Transition.h:12
static const std::string kCurrentProcess
Definition: InputTag.h:54
virtual void registerLateConsumes(eventsetup::ESRecordsToProxyIndices const &)
void throwESConsumesCallAfterFrozen(eventsetup::EventSetupRecordKey const &, eventsetup::heterocontainer::HCTypeTag const &, edm::ESInputTag const &) const
std::vector< ConsumesInfo > consumesInfo() const
char const * module
Definition: ProductLabels.h:5
std::array< std::vector< ESRecordIndex >, static_cast< unsigned int >edm::Transition::NumberOfEventSetupTransitions)> esRecordsToGetFromTransition_
static constexpr ESProxyIndex missingProxyIndex() noexcept
bool registeredToConsume(ProductResolverIndex, bool, BranchType) const
ComponentDescription const * component(EventSetupRecordKey const &iRK, DataKey const &iDK) const noexcept
std::vector< char > m_tokenLabels
std::string const & className() const
Definition: TypeID.cc:40
static const edm::InputTag kWasEmpty("@EmptyLabel@")
void throwBadToken(edm::TypeID const &iType, EDGetToken iToken) const
std::shared_ptr< ProductResolverIndexHelper const > productLookup(BranchType branchType) const
edm::SoATuple< ESTokenLookupInfo, ESProxyIndex > m_esTokenInfo
void itemsMayGet(BranchType, std::vector< ProductResolverIndexAndSkipBit > &) const
bool registeredToConsumeMany(TypeID const &, BranchType) const
void throwConsumesCallAfterFrozen(TypeToGet const &, InputTag const &) const
char const * productInstance
Definition: ProductLabels.h:6
HLT enums.
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
ESTokenIndex recordESConsumes(Transition, eventsetup::EventSetupRecordKey const &, eventsetup::heterocontainer::HCTypeTag const &, edm::ESInputTag const &iTag)
edm::InputTag const & checkIfEmpty(edm::InputTag const &tag)
virtual ~EDConsumerBase() noexcept(false)
const std::string & module() const
Definition: ESInputTag.h:99
#define UNLIKELY(x)
Definition: Likely.h:21
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:51
std::string const & process() const
Definition: InputTag.h:40
void convertCurrentProcessAlias(std::string const &processName)
Convert "@currentProcess" in InputTag process names to the actual current process name...
void throwBranchMismatch(BranchType, EDGetToken) const
def move(src, dest)
Definition: eostools.py:511
std::array< std::vector< ProductResolverIndexAndSkipBit >, edm::NumBranchTypes > itemsToGetFromBranch_
void labelsForToken(EDGetToken iToken, Labels &oLabels) const