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