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  {
119  productResolvers_.resize(reg->getNextIndexValue(bt));
120  //Now that these have been set, we can create the list of Branches we need.
121  std::string const source("source");
122  ProductRegistry::ProductList const& prodsList = reg->productList();
123  // The constructor of an alias product holder takes as an argument the product holder for which it is an alias.
124  // So, the non-alias product holders must be created first.
125  // Therefore, on this first pass, skip current EDAliases.
126  bool hasAliases = false;
127  for(auto const& prod : prodsList) {
128  BranchDescription const& bd = prod.second;
129  if(bd.branchType() == branchType_) {
130  if(isForPrimaryProcess or bd.processName() == pc.processName()) {
131  if(bd.isAlias()) {
132  hasAliases = true;
133  } else {
134  auto cbd = std::make_shared<BranchDescription const>(bd);
135  if(bd.produced()) {
136  if(bd.moduleLabel() == source) {
137  addSourceProduct(cbd);
138  } else if(bd.onDemand()) {
139  assert(branchType_ == InEvent);
141  } else {
142  addScheduledProduct(cbd);
143  }
144  } else {
145  addInputProduct(cbd);
146  }
147  }
148  } else {
149  //We are in a SubProcess and this branch is from the parent
150  auto cbd =std::make_shared<BranchDescription const>(bd);
152  }
153  }
154  }
155  // Now process any EDAliases
156  if(hasAliases) {
157  for(auto const& prod : prodsList) {
158  BranchDescription const& bd = prod.second;
159  if(bd.isAlias() && bd.branchType() == branchType_) {
160  auto cbd = std::make_shared<BranchDescription const>(bd);
161  addAliasedProduct(cbd);
162  }
163  }
164  }
165 
166  // Now create the ProductResolvers that search in reverse process
167  // order and are used for queries where the process name is the
168  // empty string
169  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
170  std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
171  std::vector<bool> ambiguous(lookupProcessNames.size(), false);
172  unsigned int beginElements = productLookup_->beginElements();
173  std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
174  std::vector<ProductResolverIndexHelper::Range> const& ranges = productLookup_->ranges();
175  std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
176  std::vector<char> const& processNamesCharArray = productLookup_->processNames();
177 
178  unsigned int numberOfMatches = 0;
180  if (!sortedTypeIDs.empty()) {
181  ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
182  for(unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
183  ProductResolverIndexHelper::Range const& range = ranges.at(k);
184  for (unsigned int i = range.begin(); i < range.end(); ++i) {
185  ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
186  if (product.startInProcessNames() == 0) {
187  if (productResolverIndex != ProductResolverIndexInvalid) {
188  if ((numberOfMatches == 1) and
189  (lastMatchIndex != ProductResolverIndexAmbiguous)) {
190  //only one choice so use a special resolver
191  productResolvers_.at(productResolverIndex) = std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
192  } else {
193  std::shared_ptr<ProductResolverBase> newHolder = std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous);
194  productResolvers_.at(productResolverIndex) = newHolder;
195  }
196  matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
197  ambiguous.assign(lookupProcessNames.size(), false);
198  numberOfMatches= 0;
199  lastMatchIndex = ProductResolverIndexInvalid;
200  }
201  productResolverIndex = product.index();
202  } else {
203  std::string process(&processNamesCharArray.at(product.startInProcessNames()));
204  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
205  assert(iter != lookupProcessNames.end());
206  ProductResolverIndex iMatchingIndex = product.index();
207  lastMatchIndex = iMatchingIndex;
208  assert(iMatchingIndex != ProductResolverIndexInvalid);
209  ++numberOfMatches;
210  if (iMatchingIndex == ProductResolverIndexAmbiguous) {
211  assert(k >= beginElements);
212  ambiguous.at(iter - lookupProcessNames.begin()) = true;
213  } else {
214  matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
215  }
216  }
217  }
218  }
219  std::shared_ptr<ProductResolverBase> newHolder = std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous);
220  productResolvers_.at(productResolverIndex) = newHolder;
221  }
222  }
223 
225  }
226 
227  // Number of products in the Principal.
228  // For products in an input file and not yet read in due to delayed read,
229  // this routine assumes a real product is there.
230  size_t
231  Principal::size() const {
232  size_t size = 0U;
233  for(auto const& prod : *this) {
234  if(prod->singleProduct() && // Not a NoProcessProductResolver
235  !prod->productUnavailable() &&
236  !prod->unscheduledWasNotRun() &&
237  !prod->branchDescription().dropped()) {
238  ++size;
239  }
240  }
241  return size;
242  }
243 
244  // adjust provenance for input products after new input file has been merged
245  bool
247  ProductRegistry::ProductList const& prodsList = reg.productList();
248  for(auto const& prod : prodsList) {
249  BranchDescription const& bd = prod.second;
250  if(!bd.produced() && (bd.branchType() == branchType_)) {
251  auto cbd = std::make_shared<BranchDescription const>(bd);
252  auto phb = getExistingProduct(cbd->branchID());
253  if(phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
254  return false;
255  }
256  phb->resetBranchDescription(cbd);
257  }
258  }
259  return true;
260  }
261 
262  void
263  Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
264  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
266  }
267 
268  void
269  Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
270  auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
272  }
273 
274  void
275  Principal::addInputProduct(std::shared_ptr<BranchDescription const> bd) {
276  addProductOrThrow(std::make_unique<InputProductResolver>(std::move(bd)));
277  }
278 
279  void
280  Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
281  addProductOrThrow(std::make_unique<UnscheduledProductResolver>(std::move(bd)));
282  }
283 
284  void
285  Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
286  ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
287  assert(index != ProductResolverIndexInvalid);
288 
289  addProductOrThrow(std::make_unique<AliasProductResolver>(std::move(bd), dynamic_cast<ProducedProductResolver&>(*productResolvers_[index])));
290  }
291 
292  void
293  Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
294  addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
295  }
296 
297  // "Zero" the principal so it can be reused for another Event.
298  void
300  processHistoryPtr_.reset();
302  reader_ = nullptr;
303  for(auto& prod : *this) {
304  prod->resetProductData();
305  }
306  }
307 
308  void
310  auto phb = getExistingProduct(id);
311  assert(nullptr != phb);
312  phb->unsafe_deleteProduct();
313  }
314 
315  // Set the principal for the Event, Lumi, or Run.
316  void
318  ProcessHistoryRegistry const& processHistoryRegistry,
320  //increment identifier here since clearPrincipal isn't called for Run/Lumi
322  if(reader) {
323  reader_ = reader;
324  }
325 
326  if (historyAppender_ && productRegistry().anyProductProduced()) {
328  historyAppender_->appendToProcessHistory(hist,
329  processHistoryRegistry.getMapped(hist),
332  }
333  else {
334  std::shared_ptr<ProcessHistory const> inputProcessHistory;
335  if (hist.isValid()) {
336  //does not own the pointer
337  auto noDel =[](void const*){};
338  inputProcessHistory =
339  std::shared_ptr<ProcessHistory const>(processHistoryRegistry.getMapped(hist),noDel);
340  if (inputProcessHistory.get() == nullptr) {
342  << "Principal::fillPrincipal\n"
343  << "Input ProcessHistory not found in registry\n"
344  << "Contact a Framework developer\n";
345  }
346  } else {
347  //Since this is static we don't want it deleted
348  inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory,[](void const*){});
349  }
351  processHistoryPtr_ = inputProcessHistory;
352  }
353 
355  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
356  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
357  unsigned int k = 0;
358  for (auto iter = processHistoryPtr_->rbegin(),
359  iEnd = processHistoryPtr_->rend();
360  iter != iEnd; ++iter) {
361  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
362  if (nameIter == lookupProcessNames.end()) {
363  continue;
364  }
365  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
366  ++k;
367  }
369  }
370  }
371 
374  return const_cast<ProductResolverBase*>( const_cast<const Principal*>(this)->getExistingProduct(branchID));
375  }
376 
377  ProductResolverBase const*
378  Principal::getExistingProduct(BranchID const& branchID) const {
379  ProductResolverIndex index = preg_->indexFrom(branchID);
380  assert(index != ProductResolverIndexInvalid);
381  return productResolvers_.at(index).get();
382  }
383 
384  ProductResolverBase const*
385  Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
386  auto phb = getExistingProduct(productResolver.branchDescription().branchID());
387  if(nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
388  BranchDescription const& newProduct = phb->branchDescription();
389  BranchDescription const& existing = productResolver.branchDescription();
390  if(newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
391  throw cms::Exception("HashCollision") << "Principal::getExistingProduct\n" <<
392  " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName() << "\n" <<
393  "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
394  } else {
395  assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
396  }
397  }
398  return phb;
399  }
400 
401  void
402  Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
403  BranchDescription const& bd = productResolver->branchDescription();
404  assert (!bd.className().empty());
405  assert (!bd.friendlyClassName().empty());
406  assert (!bd.moduleLabel().empty());
407  assert (!bd.processName().empty());
408  SharedProductPtr phb(productResolver.release());
409 
410  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
411  assert(index != ProductResolverIndexInvalid);
412  productResolvers_[index] = phb;
413  }
414 
415  void
416  Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
417  ProductResolverBase const* phb = getExistingProduct(*productResolver);
418  if(phb != nullptr) {
419  BranchDescription const& bd = productResolver->branchDescription();
420  throw Exception(errors::InsertFailure, "AlreadyPresent")
421  << "addProductOrThrow: Problem found while adding product, "
422  << "product already exists for ("
423  << bd.friendlyClassName() << ","
424  << bd.moduleLabel() << ","
425  << bd.productInstanceName() << ","
426  << bd.processName()
427  << ")\n";
428  }
429  addProduct_(std::move(productResolver));
430  }
431 
434  ProductResolverIndex index = preg_->indexFrom(bid);
435  if(index == ProductResolverIndexInvalid){
436  return ConstProductResolverPtr();
437  }
438  return getProductResolverByIndex(index);
439  }
440 
443 
445  return phb;
446  }
447 
450  TypeID const& typeID,
451  InputTag const& inputTag,
452  EDConsumerBase const* consumer,
454  ModuleCallingContext const* mcc) const {
455 
456  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
457  if(result == 0) {
458  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
459  return makeNotFoundException("getByLabel", kindOfType, typeID, inputTag.label(), inputTag.instance(), inputTag.process());
460  }));
461  }
462  return BasicHandle(result->wrapper(), &(result->provenance()));
463  }
464 
467  TypeID const& typeID,
468  std::string const& label,
469  std::string const& instance,
470  std::string const& process,
471  EDConsumerBase const* consumer,
473  ModuleCallingContext const* mcc) const {
474 
475  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process,consumer, sra, mcc);
476  if(result == 0) {
477  return BasicHandle(makeHandleExceptionFactory([=]()->std::shared_ptr<cms::Exception> {
478  return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
479  }));
480  }
481  return BasicHandle(result->wrapper(), &(result->provenance()));
482  }
483 
486  TypeID const&,
488  bool skipCurrentProcess,
489  bool& ambiguous,
491  ModuleCallingContext const* mcc) const {
492  assert(index !=ProductResolverIndexInvalid);
493  auto& productResolver = productResolvers_[index];
494  assert(0!=productResolver.get());
495  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
496  if(resolution.isAmbiguous()) {
497  ambiguous = true;
498  return BasicHandle();
499  }
500  auto productData = resolution.data();
501  if(productData == nullptr) {
502  return BasicHandle();
503  }
504  return BasicHandle(productData->wrapper(), &(productData->provenance()));
505  }
506 
507  void
510  bool skipCurrentProcess,
511  ModuleCallingContext const* mcc) const {
512  auto const& productResolver = productResolvers_.at(index);
513  assert(0!=productResolver.get());
514  productResolver->prefetchAsync(task,*this, skipCurrentProcess,nullptr,mcc);
515  }
516 
517  void
520  EDConsumerBase const* consumer,
522  ModuleCallingContext const* mcc) const {
523 
524  assert(results.empty());
525 
526  if(unlikely(consumer and (not consumer->registeredToConsumeMany(typeID,branchType())))) {
527  failedToRegisterConsumesMany(typeID);
528  }
529 
530  // This finds the indexes to all the ProductResolver's matching the type
533 
534  if (matches.numberOfMatches() == 0) {
535  return;
536  }
537 
538  results.reserve(matches.numberOfMatches());
539 
540  // Loop over the ProductResolvers. Add the products that are actually
541  // present into the results. This will also trigger delayed reading,
542  // on demand production, and check for deleted products as appropriate.
543 
544  // Over the years the code that uses getManyByType has grown to depend
545  // on the ordering of the results. The order originally was just an
546  // accident of how previous versions of the code were written, but
547  // here we have to go through some extra effort to preserve that ordering.
548 
549  // We build a list of holders that match a particular label and instance.
550  // When that list is complete we call findProducts, which loops over
551  // that list in reverse order of the ProcessHistory (starts with the
552  // most recent). Then we clear the list and repeat this until all the
553  // matching label and instance subsets have been dealt with.
554 
555  // Note that the function isFullyResolved returns true for the ProductResolvers
556  // that are associated with an empty process name. Those are the ones that
557  // know how to search for the most recent process name matching
558  // a label and instance. We do not need these for getManyByType and
559  // skip them. In addition to skipping them, we make use of the fact
560  // that they mark the beginning of each subset of holders with the same
561  // label and instance. They tell us when to call findProducts.
562 
563  std::vector<ProductResolverBase const*> holders;
564 
565  for(unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
566 
567  ProductResolverIndex index = matches.index(i);
568 
569  if(!matches.isFullyResolved(i)) {
570  if(!holders.empty()) {
571  // Process the ones with a particular module label and instance
572  findProducts(holders, typeID, results, sra, mcc);
573  holders.clear();
574  }
575  } else {
576  ProductResolverBase const* productResolver = productResolvers_.at(index).get();
577  assert(productResolver);
578  holders.push_back(productResolver);
579  }
580  }
581  // Do not miss the last subset of products
582  if(!holders.empty()) {
583  findProducts(holders, typeID, results, sra, mcc);
584  }
585  return;
586  }
587 
588  void
589  Principal::findProducts(std::vector<ProductResolverBase const*> const& holders,
590  TypeID const&,
593  ModuleCallingContext const* mcc) const {
594 
595  for (auto iter = processHistoryPtr_->rbegin(),
596  iEnd = processHistoryPtr_->rend();
597  iter != iEnd; ++iter) {
598  std::string const& process = iter->processName();
599  for (auto productResolver : holders) {
600  BranchDescription const& bd = productResolver->branchDescription();
601  if (process == bd.processName()) {
602 
603  // Ignore aliases to avoid matching the same product multiple times.
604  if(bd.isAlias()) {
605  continue;
606  }
607 
608  ProductData const* productData = productResolver->resolveProduct(*this,false, sra, mcc).data();
609  if(productData) {
610  // Skip product if not available.
611  results.emplace_back(productData->wrapper(), &(productData->provenance()));
612  }
613  }
614  }
615  }
616  }
617 
618  ProductData const*
620  TypeID const& typeID,
621  InputTag const& inputTag,
622  EDConsumerBase const* consumer,
624  ModuleCallingContext const* mcc) const {
625 
626  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
627 
629 
630  if (index == ProductResolverIndexInvalid) {
631 
632  char const* processName = inputTag.process().c_str();
633  if (skipCurrentProcess) {
634  processName = "\0";
635  }
636 
637  index = productLookup().index(kindOfType,
638  typeID,
639  inputTag.label().c_str(),
640  inputTag.instance().c_str(),
641  processName);
642 
643  if(index == ProductResolverIndexAmbiguous) {
644  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
645  } else if (index == ProductResolverIndexInvalid) {
646  return 0;
647  }
648  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
649  }
650  if(unlikely( consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
651  failedToRegisterConsumes(kindOfType,typeID,inputTag.label(),inputTag.instance(),inputTag.process());
652  }
653 
654 
655  auto const& productResolver = productResolvers_[index];
656 
657  auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
658  if(resolution.isAmbiguous()) {
659  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
660  }
661  return resolution.data();
662  }
663 
664  ProductData const*
666  TypeID const& typeID,
667  std::string const& label,
668  std::string const& instance,
669  std::string const& process,
670  EDConsumerBase const* consumer,
672  ModuleCallingContext const* mcc) const {
673 
675  typeID,
676  label.c_str(),
677  instance.c_str(),
678  process.c_str());
679 
680  if(index == ProductResolverIndexAmbiguous) {
681  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
682  } else if (index == ProductResolverIndexInvalid) {
683  return 0;
684  }
685 
686  if(unlikely( consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
687  failedToRegisterConsumes(kindOfType,typeID,label,instance,process);
688  }
689 
690  auto const& productResolver = productResolvers_[index];
691 
692  auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
693  if(resolution.isAmbiguous()) {
694  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
695  }
696  return resolution.data();
697  }
698 
699  ProductData const*
700  Principal::findProductByTag(TypeID const& typeID, InputTag const& tag, ModuleCallingContext const* mcc) const {
701  ProductData const* productData =
703  typeID,
704  tag,
705  nullptr,
706  nullptr,
707  mcc);
708  return productData;
709  }
710 
711  Provenance
713  ModuleCallingContext const* mcc) const {
715  if(phb == nullptr) {
717  }
718 
719  if(phb->unscheduledWasNotRun()) {
720  if(not phb->resolveProduct(*this,false, nullptr, mcc).data() ) {
721  throwProductNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
722  }
723  }
724  return *phb->provenance();
725  }
726 
727  // This one is mostly for test printout purposes
728  // No attempt to trigger on demand execution
729  // Skips provenance when the EDProduct is not there
730  void
731  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
732  provenances.clear();
733  for(auto const& productResolver : *this) {
734  if(productResolver->singleProduct() && productResolver->provenanceAvailable() && !productResolver->branchDescription().isAlias()) {
735  // We do not attempt to get the event/lumi/run status from the provenance,
736  // because the per event provenance may have been dropped.
737  if(productResolver->provenance()->branchDescription().present()) {
738  provenances.push_back(productResolver->provenance());
739  }
740  }
741  }
742  }
743 
744  // This one is also mostly for test printout purposes
745  // No attempt to trigger on demand execution
746  // Skips provenance for dropped branches.
747  void
748  Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
749  provenances.clear();
750  for(auto const& productResolver : *this) {
751  if(productResolver->singleProduct() && !productResolver->branchDescription().isAlias()) {
752  if(productResolver->stableProvenance()->branchDescription().present()) {
753  provenances.push_back(productResolver->stableProvenance());
754  }
755  }
756  }
757  }
758 
759  void
760  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
761  for(auto& prod : bids) {
762  ProductResolverIndex index= preg_->indexFrom(prod);
763  assert(index!=ProductResolverIndexInvalid);
764  ProductResolverIndex indexO = other.preg_->indexFrom(prod);
765  assert(indexO!=ProductResolverIndexInvalid);
767  }
768  reader_->mergeReaders(other.reader());
769  }
770 
771  WrapperBase const*
772  Principal::getIt(ProductID const&) const {
773  assert(false);
774  return nullptr;
775  }
776 
777  WrapperBase const*
778  Principal::getThinnedProduct(ProductID const&, unsigned int&) const {
779  assert(false);
780  return nullptr;
781  }
782 
783  void
785  std::vector<WrapperBase const*>&,
786  std::vector<unsigned int>&) const {
787  assert(false);
788  }
789 
790  void
791  Principal::putOrMerge(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
792  phb->putOrMergeProduct(std::move(prod));
793  }
794 
795  void
796  Principal::putOrMerge(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
797  if(edp.get() == nullptr) {
798  throw edm::Exception(edm::errors::InsertFailure,"Null Pointer")
799  << "put: Cannot put because unique_ptr to product is null."
800  << "\n";
801  }
802  auto phb = getExistingProduct(bd.branchID());
803  assert(phb);
804  // ProductResolver assumes ownership
805  putOrMerge(std::move(edp), phb);
806  }
807 
808 
809  void
811  if(preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
812  productResolvers_.resize(preg_->getNextIndexValue(branchType_));
813  for(auto const& prod : preg_->productList()) {
814  BranchDescription const& bd = prod.second;
815  if(bd.branchType() == branchType_) {
816  ProductResolverIndex index = preg_->indexFrom(bd.branchID());
817  assert(index != ProductResolverIndexInvalid);
818  if(!productResolvers_[index]) {
819  // no product holder. Must add one. The new entry must be an input product holder.
820  assert(!bd.produced());
821  auto cbd = std::make_shared<BranchDescription const>(bd);
822  addInputProduct(cbd);
823  }
824  }
825  }
826  }
827  assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
828  }
829 
830  void
832  if(not reader()) {return;}
833 
834  for(auto & prod : *this) {
835  prod->retrieveAndMerge(*this);
836  }
837  }
838 
839  void
841  for( auto & prod : *this) {
842  prod->resetFailedFromThisProcess();
843  }
844  }
845 }
BranchType branchType_
Definition: Principal.h:280
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:145
Provenance const & provenance() const
Definition: ProductData.h:30
void clearPrincipal()
Definition: Principal.cc:299
std::string const & branchName() const
size_t size() const
Definition: Principal.cc:231
DelayedReader * reader_
Definition: Principal.h:278
BranchType const & branchType() const
unsigned int ProductResolverIndex
bool getMapped(ProcessHistoryID const &key, ProcessHistory &value) const
static std::string const source("source")
ProductResolverCollection productResolvers_
Definition: Principal.h:266
std::shared_ptr< ProcessHistory const > processHistoryPtr_
Definition: Principal.h:259
static PFTauRenderPlugin instance
std::shared_ptr< ProductResolverBase > SharedProductPtr
Definition: Principal.h:66
void addProduct_(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:402
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:261
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:35
ProductResolverBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:373
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Principal.cc:731
void getAllStableProvenance(std::vector< StableProvenance const * > &provenances) const
Definition: Principal.cc:748
Provenance getProvenance(BranchID const &bid, ModuleCallingContext const *mcc) const
Definition: Principal.cc:712
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:784
std::string const & processName() const
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:275
edm::propagate_const< HistoryAppender * > historyAppender_
Definition: Principal.h:285
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:831
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:273
BasicHandle getByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:449
void addScheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:263
std::string const & className() const
ProductData const * findProductByTag(TypeID const &typeID, InputTag const &tag, ModuleCallingContext const *mcc) const
Definition: Principal.cc:700
std::shared_ptr< ProductResolverIndexHelper const > productLookup_
Definition: Principal.h:271
std::string const & moduleLabel() const
void addProductOrThrow(std::unique_ptr< ProductResolverBase > phb)
Definition: Principal.cc:416
std::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:270
std::string const & productInstanceName() const
bool registeredToConsume(ProductResolverIndex, bool, BranchType) const
CacheIdentifier_t cacheIdentifier_
Definition: Principal.h:287
BranchType const & branchType() const
Definition: Principal.h:172
std::shared_ptr< HandleExceptionFactory > makeHandleExceptionFactory(T &&iFunctor)
void putOrMerge(BranchDescription const &bd, std::unique_ptr< WrapperBase > edp) const
Definition: Principal.cc:796
void prefetchAsync(WaitingTask *waitTask, ProductResolverIndex index, bool skipCurrentProcess, ModuleCallingContext const *mcc) const
Definition: Principal.cc:508
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:269
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
ProcessHistoryID orderProcessHistoryID_
Definition: Principal.h:274
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:293
Hash< ProcessHistoryType > ProcessHistoryID
int k[5][pyjets_maxn]
string ranges
Definition: diffTwoXMLs.py:78
DelayedReader * reader() const
Definition: Principal.h:178
virtual ~Principal()
Definition: Principal.cc:224
bool willSkipCurrentProcess() const
Definition: InputTag.h:42
bool registeredToConsumeMany(TypeID const &, BranchType) const
void addUnscheduledProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:280
virtual WrapperBase const * getIt(ProductID const &) const override
Definition: Principal.cc:772
ProductResolverIndexHelper const & productLookup() const
Definition: Principal.h:147
void resetFailedFromThisProcess()
Definition: Principal.cc:840
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:62
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:589
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:175
virtual WrapperBase const * getThinnedProduct(ProductID const &, unsigned int &) const override
Definition: Principal.cc:778
bool isValid() const
Definition: Hash.h:151
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:246
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:619
ConstProductResolverPtr getProductResolverByIndex(ProductResolverIndex const &oid) const
Definition: Principal.cc:442
ConstProductResolverPtr getProductResolver(BranchID const &oid) const
Definition: Principal.cc:433
void resetBranchDescription(std::shared_ptr< BranchDescription const > bd)
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:810
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:485
void addAliasedProduct(std::shared_ptr< BranchDescription const > bd)
Definition: Principal.cc:285
void fillPrincipal(ProcessHistoryID const &hist, ProcessHistoryRegistry const &phr, DelayedReader *reader)
Definition: Principal.cc:317
void putOrMergeProduct(std::unique_ptr< WrapperBase > edp) const
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:760
std::string const & instance() const
Definition: InputTag.h:37
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:263
def move(src, dest)
Definition: eostools.py:510
std::vector< BasicHandle > BasicHandleVec
Definition: Principal.h:63
void getManyByType(TypeID const &typeID, BasicHandleVec &results, EDConsumerBase const *consumes, SharedResourcesAcquirer *sra, ModuleCallingContext const *mcc) const
Definition: Principal.cc:518
void deleteProduct(BranchID const &id) const
Definition: Principal.cc:309