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