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