CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Principal.cc
Go to the documentation of this file.
1 
5 
18 
19 #include <algorithm>
20 #include <cstring>
21 #include <limits>
22 #include <sstream>
23 #include <stdexcept>
24 #include <typeinfo>
25 
26 namespace edm {
27 
28  ProcessHistory const Principal::emptyProcessHistory_;
29 
30  static
31  void
32  maybeThrowMissingDictionaryException(TypeID const& productType, bool isElement, std::vector<std::string> const& missingDictionaries) {
33  if(binary_search_all(missingDictionaries, productType.className())) {
34  checkDictionaries(isElement ? productType.className() : wrappedClassName(productType.className()), false);
36  }
37  }
38 
39  static
40  void
42  throw Exception(error, "InvalidID")
43  << "Principal::" << where << ": no product with given branch id: "<< bid << "\n";
44  }
45 
46  static
47  void
48  throwCorruptionException(char const* where, std::string const& branchName) {
50  << "Principal::" << where <<": Product on branch " << branchName << " occurs twice in the same event.\n";
51  }
52 
53  static
54  boost::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  boost::shared_ptr<cms::Exception> exception(new 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  throwProductDeletedException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
74  exception << "Principal::" << where << ": The product matching 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  << "Was already deleted. This means there is a configuration error.\n"
78  << "The module which is asking for this data must be configured to state that it will read this data.";
79  throw exception;
80  }
81 
82  static
83  void
84  throwAmbiguousException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
85  cms::Exception exception("AmbiguousProduct");
86  exception << "Principal::" << where << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
87  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
88  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
89  << "This can only occur with get function calls using a Handle<View> argument.\n"
90  << "Try a get not using a View or change the instance name of one of the products";
91  throw exception;
92 
93  }
94 
95  static
96  void
97  throwNotFoundException(char const* where, TypeID const& productType, InputTag const& tag) {
98  boost::shared_ptr<cms::Exception> exception = makeNotFoundException(where, PRODUCT_TYPE, productType, tag.label(), tag.instance(), tag.process());
99  throw *exception;
100  }
101 
102 
103  Principal::Principal(boost::shared_ptr<ProductRegistry const> reg,
104  boost::shared_ptr<ProductHolderIndexHelper const> productLookup,
105  ProcessConfiguration const& pc,
106  BranchType bt,
107  HistoryAppender* historyAppender) :
108  EDProductGetter(),
109  processHistoryPtr_(nullptr),
110  processHistoryID_(),
111  processConfiguration_(&pc),
112  productHolders_(reg->getNextIndexValue(bt), SharedProductPtr()),
113  preg_(reg),
114  productLookup_(productLookup),
115  lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
116  reader_(),
117  productPtrs_(),
118  branchType_(bt),
119  historyAppender_(historyAppender) {
120 
121  //Now that these have been set, we can create the list of Branches we need.
122  std::string const source("source");
123  ProductRegistry::ProductList const& prodsList = reg->productList();
124  // The constructor of an alias product holder takes as an argument the product holder for which it is an alias.
125  // So, the non-alias product holders must be created first.
126  // Therefore, on this first pass, skip current EDAliases.
127  bool hasAliases = false;
128  for(auto const& prod : prodsList) {
129  BranchDescription const& bd = prod.second;
130  if(bd.branchType() == branchType_) {
131  if(bd.isAlias()) {
132  hasAliases = true;
133  } else {
134  boost::shared_ptr<ConstBranchDescription> cbd(new ConstBranchDescription(bd));
135  if(bd.produced()) {
136  if(bd.moduleLabel() == source) {
137  addSourceProduct(cbd);
138  } else if(bd.onDemand()) {
139  assert(branchType_ == InEvent);
141  } else {
142  addScheduledProduct(cbd);
143  }
144  } else {
145  addInputProduct(cbd);
146  }
147  }
148  }
149  }
150  // Now process any EDAliases
151  if(hasAliases) {
152  for(auto const& prod : prodsList) {
153  BranchDescription const& bd = prod.second;
154  if(bd.isAlias() && bd.branchType() == branchType_) {
155  boost::shared_ptr<ConstBranchDescription> cbd(new ConstBranchDescription(bd));
156  addAliasedProduct(cbd);
157  }
158  }
159  }
160 
161  // Now create the ProductHolders that search in reverse process
162  // order and are used for queries where the process name is the
163  // empty string
164  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
165  std::vector<ProductHolderIndex> matchingHolders(lookupProcessNames.size(), ProductHolderIndexInvalid);
166  std::vector<bool> ambiguous(lookupProcessNames.size(), false);
167  unsigned int beginElements = productLookup_->beginElements();
168  std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
169  std::vector<ProductHolderIndexHelper::Range> const& ranges = productLookup_->ranges();
170  std::vector<ProductHolderIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
171  std::vector<char> const& processNamesCharArray = productLookup_->processNames();
172 
173  if (!sortedTypeIDs.empty()) {
174  ProductHolderIndex productHolderIndex = ProductHolderIndexInvalid;
175  for(unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
176  ProductHolderIndexHelper::Range const& range = ranges.at(k);
177  for (unsigned int i = range.begin(); i < range.end(); ++i) {
178  ProductHolderIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
179  if (product.startInProcessNames() == 0) {
180  if (productHolderIndex != ProductHolderIndexInvalid) {
181  boost::shared_ptr<ProductHolderBase> newHolder(new NoProcessProductHolder(matchingHolders, ambiguous, this));
182  productHolders_.at(productHolderIndex) = newHolder;
183  matchingHolders.assign(lookupProcessNames.size(), ProductHolderIndexInvalid);
184  ambiguous.assign(lookupProcessNames.size(), false);
185  }
186  productHolderIndex = product.index();
187  } else {
188  std::string process(&processNamesCharArray.at(product.startInProcessNames()));
189  auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
190  assert(iter != lookupProcessNames.end());
191  ProductHolderIndex iMatchingIndex = product.index();
192  assert(iMatchingIndex != ProductHolderIndexInvalid);
193  if (iMatchingIndex == ProductHolderIndexAmbiguous) {
194  assert(k >= beginElements);
195  ambiguous.at(iter - lookupProcessNames.begin()) = true;
196  } else {
197  matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
198  }
199  }
200  }
201  }
202  boost::shared_ptr<ProductHolderBase> newHolder(new NoProcessProductHolder(matchingHolders, ambiguous, this));
203  productHolders_.at(productHolderIndex) = newHolder;
204  }
205  }
206 
208  }
209 
210  // Number of products in the Principal.
211  // For products in an input file and not yet read in due to delayed read,
212  // this routine assumes a real product is there.
213  size_t
214  Principal::size() const {
215  size_t size = 0U;
216  for(auto const& prod : *this) {
217  if(prod->singleProduct() && // Not a NoProcessProductHolder
218  !prod->productUnavailable() &&
219  !prod->onDemand() &&
220  !prod->branchDescription().dropped()) {
221  ++size;
222  }
223  }
224  return size;
225  }
226 
227  // adjust provenance for input products after new input file has been merged
228  bool
230  ProductRegistry::ProductList const& prodsList = reg.productList();
231  for(auto const& prod : prodsList) {
232  BranchDescription const& bd = prod.second;
233  if(!bd.produced() && (bd.branchType() == branchType_)) {
234  boost::shared_ptr<ConstBranchDescription> cbd(new ConstBranchDescription(bd));
235  ProductHolderBase* phb = getExistingProduct(cbd->branchID());
236  if(phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
237  return false;
238  }
239  phb->resetBranchDescription(cbd);
240  }
241  }
242  return true;
243  }
244 
245  void
246  Principal::addScheduledProduct(boost::shared_ptr<ConstBranchDescription> bd) {
247  std::auto_ptr<ProductHolderBase> phb(new ScheduledProductHolder(bd));
248  addProductOrThrow(phb);
249  }
250 
251  void
252  Principal::addSourceProduct(boost::shared_ptr<ConstBranchDescription> bd) {
253  std::auto_ptr<ProductHolderBase> phb(new SourceProductHolder(bd));
254  addProductOrThrow(phb);
255  }
256 
257  void
258  Principal::addInputProduct(boost::shared_ptr<ConstBranchDescription> bd) {
259  std::auto_ptr<ProductHolderBase> phb(new InputProductHolder(bd, this));
260  addProductOrThrow(phb);
261  }
262 
263  void
264  Principal::addUnscheduledProduct(boost::shared_ptr<ConstBranchDescription> bd) {
265  std::auto_ptr<ProductHolderBase> phb(new UnscheduledProductHolder(bd, this));
266  addProductOrThrow(phb);
267  }
268 
269  void
270  Principal::addAliasedProduct(boost::shared_ptr<ConstBranchDescription> bd) {
271  ProductHolderIndex index = preg_->indexFrom(bd->originalBranchID());
272  assert(index != ProductHolderIndexInvalid);
273 
274  std::auto_ptr<ProductHolderBase> phb(new AliasProductHolder(bd, dynamic_cast<ProducedProductHolder&>(*productHolders_[index])));
275  addProductOrThrow(phb);
276  }
277 
278  // "Zero" the principal so it can be reused for another Event.
279  void
281  processHistoryPtr_ = 0;
283  reader_ = 0;
284  for(auto const& prod : *this) {
285  prod->resetProductData();
286  }
287  productPtrs_.clear();
288  }
289 
290  void
293  assert(nullptr != phb);
294  auto itFound = productPtrs_.find(phb->product().get());
295  if(itFound != productPtrs_.end()) {
296  productPtrs_.erase(itFound);
297  }
298  phb->deleteProduct();
299  }
300 
301  // Set the principal for the Event, Lumi, or Run.
302  void
304  if(reader) {
305  reader_ = reader;
306  }
307 
308  ProcessHistory const* inputProcessHistory = 0;
309  if (historyAppender_ && productRegistry().anyProductProduced()) {
310  CachedHistory const& cachedHistory =
313  processHistoryPtr_ = cachedHistory.processHistory();
314  processHistoryID_ = cachedHistory.processHistoryID();
315  inputProcessHistory = cachedHistory.inputProcessHistory();
316  }
317  else {
318  if (hist.isValid()) {
320  inputProcessHistory = registry->getMapped(hist);
321  if (inputProcessHistory == 0) {
323  << "Principal::fillPrincipal\n"
324  << "Input ProcessHistory not found in registry\n"
325  << "Contact a Framework developer\n";
326  }
327  } else {
328  inputProcessHistory = &emptyProcessHistory_;
329  }
331  processHistoryPtr_ = inputProcessHistory;
332  }
333 
335  std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
336  lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
337  unsigned int k = 0;
338  for (auto iter = processHistoryPtr_->rbegin(),
339  iEnd = processHistoryPtr_->rend();
340  iter != iEnd; ++iter) {
341  auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
342  if (nameIter == lookupProcessNames.end()) {
343  continue;
344  }
345  lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
346  ++k;
347  }
349  }
350  }
351 
354  ProductHolderIndex index = preg_->indexFrom(branchID);
355  assert(index != ProductHolderIndexInvalid);
356  SharedProductPtr ptr = productHolders_.at(index);
357  return ptr.get();
358  }
359 
363  assert(nullptr == phb || BranchKey(productHolder.branchDescription()) == BranchKey(phb->branchDescription()));
364  return phb;
365  }
366 
367  void
368  Principal::addProduct_(std::auto_ptr<ProductHolderBase> productHolder) {
369  ConstBranchDescription const& bd = productHolder->branchDescription();
370  assert (!bd.className().empty());
371  assert (!bd.friendlyClassName().empty());
372  assert (!bd.moduleLabel().empty());
373  assert (!bd.processName().empty());
374  SharedProductPtr phb(productHolder);
375 
376  ProductHolderIndex index = preg_->indexFrom(bd.branchID());
377  assert(index != ProductHolderIndexInvalid);
378  productHolders_[index] = phb;
379  }
380 
381  void
382  Principal::addProductOrThrow(std::auto_ptr<ProductHolderBase> productHolder) {
383  ProductHolderBase const* phb = getExistingProduct(*productHolder);
384  if(phb != nullptr) {
385  ConstBranchDescription const& bd = productHolder->branchDescription();
386  throw Exception(errors::InsertFailure, "AlreadyPresent")
387  << "addProductOrThrow: Problem found while adding product, "
388  << "product already exists for ("
389  << bd.friendlyClassName() << ","
390  << bd.moduleLabel() << ","
391  << bd.productInstanceName() << ","
392  << bd.processName()
393  << ")\n";
394  }
395  addProduct_(productHolder);
396  }
397 
399  Principal::getProductHolder(BranchID const& bid, bool resolveProd, bool fillOnDemand) const {
400  ProductHolderIndex index = preg_->indexFrom(bid);
401  if(index == ProductHolderIndexInvalid){
402  return ConstProductPtr();
403  }
404  return getProductByIndex(index, resolveProd, fillOnDemand);
405  }
406 
408  Principal::getProductByIndex(ProductHolderIndex const& index, bool resolveProd, bool fillOnDemand) const {
409 
410  ConstProductPtr const phb = productHolders_[index].get();
411  if(nullptr == phb) {
412  return phb;
413  }
414  if(resolveProd && !phb->productUnavailable()) {
415  this->resolveProduct(*phb, fillOnDemand);
416  }
417  return phb;
418  }
419 
422  TypeID const& typeID,
423  InputTag const& inputTag) const {
424 
425  ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag);
426  if(result == 0) {
427  boost::shared_ptr<cms::Exception> whyFailed =
428  makeNotFoundException("getByLabel", kindOfType, typeID, inputTag.label(), inputTag.instance(), inputTag.process());
429  return BasicHandle(whyFailed);
430  }
431  return BasicHandle(*result);
432  }
433 
436  TypeID const& typeID,
437  std::string const& label,
438  std::string const& instance,
439  std::string const& process) const {
440 
441  ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process);
442  if(result == 0) {
443  boost::shared_ptr<cms::Exception> whyFailed =
444  makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
445  return BasicHandle(whyFailed);
446  }
447  return BasicHandle(*result);
448  }
449 
452  TypeID const& typeID,
454  bool skipCurrentProcess,
455  bool& ambiguous) const {
456  assert(index !=ProductHolderIndexInvalid);
457  boost::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
458  assert(0!=productHolder.get());
459  ProductHolderBase::ResolveStatus resolveStatus;
460  ProductData const* productData = productHolder->resolveProduct(resolveStatus, skipCurrentProcess);
461  if(resolveStatus == ProductHolderBase::Ambiguous) {
462  ambiguous = true;
463  return BasicHandle();
464  }
465  if(productData == 0) {
466  return BasicHandle();
467  }
468  return BasicHandle(*productData);
469  }
470 
471  void
473  BasicHandleVec& results) const {
474 
475  assert(results.empty());
476 
477  // This finds the indexes to all the ProductHolder's matching the type
480 
481  if (matches.numberOfMatches() == 0) {
482  maybeThrowMissingDictionaryException(typeID, false, preg_->missingDictionaries());
483  return;
484  }
485 
486  results.reserve(matches.numberOfMatches());
487 
488  // Loop over the ProductHolders. Add the products that are actually
489  // present into the results. This will also trigger delayed reading,
490  // on demand production, and check for deleted products as appropriate.
491 
492  // Over the years the code that uses getManyByType has grown to depend
493  // on the ordering of the results. The order originally was just an
494  // accident of how previous versions of the code were written, but
495  // here we have to go through some extra effort to preserve that ordering.
496 
497  // We build a list of holders that match a particular label and instance.
498  // When that list is complete we call findProducts, which loops over
499  // that list in reverse order of the ProcessHistory (starts with the
500  // most recent). Then we clear the list and repeat this until all the
501  // matching label and instance subsets have been dealt with.
502 
503  // Note that the function isFullyResolved returns true for the ProductHolders
504  // that are associated with an empty process name. Those are the ones that
505  // know how to search for the most recent process name matching
506  // a label and instance. We do not need these for getManyByType and
507  // skip them. In addition to skipping them, we make use of the fact
508  // that they mark the beginning of each subset of holders with the same
509  // label and instance. They tell us when to call findProducts.
510 
511  std::vector<ProductHolderBase const*> holders;
512 
513  for(unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
514 
515  ProductHolderIndex index = matches.index(i);
516 
517  if(!matches.isFullyResolved(i)) {
518  if(!holders.empty()) {
519  // Process the ones with a particular module label and instance
520  findProducts(holders, typeID, results);
521  holders.clear();
522  }
523  } else {
524  ProductHolderBase const* productHolder = productHolders_.at(index).get();
525  assert(productHolder);
526  holders.push_back(productHolder);
527  }
528  }
529  // Do not miss the last subset of products
530  if(!holders.empty()) {
531  findProducts(holders, typeID, results);
532  }
533  return;
534  }
535 
536  void
537  Principal::findProducts(std::vector<ProductHolderBase const*> const& holders,
538  TypeID const& typeID,
539  BasicHandleVec& results) const {
540 
541  for (auto iter = processHistoryPtr_->rbegin(),
542  iEnd = processHistoryPtr_->rend();
543  iter != iEnd; ++iter) {
544  std::string const& process = iter->processName();
545  for (auto productHolder : holders) {
546  ConstBranchDescription const& bd = productHolder->branchDescription();
547  if (process == bd.processName()) {
548 
549  // Ignore aliases to avoid matching the same product multiple times.
550  if(bd.isAlias()) {
551  continue;
552  }
553 
554  //NOTE sometimes 'productHolder->productUnavailable()' is true if was already deleted
555  if(productHolder->productWasDeleted()) {
556  throwProductDeletedException("findProducts",
557  typeID,
558  bd.moduleLabel(),
559  bd.productInstanceName(),
560  bd.processName());
561  }
562 
563  // Skip product if not available.
564  if(!productHolder->productUnavailable()) {
565 
566  this->resolveProduct(*productHolder, true);
567  // If the product is a dummy filler, product holder will now be marked unavailable.
568  // Unscheduled execution can fail to produce the EDProduct so check
569  if(productHolder->product() && !productHolder->productUnavailable() && !productHolder->onDemand()) {
570  // Found a good match, save it
571  BasicHandle bh(productHolder->productData());
572  results.push_back(bh);
573  }
574  }
575  }
576  }
577  }
578  }
579 
580  ProductData const*
582  TypeID const& typeID,
583  InputTag const& inputTag) const {
584 
585  bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
586 
587  ProductHolderIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
588 
589  if (index == ProductHolderIndexInvalid) {
590 
591  char const* processName = inputTag.process().c_str();
592  if (skipCurrentProcess) {
593  processName = "\0";
594  }
595 
596  index = productLookup().index(kindOfType,
597  typeID,
598  inputTag.label().c_str(),
599  inputTag.instance().c_str(),
600  processName);
601 
602  if(index == ProductHolderIndexAmbiguous) {
603  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
604  } else if (index == ProductHolderIndexInvalid) {
606  productLookup().relatedIndexes(kindOfType, typeID);
607 
608  if (matches.numberOfMatches() == 0) {
609  maybeThrowMissingDictionaryException(typeID, kindOfType == ELEMENT_TYPE, preg_->missingDictionaries());
610  }
611  return 0;
612  }
613  inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
614  }
615 
616  boost::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
617 
618  ProductHolderBase::ResolveStatus resolveStatus;
619  ProductData const* productData = productHolder->resolveProduct(resolveStatus, skipCurrentProcess);
620  if(resolveStatus == ProductHolderBase::Ambiguous) {
621  throwAmbiguousException("findProductByLabel", typeID, inputTag.label(), inputTag.instance(), inputTag.process());
622  }
623  return productData;
624  }
625 
626  ProductData const*
628  TypeID const& typeID,
629  std::string const& label,
630  std::string const& instance,
631  std::string const& process) const {
632 
634  typeID,
635  label.c_str(),
636  instance.c_str(),
637  process.c_str());
638 
639  if(index == ProductHolderIndexAmbiguous) {
640  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
641  } else if (index == ProductHolderIndexInvalid) {
643  productLookup().relatedIndexes(kindOfType, typeID);
644 
645  if (matches.numberOfMatches() == 0) {
646  maybeThrowMissingDictionaryException(typeID, kindOfType == ELEMENT_TYPE, preg_->missingDictionaries());
647  }
648  return 0;
649  }
650  boost::shared_ptr<ProductHolderBase> const& productHolder = productHolders_[index];
651 
652  ProductHolderBase::ResolveStatus resolveStatus;
653  ProductData const* productData = productHolder->resolveProduct(resolveStatus, false);
654  if(resolveStatus == ProductHolderBase::Ambiguous) {
655  throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
656  }
657  return productData;
658  }
659 
660  ProductData const*
661  Principal::findProductByTag(TypeID const& typeID, InputTag const& tag) const {
662  ProductData const* productData =
664  typeID,
665  tag);
666  if(productData == nullptr) {
667  throwNotFoundException("findProductByTag", typeID, tag);
668  }
669  return productData;
670  }
671 
673  Principal::getForOutput(BranchID const& bid, bool getProd) const {
674  ConstProductPtr const phb = getProductHolder(bid, getProd, true);
675  if(phb == nullptr) {
677  }
678  if (phb->productWasDeleted()) {
679  throwProductDeletedException("getForOutput",phb->productType(),
680  phb->moduleLabel(),
681  phb->productInstanceName(),
682  phb->processName());
683  }
684  if(!phb->provenance() || (!phb->product() && !phb->productProvenancePtr())) {
685  return OutputHandle();
686  }
687  return OutputHandle(WrapperHolder(phb->product().get(), phb->productData().getInterface()), &phb->branchDescription(), phb->productProvenancePtr());
688  }
689 
690  Provenance
691  Principal::getProvenance(BranchID const& bid) const {
692  ConstProductPtr const phb = getProductHolder(bid, false, true);
693  if(phb == nullptr) {
695  }
696 
697  if(phb->onDemand()) {
698  unscheduledFill(phb->branchDescription().moduleLabel());
699  }
700  // We already tried to produce the unscheduled products above
701  // If they still are not there, then throw
702  if(phb->onDemand()) {
703  throwProductNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
704  }
705 
706  return *phb->provenance();
707  }
708 
709  // This one is mostly for test printout purposes
710  // No attempt to trigger on demand execution
711  // Skips provenance when the EDProduct is not there
712  void
713  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
714  provenances.clear();
715  for(auto const& productHolder : *this) {
716  if(productHolder->singleProduct() && productHolder->provenanceAvailable() && !productHolder->branchDescription().isAlias()) {
717  // We do not attempt to get the event/lumi/run status from the provenance,
718  // because the per event provenance may have been dropped.
719  if(productHolder->provenance()->product().present()) {
720  provenances.push_back(productHolder->provenance());
721  }
722  }
723  }
724  }
725 
726  void
727  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
728  for(auto const& prod : bids) {
729  ProductHolderIndex index= preg_->indexFrom(prod);
730  assert(index!=ProductHolderIndexInvalid);
731  ProductHolderIndex indexO = other.preg_->indexFrom(prod);
732  assert(indexO!=ProductHolderIndexInvalid);
733  productHolders_[index].swap(other.productHolders_[indexO]);
734  productHolders_[index]->setPrincipal(this);
735  }
736  reader_->mergeReaders(other.reader());
737  }
738 
740  Principal::getIt(ProductID const&) const {
741  assert(nullptr);
742  return WrapperHolder();
743  }
744 
745  void
747  if(!prod.isValid()) return;
748  // These are defensive checks against things that should never happen, but have.
749  // Checks that the same physical product has not already been put into the event.
750  bool alreadyPresent = !productPtrs_.insert(prod.wrapper()).second;
751  if(alreadyPresent) {
752  phb->checkType(prod);
753  const_cast<WrapperOwningHolder&>(prod).reset();
754  throwCorruptionException("checkUniquenessAndType", phb->branchDescription().branchName());
755  }
756  // Checks that the real type of the product matches the branch.
757  phb->checkType(prod);
758  }
759 
760  void
762  bool willBePut = phb->putOrMergeProduct();
763  if(willBePut) {
764  checkUniquenessAndType(prod, phb);
765  phb->putProduct(prod);
766  } else {
767  phb->checkType(prod);
768  phb->mergeProduct(prod);
769  }
770  }
771 
772  void
774  bool willBePut = phb->putOrMergeProduct();
775  if(willBePut) {
776  checkUniquenessAndType(prod, phb);
777  phb->putProduct(prod, prov);
778  } else {
779  phb->checkType(prod);
780  phb->mergeProduct(prod, prov);
781  }
782  }
783 
784  void
786  if(preg_->getNextIndexValue(branchType_) != productHolders_.size()) {
787  productHolders_.resize(preg_->getNextIndexValue(branchType_));
788  for(auto const& prod : preg_->productList()) {
789  BranchDescription const& bd = prod.second;
790  if(bd.branchType() == branchType_) {
791  ProductHolderIndex index = preg_->indexFrom(bd.branchID());
792  assert(index != ProductHolderIndexInvalid);
793  if(!productHolders_[index]) {
794  // no product holder. Must add one. The new entry must be an input product holder.
795  assert(!bd.produced());
796  boost::shared_ptr<ConstBranchDescription> cbd(new ConstBranchDescription(bd));
797  addInputProduct(cbd);
798  }
799  }
800  }
801  }
802  assert(preg_->getNextIndexValue(branchType_) == productHolders_.size());
803  }
804 }
const_reverse_iterator rbegin() const
BranchType branchType_
Definition: Principal.h:242
std::string const & processName() const
void resolveProduct(ProductHolderBase const &phb, bool fillOnDemand) const
Definition: Principal.h:167
ProductRegistry const & productRegistry() const
Definition: Principal.h:135
Matches relatedIndexes(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance) const
void clearPrincipal()
Definition: Principal.cc:280
int i
Definition: DBlmapReader.cc:9
size_t size() const
Definition: Principal.cc:214
DelayedReader * reader_
Definition: Principal.h:237
void addUnscheduledProduct(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:264
BranchType const & branchType() const
static const ProcessHistory emptyProcessHistory_
Definition: Principal.h:249
HistoryAppender * historyAppender_
Definition: Principal.h:247
ConstProductPtr getProductByIndex(ProductHolderIndex const &oid, bool resolveProd, bool fillOnDemand) const
Definition: Principal.cc:408
void putOrMerge(WrapperOwningHolder const &prod, ProductHolderBase const *productHolder) const
Definition: Principal.cc:761
ProductHolderIndex indexFor(TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:186
static void throwNotFoundException(char const *where, TypeID const &productType, InputTag const &tag)
Definition: Principal.cc:97
static PFTauRenderPlugin instance
ConstBranchDescription const & branchDescription() const
Definition: ProductHolder.h:93
static ThreadSafeRegistry * instance()
static void throwProductDeletedException(ProductID const &pid, edm::EventPrincipal::ConstProductPtr const phb)
ProductHolderIndex index(KindOfType kindOfType, TypeID const &typeID, char const *moduleLabel, char const *instance, char const *process=0) const
ConstProductPtr getProductHolder(BranchID const &oid, bool resolveProd, bool fillOnDemand) const
Definition: Principal.cc:399
std::map< BranchKey, BranchDescription > ProductList
ProcessHistoryID processHistoryID_
Definition: Principal.h:220
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:25
bool & produced() const
#define nullptr
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Principal.cc:713
static void throwCorruptionException(char const *where, std::string const &branchName)
Definition: Principal.cc:48
void checkUniquenessAndType(WrapperOwningHolder const &prod, ProductHolderBase const *productHolder) const
Definition: Principal.cc:746
bool & onDemand() const
bool getMapped(key_type const &k, value_type &result) const
void addScheduledProduct(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:246
void getManyByType(TypeID const &typeID, BasicHandleVec &results) const
Definition: Principal.cc:472
CachedHistory const & appendToProcessHistory(ProcessHistoryID const &inputPHID, ProcessConfiguration const &pc)
boost::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:229
ProcessHistory const * processHistoryPtr_
Definition: Principal.h:218
Principal(boost::shared_ptr< ProductRegistry const > reg, boost::shared_ptr< ProductHolderIndexHelper const > productLookup, ProcessConfiguration const &pc, BranchType bt, HistoryAppender *historyAppender)
Definition: Principal.cc:103
std::string const & friendlyClassName() const
unsigned int ProductHolderIndex
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
boost::shared_ptr< ProductHolderBase > SharedProductPtr
Definition: Principal.h:61
BranchType
Definition: BranchType.h:11
void checkType(WrapperOwningHolder const &prod) const
boost::shared_ptr< void const > product() const
Definition: ProductHolder.h:81
void addInputProduct(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:258
static void throwAmbiguousException(const char *where, TypeID const &productType, std::string const &label, std::string const &instance, std::string const &process)
Definition: Principal.cc:84
ProductList const & productList() const
U second(std::pair< T, U > const &p)
ProcessHistoryID const & processHistoryID() const
std::vector< unsigned int > lookupProcessOrder_
Definition: Principal.h:232
void findProducts(std::vector< ProductHolderBase const * > const &holders, TypeID const &typeID, BasicHandleVec &results) const
Definition: Principal.cc:537
const_reverse_iterator rend() const
std::string const & moduleLabel() const
BasicHandle getByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag) const
Definition: Principal.cc:421
boost::shared_ptr< ProductHolderIndexHelper const > productLookup_
Definition: Principal.h:230
std::string const & productInstanceName() const
BranchType const & branchType() const
Definition: Principal.h:152
ProductHolderCollection productHolders_
Definition: Principal.h:225
void addProduct_(std::auto_ptr< ProductHolderBase > phb)
Definition: Principal.cc:368
BasicHandle getByToken(KindOfType kindOfType, TypeID const &typeID, ProductHolderIndex index, bool skipCurrentProcess, bool &ambiguous) const
Definition: Principal.cc:451
tuple result
Definition: query.py:137
void checkDictionaries(std::string const &name, bool noComponents=false)
BranchID const & branchID() const
ProcessHistoryID orderProcessHistoryID_
Definition: Principal.h:233
void mergeProduct(WrapperOwningHolder const &edp, ProductProvenance &productProvenance)
void addAliasedProduct(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:270
OutputHandle getForOutput(BranchID const &bid, bool getProd) const
Definition: Principal.cc:673
BranchID const & branchID() const
Hash< ProcessHistoryType > ProcessHistoryID
void throwMissingDictionariesException()
std::set< void const * > productPtrs_
Definition: Principal.h:240
int k[5][pyjets_maxn]
string ranges
Definition: diffTwoXMLs.py:78
DelayedReader * reader() const
Definition: Principal.h:154
static void maybeThrowMissingDictionaryException(TypeID const &productType, bool isElement, std::vector< std::string > const &missingDictionaries)
Definition: Principal.cc:32
virtual ~Principal()
Definition: Principal.cc:207
bool willSkipCurrentProcess() const
Definition: InputTag.h:48
std::string const & className() const
static boost::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
bool putOrMergeProduct() const
std::string wrappedClassName(std::string const &iFullName)
ProductData const * findProductByLabel(KindOfType kindOfType, TypeID const &typeID, InputTag const &inputTag) const
Definition: Principal.cc:581
void tryToCacheIndex(ProductHolderIndex index, TypeID const &typeID, BranchType branchType, void const *productRegistry) const
Definition: InputTag.cc:204
virtual WrapperHolder getIt(ProductID const &) const
Definition: Principal.cc:740
void resetBranchDescription(boost::shared_ptr< ConstBranchDescription > bd)
std::string const & label() const
Definition: InputTag.h:42
std::string const & process() const
Definition: InputTag.h:46
std::string const & branchName() const
void addProductOrThrow(std::auto_ptr< ProductHolderBase > phb)
Definition: Principal.cc:382
bool isValid() const
Definition: Hash.h:146
ProductHolderBase const * ConstProductPtr
Definition: Principal.h:57
virtual bool unscheduledFill(std::string const &moduleLabel) const =0
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:229
std::string const & className() const
Definition: TypeID.cc:40
void putProduct(WrapperOwningHolder const &edp, ProductProvenance const &productProvenance)
ProductData const * findProductByTag(TypeID const &typeID, InputTag const &tag) const
Definition: Principal.cc:661
bool isValid() const
Definition: WrapperHolder.h:27
void fillPrincipal(ProcessHistoryID const &hist, DelayedReader *reader)
Definition: Principal.cc:303
bool binary_search_all(ForwardSequence const &s, Datum const &d)
wrappers for std::binary_search
Definition: Algorithms.h:76
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:785
static void throwProductNotFoundException(char const *where, errors::ErrorCodes error, BranchID const &bid)
Definition: Principal.cc:41
void const * wrapper() const
Definition: WrapperHolder.h:76
static Interceptor::Registry registry("Interceptor")
void addSourceProduct(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:252
tuple process
Definition: LaserDQM_cfg.py:3
ProcessHistory const * processHistory() const
void reset(double vett[256])
Definition: TPedValues.cc:11
Provenance getProvenance(BranchID const &bid) const
Definition: Principal.cc:691
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:727
ProcessHistory const * inputProcessHistory() const
std::string const & instance() const
Definition: InputTag.h:43
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:222
tuple size
Write out results.
std::vector< BasicHandle > BasicHandleVec
Definition: Principal.h:58
ProductHolderBase * getExistingProduct(BranchID const &branchID)
Definition: Principal.cc:353
std::string const & moduleLabel() const
ProductHolderIndexHelper const & productLookup() const
Definition: Principal.h:137
void deleteProduct(BranchID const &id)
Definition: Principal.cc:291