CMS 3D CMS Logo

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