CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Principal.cc
Go to the documentation of this file.
1 
5 
20 
22 
23 #include "TClass.h"
24 
25 #include <algorithm>
26 #include <cstring>
27 #include <limits>
28 #include <sstream>
29 #include <stdexcept>
30 #include <typeinfo>
31 #include <atomic>
32 
33 namespace edm {
34 
36 
37  static
38  void
39  maybeThrowMissingDictionaryException(TypeID const& productType, bool isElement, std::vector<TypeID> const& missingDictionaries) {
40  if(isElement) {
41  if(binary_search_all(missingDictionaries, productType)) {
42  checkTypeDictionary(productType);
44  }
45  } else {
46  TClass* cl = TClass::GetClass(wrappedClassName(productType.className()).c_str());
47  TypeID wrappedProductType = TypeID(cl->GetTypeInfo());
48  if(binary_search_all(missingDictionaries, wrappedProductType)) {
49  checkClassDictionary(wrappedProductType);
51  }
52  }
53  }
54 
55  static
56  void
58  throw Exception(error, "InvalidID")
59  << "Principal::" << where << ": no product with given branch id: "<< bid << "\n";
60  }
61 
62  static
63  void
64  throwCorruptionException(char const* where, std::string const& branchName) {
66  << "Principal::" << where <<": Product on branch " << branchName << " occurs twice in the same event.\n";
67  }
68 
69  static
70  std::shared_ptr<cms::Exception>
71  makeNotFoundException(char const* where, KindOfType kindOfType,
72  TypeID const& productType, std::string const& label, std::string const& instance, std::string const& process) {
73  std::shared_ptr<cms::Exception> exception = std::make_shared<Exception>(errors::ProductNotFound);
74  if (kindOfType == PRODUCT_TYPE) {
75  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
76  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
77  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
78  } else {
79  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for a container with elements of type: " << productType << "\n"
80  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
81  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
82  }
83  return exception;
84  }
85 
86  static
87  void
88  throwProductDeletedException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
90  exception << "Principal::" << where << ": The product matching all criteria\nLooking for type: " << productType << "\n"
91  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
92  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
93  << "Was already deleted. This means there is a configuration error.\n"
94  << "The module which is asking for this data must be configured to state that it will read this data.";
95  throw exception;
96  }
97 
98  static
99  void
100  throwAmbiguousException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
101  cms::Exception exception("AmbiguousProduct");
102  exception << "Principal::" << where << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
103  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
104  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
105  << "This can only occur with get function calls using a Handle<View> argument.\n"
106  << "Try a get not using a View or change the instance name of one of the products";
107  throw exception;
108 
109  }
110 
111  namespace {
112  void failedToRegisterConsumesMany(edm::TypeID const& iType) {
113  cms::Exception exception("GetManyWithoutRegistration");
114  exception << "::getManyByType called for " << iType
115  << " without a corresponding consumesMany being called for this module. \n";
116  throw exception;
117  }
118 
119  void failedToRegisterConsumes(KindOfType kindOfType,
120  TypeID const& productType,
121  std::string const& moduleLabel,
122  std::string const& productInstanceName,
123  std::string const& processName) {
124  cms::Exception exception("GetByLabelWithoutRegistration");
125  exception << "::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
126  << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<") << productType
127  << (kindOfType == PRODUCT_TYPE ? "\n module label: " : ">\n module label: ") << moduleLabel
128  <<"\n product instance name: '" << productInstanceName
129  <<"'\n process name: '" << processName << "'\n";
130  throw exception;
131  }
132 }
133 
134  //0 means unset
135  static std::atomic<Principal::CacheIdentifier_t> s_nextIdentifier{1};
137  return s_nextIdentifier.fetch_add(1,std::memory_order_acq_rel);
138  }
139 
140  Principal::Principal(std::shared_ptr<ProductRegistry const> reg,
141  std::shared_ptr<ProductHolderIndexHelper const> productLookup,
142  ProcessConfiguration const& pc,
143  BranchType bt,
144  HistoryAppender* historyAppender) :
145  EDProductGetter(),
146  processHistoryPtr_(),
147  processHistoryID_(),
148  processConfiguration_(&pc),
149  productHolders_(reg->getNextIndexValue(bt), SharedProductPtr()),
150  preg_(reg),
151  productLookup_(productLookup),
152  lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
153  reader_(),
154  productPtrs_(),
155  branchType_(bt),
156  historyAppender_(historyAppender),
157  cacheIdentifier_(nextIdentifier())
158  {
159 
160  //Now that these have been set, we can create the list of Branches we need.
161  std::string const source("source");
162  ProductRegistry::ProductList const& prodsList = reg->productList();
163  // The constructor of an alias product holder takes as an argument the product holder for which it is an alias.
164  // So, the non-alias product holders must be created first.
165  // Therefore, on this first pass, skip current EDAliases.
166  bool hasAliases = false;
167  for(auto const& prod : prodsList) {
168  BranchDescription const& bd = prod.second;
169  if(bd.branchType() == branchType_) {
170  if(bd.isAlias()) {
171  hasAliases = true;
172  } else {
173  auto cbd = std::make_shared<BranchDescription const>(bd);
174  if(bd.produced()) {
175  if(bd.moduleLabel() == source) {
176  addSourceProduct(cbd);
177  } else if(bd.onDemand()) {
180  } else {
181  addScheduledProduct(cbd);
182  }
183  } else {
184  addInputProduct(cbd);
185  }
186  }
187  }
188  }
189  // Now process any EDAliases
190  if(hasAliases) {
191  for(auto const& prod : prodsList) {
192  BranchDescription const& bd = prod.second;
193  if(bd.isAlias() && bd.branchType() == branchType_) {
194  auto cbd = std::make_shared<BranchDescription const>(bd);
195  addAliasedProduct(cbd);
196  }
197  }
198  }
199 
200  // Now create the ProductHolders that search in reverse process
201  // order and are used for queries where the process name is the
202  // empty string
203  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
204  std::vector<ProductHolderIndex> matchingHolders(lookupProcessNames.size(), ProductHolderIndexInvalid);
205  std::vector<bool> ambiguous(lookupProcessNames.size(), false);
206  unsigned int beginElements = productLookup_->beginElements();
207  std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
208  std::vector<ProductHolderIndexHelper::Range> const& ranges = productLookup_->ranges();
209  std::vector<ProductHolderIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
210  std::vector<char> const& processNamesCharArray = productLookup_->processNames();
211 
212  if (!sortedTypeIDs.empty()) {
213  ProductHolderIndex productHolderIndex = ProductHolderIndexInvalid;
214  for(unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
215  ProductHolderIndexHelper::Range const& range = ranges.at(k);
216  for (unsigned int i = range.begin(); i < range.end(); ++i) {
217  ProductHolderIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
218  if (product.startInProcessNames() == 0) {
219  if (productHolderIndex != ProductHolderIndexInvalid) {
220  std::shared_ptr<ProductHolderBase> newHolder = std::make_shared<NoProcessProductHolder>(matchingHolders, ambiguous, this);
221  productHolders_.at(productHolderIndex) = newHolder;
222  matchingHolders.assign(lookupProcessNames.size(), ProductHolderIndexInvalid);
223  ambiguous.assign(lookupProcessNames.size(), false);
224  }
225  productHolderIndex = product.index();
226  } else {
227  std::string process(&processNamesCharArray.at(product.startInProcessNames()));
228  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
229  assert(iter != lookupProcessNames.end());
230  ProductHolderIndex iMatchingIndex = product.index();
231  assert(iMatchingIndex != ProductHolderIndexInvalid);
232  if (iMatchingIndex == ProductHolderIndexAmbiguous) {
233  assert(k >= beginElements);
234  ambiguous.at(iter - lookupProcessNames.begin()) = true;
235  } else {
236  matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
237  }
238  }
239  }
240  }
241  std::shared_ptr<ProductHolderBase> newHolder = std::make_shared<NoProcessProductHolder>(matchingHolders, ambiguous, this);
242  productHolders_.at(productHolderIndex) = newHolder;
243  }
244  }
245 
247  }
248 
249  // Number of products in the Principal.
250  // For products in an input file and not yet read in due to delayed read,
251  // this routine assumes a real product is there.
252  size_t
253  Principal::size() const {
254  size_t size = 0U;
255  for(auto const& prod : *this) {
256  if(prod->singleProduct() && // Not a NoProcessProductHolder
257  !prod->productUnavailable() &&
258  !prod->onDemand() &&
259  !prod->branchDescription().dropped()) {
260  ++size;
261  }
262  }
263  return size;
264  }
265 
266  // adjust provenance for input products after new input file has been merged
267  bool
269  ProductRegistry::ProductList const& prodsList = reg.productList();
270  for(auto const& prod : prodsList) {
271  BranchDescription const& bd = prod.second;
272  if(!bd.produced() && (bd.branchType() == branchType_)) {
273  auto cbd = std::make_shared<BranchDescription const>(bd);
274  ProductHolderBase* phb = getExistingProduct(cbd->branchID());
275  if(phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
276  return false;
277  }
278  phb->resetBranchDescription(cbd);
279  }
280  }
281  return true;
282  }
283 
284  void
285  Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
286  std::auto_ptr<ProductHolderBase> phb(new ScheduledProductHolder(bd));
287  addProductOrThrow(phb);
288  }
289 
290  void
291  Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
292  std::auto_ptr<ProductHolderBase> phb(new SourceProductHolder(bd));
293  addProductOrThrow(phb);
294  }
295 
296  void
297  Principal::addInputProduct(std::shared_ptr<BranchDescription const> bd) {
298  std::auto_ptr<ProductHolderBase> phb(new InputProductHolder(bd, this));
299  addProductOrThrow(phb);
300  }
301 
302  void
303  Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
304  std::auto_ptr<ProductHolderBase> phb(new UnscheduledProductHolder(bd, this));
305  addProductOrThrow(phb);
306  }
307 
308  void
309  Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
310  ProductHolderIndex index = preg_->indexFrom(bd->originalBranchID());
312 
313  std::auto_ptr<ProductHolderBase> phb(new AliasProductHolder(bd, dynamic_cast<ProducedProductHolder&>(*productHolders_[index])));
314  addProductOrThrow(phb);
315  }
316 
317  // "Zero" the principal so it can be reused for another Event.
318  void
320  processHistoryPtr_.reset();
322  reader_ = nullptr;
323  for(auto const& prod : *this) {
324  prod->resetProductData();
325  }
326  productPtrs_.clear();
327  }
328 
329  void
332  assert(nullptr != phb);
333  auto itFound = productPtrs_.find(phb->product());
334  if(itFound != productPtrs_.end()) {
335  productPtrs_.erase(itFound);
336  }
337  phb->deleteProduct();
338  }
339 
340  // Set the principal for the Event, Lumi, or Run.
341  void
343  ProcessHistoryRegistry const& processHistoryRegistry,
345  //increment identifier here since clearPrincipal isn't called for Run/Lumi
347  if(reader) {
348  reader_ = reader;
349  }
350 
351  if (historyAppender_ && productRegistry().anyProductProduced()) {
354  processHistoryRegistry.getMapped(hist),
357  }
358  else {
359  std::shared_ptr<ProcessHistory const> inputProcessHistory;
360  if (hist.isValid()) {
361  //does not own the pointer
362  auto noDel =[](void const*){};
363  inputProcessHistory =
364  std::shared_ptr<ProcessHistory const>(processHistoryRegistry.getMapped(hist),noDel);
365  if (inputProcessHistory.get() == nullptr) {
367  << "Principal::fillPrincipal\n"
368  << "Input ProcessHistory not found in registry\n"
369  << "Contact a Framework developer\n";
370  }
371  } else {
372  //Since this is static we don't want it deleted
373  inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory,[](void const*){});
374  }
376  processHistoryPtr_ = inputProcessHistory;
377  }
378 
380  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
381  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
382  unsigned int k = 0;
383  for (auto iter = processHistoryPtr_->rbegin(),
384  iEnd = processHistoryPtr_->rend();
385  iter != iEnd; ++iter) {
386  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
387  if (nameIter == lookupProcessNames.end()) {
388  continue;
389  }
390  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
391  ++k;
392  }
394  }
395  }
396 
399  ProductHolderIndex index = preg_->indexFrom(branchID);
401  SharedProductPtr ptr = productHolders_.at(index);
402  return ptr.get();
403  }
404 
408  if(nullptr != phb && BranchKey(productHolder.branchDescription()) != BranchKey(phb->branchDescription())) {
409  BranchDescription const& newProduct = phb->branchDescription();
410  BranchDescription const& existing = productHolder.branchDescription();
411  if(newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
412  throw cms::Exception("HashCollision") << "Principal::getExistingProduct\n" <<
413  " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName() << "\n" <<
414  "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
415  } else {
416  assert(nullptr == phb || BranchKey(productHolder.branchDescription()) == BranchKey(phb->branchDescription()));
417  }
418  }
419  return phb;
420  }
421 
422  void
423  Principal::addProduct_(std::auto_ptr<ProductHolderBase> productHolder) {
424  BranchDescription const& bd = productHolder->branchDescription();
425  assert (!bd.className().empty());
426  assert (!bd.friendlyClassName().empty());
427  assert (!bd.moduleLabel().empty());
428  assert (!bd.processName().empty());
429  SharedProductPtr phb(productHolder.release());
430 
431  ProductHolderIndex index = preg_->indexFrom(bd.branchID());
433  productHolders_[index] = phb;
434  }
435 
436  void
437  Principal::addProductOrThrow(std::auto_ptr<ProductHolderBase> productHolder) {
438  ProductHolderBase const* phb = getExistingProduct(*productHolder);
439  if(phb != nullptr) {
440  BranchDescription const& bd = productHolder->branchDescription();
441  throw Exception(errors::InsertFailure, "AlreadyPresent")
442  << "addProductOrThrow: Problem found while adding product, "
443  << "product already exists for ("
444  << bd.friendlyClassName() << ","
445  << bd.moduleLabel() << ","
446  << bd.productInstanceName() << ","
447  << bd.processName()
448  << ")\n";
449  }
450  addProduct_(productHolder);
451  }
452 
455  ProductHolderIndex index = preg_->indexFrom(bid);
456  if(index == ProductHolderIndexInvalid){
457  return ConstProductHolderPtr();
458  }
459  return getProductHolderByIndex(index);
460  }
461 
464 
465  ConstProductHolderPtr const phb = productHolders_[index].get();
466  return phb;
467  }
468 
471  TypeID const& typeID,
472  InputTag const& inputTag,
473  EDConsumerBase const* consumer,
475  ModuleCallingContext const* mcc) const {
476 
477  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
478  if(result == 0) {
479  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
480  return makeNotFoundException("getByLabel", kindOfType, typeID, inputTag.label(), inputTag.instance(), inputTag.process());
481  }));
482  }
483  return BasicHandle(*result);
484  }
485 
488  TypeID const& typeID,
489  std::string const& label,
490  std::string const& instance,
491  std::string const& process,
492  EDConsumerBase const* consumer,
494  ModuleCallingContext const* mcc) const {
495 
496  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process,consumer, sra, mcc);
497  if(result == 0) {
498  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
499  return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
500  }));
501  }
502  return BasicHandle(*result);
503  }
504 
507  TypeID const&,
509  bool skipCurrentProcess,
510  bool& ambiguous,
512  ModuleCallingContext const* mcc) const {
514  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
515  assert(0!=productHolder.get());
516  ProductHolderBase::ResolveStatus resolveStatus;
517  ProductData const* productData = productHolder->resolveProduct(resolveStatus, skipCurrentProcess, sra, mcc);
518  if(resolveStatus == ProductHolderBase::Ambiguous) {
519  ambiguous = true;
520  return BasicHandle();
521  }
522  if(productData == 0) {
523  return BasicHandle();
524  }
525  return BasicHandle(*productData);
526  }
527 
528  void
530  bool skipCurrentProcess,
531  ModuleCallingContext const* mcc) const {
532  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_.at(index);
533  assert(0!=productHolder.get());
534  ProductHolderBase::ResolveStatus resolveStatus;
535  productHolder->resolveProduct(resolveStatus, skipCurrentProcess, nullptr, mcc);
536  }
537 
538  void
541  EDConsumerBase const* consumer,
543  ModuleCallingContext const* mcc) const {
544 
545  assert(results.empty());
546 
547  if(unlikely(consumer and (not consumer->registeredToConsumeMany(typeID,branchType())))) {
548  failedToRegisterConsumesMany(typeID);
549  }
550 
551  // This finds the indexes to all the ProductHolder's matching the type
554 
555  if (matches.numberOfMatches() == 0) {
556  maybeThrowMissingDictionaryException(typeID, false, preg_->missingDictionaries());
557  return;
558  }
559 
560  results.reserve(matches.numberOfMatches());
561 
562  // Loop over the ProductHolders. Add the products that are actually
563  // present into the results. This will also trigger delayed reading,
564  // on demand production, and check for deleted products as appropriate.
565 
566  // Over the years the code that uses getManyByType has grown to depend
567  // on the ordering of the results. The order originally was just an
568  // accident of how previous versions of the code were written, but
569  // here we have to go through some extra effort to preserve that ordering.
570 
571  // We build a list of holders that match a particular label and instance.
572  // When that list is complete we call findProducts, which loops over
573  // that list in reverse order of the ProcessHistory (starts with the
574  // most recent). Then we clear the list and repeat this until all the
575  // matching label and instance subsets have been dealt with.
576 
577  // Note that the function isFullyResolved returns true for the ProductHolders
578  // that are associated with an empty process name. Those are the ones that
579  // know how to search for the most recent process name matching
580  // a label and instance. We do not need these for getManyByType and
581  // skip them. In addition to skipping them, we make use of the fact
582  // that they mark the beginning of each subset of holders with the same
583  // label and instance. They tell us when to call findProducts.
584 
585  std::vector<ProductHolderBase const*> holders;
586 
587  for(unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
588 
589  ProductHolderIndex index = matches.index(i);
590 
591  if(!matches.isFullyResolved(i)) {
592  if(!holders.empty()) {
593  // Process the ones with a particular module label and instance
594  findProducts(holders, typeID, results, sra, mcc);
595  holders.clear();
596  }
597  } else {
598  ProductHolderBase const* productHolder = productHolders_.at(index).get();
599  assert(productHolder);
600  holders.push_back(productHolder);
601  }
602  }
603  // Do not miss the last subset of products
604  if(!holders.empty()) {
605  findProducts(holders, typeID, results, sra, mcc);
606  }
607  return;
608  }
609 
610  void
611  Principal::findProducts(std::vector<ProductHolderBase const*> const& holders,
612  TypeID const&,
615  ModuleCallingContext const* mcc) const {
616 
617  for (auto iter = processHistoryPtr_->rbegin(),
618  iEnd = processHistoryPtr_->rend();
619  iter != iEnd; ++iter) {
620  std::string const& process = iter->processName();
621  for (auto productHolder : holders) {
622  BranchDescription const& bd = productHolder->branchDescription();
623  if (process == bd.processName()) {
624 
625  // Ignore aliases to avoid matching the same product multiple times.
626  if(bd.isAlias()) {
627  continue;
628  }
629 
630  ProductHolderBase::ResolveStatus resolveStatus;
631  ProductData const* productData = productHolder->resolveProduct(resolveStatus, false, sra, mcc);
632  if(productData) {
633  // Skip product if not available.
634  results.emplace_back(*productData);
635  }
636  }
637  }
638  }
639  }
640 
641  ProductData const*
643  TypeID const& typeID,
644  InputTag const& inputTag,
645  EDConsumerBase const* consumer,
647  ModuleCallingContext const* mcc) const {
648 
649  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
650 
651  ProductHolderIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
652 
653  if (index == ProductHolderIndexInvalid) {
654 
655  char const* processName = inputTag.process().c_str();
656  if (skipCurrentProcess) {
657  processName = "\0";
658  }
659 
660  index = productLookup().index(kindOfType,
661  typeID,
662  inputTag.label().c_str(),
663  inputTag.instance().c_str(),
664  processName);
665 
666  if(index == ProductHolderIndexAmbiguous) {
667  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
668  } else if (index == ProductHolderIndexInvalid) {
670  productLookup().relatedIndexes(kindOfType, typeID);
671 
672  if (matches.numberOfMatches() == 0) {
673  maybeThrowMissingDictionaryException(typeID, kindOfType == ELEMENT_TYPE, preg_->missingDictionaries());
674  }
675  return 0;
676  }
677  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
678  }
679  if(unlikely( consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
680  failedToRegisterConsumes(kindOfType,typeID,inputTag.label(),inputTag.instance(),inputTag.process());
681  }
682 
683 
684  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
685 
686  ProductHolderBase::ResolveStatus resolveStatus;
687  ProductData const* productData = productHolder->resolveProduct(resolveStatus, skipCurrentProcess, sra, mcc);
688  if(resolveStatus == ProductHolderBase::Ambiguous) {
689  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
690  }
691  return productData;
692  }
693 
694  ProductData const*
696  TypeID const& typeID,
697  std::string const& label,
698  std::string const& instance,
699  std::string const& process,
700  EDConsumerBase const* consumer,
702  ModuleCallingContext const* mcc) const {
703 
705  typeID,
706  label.c_str(),
707  instance.c_str(),
708  process.c_str());
709 
710  if(index == ProductHolderIndexAmbiguous) {
711  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
712  } else if (index == ProductHolderIndexInvalid) {
714  productLookup().relatedIndexes(kindOfType, typeID);
715 
716  if (matches.numberOfMatches() == 0) {
717  maybeThrowMissingDictionaryException(typeID, kindOfType == ELEMENT_TYPE, preg_->missingDictionaries());
718  }
719  return 0;
720  }
721 
722  if(unlikely( consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
723  failedToRegisterConsumes(kindOfType,typeID,label,instance,process);
724  }
725 
726  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
727 
728  ProductHolderBase::ResolveStatus resolveStatus;
729  ProductData const* productData = productHolder->resolveProduct(resolveStatus, false, sra, mcc);
730  if(resolveStatus == ProductHolderBase::Ambiguous) {
731  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
732  }
733  return productData;
734  }
735 
736  ProductData const*
737  Principal::findProductByTag(TypeID const& typeID, InputTag const& tag, ModuleCallingContext const* mcc) const {
738  ProductData const* productData =
740  typeID,
741  tag,
742  nullptr,
743  nullptr,
744  mcc);
745  return productData;
746  }
747 
749  Principal::getForOutput(BranchID const& bid, bool getProd,
750  ModuleCallingContext const* mcc) const {
751  ConstProductHolderPtr const phb = getProductHolder(bid);
752  if(phb == nullptr) {
754  }
755  if (phb->productWasDeleted()) {
756  throwProductDeletedException("getForOutput",phb->productType(),
757  phb->moduleLabel(),
758  phb->productInstanceName(),
759  phb->processName());
760  }
761  if(getProd) {
763  phb->resolveProduct(status,false,nullptr, mcc);
764  }
765  if(!phb->provenance() || (!phb->product() && !phb->productProvenancePtr())) {
766  return OutputHandle();
767  }
768  return OutputHandle(phb->product(), &phb->branchDescription(), phb->productProvenancePtr());
769  }
770 
771  Provenance
773  ModuleCallingContext const* mcc) const {
774  ConstProductHolderPtr const phb = getProductHolder(bid);
775  if(phb == nullptr) {
777  }
778 
779  if(phb->onDemand()) {
781  if(not phb->resolveProduct(status,false, nullptr, mcc) ) {
782  throwProductNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
783  }
784  }
785  return *phb->provenance();
786  }
787 
788  // This one is mostly for test printout purposes
789  // No attempt to trigger on demand execution
790  // Skips provenance when the EDProduct is not there
791  void
792  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
793  provenances.clear();
794  for(auto const& productHolder : *this) {
795  if(productHolder->singleProduct() && productHolder->provenanceAvailable() && !productHolder->branchDescription().isAlias()) {
796  // We do not attempt to get the event/lumi/run status from the provenance,
797  // because the per event provenance may have been dropped.
798  if(productHolder->provenance()->product().present()) {
799  provenances.push_back(productHolder->provenance());
800  }
801  }
802  }
803  }
804 
805  void
806  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
807  for(auto const& prod : bids) {
808  ProductHolderIndex index= preg_->indexFrom(prod);
810  ProductHolderIndex indexO = other.preg_->indexFrom(prod);
812  productHolders_[index].swap(other.productHolders_[indexO]);
813  productHolders_[index]->setPrincipal(this);
814  }
815  reader_->mergeReaders(other.reader());
816  }
817 
818  WrapperBase const*
819  Principal::getIt(ProductID const&) const {
820  assert(nullptr);
821  return nullptr;
822  }
823 
824  WrapperBase const*
825  Principal::getThinnedProduct(ProductID const&, unsigned int&) const {
826  assert(nullptr);
827  return nullptr;
828  }
829 
830  void
832  std::vector<WrapperBase const*>&,
833  std::vector<unsigned int>&) const {
834  assert(nullptr);
835  }
836 
837  void
839  if(prod == nullptr) return;
840  // These are defensive checks against things that should never happen, but have.
841  // Checks that the same physical product has not already been put into the event.
842  bool alreadyPresent = !productPtrs_.insert(prod).second;
843  if(alreadyPresent) {
844  phb->checkType(*prod);
845  throwCorruptionException("checkUniquenessAndType", phb->branchDescription().branchName());
846  }
847  // Checks that the real type of the product matches the branch.
848  phb->checkType(*prod);
849  }
850 
851  void
852  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductHolderBase const* phb) const {
853  bool willBePut = phb->putOrMergeProduct();
854  if(willBePut) {
855  checkUniquenessAndType(prod.get(), phb);
856  phb->putProduct(std::move(prod));
857  } else {
858  phb->checkType(*prod);
859  phb->mergeProduct(std::move(prod));
860  }
861  }
862 
863  void
864  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductProvenance& prov, ProductHolderBase* phb) {
865  bool willBePut = phb->putOrMergeProduct();
866  if(willBePut) {
867  checkUniquenessAndType(prod.get(), phb);
868  phb->putProduct(std::move(prod), prov);
869  } else {
870  phb->checkType(*prod);
871  phb->mergeProduct(std::move(prod), prov);
872  }
873  }
874 
875  void
877  if(preg_->getNextIndexValue(branchType_) != productHolders_.size()) {
878  productHolders_.resize(preg_->getNextIndexValue(branchType_));
879  for(auto const& prod : preg_->productList()) {
880  BranchDescription const& bd = prod.second;
881  if(bd.branchType() == branchType_) {
882  ProductHolderIndex index = preg_->indexFrom(bd.branchID());
884  if(!productHolders_[index]) {
885  // no product holder. Must add one. The new entry must be an input product holder.
886  assert(!bd.produced());
887  auto cbd = std::make_shared<BranchDescription const>(bd);
888  addInputProduct(cbd);
889  }
890  }
891  }
892  }
893  assert(preg_->getNextIndexValue(branchType_) == productHolders_.size());
894  }
895 }
BranchType branchType_
Definition: Principal.h:276
static ProcessHistory const s_emptyProcessHistory
Definition: Principal.cc:35
void putOrMerge(std::unique_ptr< WrapperBase > prod, ProductHolderBase const *productHolder) const
Definition: Principal.cc:852
ProductRegistry const & productRegistry() const
Definition: Principal.h:152
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
void clearPrincipal()
Definition: Principal.cc:319
virtual void getThinnedProducts(ProductID const &, std::vector< WrapperBase const * > &, std::vector< unsigned int > &) const override
Definition: Principal.cc:831
int i
Definition: DBlmapReader.cc:9
std::string const & branchName() const
WrapperBase * product() const
Definition: ProductHolder.h:84
size_t size() const
Definition: Principal.cc:253
DelayedReader * reader_
Definition: Principal.h:271
BranchType const & branchType() const
HistoryAppender * historyAppender_
Definition: Principal.h:281
ConstProductHolderPtr getProductHolder(BranchID const &oid) const
Definition: Principal.cc:454
bool checkTypeDictionary(TypeID const &type)
bool getMapped(ProcessHistoryID const &key, ProcessHistory &value) const
std::shared_ptr< ProductHolderBase > SharedProductPtr
Definition: Principal.h:63
static std::string const source("source")
ProductHolderIndex indexFor(TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:186
std::shared_ptr< ProcessHistory const > processHistoryPtr_
Definition: Principal.h:252
void checkType(WrapperBase const &prod) const
ProductHolderBase const * ConstProductHolderPtr
Definition: Principal.h:59
static PFTauRenderPlugin instance
virtual WrapperBase const * getThinnedProduct(ProductID const &, unsigned int &) const override
Definition: Principal.cc:825
ProductHolderIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
static std::atomic< Principal::CacheIdentifier_t > s_nextIdentifier
Definition: Principal.cc:135
std::map< BranchKey, BranchDescription > ProductList
static Principal::CacheIdentifier_t nextIdentifier()
Definition: Principal.cc:136
ProcessHistoryID processHistoryID_
Definition: Principal.h:254
std::shared_ptr< ProcessHistory const > appendToProcessHistory(ProcessHistoryID const &inputPHID, ProcessHistory const *inputProcessHistory, ProcessConfiguration const &pc)
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:24
assert(m_qm.get())
void resetBranchDescription(std::shared_ptr< BranchDescription const > bd)
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Principal.cc:792
static void throwCorruptionException(char const *where, std::string const &branchName)
Definition: Principal.cc:64
Provenance getProvenance(BranchID const &bid, ModuleCallingContext const *mcc) const
Definition: Principal.cc:772
std::string const & processName() const
unsigned int ProductHolderIndex
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
void addInputProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:297
BranchType
Definition: BranchType.h:11
static void throwAmbiguousException(const char *where, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:100
#define unlikely(x)
ProductList const & productList() const
std::vector< unsigned int > lookupProcessOrder_
Definition: Principal.h:266
static void throwProductDeletedException(ProductID const &pid, edm::EventPrincipal::ConstProductHolderPtr const phb)
BasicHandle getByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:470
BasicHandle getByToken(KindOfType kindOfType, TypeID const &typeID, ProductHolderIndex index, bool skipCurrentProcess, bool &ambiguous, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:506
void addScheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:285
BranchDescription const & branchDescription() const
Definition: ProductHolder.h:93
std::string const & className() const
ProductData const * findProductByTag(TypeID const &typeID, InputTag const &tag, ModuleCallingContext const *mcc) const
Definition: Principal.cc:737
std::string const & moduleLabel() const
ConstProductHolderPtr getProductHolderByIndex(ProductHolderIndex const &oid) const
Definition: Principal.cc:463
std::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:263
std::string const & productInstanceName() const
CacheIdentifier_t cacheIdentifier_
Definition: Principal.h:283
BranchType const & branchType() const
Definition: Principal.h:170
ProductHolderCollection productHolders_
Definition: Principal.h:259
std::shared_ptr< HandleExceptionFactory > makeHandleExceptionFactory(T &&iFunctor)
void addProduct_(std::auto_ptr< ProductHolderBase > phb)
Definition: Principal.cc:423
void checkUniquenessAndType(WrapperBase const *prod, ProductHolderBase const *productHolder) const
Definition: Principal.cc:838
void addSourceProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:291
tuple result
Definition: query.py:137
ProcessHistoryID orderProcessHistoryID_
Definition: Principal.h:267
ProductHolderIndex index(unsigned int i) const
std::string const & friendlyClassName() const
BranchID const & branchID() const
Hash< ProcessHistoryType > ProcessHistoryID
void throwMissingDictionariesException()
std::set< void const * > productPtrs_
Definition: Principal.h:274
std::shared_ptr< ProductHolderIndexHelper const > productLookup_
Definition: Principal.h:264
string ranges
Definition: diffTwoXMLs.py:78
Principal(std::shared_ptr< ProductRegistry const > reg, std::shared_ptr< ProductHolderIndexHelper const > productLookup, ProcessConfiguration const &pc, BranchType bt, HistoryAppender *historyAppender)
Definition: Principal.cc:140
OutputHandle getForOutput(BranchID const &bid, bool getProd, ModuleCallingContext const *mcc) const
Definition: Principal.cc:749
DelayedReader * reader() const
Definition: Principal.h:176
virtual ~Principal()
Definition: Principal.cc:246
bool willSkipCurrentProcess() const
Definition: InputTag.h:49
void prefetch(ProductHolderIndex index, bool skipCurrentProcess, ModuleCallingContext const *mcc) const
Definition: Principal.cc:529
bool registeredToConsumeMany(TypeID const &, BranchType) const
void addUnscheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:303
bool putOrMergeProduct() const
std::string wrappedClassName(std::string const &iFullName)
void tryToCacheIndex(ProductHolderIndex index, TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:204
static std::shared_ptr< cms::Exception > makeNotFoundException(char const *where, KindOfType kindOfType, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:71
std::string const & label() const
Definition: InputTag.h:43
void findProducts(std::vector< ProductHolderBase const * > const &holders, TypeID const &typeID, BasicHandleVec &results, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:611
std::string const & process() const
Definition: InputTag.h:47
unsigned long CacheIdentifier_t
Definition: Principal.h:173
virtual WrapperBase const * getIt(ProductID const &) const override
Definition: Principal.cc:819
bool registeredToConsume(ProductHolderIndex, bool, BranchType) const
void addProductOrThrow(std::auto_ptr< ProductHolderBase > phb)
Definition: Principal.cc:437
bool isValid() const
Definition: Hash.h:150
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:268
ProductData const * findProductByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumer, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:642
std::string const & className() const
Definition: TypeID.cc:46
bool binary_search_all(ForwardSequence const &s, Datum const &d)
wrappers for std::binary_search
Definition: Algorithms.h:76
void mergeProduct(std::unique_ptr< WrapperBase > edp, ProductProvenance &productProvenance)
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:876
static void throwProductNotFoundException(char const *where, errors::ErrorCodes error, BranchID const &bid)
Definition: Principal.cc:57
tuple status
Definition: ntuplemaker.py:245
tuple process
Definition: LaserDQM_cfg.py:3
void addAliasedProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:309
void fillPrincipal(ProcessHistoryID const &hist, ProcessHistoryRegistry const &phr, DelayedReader *reader)
Definition: Principal.cc:342
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:806
void putProduct(std::unique_ptr< WrapperBase > edp, ProductProvenance const &productProvenance)
std::string const & instance() const
Definition: InputTag.h:44
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:256
tuple size
Write out results.
std::vector< BasicHandle > BasicHandleVec
Definition: Principal.h:60
void getManyByType(TypeID const &typeID, BasicHandleVec &results, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:539
ProductHolderBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:398
bool checkClassDictionary(TypeID const &type)
static void maybeThrowMissingDictionaryException(TypeID const &productType, bool isElement, std::vector< TypeID > const &missingDictionaries)
Definition: Principal.cc:39
ProductHolderIndexHelper const & productLookup() const
Definition: Principal.h:154
void deleteProduct(BranchID const &id)
Definition: Principal.cc:330