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  LogError("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  LogError("GetByLabelWithoutRegistration")<<"::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
122  << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<")<<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  if(nullptr != phb && BranchKey(productHolder.branchDescription()) != BranchKey(phb->branchDescription())) {
404  BranchDescription const& newProduct = phb->branchDescription();
405  BranchDescription const& existing = productHolder.branchDescription();
406  if(newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
407  throw cms::Exception("HashCollision") << "Principal::getExistingProduct\n" <<
408  " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName() << "\n" <<
409  "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
410  } else {
411  assert(nullptr == phb || BranchKey(productHolder.branchDescription()) == BranchKey(phb->branchDescription()));
412  }
413  }
414  return phb;
415  }
416 
417  void
418  Principal::addProduct_(std::auto_ptr<ProductHolderBase> productHolder) {
419  BranchDescription const& bd = productHolder->branchDescription();
420  assert (!bd.className().empty());
421  assert (!bd.friendlyClassName().empty());
422  assert (!bd.moduleLabel().empty());
423  assert (!bd.processName().empty());
424  SharedProductPtr phb(productHolder.release());
425 
426  ProductHolderIndex index = preg_->indexFrom(bd.branchID());
428  productHolders_[index] = phb;
429  }
430 
431  void
432  Principal::addProductOrThrow(std::auto_ptr<ProductHolderBase> productHolder) {
433  ProductHolderBase const* phb = getExistingProduct(*productHolder);
434  if(phb != nullptr) {
435  BranchDescription const& bd = productHolder->branchDescription();
436  throw Exception(errors::InsertFailure, "AlreadyPresent")
437  << "addProductOrThrow: Problem found while adding product, "
438  << "product already exists for ("
439  << bd.friendlyClassName() << ","
440  << bd.moduleLabel() << ","
441  << bd.productInstanceName() << ","
442  << bd.processName()
443  << ")\n";
444  }
445  addProduct_(productHolder);
446  }
447 
450  ProductHolderIndex index = preg_->indexFrom(bid);
451  if(index == ProductHolderIndexInvalid){
452  return ConstProductHolderPtr();
453  }
454  return getProductHolderByIndex(index);
455  }
456 
459 
460  ConstProductHolderPtr const phb = productHolders_[index].get();
461  return phb;
462  }
463 
466  TypeID const& typeID,
467  InputTag const& inputTag,
468  EDConsumerBase const* consumer,
469  ModuleCallingContext const* mcc) const {
470 
471  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, mcc);
472  if(result == 0) {
473  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
474  return makeNotFoundException("getByLabel", kindOfType, typeID, inputTag.label(), inputTag.instance(), inputTag.process());
475  }));
476  }
477  return BasicHandle(*result);
478  }
479 
482  TypeID const& typeID,
483  std::string const& label,
484  std::string const& instance,
485  std::string const& process,
486  EDConsumerBase const* consumer,
487  ModuleCallingContext const* mcc) const {
488 
489  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process,consumer, mcc);
490  if(result == 0) {
491  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
492  return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
493  }));
494  }
495  return BasicHandle(*result);
496  }
497 
500  TypeID const&,
502  bool skipCurrentProcess,
503  bool& ambiguous,
504  ModuleCallingContext const* mcc) const {
506  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
507  assert(0!=productHolder.get());
508  ProductHolderBase::ResolveStatus resolveStatus;
509  ProductData const* productData = productHolder->resolveProduct(resolveStatus, skipCurrentProcess, mcc);
510  if(resolveStatus == ProductHolderBase::Ambiguous) {
511  ambiguous = true;
512  return BasicHandle();
513  }
514  if(productData == 0) {
515  return BasicHandle();
516  }
517  return BasicHandle(*productData);
518  }
519 
520  void
522  bool skipCurrentProcess,
523  ModuleCallingContext const* mcc) const {
524  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_.at(index);
525  assert(0!=productHolder.get());
526  ProductHolderBase::ResolveStatus resolveStatus;
527  productHolder->resolveProduct(resolveStatus, skipCurrentProcess, mcc);
528  }
529 
530  void
533  EDConsumerBase const* consumer,
534  ModuleCallingContext const* mcc) const {
535 
536  assert(results.empty());
537 
538  if(unlikely(consumer and (not consumer->registeredToConsumeMany(typeID,branchType())))) {
539  failedToRegisterConsumesMany(typeID);
540  }
541 
542  // This finds the indexes to all the ProductHolder's matching the type
545 
546  if (matches.numberOfMatches() == 0) {
547  maybeThrowMissingDictionaryException(typeID, false, preg_->missingDictionaries());
548  return;
549  }
550 
551  results.reserve(matches.numberOfMatches());
552 
553  // Loop over the ProductHolders. Add the products that are actually
554  // present into the results. This will also trigger delayed reading,
555  // on demand production, and check for deleted products as appropriate.
556 
557  // Over the years the code that uses getManyByType has grown to depend
558  // on the ordering of the results. The order originally was just an
559  // accident of how previous versions of the code were written, but
560  // here we have to go through some extra effort to preserve that ordering.
561 
562  // We build a list of holders that match a particular label and instance.
563  // When that list is complete we call findProducts, which loops over
564  // that list in reverse order of the ProcessHistory (starts with the
565  // most recent). Then we clear the list and repeat this until all the
566  // matching label and instance subsets have been dealt with.
567 
568  // Note that the function isFullyResolved returns true for the ProductHolders
569  // that are associated with an empty process name. Those are the ones that
570  // know how to search for the most recent process name matching
571  // a label and instance. We do not need these for getManyByType and
572  // skip them. In addition to skipping them, we make use of the fact
573  // that they mark the beginning of each subset of holders with the same
574  // label and instance. They tell us when to call findProducts.
575 
576  std::vector<ProductHolderBase const*> holders;
577 
578  for(unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
579 
580  ProductHolderIndex index = matches.index(i);
581 
582  if(!matches.isFullyResolved(i)) {
583  if(!holders.empty()) {
584  // Process the ones with a particular module label and instance
585  findProducts(holders, typeID, results, mcc);
586  holders.clear();
587  }
588  } else {
589  ProductHolderBase const* productHolder = productHolders_.at(index).get();
590  assert(productHolder);
591  holders.push_back(productHolder);
592  }
593  }
594  // Do not miss the last subset of products
595  if(!holders.empty()) {
596  findProducts(holders, typeID, results, mcc);
597  }
598  return;
599  }
600 
601  void
602  Principal::findProducts(std::vector<ProductHolderBase const*> const& holders,
603  TypeID const&,
605  ModuleCallingContext const* mcc) const {
606 
607  for (auto iter = processHistoryPtr_->rbegin(),
608  iEnd = processHistoryPtr_->rend();
609  iter != iEnd; ++iter) {
610  std::string const& process = iter->processName();
611  for (auto productHolder : holders) {
612  BranchDescription const& bd = productHolder->branchDescription();
613  if (process == bd.processName()) {
614 
615  // Ignore aliases to avoid matching the same product multiple times.
616  if(bd.isAlias()) {
617  continue;
618  }
619 
620  ProductHolderBase::ResolveStatus resolveStatus;
621  ProductData const* productData = productHolder->resolveProduct(resolveStatus, false, mcc);
622  if(productData) {
623  // Skip product if not available.
624  results.emplace_back(*productData);
625  }
626  }
627  }
628  }
629  }
630 
631  ProductData const*
633  TypeID const& typeID,
634  InputTag const& inputTag,
635  EDConsumerBase const* consumer,
636  ModuleCallingContext const* mcc) const {
637 
638  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
639 
640  ProductHolderIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
641 
642  if (index == ProductHolderIndexInvalid) {
643 
644  char const* processName = inputTag.process().c_str();
645  if (skipCurrentProcess) {
646  processName = "\0";
647  }
648 
649  index = productLookup().index(kindOfType,
650  typeID,
651  inputTag.label().c_str(),
652  inputTag.instance().c_str(),
653  processName);
654 
655  if(index == ProductHolderIndexAmbiguous) {
656  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
657  } else if (index == ProductHolderIndexInvalid) {
659  productLookup().relatedIndexes(kindOfType, typeID);
660 
661  if (matches.numberOfMatches() == 0) {
662  maybeThrowMissingDictionaryException(typeID, kindOfType == ELEMENT_TYPE, preg_->missingDictionaries());
663  }
664  return 0;
665  }
666  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
667  }
668  if(unlikely( consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
669  failedToRegisterConsumes(kindOfType,typeID,inputTag.label(),inputTag.instance(),inputTag.process());
670  }
671 
672 
673  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
674 
675  ProductHolderBase::ResolveStatus resolveStatus;
676  ProductData const* productData = productHolder->resolveProduct(resolveStatus, skipCurrentProcess, mcc);
677  if(resolveStatus == ProductHolderBase::Ambiguous) {
678  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
679  }
680  return productData;
681  }
682 
683  ProductData const*
685  TypeID const& typeID,
686  std::string const& label,
687  std::string const& instance,
688  std::string const& process,
689  EDConsumerBase const* consumer,
690  ModuleCallingContext const* mcc) const {
691 
693  typeID,
694  label.c_str(),
695  instance.c_str(),
696  process.c_str());
697 
698  if(index == ProductHolderIndexAmbiguous) {
699  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
700  } else if (index == ProductHolderIndexInvalid) {
702  productLookup().relatedIndexes(kindOfType, typeID);
703 
704  if (matches.numberOfMatches() == 0) {
705  maybeThrowMissingDictionaryException(typeID, kindOfType == ELEMENT_TYPE, preg_->missingDictionaries());
706  }
707  return 0;
708  }
709 
710  if(unlikely( consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
711  failedToRegisterConsumes(kindOfType,typeID,label,instance,process);
712  }
713 
714  std::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
715 
716  ProductHolderBase::ResolveStatus resolveStatus;
717  ProductData const* productData = productHolder->resolveProduct(resolveStatus, false, mcc);
718  if(resolveStatus == ProductHolderBase::Ambiguous) {
719  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
720  }
721  return productData;
722  }
723 
724  ProductData const*
725  Principal::findProductByTag(TypeID const& typeID, InputTag const& tag, ModuleCallingContext const* mcc) const {
726  ProductData const* productData =
728  typeID,
729  tag,
730  nullptr,
731  mcc);
732  return productData;
733  }
734 
736  Principal::getForOutput(BranchID const& bid, bool getProd,
737  ModuleCallingContext const* mcc) const {
738  ConstProductHolderPtr const phb = getProductHolder(bid);
739  if(phb == nullptr) {
741  }
742  if (phb->productWasDeleted()) {
743  throwProductDeletedException("getForOutput",phb->productType(),
744  phb->moduleLabel(),
745  phb->productInstanceName(),
746  phb->processName());
747  }
748  if(getProd) {
750  phb->resolveProduct(status,false,mcc);
751  }
752  if(!phb->provenance() || (!phb->product() && !phb->productProvenancePtr())) {
753  return OutputHandle();
754  }
755  return OutputHandle(phb->product(), &phb->branchDescription(), phb->productProvenancePtr());
756  }
757 
758  Provenance
760  ModuleCallingContext const* mcc) const {
761  ConstProductHolderPtr const phb = getProductHolder(bid);
762  if(phb == nullptr) {
764  }
765 
766  if(phb->onDemand()) {
768  if(not phb->resolveProduct(status,false,mcc) ) {
769  throwProductNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
770  }
771  }
772  return *phb->provenance();
773  }
774 
775  // This one is mostly for test printout purposes
776  // No attempt to trigger on demand execution
777  // Skips provenance when the EDProduct is not there
778  void
779  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
780  provenances.clear();
781  for(auto const& productHolder : *this) {
782  if(productHolder->singleProduct() && productHolder->provenanceAvailable() && !productHolder->branchDescription().isAlias()) {
783  // We do not attempt to get the event/lumi/run status from the provenance,
784  // because the per event provenance may have been dropped.
785  if(productHolder->provenance()->product().present()) {
786  provenances.push_back(productHolder->provenance());
787  }
788  }
789  }
790  }
791 
792  void
793  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
794  for(auto const& prod : bids) {
795  ProductHolderIndex index= preg_->indexFrom(prod);
797  ProductHolderIndex indexO = other.preg_->indexFrom(prod);
799  productHolders_[index].swap(other.productHolders_[indexO]);
800  productHolders_[index]->setPrincipal(this);
801  }
802  reader_->mergeReaders(other.reader());
803  }
804 
805  WrapperBase const*
806  Principal::getIt(ProductID const&) const {
807  assert(nullptr);
808  return nullptr;
809  }
810 
811  WrapperBase const*
812  Principal::getThinnedProduct(ProductID const&, unsigned int&) const {
813  assert(nullptr);
814  return nullptr;
815  }
816 
817  void
819  std::vector<WrapperBase const*>&,
820  std::vector<unsigned int>&) const {
821  assert(nullptr);
822  }
823 
824  void
826  if(prod == nullptr) return;
827  // These are defensive checks against things that should never happen, but have.
828  // Checks that the same physical product has not already been put into the event.
829  bool alreadyPresent = !productPtrs_.insert(prod).second;
830  if(alreadyPresent) {
831  phb->checkType(*prod);
832  throwCorruptionException("checkUniquenessAndType", phb->branchDescription().branchName());
833  }
834  // Checks that the real type of the product matches the branch.
835  phb->checkType(*prod);
836  }
837 
838  void
839  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductHolderBase const* phb) const {
840  bool willBePut = phb->putOrMergeProduct();
841  if(willBePut) {
842  checkUniquenessAndType(prod.get(), phb);
843  phb->putProduct(std::move(prod));
844  } else {
845  phb->checkType(*prod);
846  phb->mergeProduct(std::move(prod));
847  }
848  }
849 
850  void
851  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductProvenance& prov, ProductHolderBase* phb) {
852  bool willBePut = phb->putOrMergeProduct();
853  if(willBePut) {
854  checkUniquenessAndType(prod.get(), phb);
855  phb->putProduct(std::move(prod), prov);
856  } else {
857  phb->checkType(*prod);
858  phb->mergeProduct(std::move(prod), prov);
859  }
860  }
861 
862  void
864  if(preg_->getNextIndexValue(branchType_) != productHolders_.size()) {
865  productHolders_.resize(preg_->getNextIndexValue(branchType_));
866  for(auto const& prod : preg_->productList()) {
867  BranchDescription const& bd = prod.second;
868  if(bd.branchType() == branchType_) {
869  ProductHolderIndex index = preg_->indexFrom(bd.branchID());
871  if(!productHolders_[index]) {
872  // no product holder. Must add one. The new entry must be an input product holder.
873  assert(!bd.produced());
874  auto cbd = std::make_shared<BranchDescription const>(bd);
875  addInputProduct(cbd);
876  }
877  }
878  }
879  }
880  assert(preg_->getNextIndexValue(branchType_) == productHolders_.size());
881  }
882 }
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:839
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:818
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:449
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:812
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:779
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:759
void getManyByType(TypeID const &typeID, BasicHandleVec &results, EDConsumerBase const *consumes, ModuleCallingContext const *mcc) const
Definition: Principal.cc:531
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:499
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:725
std::string const & moduleLabel() const
ConstProductHolderPtr getProductHolderByIndex(ProductHolderIndex const &oid) const
Definition: Principal.cc:458
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:632
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:418
void checkUniquenessAndType(WrapperBase const *prod, ProductHolderBase const *productHolder) const
Definition: Principal.cc:825
void addSourceProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:286
tuple result
Definition: query.py:137
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:602
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:736
DelayedReader * reader() const
Definition: Principal.h:171
virtual ~Principal()
Definition: Principal.cc:241
bool willSkipCurrentProcess() const
Definition: InputTag.h:49
void prefetch(ProductHolderIndex index, bool skipCurrentProcess, ModuleCallingContext const *mcc) const
Definition: Principal.cc:521
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:43
std::string const & process() const
Definition: InputTag.h:47
unsigned long CacheIdentifier_t
Definition: Principal.h:168
virtual WrapperBase const * getIt(ProductID const &) const override
Definition: Principal.cc:806
bool registeredToConsume(ProductHolderIndex, bool, BranchType) const
void addProductOrThrow(std::auto_ptr< ProductHolderBase > phb)
Definition: Principal.cc:432
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:863
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:465
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:793
void putProduct(std::unique_ptr< WrapperBase > edp, ProductProvenance const &productProvenance)
std::string const & instance() const
Definition: InputTag.h:44
ProcessConfiguration const * processConfiguration_
Definition: Principal.h: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