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