CMS 3D CMS Logo

Principal.cc
Go to the documentation of this file.
1 
5 
14 #include "ProductResolvers.h"
19 
21 
22 #include <algorithm>
23 #include <cstring>
24 #include <limits>
25 #include <sstream>
26 #include <stdexcept>
27 #include <typeinfo>
28 #include <atomic>
29 
30 namespace edm {
31 
33 
34  static
35  void
37  throw Exception(error, "InvalidID")
38  << "Principal::" << where << ": no product with given branch id: "<< bid << "\n";
39  }
40 
41  static
42  std::shared_ptr<cms::Exception>
43  makeNotFoundException(char const* where, KindOfType kindOfType,
44  TypeID const& productType, std::string const& label, std::string const& instance, std::string const& process) {
45  std::shared_ptr<cms::Exception> exception = std::make_shared<Exception>(errors::ProductNotFound);
46  if (kindOfType == PRODUCT_TYPE) {
47  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
48  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
49  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
50  } else {
51  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for a container with elements of type: " << productType << "\n"
52  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
53  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
54  }
55  return exception;
56  }
57 
58  static
59  void
60  throwAmbiguousException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
61  cms::Exception exception("AmbiguousProduct");
62  exception << "Principal::" << where << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
63  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
64  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
65  << "This can only occur with get function calls using a Handle<View> argument.\n"
66  << "Try a get not using a View or change the instance name of one of the products";
67  throw exception;
68 
69  }
70 
71  namespace {
72  void failedToRegisterConsumesMany(edm::TypeID const& iType) {
73  cms::Exception exception("GetManyWithoutRegistration");
74  exception << "::getManyByType called for " << iType
75  << " without a corresponding consumesMany being called for this module. \n";
76  throw exception;
77  }
78 
79  void failedToRegisterConsumes(KindOfType kindOfType,
80  TypeID const& productType,
81  std::string const& moduleLabel,
82  std::string const& productInstanceName,
83  std::string const& processName) {
84  cms::Exception exception("GetByLabelWithoutRegistration");
85  exception << "::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
86  << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<") << productType
87  << (kindOfType == PRODUCT_TYPE ? "\n module label: " : ">\n module label: ") << moduleLabel
88  <<"\n product instance name: '" << productInstanceName
89  <<"'\n process name: '" << processName << "'\n";
90  throw exception;
91  }
92 }
93 
94  //0 means unset
95  static std::atomic<Principal::CacheIdentifier_t> s_nextIdentifier{1};
97  return s_nextIdentifier.fetch_add(1,std::memory_order_acq_rel);
98  }
99 
100  Principal::Principal(std::shared_ptr<ProductRegistry const> reg,
101  std::shared_ptr<ProductResolverIndexHelper const> productLookup,
102  ProcessConfiguration const& pc,
103  BranchType bt,
104  HistoryAppender* historyAppender,
105  bool isForPrimaryProcess) :
106  EDProductGetter(),
107  processHistoryPtr_(),
108  processHistoryID_(),
109  processConfiguration_(&pc),
110  productResolvers_(),
111  preg_(reg),
112  productLookup_(productLookup),
113  lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
114  reader_(),
115  branchType_(bt),
116  historyAppender_(historyAppender),
117  cacheIdentifier_(nextIdentifier()),
118  atEndTransition_(false)
119  {
120  productResolvers_.resize(reg->getNextIndexValue(bt));
121  //Now that these have been set, we can create the list of Branches we need.
122  std::string const source("source");
123  ProductRegistry::ProductList const& prodsList = reg->productList();
124  // The constructor of an alias product holder takes as an argument the product holder for which it is an alias.
125  // So, the non-alias product holders must be created first.
126  // Therefore, on this first pass, skip current EDAliases.
127  bool hasAliases = false;
128  for(auto const& prod : prodsList) {
129  BranchDescription const& bd = prod.second;
130  if(bd.branchType() == branchType_) {
131  if(isForPrimaryProcess or bd.processName() == pc.processName()) {
132  if(bd.isAlias()) {
133  hasAliases = true;
134  } else {
135  auto cbd = std::make_shared<BranchDescription const>(bd);
136  if(bd.produced()) {
137  if(bd.moduleLabel() == source) {
138  addSourceProduct(cbd);
139  } else if(bd.onDemand()) {
140  assert(branchType_ == InEvent);
142  } else {
143  addScheduledProduct(cbd);
144  }
145  } else {
146  addInputProduct(cbd);
147  }
148  }
149  } else {
150  //We are in a SubProcess and this branch is from the parent
151  auto cbd =std::make_shared<BranchDescription const>(bd);
153  }
154  }
155  }
156  // Now process any EDAliases
157  if(hasAliases) {
158  for(auto const& prod : prodsList) {
159  BranchDescription const& bd = prod.second;
160  if(bd.isAlias() && bd.branchType() == branchType_) {
161  auto cbd = std::make_shared<BranchDescription const>(bd);
162  addAliasedProduct(cbd);
163  }
164  }
165  }
166 
167  // Now create the ProductResolvers that search in reverse process
168  // order and are used for queries where the process name is the
169  // empty string
170  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
171  std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
172  std::vector<bool> ambiguous(lookupProcessNames.size(), false);
173  unsigned int beginElements = productLookup_->beginElements();
174  std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
175  std::vector<ProductResolverIndexHelper::Range> const& ranges = productLookup_->ranges();
176  std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
177  std::vector<char> const& processNamesCharArray = productLookup_->processNames();
178 
179  unsigned int numberOfMatches = 0;
181  if (!sortedTypeIDs.empty()) {
182  ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
183  for(unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
184  ProductResolverIndexHelper::Range const& range = ranges.at(k);
185  for (unsigned int i = range.begin(); i < range.end(); ++i) {
186  ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
187  if (product.startInProcessNames() == 0) {
188  if (productResolverIndex != ProductResolverIndexInvalid) {
189  if ((numberOfMatches == 1) and
190  (lastMatchIndex != ProductResolverIndexAmbiguous)) {
191  //only one choice so use a special resolver
192  productResolvers_.at(productResolverIndex) = std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
193  } else {
194  std::shared_ptr<ProductResolverBase> newHolder = std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous);
195  productResolvers_.at(productResolverIndex) = newHolder;
196  }
197  matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
198  ambiguous.assign(lookupProcessNames.size(), false);
199  numberOfMatches= 0;
200  lastMatchIndex = ProductResolverIndexInvalid;
201  }
202  productResolverIndex = product.index();
203  } else {
204  std::string process(&processNamesCharArray.at(product.startInProcessNames()));
205  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
206  assert(iter != lookupProcessNames.end());
207  ProductResolverIndex iMatchingIndex = product.index();
208  lastMatchIndex = iMatchingIndex;
209  assert(iMatchingIndex != ProductResolverIndexInvalid);
210  ++numberOfMatches;
211  if (iMatchingIndex == ProductResolverIndexAmbiguous) {
212  assert(k >= beginElements);
213  ambiguous.at(iter - lookupProcessNames.begin()) = true;
214  } else {
215  matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
216  }
217  }
218  }
219  }
220  std::shared_ptr<ProductResolverBase> newHolder = std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous);
221  productResolvers_.at(productResolverIndex) = newHolder;
222  }
223  }
224 
226  }
227 
228  // Number of products in the Principal.
229  // For products in an input file and not yet read in due to delayed read,
230  // this routine assumes a real product is there.
231  size_t
232  Principal::size() const {
233  size_t size = 0U;
234  for(auto const& prod : *this) {
235  if(prod->singleProduct() && // Not a NoProcessProductResolver
236  !prod->productUnavailable() &&
237  !prod->unscheduledWasNotRun() &&
238  !prod->branchDescription().dropped()) {
239  ++size;
240  }
241  }
242  return size;
243  }
244 
245  // adjust provenance for input products after new input file has been merged
246  bool
248  ProductRegistry::ProductList const& prodsList = reg.productList();
249  for(auto const& prod : prodsList) {
250  BranchDescription const& bd = prod.second;
251  if(!bd.produced() && (bd.branchType() == branchType_)) {
252  auto cbd = std::make_shared<BranchDescription const>(bd);
253  auto phb = getExistingProduct(cbd->branchID());
254  if(phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
255  return false;
256  }
257  phb->resetBranchDescription(cbd);
258  }
259  }
260  return true;
261  }
262 
263  void
264  Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
265  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
267  }
268 
269  void
270  Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
271  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
273  }
274 
275  void
276  Principal::addInputProduct(std::shared_ptr<BranchDescription const> bd) {
277  addProductOrThrow(std::make_unique<InputProductResolver>(std::move(bd)));
278  }
279 
280  void
281  Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
282  addProductOrThrow(std::make_unique<UnscheduledProductResolver>(std::move(bd)));
283  }
284 
285  void
286  Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
287  ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
288  assert(index != ProductResolverIndexInvalid);
289 
290  addProductOrThrow(std::make_unique<AliasProductResolver>(std::move(bd), dynamic_cast<ProducedProductResolver&>(*productResolvers_[index])));
291  }
292 
293  void
294  Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
295  addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
296  }
297 
298  // "Zero" the principal so it can be reused for another Event.
299  void
301  processHistoryPtr_.reset();
303  reader_ = nullptr;
304  for(auto& prod : *this) {
305  prod->resetProductData();
306  }
307  }
308 
309  void
311  atEndTransition_ = iAtEnd;
312  }
313 
314  void
316  auto phb = getExistingProduct(id);
317  assert(nullptr != phb);
318  phb->unsafe_deleteProduct();
319  }
320 
321  void
323  applyToResolvers([&iConfigure](ProductResolverBase* iResolver) {
324  iResolver->setupUnscheduled(iConfigure);
325  });
326  }
327 
328 
329  // Set the principal for the Event, Lumi, or Run.
330  void
332  ProcessHistoryRegistry const& processHistoryRegistry,
334  //increment identifier here since clearPrincipal isn't called for Run/Lumi
336  atEndTransition_=false;
337  if(reader) {
338  reader_ = reader;
339  }
340 
341  if (historyAppender_ && productRegistry().anyProductProduced()) {
343  historyAppender_->appendToProcessHistory(hist,
344  processHistoryRegistry.getMapped(hist),
347  }
348  else {
349  std::shared_ptr<ProcessHistory const> inputProcessHistory;
350  if (hist.isValid()) {
351  //does not own the pointer
352  auto noDel =[](void const*){};
353  inputProcessHistory =
354  std::shared_ptr<ProcessHistory const>(processHistoryRegistry.getMapped(hist),noDel);
355  if (inputProcessHistory.get() == nullptr) {
357  << "Principal::fillPrincipal\n"
358  << "Input ProcessHistory not found in registry\n"
359  << "Contact a Framework developer\n";
360  }
361  } else {
362  //Since this is static we don't want it deleted
363  inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory,[](void const*){});
364  }
366  processHistoryPtr_ = inputProcessHistory;
367  }
368 
370  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
371  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
372  unsigned int k = 0;
373  for (auto iter = processHistoryPtr_->rbegin(),
374  iEnd = processHistoryPtr_->rend();
375  iter != iEnd; ++iter) {
376  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
377  if (nameIter == lookupProcessNames.end()) {
378  continue;
379  }
380  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
381  ++k;
382  }
384  }
385  }
386 
389  return const_cast<ProductResolverBase*>( const_cast<const Principal*>(this)->getExistingProduct(branchID));
390  }
391 
392  ProductResolverBase const*
393  Principal::getExistingProduct(BranchID const& branchID) const {
394  ProductResolverIndex index = preg_->indexFrom(branchID);
395  assert(index != ProductResolverIndexInvalid);
396  return productResolvers_.at(index).get();
397  }
398 
399  ProductResolverBase const*
400  Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
401  auto phb = getExistingProduct(productResolver.branchDescription().branchID());
402  if(nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
403  BranchDescription const& newProduct = phb->branchDescription();
404  BranchDescription const& existing = productResolver.branchDescription();
405  if(newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
406  throw cms::Exception("HashCollision") << "Principal::getExistingProduct\n" <<
407  " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName() << "\n" <<
408  "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
409  } else {
410  assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
411  }
412  }
413  return phb;
414  }
415 
416  void
417  Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
418  BranchDescription const& bd = productResolver->branchDescription();
419  assert (!bd.className().empty());
420  assert (!bd.friendlyClassName().empty());
421  assert (!bd.moduleLabel().empty());
422  assert (!bd.processName().empty());
423  SharedProductPtr phb(productResolver.release());
424 
425  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
426  assert(index != ProductResolverIndexInvalid);
427  productResolvers_[index] = phb;
428  }
429 
430  void
431  Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
432  ProductResolverBase const* phb = getExistingProduct(*productResolver);
433  if(phb != nullptr) {
434  BranchDescription const& bd = productResolver->branchDescription();
435  throw Exception(errors::InsertFailure, "AlreadyPresent")
436  << "addProductOrThrow: Problem found while adding product, "
437  << "product already exists for ("
438  << bd.friendlyClassName() << ","
439  << bd.moduleLabel() << ","
440  << bd.productInstanceName() << ","
441  << bd.processName()
442  << ")\n";
443  }
444  addProduct_(std::move(productResolver));
445  }
446 
449  ProductResolverIndex index = preg_->indexFrom(bid);
450  if(index == ProductResolverIndexInvalid){
451  return ConstProductResolverPtr();
452  }
453  return getProductResolverByIndex(index);
454  }
455 
458 
460  return phb;
461  }
462 
465  TypeID const& typeID,
466  InputTag const& inputTag,
467  EDConsumerBase const* consumer,
469  ModuleCallingContext const* mcc) const {
470 
471  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, 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->wrapper(), &(result->provenance()));
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,
488  ModuleCallingContext const* mcc) const {
489 
490  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process,consumer, sra, mcc);
491  if(result == 0) {
492  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
493  return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
494  }));
495  }
496  return BasicHandle(result->wrapper(), &(result->provenance()));
497  }
498 
501  TypeID const&,
503  bool skipCurrentProcess,
504  bool& ambiguous,
506  ModuleCallingContext const* mcc) const {
507  assert(index !=ProductResolverIndexInvalid);
508  auto& productResolver = productResolvers_[index];
509  assert(0!=productResolver.get());
510  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
511  if(resolution.isAmbiguous()) {
512  ambiguous = true;
513  return BasicHandle();
514  }
515  auto productData = resolution.data();
516  if(productData == nullptr) {
517  return BasicHandle();
518  }
519  return BasicHandle(productData->wrapper(), &(productData->provenance()));
520  }
521 
522  void
525  bool skipCurrentProcess,
526  ModuleCallingContext const* mcc) const {
527  auto const& productResolver = productResolvers_.at(index);
528  assert(0!=productResolver.get());
529  productResolver->prefetchAsync(task,*this, skipCurrentProcess,nullptr,mcc);
530  }
531 
532  void
535  EDConsumerBase const* consumer,
537  ModuleCallingContext const* mcc) const {
538 
539  assert(results.empty());
540 
541  if(unlikely(consumer and (not consumer->registeredToConsumeMany(typeID,branchType())))) {
542  failedToRegisterConsumesMany(typeID);
543  }
544 
545  // This finds the indexes to all the ProductResolver's matching the type
548 
549  if (matches.numberOfMatches() == 0) {
550  return;
551  }
552 
553  results.reserve(matches.numberOfMatches());
554 
555  // Loop over the ProductResolvers. Add the products that are actually
556  // present into the results. This will also trigger delayed reading,
557  // on demand production, and check for deleted products as appropriate.
558 
559  // Over the years the code that uses getManyByType has grown to depend
560  // on the ordering of the results. The order originally was just an
561  // accident of how previous versions of the code were written, but
562  // here we have to go through some extra effort to preserve that ordering.
563 
564  // We build a list of holders that match a particular label and instance.
565  // When that list is complete we call findProducts, which loops over
566  // that list in reverse order of the ProcessHistory (starts with the
567  // most recent). Then we clear the list and repeat this until all the
568  // matching label and instance subsets have been dealt with.
569 
570  // Note that the function isFullyResolved returns true for the ProductResolvers
571  // that are associated with an empty process name. Those are the ones that
572  // know how to search for the most recent process name matching
573  // a label and instance. We do not need these for getManyByType and
574  // skip them. In addition to skipping them, we make use of the fact
575  // that they mark the beginning of each subset of holders with the same
576  // label and instance. They tell us when to call findProducts.
577 
578  std::vector<ProductResolverBase const*> holders;
579 
580  for(unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
581 
582  ProductResolverIndex index = matches.index(i);
583 
584  if(!matches.isFullyResolved(i)) {
585  if(!holders.empty()) {
586  // Process the ones with a particular module label and instance
587  findProducts(holders, typeID, results, sra, mcc);
588  holders.clear();
589  }
590  } else {
591  ProductResolverBase const* productResolver = productResolvers_.at(index).get();
592  assert(productResolver);
593  holders.push_back(productResolver);
594  }
595  }
596  // Do not miss the last subset of products
597  if(!holders.empty()) {
598  findProducts(holders, typeID, results, sra, mcc);
599  }
600  return;
601  }
602 
603  void
604  Principal::findProducts(std::vector<ProductResolverBase const*> const& holders,
605  TypeID const&,
608  ModuleCallingContext const* mcc) const {
609 
610  for (auto iter = processHistoryPtr_->rbegin(),
611  iEnd = processHistoryPtr_->rend();
612  iter != iEnd; ++iter) {
613  std::string const& process = iter->processName();
614  for (auto productResolver : holders) {
615  BranchDescription const& bd = productResolver->branchDescription();
616  if (process == bd.processName()) {
617 
618  // Ignore aliases to avoid matching the same product multiple times.
619  if(bd.isAlias()) {
620  continue;
621  }
622 
623  ProductData const* productData = productResolver->resolveProduct(*this,false, sra, mcc).data();
624  if(productData) {
625  // Skip product if not available.
626  results.emplace_back(productData->wrapper(), &(productData->provenance()));
627  }
628  }
629  }
630  }
631  }
632 
633  ProductData const*
635  TypeID const& typeID,
636  InputTag const& inputTag,
637  EDConsumerBase const* consumer,
639  ModuleCallingContext const* mcc) const {
640 
641  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
642 
644 
645  if (index == ProductResolverIndexInvalid) {
646 
647  char const* processName = inputTag.process().c_str();
648  if (skipCurrentProcess) {
649  processName = "\0";
650  }
651 
652  index = productLookup().index(kindOfType,
653  typeID,
654  inputTag.label().c_str(),
655  inputTag.instance().c_str(),
656  processName);
657 
658  if(index == ProductResolverIndexAmbiguous) {
659  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
660  } else if (index == ProductResolverIndexInvalid) {
661  return 0;
662  }
663  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
664  }
665  if(unlikely( consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
666  failedToRegisterConsumes(kindOfType,typeID,inputTag.label(),inputTag.instance(),inputTag.process());
667  }
668 
669 
670  auto const& productResolver = productResolvers_[index];
671 
672  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
673  if(resolution.isAmbiguous()) {
674  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
675  }
676  return resolution.data();
677  }
678 
679  ProductData const*
681  TypeID const& typeID,
682  std::string const& label,
683  std::string const& instance,
684  std::string const& process,
685  EDConsumerBase const* consumer,
687  ModuleCallingContext const* mcc) const {
688 
690  typeID,
691  label.c_str(),
692  instance.c_str(),
693  process.c_str());
694 
695  if(index == ProductResolverIndexAmbiguous) {
696  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
697  } else if (index == ProductResolverIndexInvalid) {
698  return 0;
699  }
700 
701  if(unlikely( consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
702  failedToRegisterConsumes(kindOfType,typeID,label,instance,process);
703  }
704 
705  auto const& productResolver = productResolvers_[index];
706 
707  auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
708  if(resolution.isAmbiguous()) {
709  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
710  }
711  return resolution.data();
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  nullptr,
722  mcc);
723  return productData;
724  }
725 
726  Provenance
728  ModuleCallingContext const* mcc) const {
730  if(phb == nullptr) {
732  }
733 
734  if(phb->unscheduledWasNotRun()) {
735  if(not phb->resolveProduct(*this,false, nullptr, mcc).data() ) {
736  throwProductNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
737  }
738  }
739  return *phb->provenance();
740  }
741 
742  // This one is mostly for test printout purposes
743  // No attempt to trigger on demand execution
744  // Skips provenance when the EDProduct is not there
745  void
746  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
747  provenances.clear();
748  for(auto const& productResolver : *this) {
749  if(productResolver->singleProduct() && productResolver->provenanceAvailable() && !productResolver->branchDescription().isAlias()) {
750  // We do not attempt to get the event/lumi/run status from the provenance,
751  // because the per event provenance may have been dropped.
752  if(productResolver->provenance()->branchDescription().present()) {
753  provenances.push_back(productResolver->provenance());
754  }
755  }
756  }
757  }
758 
759  // This one is also mostly for test printout purposes
760  // No attempt to trigger on demand execution
761  // Skips provenance for dropped branches.
762  void
763  Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
764  provenances.clear();
765  for(auto const& productResolver : *this) {
766  if(productResolver->singleProduct() && !productResolver->branchDescription().isAlias()) {
767  if(productResolver->stableProvenance()->branchDescription().present()) {
768  provenances.push_back(productResolver->stableProvenance());
769  }
770  }
771  }
772  }
773 
774  void
775  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
776  for(auto& prod : bids) {
777  ProductResolverIndex index= preg_->indexFrom(prod);
778  assert(index!=ProductResolverIndexInvalid);
779  ProductResolverIndex indexO = other.preg_->indexFrom(prod);
780  assert(indexO!=ProductResolverIndexInvalid);
782  }
783  reader_->mergeReaders(other.reader());
784  }
785 
786  WrapperBase const*
787  Principal::getIt(ProductID const&) const {
788  assert(false);
789  return nullptr;
790  }
791 
792  WrapperBase const*
793  Principal::getThinnedProduct(ProductID const&, unsigned int&) const {
794  assert(false);
795  return nullptr;
796  }
797 
798  void
800  std::vector<WrapperBase const*>&,
801  std::vector<unsigned int>&) const {
802  assert(false);
803  }
804 
805  void
806  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
807  phb->putOrMergeProduct(std::move(prod));
808  }
809 
810  void
811  Principal::putOrMerge(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
812  if(edp.get() == nullptr) {
813  throw edm::Exception(edm::errors::InsertFailure,"Null Pointer")
814  << "put: Cannot put because unique_ptr to product is null."
815  << "\n";
816  }
817  auto phb = getExistingProduct(bd.branchID());
818  assert(phb);
819  // ProductResolver assumes ownership
820  putOrMerge(std::move(edp), phb);
821  }
822 
823 
824  void
826  if(preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
827  productResolvers_.resize(preg_->getNextIndexValue(branchType_));
828  for(auto const& prod : preg_->productList()) {
829  BranchDescription const& bd = prod.second;
830  if(bd.branchType() == branchType_) {
831  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
832  assert(index != ProductResolverIndexInvalid);
833  if(!productResolvers_[index]) {
834  // no product holder. Must add one. The new entry must be an input product holder.
835  assert(!bd.produced());
836  auto cbd = std::make_shared<BranchDescription const>(bd);
837  addInputProduct(cbd);
838  }
839  }
840  }
841  }
842  assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
843  }
844 
845  void
847  if(not reader()) {return;}
848 
849  for(auto & prod : *this) {
850  prod->retrieveAndMerge(*this);
851  }
852  }
853 
854  void
856  for( auto & prod : *this) {
857  prod->resetFailedFromThisProcess();
858  }
859  }
860 }
BranchType branchType_
Definition: Principal.h:286
size
Write out results.
ProductResolverIndex index(unsigned int i) const
static ProcessHistory const s_emptyProcessHistory
Definition: Principal.cc:32
ProductRegistry const & productRegistry() const
Definition: Principal.h:151
Provenance const & provenance() const
Definition: ProductData.h:30
void clearPrincipal()
Definition: Principal.cc:300
std::string const & branchName() const
size_t size() const
Definition: Principal.cc:232
DelayedReader * reader_
Definition: Principal.h:284
BranchType const & branchType() const
void setupUnscheduled(UnscheduledConfigurator const &)
Definition: Principal.cc:322
unsigned int ProductResolverIndex
bool getMapped(ProcessHistoryID const &key, ProcessHistory &value) const
static std::string const source("source")
ProductResolverCollection productResolvers_
Definition: Principal.h:272
std::shared_ptr< ProcessHistory const > processHistoryPtr_
Definition: Principal.h:265
static PFTauRenderPlugin instance
std::shared_ptr< ProductResolverBase > SharedProductPtr
Definition: Principal.h:67
void addProduct_(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:417
static std::atomic< Principal::CacheIdentifier_t > s_nextIdentifier
Definition: Principal.cc:95
std::map< BranchKey, BranchDescription > ProductList
static Principal::CacheIdentifier_t nextIdentifier()
Definition: Principal.cc:96
ProcessHistoryID processHistoryID_
Definition: Principal.h:267
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:35
ProductResolverBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:388
virtual void setupUnscheduled(UnscheduledConfigurator const &)
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Principal.cc:746
void applyToResolvers(F iFunc)
Definition: Principal.h:217
void getAllStableProvenance(std::vector< StableProvenance const * > &provenances) const
Definition: Principal.cc:763
Provenance getProvenance(BranchID const &bid, ModuleCallingContext const *mcc) const
Definition: Principal.cc:727
WrapperBase const * wrapper() const
Definition: ProductData.h:32
virtual void getThinnedProducts(ProductID const &, std::vector< WrapperBase const * > &, std::vector< unsigned int > &) const override
Definition: Principal.cc:799
std::string const & processName() const
void setAtEndTransition(bool iAtEnd)
Definition: Principal.cc:310
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
Principal(std::shared_ptr< ProductRegistry const > reg, std::shared_ptr< ProductResolverIndexHelper const > productLookup, ProcessConfiguration const &pc, BranchType bt, HistoryAppender *historyAppender, bool isForPrimaryProcess=true)
Definition: Principal.cc:100
void addInputProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:276
edm::propagate_const< HistoryAppender * > historyAppender_
Definition: Principal.h:291
BranchType
Definition: BranchType.h:11
ProductResolverIndex indexFor(TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:186
void tryToCacheIndex(ProductResolverIndex index, TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:204
void readAllFromSourceAndMergeImmediately()
Definition: Principal.cc:846
static void throwAmbiguousException(const char *where, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:60
std::string const & processName() const
#define unlikely(x)
ProductList const & productList() const
std::vector< unsigned int > lookupProcessOrder_
Definition: Principal.h:279
BasicHandle getByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:464
void addScheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:264
std::string const & className() const
ProductData const * findProductByTag(TypeID const &typeID, InputTag const &tag, ModuleCallingContext const *mcc) const
Definition: Principal.cc:715
std::shared_ptr< ProductResolverIndexHelper const > productLookup_
Definition: Principal.h:277
std::string const & moduleLabel() const
void addProductOrThrow(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:431
std::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:276
std::string const & productInstanceName() const
bool registeredToConsume(ProductResolverIndex, bool, BranchType) const
CacheIdentifier_t cacheIdentifier_
Definition: Principal.h:293
BranchType const & branchType() const
Definition: Principal.h:178
std::shared_ptr< HandleExceptionFactory > makeHandleExceptionFactory(T &&iFunctor)
void putOrMerge(BranchDescription const &bd, std::unique_ptr< WrapperBase > edp) const
Definition: Principal.cc:811
void prefetchAsync(WaitingTask *waitTask, ProductResolverIndex index, bool skipCurrentProcess, ModuleCallingContext const *mcc) const
Definition: Principal.cc:523
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void addSourceProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:270
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
ProcessHistoryID orderProcessHistoryID_
Definition: Principal.h:280
std::string const & friendlyClassName() const
BranchID const & branchID() const
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
void addParentProcessProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:294
Hash< ProcessHistoryType > ProcessHistoryID
int k[5][pyjets_maxn]
string ranges
Definition: diffTwoXMLs.py:78
DelayedReader * reader() const
Definition: Principal.h:184
virtual ~Principal()
Definition: Principal.cc:225
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
bool registeredToConsumeMany(TypeID const &, BranchType) const
void addUnscheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:281
virtual WrapperBase const * getIt(ProductID const &) const override
Definition: Principal.cc:787
ProductResolverIndexHelper const & productLookup() const
Definition: Principal.h:153
void resetFailedFromThisProcess()
Definition: Principal.cc:855
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:43
ProductResolverBase const * ConstProductResolverPtr
Definition: Principal.h:63
std::string const & label() const
Definition: InputTag.h:36
void findProducts(std::vector< ProductResolverBase const * > const &holders, TypeID const &typeID, BasicHandleVec &results, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:604
std::string const & process() const
Definition: InputTag.h:40
ProductResolverIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
HLT enums.
unsigned long CacheIdentifier_t
Definition: Principal.h:181
virtual WrapperBase const * getThinnedProduct(ProductID const &, unsigned int &) const override
Definition: Principal.cc:793
bool isValid() const
Definition: Hash.h:151
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:247
BranchDescription const & branchDescription() const
ProductData const * findProductByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumer, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:634
ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const &oid) const
Definition: Principal.cc:457
ConstProductResolverPtr getProductResolver(BranchID const &oid) const
Definition: Principal.cc:448
void resetBranchDescription(std::shared_ptr< BranchDescription const > bd)
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:825
static void throwProductNotFoundException(char const *where, errors::ErrorCodes error, BranchID const &bid)
Definition: Principal.cc:36
BasicHandle getByToken(KindOfType kindOfType, TypeID const &typeID, ProductResolverIndex index, bool skipCurrentProcess, bool &ambiguous, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:500
void addAliasedProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:286
void fillPrincipal(ProcessHistoryID const &hist, ProcessHistoryRegistry const &phr, DelayedReader *reader)
Definition: Principal.cc:331
void putOrMergeProduct(std::unique_ptr< WrapperBase > edp) const
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:775
bool atEndTransition_
Definition: Principal.h:295
std::string const & instance() const
Definition: InputTag.h:37
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:269
def move(src, dest)
Definition: eostools.py:510
std::vector< BasicHandle > BasicHandleVec
Definition: Principal.h:64
void getManyByType(TypeID const &typeID, BasicHandleVec &results, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:533
void deleteProduct(BranchID const &id) const
Definition: Principal.cc:315