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 
16 
17 #include <algorithm>
18 #include <cstring>
19 #include <limits>
20 #include <sstream>
21 #include <stdexcept>
22 
23 //using boost::lambda::_1;
24 
25 namespace edm {
26 
27  ProcessHistory Principal::emptyProcessHistory_;
28 
29  static
30  void
31  maybeThrowMissingDictionaryException(TypeID const& productType, bool isElement, std::vector<std::string> const& missingDictionaries) {
32  if(binary_search_all(missingDictionaries, productType.className())) {
33  checkDictionaries(isElement ? productType.className() : wrappedClassName(productType.className()), false);
35  }
36  }
37 
38  static
39  void
40  throwMultiFoundException(char const* where, int nFound, TypeID const& productType) {
42  << "Principal::" << where << ": Found " << nFound << " products rather than one which match all criteria\n"
43  << "Looking for type: " << productType << "\n";
44  }
45 
46  static
47  void
49  throw Exception(error, "InvalidID")
50  << "Principal::" << where << ": no product with given branch id: "<< bid << "\n";
51  }
52 
53  static
54  void
55  throwCorruptionException(char const* where, std::string const& branchName) {
57  << "Principal::" << where <<": Product on branch " << branchName << " occurs twice in the same event.\n";
58  }
59 
60  static
61  boost::shared_ptr<cms::Exception>
62  makeNotFoundException(char const* where, TypeID const& productType) {
63  boost::shared_ptr<cms::Exception> exception(new Exception(errors::ProductNotFound));
64  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n";
65  return exception;
66  }
67 
68  static
69  boost::shared_ptr<cms::Exception>
70  makeNotFoundException(char const* where, TypeID const& productType, std::string const& label, std::string const& instance, std::string const& process) {
71  boost::shared_ptr<cms::Exception> exception(new Exception(errors::ProductNotFound));
72  *exception << "Principal::" << where << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
73  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
74  << (process.empty() ? "" : "Looking for process: ") << process << "\n";
75  return exception;
76  }
77 
78  static
79  void
80  throwProductDeletedException(const char* where, TypeID const& productType,std::string const& label, std::string const& instance, std::string const& process) {
81  boost::shared_ptr<cms::Exception> exception(new ProductDeletedException());
82  *exception << "Principal::" << where << ": The product matching all criteria\nLooking for type: " << productType << "\n"
83  << "Looking for module label: " << label << "\n" << "Looking for productInstanceName: " << instance << "\n"
84  << (process.empty() ? "" : "Looking for process: ") << process << "\n"
85  << "Was already deleted. This means there is a configuration error.\nThe module which is asking for this data must be configured to state that it will read this data.";
86  throw exception;
87 
88  }
89 
90 
91  static
92  void
93  throwNotFoundException(char const* where, TypeID const& productType, InputTag const& tag) {
94  boost::shared_ptr<cms::Exception> exception = makeNotFoundException(where, productType, tag.label(), tag.instance(), tag.process());
95  throw *exception;
96  }
97 
98 
99  Principal::Principal(boost::shared_ptr<ProductRegistry const> reg,
100  ProcessConfiguration const& pc,
101  BranchType bt,
102  HistoryAppender* historyAppender) :
103  EDProductGetter(),
104  processHistoryPtr_(0),
105  processHistoryID_(),
106  processConfiguration_(&pc),
107  groups_(reg->constProductList().size(), SharedGroupPtr()),
108  preg_(reg),
109  reader_(),
110  productPtrs_(),
111  branchType_(bt),
112  historyAppender_(historyAppender) {
113 
114  //Now that these have been set, we can create the list of Branches we need.
115  std::string const source("source");
116  ProductRegistry::ProductList const& prodsList = reg->productList();
117  for(ProductRegistry::ProductList::const_iterator itProdInfo = prodsList.begin(),
118  itProdInfoEnd = prodsList.end();
119  itProdInfo != itProdInfoEnd;
120  ++itProdInfo) {
121  if(itProdInfo->second.branchType() == branchType_) {
122  boost::shared_ptr<ConstBranchDescription> bd(new ConstBranchDescription(itProdInfo->second));
123  if(bd->produced()) {
124  if(bd->moduleLabel() == source) {
125  addGroupSource(bd);
126  } else if(bd->onDemand()) {
127  assert(bt == InEvent);
128  addOnDemandGroup(bd);
129  } else {
130  addGroupScheduled(bd);
131  }
132  } else {
133  addGroupInput(bd);
134  }
135  }
136  }
137  }
138 
140  }
141 
142  // Number of products in the Principal.
143  // For products in an input file and not yet read in due to delayed read,
144  // this routine assumes a real product is there.
145  size_t
146  Principal::size() const {
147  size_t size = 0U;
148  for(const_iterator it = this->begin(), itEnd = this->end(); it != itEnd; ++it) {
149  Group const& g = **it;
150  if(!g.productUnavailable() && !g.onDemand() && !g.branchDescription().dropped()) {
151  ++size;
152  }
153  }
154  return size;
155  }
156 
157  //adjust provenance for input groups after new input file has been merged
158  bool
160  if(reg.constProductList().size() > groups_.size()) {
161  return false;
162  }
163  ProductRegistry::ProductList const& prodsList = reg.productList();
164  for(ProductRegistry::ProductList::const_iterator itProdInfo = prodsList.begin(),
165  itProdInfoEnd = prodsList.end();
166  itProdInfo != itProdInfoEnd;
167  ++itProdInfo) {
168  if(!itProdInfo->second.produced() && (itProdInfo->second.branchType() == branchType_)) {
169  boost::shared_ptr<ConstBranchDescription> bd(new ConstBranchDescription(itProdInfo->second));
170  Group *g = getExistingGroup(itProdInfo->second.branchID());
171  if(g == 0 || g->branchDescription().branchName() != bd->branchName()) {
172  return false;
173  }
174  g->resetBranchDescription(bd);
175  }
176  }
177  return true;
178  }
179 
180  void
181  Principal::addGroupScheduled(boost::shared_ptr<ConstBranchDescription> bd) {
182  std::auto_ptr<Group> g(new ScheduledGroup(bd));
183  addGroupOrThrow(g);
184  }
185 
186  void
187  Principal::addGroupSource(boost::shared_ptr<ConstBranchDescription> bd) {
188  std::auto_ptr<Group> g(new SourceGroup(bd));
189  addGroupOrThrow(g);
190  }
191 
192  void
193  Principal::addGroupInput(boost::shared_ptr<ConstBranchDescription> bd) {
194  std::auto_ptr<Group> g(new InputGroup(bd));
195  addGroupOrThrow(g);
196  }
197 
198  void
199  Principal::addOnDemandGroup(boost::shared_ptr<ConstBranchDescription> bd) {
200  std::auto_ptr<Group> g(new UnscheduledGroup(bd));
201  addGroupOrThrow(g);
202  }
203 
204  // "Zero" the principal so it can be reused for another Event.
205  void
207  processHistoryPtr_ = 0;
209  reader_ = 0;
210  for (Principal::const_iterator i = begin(), iEnd = end(); i != iEnd; ++i) {
211  (*i)->resetProductData();
212  }
213  productPtrs_.clear();
214  }
215 
216  void
218  Group* g = getExistingGroup(id);
219  assert(0!=g);
220  auto itFound = productPtrs_.find(g->product().get());
221  if(itFound != productPtrs_.end()) {
222  productPtrs_.erase(itFound);
223  }
224  g->deleteProduct();
225  }
226 
227  // Set the principal for the Event, Lumi, or Run.
228  void
230  if(reader) {
231  reader_ = reader;
232  }
233 
234  ProcessHistory const* inputProcessHistory = 0;
235  if (historyAppender_ && productRegistry().anyProductProduced()) {
236  CachedHistory const& cachedHistory =
239  processHistoryPtr_ = cachedHistory.processHistory();
240  processHistoryID_ = cachedHistory.processHistoryID();
241  inputProcessHistory = cachedHistory.inputProcessHistory();
242  }
243  else {
244  if (hist.isValid()) {
246  inputProcessHistory = registry->getMapped(hist);
247  if (inputProcessHistory == 0) {
249  << "Principal::fillPrincipal\n"
250  << "Input ProcessHistory not found in registry\n"
251  << "Contact a Framework developer\n";
252  }
253  } else {
254  inputProcessHistory = &emptyProcessHistory_;
255  }
257  processHistoryPtr_ = inputProcessHistory;
258  }
259 
260  preg_->productLookup().reorderIfNecessary(branchType_, *inputProcessHistory,
262  preg_->elementLookup().reorderIfNecessary(branchType_, *inputProcessHistory,
264  }
265 
266  Group*
268  ProductTransientIndex index = preg_->indexFrom(branchID);
269  assert(index != ProductRegistry::kInvalidIndex);
270  SharedGroupPtr ptr = groups_.at(index);
271  return ptr.get();
272  }
273 
274  Group*
277  assert(0 == g || BranchKey(group.branchDescription()) == BranchKey(g->branchDescription()));
278  return g;
279  }
280 
281  void
282  Principal::addGroup_(std::auto_ptr<Group> group) {
283  ConstBranchDescription const& bd = group->branchDescription();
284  assert (!bd.className().empty());
285  assert (!bd.friendlyClassName().empty());
286  assert (!bd.moduleLabel().empty());
287  assert (!bd.processName().empty());
288  SharedGroupPtr g(group);
289 
290  ProductTransientIndex index = preg_->indexFrom(bd.branchID());
291  assert(index != ProductRegistry::kInvalidIndex);
292  groups_[index] = g;
293  }
294 
295  void
296  Principal::addGroupOrThrow(std::auto_ptr<Group> group) {
297  Group const* g = getExistingGroup(*group);
298  if(g != 0) {
299  ConstBranchDescription const& bd = group->branchDescription();
300  throw Exception(errors::InsertFailure, "AlreadyPresent")
301  << "addGroupOrThrow: Problem found while adding product, "
302  << "product already exists for ("
303  << bd.friendlyClassName() << ","
304  << bd.moduleLabel() << ","
305  << bd.productInstanceName() << ","
306  << bd.processName()
307  << ")\n";
308  }
309  addGroup_(group);
310  }
311 
313  Principal::getGroup(BranchID const& bid, bool resolveProd, bool fillOnDemand) const {
314  ProductTransientIndex index = preg_->indexFrom(bid);
315  if(index == ProductRegistry::kInvalidIndex){
316  return ConstGroupPtr();
317  }
318  return getGroupByIndex(index, resolveProd, fillOnDemand);
319  }
320 
322  Principal::getGroupByIndex(ProductTransientIndex const& index, bool resolveProd, bool fillOnDemand) const {
323 
324  ConstGroupPtr const g = groups_[index].get();
325  if(0 == g) {
326  return g;
327  }
328  if(resolveProd && !g->productUnavailable()) {
329  this->resolveProduct(*g, fillOnDemand);
330  }
331  return g;
332  }
333 
335  Principal::getBySelector(TypeID const& productType,
336  SelectorBase const& sel) const {
338 
339  int nFound = findGroup(productType,
340  preg_->productLookup(),
341  sel,
342  result);
343 
344  if(nFound == 0) {
345  boost::shared_ptr<cms::Exception> whyFailed = makeNotFoundException("getBySelector", productType);
346  return BasicHandle(whyFailed);
347  }
348  if(nFound > 1) {
349  throwMultiFoundException("getBySelector", nFound, productType);
350  }
351  return result;
352  }
353 
355  Principal::getByLabel(TypeID const& productType,
356  std::string const& label,
357  std::string const& productInstanceName,
358  std::string const& processName,
359  size_t& cachedOffset,
360  int& fillCount) const {
361 
362  ProductData const* result = findGroupByLabel(productType,
363  preg_->productLookup(),
364  label,
365  productInstanceName,
366  processName,
367  cachedOffset,
368  fillCount);
369 
370  if(result == 0) {
371  boost::shared_ptr<cms::Exception> whyFailed = makeNotFoundException("getByLabel", productType, label, productInstanceName, processName);
372  return BasicHandle(whyFailed);
373  }
374  return BasicHandle(*result);
375  }
376 
377 
378  void
379  Principal::getMany(TypeID const& productType,
380  SelectorBase const& sel,
381  BasicHandleVec& results) const {
382 
383  findGroups(productType,
384  preg_->productLookup(),
385  sel,
386  results);
387 
388  return;
389  }
390 
392  Principal::getByType(TypeID const& productType) const {
393 
396 
397  int nFound = findGroup(productType,
398  preg_->productLookup(),
399  sel,
400  result);
401 
402  if(nFound == 0) {
403  boost::shared_ptr<cms::Exception> whyFailed = makeNotFoundException("getByType", productType);
404  return BasicHandle(whyFailed);
405  }
406 
407  if(nFound > 1) {
408  throwMultiFoundException("getByType", nFound, productType);
409  }
410  return result;
411  }
412 
413  void
414  Principal::getManyByType(TypeID const& productType,
415  BasicHandleVec& results) const {
416 
418 
419  findGroups(productType,
420  preg_->productLookup(),
421  sel,
422  results);
423  return;
424  }
425 
426  size_t
428  SelectorBase const& selector,
429  BasicHandle& result) const {
430 
431  // One new argument is the element lookup container
432  // Otherwise this just passes through the arguments to findGroup
433  return findGroup(typeID,
434  preg_->elementLookup(),
435  selector,
436  result);
437  }
438 
439  size_t
441  TransientProductLookupMap const& typeLookup,
442  SelectorBase const& selector,
443  BasicHandleVec& results) const {
444  assert(results.empty());
445 
447  // A class without a dictionary cannot be in an Event/Lumi/Run.
448  // First, we check if the class has a dictionary. If it does not, we throw an exception.
449  // The missing dictionary might be for the class itself, the wrapped class, or a component of the class.
450  std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> const range = typeLookup.equal_range(TypeInBranchType(typeID, branchType_));
451  if(range.first == range.second) {
452  maybeThrowMissingDictionaryException(typeID, &typeLookup == &preg_->elementLookup(), preg_->missingDictionaries());
453  }
454 
455  results.reserve(range.second - range.first);
456 
457  for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
458 
459  if(selector.match(*(it->branchDescription()))) {
460 
461  //now see if the data is actually available
462  ConstGroupPtr const& group = getGroupByIndex(it->index(), false, false);
463  //NOTE sometimes 'group->productUnavailable()' is true if was already deleted
464  if(group && group->productWasDeleted()) {
465  throwProductDeletedException("findGroups",
466  typeID,
467  it->branchDescription()->moduleLabel(),
468  it->branchDescription()->productInstanceName(),
469  it->branchDescription()->processName());
470  }
471 
472  // Skip product if not available.
473  if(group && !group->productUnavailable()) {
474 
475  this->resolveProduct(*group, true);
476  // If the product is a dummy filler, group will now be marked unavailable.
477  // Unscheduled execution can fail to produce the EDProduct so check
478  if(group->product() && !group->productUnavailable() && !group->onDemand()) {
479  // Found a good match, save it
480  BasicHandle bh(group->productData());
481  results.push_back(bh);
482  }
483  }
484  }
485  }
486  return results.size();
487  }
488 
489  size_t
491  TransientProductLookupMap const& typeLookup,
492  SelectorBase const& selector,
493  BasicHandle& result) const {
494  assert(!result.isValid());
495 
496  size_t count = 0U;
497 
499  // A class without a dictionary cannot be in an Event/Lumi/Run.
500  // First, we check if the class has a dictionary. If it does not, we throw an exception.
501  // The missing dictionary might be for the class itself, the wrapped class, or a component of the class.
502  std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> const range = typeLookup.equal_range(TypeInBranchType(typeID, branchType_));
503  if(range.first == range.second) {
504  maybeThrowMissingDictionaryException(typeID, &typeLookup == &preg_->elementLookup(), preg_->missingDictionaries());
505  }
506 
507  unsigned int processLevelFound = std::numeric_limits<unsigned int>::max();
508  for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
509  if(it->processIndex() > processLevelFound) {
510  //this is for a less recent process and we've already found a match for a more recent process
511  continue;
512  }
513 
514  if(selector.match(*(it->branchDescription()))) {
515 
516  //now see if the data is actually available
517  ConstGroupPtr const& group = getGroupByIndex(it->index(), false, false);
518  if(group && group->productWasDeleted()) {
519  throwProductDeletedException("findGroup",
520  typeID,
521  it->branchDescription()->moduleLabel(),
522  it->branchDescription()->productInstanceName(),
523  it->branchDescription()->processName());
524  }
525 
526  // Skip product if not available.
527  if(group && !group->productUnavailable()) {
528 
529  this->resolveProduct(*group, true);
530  // If the product is a dummy filler, group will now be marked unavailable.
531  // Unscheduled execution can fail to produce the EDProduct so check
532  if(group->product() && !group->productUnavailable() && !group->onDemand()) {
533  if(it->processIndex() < processLevelFound) {
534  processLevelFound = it->processIndex();
535  count = 0U;
536  }
537  if(count == 0U) {
538  // Found a unique (so far) match, save it
539  result = BasicHandle(group->productData());
540  }
541  ++count;
542  }
543  }
544  }
545  }
546  if(count != 1) result = BasicHandle();
547  return count;
548  }
549 
550  ProductData const*
552  TransientProductLookupMap const& typeLookup,
553  std::string const& moduleLabel,
554  std::string const& productInstanceName,
555  std::string const& processName,
556  size_t& cachedOffset,
557  int& fillCount) const {
558 
560  bool isCached = (fillCount > 0 && fillCount == typeLookup.fillCount());
561  bool toBeCached = (fillCount >= 0 && !isCached);
562 
563  std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> range =
564  (isCached ? std::make_pair(typeLookup.begin() + cachedOffset, typeLookup.end()) : typeLookup.equal_range(TypeInBranchType(typeID, branchType_), moduleLabel, productInstanceName));
565 
566  if(toBeCached) {
567  cachedOffset = range.first - typeLookup.begin();
568  fillCount = typeLookup.fillCount();
569  }
570 
571  if(range.first == range.second) {
572  if(toBeCached) {
573  cachedOffset = typeLookup.end() - typeLookup.begin();
574  }
575  // We check for a missing dictionary. We do this only in this error leg.
576  // A class without a dictionary cannot be in an Event/Lumi/Run.
577  // We check if the class has a dictionary. If it does not, we throw an exception.
578  // The missing dictionary might be for the class itself, the wrapped class, or a component of the class.
579  std::pair<TypeLookup::const_iterator, TypeLookup::const_iterator> const typeRange = typeLookup.equal_range(TypeInBranchType(typeID, branchType_));
580  if(typeRange.first == typeRange.second) {
581  maybeThrowMissingDictionaryException(typeID, &typeLookup == &preg_->elementLookup(), preg_->missingDictionaries());
582  }
583  return 0;
584  }
585 
586  if(!processName.empty()) {
587  if(isCached) {
588  assert(processName == range.first->branchDescription()->processName());
589  range.second = range.first + 1;
590  } else if(toBeCached) {
591  bool processFound = false;
592  for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
593  if(it->isFirst() && it != range.first) {
594  break;
595  }
596  if(processName == it->branchDescription()->processName()) {
597  processFound = true;
598  range.first = it;
599  cachedOffset = range.first - typeLookup.begin();
600  range.second = range.first + 1;
601  break;
602  }
603  }
604  if(!processFound) {
605  cachedOffset = typeLookup.end() - typeLookup.begin();
606  return 0;
607  }
608  } // end if(toBeCached)
609  }
610 
611  for(TypeLookup::const_iterator it = range.first; it != range.second; ++it) {
612  if(it->isFirst() && it != range.first) {
613  return 0;
614  }
615  if(!processName.empty() && processName != it->branchDescription()->processName()) {
616  continue;
617  }
618  //now see if the data is actually available
619  ConstGroupPtr const& group = getGroupByIndex(it->index(), false, false);
620  if(group && group->productWasDeleted()) {
621  throwProductDeletedException("findGroupByLabel",
622  typeID,
623  moduleLabel,
624  productInstanceName,
625  processName);
626  }
627 
628  // Skip product if not available.
629  if(group && !group->productUnavailable()) {
630  this->resolveProduct(*group, true);
631  // If the product is a dummy filler, group will now be marked unavailable.
632  // Unscheduled execution can fail to produce the EDProduct so check
633  if(group->product() && !group->productUnavailable() && !group->onDemand()) {
634  // Found the match
635  return &group->productData();
636  }
637  }
638  }
639  return 0;
640  }
641 
642  ProductData const*
643  Principal::findGroupByTag(TypeID const& typeID, InputTag const& tag) const {
644  ProductData const* productData =
645  findGroupByLabel(typeID,
646  preg_->productLookup(),
647  tag.label(),
648  tag.instance(),
649  tag.process(),
650  tag.cachedOffset(),
651  tag.fillCount());
652  if(productData == 0) {
653  throwNotFoundException("findProductByTag", typeID, tag);
654  }
655  return productData;
656  }
657 
659  Principal::getForOutput(BranchID const& bid, bool getProd) const {
660  ConstGroupPtr const g = getGroup(bid, getProd, true);
661  if(g == 0) {
662  throwGroupNotFoundException("getForOutput", errors::LogicError, bid);
663  }
664  if (g->productWasDeleted()) {
665  throwProductDeletedException("getForOutput",g->productType(),
666  g->moduleLabel(),
667  g->productInstanceName(),
668  g->processName());
669  }
670  if(!g->provenance() || (!g->product() && !g->productProvenancePtr())) {
671  return OutputHandle();
672  }
673  return OutputHandle(WrapperHolder(g->product().get(), g->productData().getInterface()), &g->branchDescription(), g->productProvenancePtr());
674  }
675 
676  Provenance
677  Principal::getProvenance(BranchID const& bid) const {
678  ConstGroupPtr const g = getGroup(bid, false, true);
679  if(g == 0) {
681  }
682 
683  if(g->onDemand()) {
684  unscheduledFill(g->branchDescription().moduleLabel());
685  }
686  // We already tried to produce the unscheduled products above
687  // If they still are not there, then throw
688  if(g->onDemand()) {
689  throwGroupNotFoundException("getProvenance(onDemand)", errors::ProductNotFound, bid);
690  }
691 
692  return *g->provenance();
693  }
694 
695  // This one is mostly for test printout purposes
696  // No attempt to trigger on demand execution
697  // Skips provenance when the EDProduct is not there
698  void
699  Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
700  provenances.clear();
701  for (const_iterator i = begin(), iEnd = end(); i != iEnd; ++i) {
702  if((*i)->provenanceAvailable()) {
703  // We do not attempt to get the event/lumi/run status from the provenance,
704  // because the per event provenance may have been dropped.
705  if((*i)->provenance()->product().present()) {
706  provenances.push_back((*i)->provenance());
707  }
708  }
709  }
710  }
711 
712  void
713  Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
714  for (std::vector<BranchID>::const_iterator it = bids.begin(), itEnd = bids.end(); it != itEnd; ++it) {
715  ProductTransientIndex index= preg_->indexFrom(*it);
716  assert(index!=ProductRegistry::kInvalidIndex);
717  ProductTransientIndex indexO = other.preg_->indexFrom(*it);
718  assert(indexO!=ProductRegistry::kInvalidIndex);
719  groups_[index].swap(other.groups_[indexO]);
720  }
721  reader_->mergeReaders(other.reader());
722  }
723 
725  Principal::getIt(ProductID const&) const {
726  assert(0);
727  return WrapperHolder();
728  }
729 
730  void
731  Principal::maybeFlushCache(TypeID const& tid, InputTag const& tag) const {
732  if(tag.typeID() != tid ||
733  tag.branchType() != branchType() ||
734  tag.productRegistry() != &productRegistry()) {
735  tag.fillCount() = 0;
736  tag.cachedOffset() = 0U;
737  tag.typeID() = tid;
738  tag.branchType() = branchType();
739  tag.productRegistry() = &productRegistry();
740  }
741  }
742 
743  void
745  if(!prod.isValid()) return;
746  // These are defensive checks against things that should never happen, but have.
747  // Checks that the same physical product has not already been put into the event.
748  bool alreadyPresent = !productPtrs_.insert(prod.wrapper()).second;
749  if(alreadyPresent) {
750  g->checkType(prod);
751  const_cast<WrapperOwningHolder&>(prod).reset();
752  throwCorruptionException("checkUniquenessAndType", g->branchDescription().branchName());
753  }
754  // Checks that the real type of the product matches the branch.
755  g->checkType(prod);
756  }
757 
758  void
760  bool willBePut = g->putOrMergeProduct();
761  if(willBePut) {
762  checkUniquenessAndType(prod, g);
763  g->putProduct(prod);
764  } else {
765  g->checkType(prod);
766  g->mergeProduct(prod);
767  }
768  }
769 
770  void
772  bool willBePut = g->putOrMergeProduct();
773  if(willBePut) {
774  checkUniquenessAndType(prod, g);
775  g->putProduct(prod, prov);
776  } else {
777  g->checkType(prod);
778  g->mergeProduct(prod, prov);
779  }
780  }
781 
782  void
784  if(preg_->constProductList().size() > groups_.size()) {
785  GroupCollection newGroups(preg_->constProductList().size(), SharedGroupPtr());
786  for (Principal::const_iterator i = begin(), iEnd = end(); i != iEnd; ++i) {
787  ProductTransientIndex index = preg_->indexFrom((*i)->branchDescription().branchID());
788  assert(index != ProductRegistry::kInvalidIndex);
789  newGroups[index] = *i;
790  }
791  groups_.swap(newGroups);
792  // Now we must add new groups for any new product registry entries.
793  ProductRegistry::ProductList const& prodsList = preg_->productList();
794  for(ProductRegistry::ProductList::const_iterator itProdInfo = prodsList.begin(),
795  itProdInfoEnd = prodsList.end();
796  itProdInfo != itProdInfoEnd;
797  ++itProdInfo) {
798  if(itProdInfo->second.branchType() == branchType_) {
799  ProductTransientIndex index = preg_->indexFrom(itProdInfo->second.branchID());
800  assert(index != ProductRegistry::kInvalidIndex);
801  if(!groups_[index]) {
802  // no group. Must add one. The new entry must be an input group.
803  assert(!itProdInfo->second.produced());
804  boost::shared_ptr<ConstBranchDescription> bd(new ConstBranchDescription(itProdInfo->second));
805  addGroupInput(bd);
806  }
807  }
808  }
809  }
810  }
811 }
BranchType branchType_
Definition: Principal.h:236
std::string const & processName() const
void maybeFlushCache(TypeID const &tid, InputTag const &tag) const
Definition: Principal.cc:731
ProductRegistry const & productRegistry() const
Definition: Principal.h:132
void clearPrincipal()
Definition: Principal.cc:206
int i
Definition: DBlmapReader.cc:9
size_t size() const
Definition: Principal.cc:146
size_t findGroup(TypeID const &typeID, TypeLookup const &typeLookup, SelectorBase const &selector, BasicHandle &result) const
Definition: Principal.cc:490
void addGroupScheduled(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:181
DelayedReader * reader_
Definition: Principal.h:231
HistoryAppender * historyAppender_
Definition: Principal.h:241
ConstProductList & constProductList() const
static void throwNotFoundException(char const *where, TypeID const &productType, InputTag const &tag)
Definition: Principal.cc:93
BasicHandle getByLabel(TypeID const &tid, std::string const &label, std::string const &productInstanceName, std::string const &processName, size_t &cachedOffset, int &fillCount) const
Definition: Principal.cc:355
const_iterator end() const
Definition: Principal.h:141
void addGroup_(std::auto_ptr< Group > g)
Definition: Principal.cc:282
static PFTauRenderPlugin instance
Group * getExistingGroup(BranchID const &branchID)
Definition: Principal.cc:267
void addGroupOrThrow(std::auto_ptr< Group > g)
Definition: Principal.cc:296
ConstGroupPtr getGroup(BranchID const &oid, bool resolveProd, bool fillOnDemand) const
Definition: Principal.cc:313
std::map< BranchKey, BranchDescription > ProductList
ProcessHistoryID processHistoryID_
Definition: Principal.h:218
void mergeReaders(DelayedReader *other)
Definition: DelayedReader.h:25
static void throwProductDeletedException(ProductID const &pid, edm::EventPrincipal::ConstGroupPtr const g)
static ProductTransientIndex const kInvalidIndex
static boost::shared_ptr< cms::Exception > makeNotFoundException(char const *where, TypeID const &productType)
Definition: Principal.cc:62
void getAllProvenance(std::vector< Provenance const * > &provenances) const
Definition: Principal.cc:699
static void throwCorruptionException(char const *where, std::string const &branchName)
Definition: Principal.cc:55
static ThreadSafeRegistry * instance()
CachedHistory const & appendToProcessHistory(ProcessHistoryID const &inputPHID, ProcessConfiguration const &pc)
boost::shared_ptr< ProductRegistry const > preg_
Definition: Principal.h:227
ProcessHistory const * processHistoryPtr_
Definition: Principal.h:216
std::string const & friendlyClassName() const
BranchType & branchType() const
Definition: InputTag.h:35
void addGroupSource(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:187
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 g
Definition: Activities.doc:4
ProductData const * findGroupByTag(TypeID const &typeID, InputTag const &tag) const
Definition: Principal.cc:643
BranchType
Definition: BranchType.h:11
void resolveProduct(Group const &g, bool fillOnDemand) const
Definition: Principal.h:178
size_t & cachedOffset() const
Definition: InputTag.h:37
ProductLookupIndexList::const_iterator const_iterator
GroupCollection groups_
Definition: Principal.h:223
bool match(ConstBranchDescription const &p) const
Definition: SelectorBase.cc:15
std::string const & processName() const
Group const * ConstGroupPtr
Definition: Principal.h:57
ProductList const & productList() const
U second(std::pair< T, U > const &p)
ProcessHistoryID const & processHistoryID() const
static void throwGroupNotFoundException(char const *where, errors::ErrorCodes error, BranchID const &bid)
Definition: Principal.cc:48
TypeID & typeID() const
Definition: InputTag.h:33
bool getMapped(key_type const &k, value_type &result) const
bool onDemand() const
Definition: Group.h:49
int & fillCount() const
Definition: InputTag.h:39
boost::shared_ptr< Group > SharedGroupPtr
Definition: Principal.h:61
const T & max(const T &a, const T &b)
void getMany(TypeID const &tid, SelectorBase const &, BasicHandleVec &results) const
Definition: Principal.cc:379
std::string const & productInstanceName() const
BranchType const & branchType() const
Definition: Principal.h:147
size_t findGroups(TypeID const &typeID, TypeLookup const &typeLookup, SelectorBase const &selector, BasicHandleVec &results) const
Definition: Principal.cc:440
ProductData const * findGroupByLabel(TypeID const &typeID, TypeLookup const &typeLookup, std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName, size_t &cachedOffset, int &fillCount) const
Definition: Principal.cc:551
tuple result
Definition: query.py:137
void checkDictionaries(std::string const &name, bool noComponents=false)
Definition: ReflexTools.cc:199
size_t getMatchingSequence(TypeID const &typeID, SelectorBase const &selector, BasicHandle &result) const
Definition: Principal.cc:427
BranchID const & branchID() const
OutputHandle getForOutput(BranchID const &bid, bool getProd) const
Definition: Principal.cc:659
static void throwMultiFoundException(char const *where, int nFound, TypeID const &productType)
Definition: Principal.cc:40
std::string className() const
Definition: TypeID.cc:51
Hash< ProcessHistoryType > ProcessHistoryID
void throwMissingDictionariesException()
Definition: ReflexTools.cc:209
std::set< void const * > productPtrs_
Definition: Principal.h:234
bool putOrMergeProduct() const
Definition: Group.h:117
DelayedReader * reader() const
Definition: Principal.h:149
ConstGroupPtr getGroupByIndex(ProductTransientIndex const &oid, bool resolveProd, bool fillOnDemand) const
Definition: Principal.cc:322
static void maybeThrowMissingDictionaryException(TypeID const &productType, bool isElement, std::vector< std::string > const &missingDictionaries)
Definition: Principal.cc:31
virtual ~Principal()
Definition: Principal.cc:139
void const *& productRegistry() const
Definition: InputTag.h:41
std::string const & className() const
boost::shared_ptr< void const > product() const
Definition: Group.h:55
std::string wrappedClassName(std::string const &iFullName)
std::pair< const_iterator, const_iterator > equal_range(TypeInBranchType const &) const
returns a pair of iterators that define the range for items matching the TypeInBranchType ...
const_iterator begin() const
Definition: Principal.h:140
void mergeProduct(WrapperOwningHolder const &edp, ProductProvenance &productProvenance)
Definition: Group.h:122
virtual WrapperHolder getIt(ProductID const &) const
Definition: Principal.cc:725
void deleteProduct()
Definition: Group.h:37
void checkType(WrapperOwningHolder const &prod) const
Definition: Group.h:135
bool isValid() const
Definition: BasicHandle.h:90
void getManyByType(TypeID const &tid, BasicHandleVec &results) const
Definition: Principal.cc:414
std::string const & label() const
Definition: InputTag.h:25
std::string const & process() const
Definition: InputTag.h:29
std::string const & branchName() const
void addGroupInput(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:193
BasicHandle getByType(TypeID const &tid) const
Definition: Principal.cc:392
boost::filter_iterator< FilledGroupPtr, GroupCollection::const_iterator > const_iterator
Definition: Principal.h:55
author Stefano ARGIRO author Bill Tanenbaum
bool isValid() const
Definition: Hash.h:146
virtual bool unscheduledFill(std::string const &moduleLabel) const =0
bool adjustToNewProductRegistry(ProductRegistry const &reg)
Definition: Principal.cc:159
BasicHandle getBySelector(TypeID const &tid, SelectorBase const &s) const
Definition: Principal.cc:335
Principal(boost::shared_ptr< ProductRegistry const > reg, ProcessConfiguration const &pc, BranchType bt, HistoryAppender *historyAppender)
Definition: Principal.cc:99
void resetBranchDescription(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Group.h:72
std::vector< boost::shared_ptr< Group > > GroupCollection
Definition: Principal.h:54
bool isValid() const
Definition: WrapperHolder.h:27
void fillPrincipal(ProcessHistoryID const &hist, DelayedReader *reader)
Definition: Principal.cc:229
bool binary_search_all(ForwardSequence const &s, Datum const &d)
wrappers for std::binary_search
Definition: Algorithms.h:76
TransientProductLookupMap TypeLookup
Definition: Principal.h:193
void adjustIndexesAfterProductRegistryAddition()
Definition: Principal.cc:783
bool productUnavailable() const
Definition: Group.h:43
void const * wrapper() const
Definition: WrapperHolder.h:76
static Interceptor::Registry registry("Interceptor")
void putProduct(WrapperOwningHolder const &edp, ProductProvenance const &productProvenance)
Definition: Group.h:107
tuple process
Definition: LaserDQM_cfg.py:3
ProcessHistory const * processHistory() const
static ProcessHistory emptyProcessHistory_
Definition: Principal.h:243
void reset(double vett[256])
Definition: TPedValues.cc:11
Provenance getProvenance(BranchID const &bid) const
Definition: Principal.cc:677
void recombine(Principal &other, std::vector< BranchID > const &bids)
Definition: Principal.cc:713
ProcessHistory const * inputProcessHistory() const
std::string const & instance() const
Definition: InputTag.h:26
void checkUniquenessAndType(WrapperOwningHolder const &prod, Group const *group) const
Definition: Principal.cc:744
ProcessConfiguration const * processConfiguration_
Definition: Principal.h:220
tuple size
Write out results.
ConstBranchDescription const & branchDescription() const
Definition: Group.h:69
std::vector< BasicHandle > BasicHandleVec
Definition: Principal.h:58
std::string const & moduleLabel() const
void addOnDemandGroup(boost::shared_ptr< ConstBranchDescription > bd)
Definition: Principal.cc:199
void putOrMerge(WrapperOwningHolder const &prod, Group const *group) const
Definition: Principal.cc:759
void deleteProduct(BranchID const &id)
Definition: Principal.cc:217