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