File indexing completed on 2025-05-23 23:48:33
0001
0002
0003 #ifdef __clang__
0004 #pragma GCC diagnostic ignored "-Wc++20-extensions"
0005 #endif
0006
0007 #include "FWCore/Framework/interface/Principal.h"
0008
0009 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0010 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0011 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0012 #include "DataFormats/Common/interface/FunctorHandleExceptionFactory.h"
0013 #include "FWCore/Framework/interface/DelayedReader.h"
0014 #include "FWCore/Framework/interface/HistoryAppender.h"
0015 #include "FWCore/Framework/src/ProductDeletedException.h"
0016 #include "FWCore/Framework/interface/ProductPutterBase.h"
0017 #include "FWCore/Framework/interface/EDConsumerBase.h"
0018 #include "DroppedDataProductResolver.h"
0019 #include "FWCore/Utilities/interface/EDMException.h"
0020 #include "FWCore/Utilities/interface/ProductResolverIndex.h"
0021 #include "FWCore/Utilities/interface/TypeID.h"
0022 #include "FWCore/Utilities/interface/WrappedClassName.h"
0023 #include "FWCore/Utilities/interface/Likely.h"
0024 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0025
0026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0027
0028 #include <algorithm>
0029 #include <cstring>
0030 #include <limits>
0031 #include <sstream>
0032 #include <stdexcept>
0033 #include <typeinfo>
0034 #include <atomic>
0035 namespace edm {
0036
0037 static ProcessHistory const s_emptyProcessHistory;
0038
0039 static std::string appendCurrentProcessIfAlias(std::string const& processFromInputTag,
0040 std::string const& currentProcess) {
0041 if (processFromInputTag == InputTag::kCurrentProcess) {
0042 std::string returnValue = processFromInputTag;
0043 returnValue += " (";
0044 returnValue += currentProcess;
0045 returnValue += ")";
0046 return returnValue;
0047 }
0048 return processFromInputTag;
0049 }
0050
0051 static void throwProductNotFoundException(char const* where, errors::ErrorCodes error, BranchID const& bid) {
0052 throw Exception(error, "InvalidID") << "Principal::" << where << ": no product with given branch id: " << bid
0053 << "\n";
0054 }
0055
0056 static std::shared_ptr<cms::Exception> makeNotFoundException(char const* where,
0057 KindOfType kindOfType,
0058 TypeID const& productType,
0059 std::string const& label,
0060 std::string const& instance,
0061 std::string const& process) {
0062 std::shared_ptr<cms::Exception> exception = std::make_shared<Exception>(errors::ProductNotFound);
0063 if (kindOfType == PRODUCT_TYPE) {
0064 *exception << "Principal::" << where
0065 << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
0066 << "Looking for module label: " << label << "\n"
0067 << "Looking for productInstanceName: " << instance << "\n"
0068 << (process.empty() ? "" : "Looking for process: ") << process << "\n";
0069 } else {
0070 *exception << "Principal::" << where
0071 << ": Found zero products matching all criteria\nLooking for a container with elements of type: "
0072 << productType << "\n"
0073 << "Looking for module label: " << label << "\n"
0074 << "Looking for productInstanceName: " << instance << "\n"
0075 << (process.empty() ? "" : "Looking for process: ") << process << "\n";
0076 }
0077 return exception;
0078 }
0079
0080 static void throwAmbiguousException(const char* where,
0081 TypeID const& productType,
0082 std::string const& label,
0083 std::string const& instance,
0084 std::string const& process) {
0085 cms::Exception exception("AmbiguousProduct");
0086 exception << "Principal::" << where
0087 << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
0088 << "Looking for module label: " << label << "\n"
0089 << "Looking for productInstanceName: " << instance << "\n"
0090 << (process.empty() ? "" : "Looking for process: ") << process << "\n"
0091 << "This can only occur with get function calls using a Handle<View> argument.\n"
0092 << "Try a get not using a View or change the instance name of one of the products";
0093 throw exception;
0094 }
0095
0096 namespace {
0097 void failedToRegisterConsumes(KindOfType kindOfType,
0098 TypeID const& productType,
0099 std::string const& moduleLabel,
0100 std::string const& productInstanceName,
0101 std::string const& processName) {
0102 cms::Exception exception("GetByLabelWithoutRegistration");
0103 exception << "::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
0104 << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<") << productType
0105 << (kindOfType == PRODUCT_TYPE ? "\n module label: " : ">\n module label: ") << moduleLabel
0106 << "\n product instance name: '" << productInstanceName << "'\n process name: '" << processName
0107 << "'\n";
0108 throw exception;
0109 }
0110 }
0111
0112
0113 CMS_THREAD_SAFE static std::array<std::atomic<Principal::CacheIdentifier_t>, edm::NumBranchTypes> s_nextIdentifiers{
0114 {1, 1, 1, 1}};
0115 static inline Principal::CacheIdentifier_t nextIdentifier(edm::BranchType bt) {
0116 return s_nextIdentifiers[bt].fetch_add(1, std::memory_order_acq_rel);
0117 }
0118
0119 Principal::Principal(std::shared_ptr<ProductRegistry const> reg,
0120 std::vector<std::shared_ptr<ProductResolverBase>>&& resolvers,
0121 ProcessConfiguration const& pc,
0122 BranchType bt,
0123 HistoryAppender* historyAppender)
0124 : EDProductGetter(),
0125 processHistoryPtr_(),
0126 processHistoryID_(),
0127 processHistoryIDBeforeConfig_(),
0128 processConfiguration_(&pc),
0129 productResolvers_(resolvers.begin(), resolvers.end()),
0130 preg_(reg),
0131 productLookup_(reg->productLookup(bt)),
0132 lookupProcessOrder_(productLookup_->lookupProcessNames().size(), 0),
0133 reader_(),
0134 branchType_(bt),
0135 historyAppender_(historyAppender),
0136 cacheIdentifier_(0) {}
0137 Principal::~Principal() {}
0138
0139
0140
0141
0142 size_t Principal::size() const {
0143 size_t size = 0U;
0144 for (auto const& prod : *this) {
0145 if (prod->singleProduct() &&
0146 !prod->productUnavailable() && !prod->unscheduledWasNotRun() && !prod->productDescription().dropped()) {
0147 ++size;
0148 }
0149 }
0150 return size;
0151 }
0152
0153 void Principal::possiblyUpdateAfterAddition(std::shared_ptr<ProductRegistry const> iProd) {
0154 if (iProd.get() != preg_.get() || iProd->cacheIdentifier() != preg_->cacheIdentifier()) {
0155 preg_ = iProd;
0156 adjustIndexesAfterProductRegistryAddition();
0157 }
0158 }
0159
0160 void Principal::addDroppedProduct(ProductDescription const& bd) {
0161 addProductOrThrow(std::make_unique<DroppedDataProductResolver>(std::make_shared<ProductDescription const>(bd)));
0162 }
0163
0164
0165 void Principal::clearPrincipal() {
0166
0167
0168
0169 reader_ = nullptr;
0170 for (auto& prod : *this) {
0171 prod->resetProductData();
0172 }
0173 }
0174
0175 void Principal::deleteProduct(BranchID const& id) const {
0176 auto phb = getExistingProduct(id);
0177 assert(nullptr != phb);
0178 phb->unsafe_deleteProduct();
0179 }
0180
0181 void Principal::setupUnscheduled(UnscheduledConfigurator const& iConfigure) {
0182 applyToResolvers([&iConfigure](ProductResolverBase* iResolver) { iResolver->setupUnscheduled(iConfigure); });
0183 }
0184
0185 void Principal::fillPrincipal(DelayedReader* reader) {
0186
0187 cacheIdentifier_ = nextIdentifier(branchType_);
0188 if (reader) {
0189 reader_ = reader;
0190 }
0191 }
0192
0193
0194 void Principal::fillPrincipal(ProcessHistoryID const& hist,
0195 ProcessHistory const* processHistory,
0196 DelayedReader* reader) {
0197 fillPrincipal(reader);
0198
0199 if (historyAppender_ && productRegistry().anyProductProduced()) {
0200 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0201 processHistoryPtr_ = historyAppender_->appendToProcessHistory(hist, processHistory, *processConfiguration_);
0202 processHistoryID_ = processHistoryPtr_->id();
0203 processHistoryIDBeforeConfig_ = hist;
0204 }
0205 } else {
0206 std::shared_ptr<ProcessHistory const> inputProcessHistory;
0207 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0208 if (hist.isValid()) {
0209
0210 auto noDel = [](void const*) {};
0211 inputProcessHistory = std::shared_ptr<ProcessHistory const>(processHistory, noDel);
0212 if (inputProcessHistory.get() == nullptr) {
0213 throw Exception(errors::LogicError) << "Principal::fillPrincipal\n"
0214 << "Input ProcessHistory not found in registry\n"
0215 << "Contact a Framework developer\n";
0216 }
0217 } else {
0218
0219 inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory, [](void const*) {});
0220
0221 orderProcessHistoryID_ = hist;
0222 }
0223 processHistoryID_ = hist;
0224 processHistoryPtr_ = inputProcessHistory;
0225 processHistoryIDBeforeConfig_ = hist;
0226 }
0227 }
0228
0229 if (orderProcessHistoryID_ != processHistoryID_) {
0230 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0231 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0232 unsigned int k = 0;
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 {
0243 auto nameIterCurrentProcess =
0244 std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processConfiguration_->processName());
0245 if (nameIterCurrentProcess != lookupProcessNames.end()) {
0246 lookupProcessOrder_.at(k) = nameIterCurrentProcess - lookupProcessNames.begin();
0247 ++k;
0248 }
0249 }
0250
0251
0252
0253 auto iter = processHistoryPtr_->rbegin();
0254 if (iter->processName() == processConfiguration_->processName()) {
0255 ++iter;
0256 }
0257
0258 for (auto iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
0259 auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
0260 if (nameIter == lookupProcessNames.end()) {
0261 continue;
0262 }
0263 lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
0264 ++k;
0265 }
0266 orderProcessHistoryID_ = processHistoryID_;
0267 }
0268 }
0269
0270
0271 void Principal::fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader) {
0272 fillPrincipal(reader);
0273
0274 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0275 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0276 if (!lookupProcessOrder_.empty()) {
0277 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processNameOfBlock);
0278 if (iter != lookupProcessNames.end()) {
0279 lookupProcessOrder_[0] = iter - lookupProcessNames.begin();
0280 }
0281 }
0282 }
0283
0284 ProductResolverBase* Principal::getExistingProduct(BranchID const& branchID) {
0285 return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getExistingProduct(branchID));
0286 }
0287
0288 ProductResolverBase const* Principal::getExistingProduct(BranchID const& branchID) const {
0289 ProductResolverIndex index = preg_->indexFrom(branchID);
0290 assert(index != ProductResolverIndexInvalid);
0291 return productResolvers_.at(index).get();
0292 }
0293
0294 ProductResolverBase const* Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
0295 auto phb = getExistingProduct(productResolver.productDescription().branchID());
0296 if (nullptr != phb && BranchKey(productResolver.productDescription()) != BranchKey(phb->productDescription())) {
0297 ProductDescription const& newProduct = phb->productDescription();
0298 ProductDescription const& existing = productResolver.productDescription();
0299 if (newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
0300 throw cms::Exception("HashCollision")
0301 << "Principal::getExistingProduct\n"
0302 << " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName()
0303 << "\n"
0304 << "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
0305 } else {
0306 assert(nullptr == phb ||
0307 BranchKey(productResolver.productDescription()) == BranchKey(phb->productDescription()));
0308 }
0309 }
0310 return phb;
0311 }
0312
0313 std::vector<ProductDescription const*> Principal::productDescriptions() const {
0314 std::vector<ProductDescription const*> retValue;
0315 for (auto const& p : productRegistry().productList()) {
0316 if (p.second.branchType() == branchType()) {
0317 retValue.push_back(&p.second);
0318 }
0319 }
0320 return retValue;
0321 }
0322
0323 void Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
0324 ProductDescription const& bd = productResolver->productDescription();
0325 assert(!bd.className().empty());
0326 assert(!bd.friendlyClassName().empty());
0327 assert(!bd.moduleLabel().empty());
0328 assert(!bd.processName().empty());
0329 SharedProductPtr phb(productResolver.release());
0330
0331 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0332 assert(index != ProductResolverIndexInvalid);
0333 productResolvers_[index] = phb;
0334 }
0335
0336 void Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
0337 ProductResolverBase const* phb = getExistingProduct(*productResolver);
0338 if (phb != nullptr) {
0339 ProductDescription const& bd = productResolver->productDescription();
0340 throw Exception(errors::InsertFailure, "AlreadyPresent")
0341 << "addProductOrThrow: Problem found while adding product, "
0342 << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
0343 << bd.productInstanceName() << "," << bd.processName() << ")\n";
0344 }
0345 addProduct_(std::move(productResolver));
0346 }
0347
0348 Principal::ConstProductResolverPtr Principal::getProductResolver(BranchID const& bid) const {
0349 ProductResolverIndex index = preg_->indexFrom(bid);
0350 if (index == ProductResolverIndexInvalid) {
0351 return ConstProductResolverPtr();
0352 }
0353 return getProductResolverByIndex(index);
0354 }
0355
0356 Principal::ConstProductResolverPtr Principal::getProductResolverByIndex(
0357 ProductResolverIndex const& index) const noexcept {
0358 assert(index < productResolvers_.size());
0359 ConstProductResolverPtr const phb = productResolvers_[index].get();
0360 return phb;
0361 }
0362
0363 unsigned int Principal::processBlockIndex(std::string const&) const {
0364 throw Exception(errors::LogicError) << "Principal::processBlockIndex not implemented for this type of Principal";
0365 }
0366
0367 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0368 TypeID const& typeID,
0369 InputTag const& inputTag,
0370 EDConsumerBase const* consumer,
0371 SharedResourcesAcquirer* sra,
0372 ModuleCallingContext const* mcc) const {
0373
0374
0375 assert(branchType_ != InProcess);
0376
0377 ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
0378 if (result == nullptr) {
0379 return BasicHandle(makeHandleExceptionFactory([=, this]() -> std::shared_ptr<cms::Exception> {
0380 return makeNotFoundException(
0381 "getByLabel",
0382 kindOfType,
0383 typeID,
0384 inputTag.label(),
0385 inputTag.instance(),
0386 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0387 }));
0388 }
0389 return BasicHandle(result->wrapper(), &(result->provenance()));
0390 }
0391
0392 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0393 TypeID const& typeID,
0394 std::string const& label,
0395 std::string const& instance,
0396 std::string const& process,
0397 EDConsumerBase const* consumer,
0398 SharedResourcesAcquirer* sra,
0399 ModuleCallingContext const* mcc) const {
0400 ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process, consumer, sra, mcc);
0401 if (result == nullptr) {
0402 return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
0403 return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
0404 }));
0405 }
0406 return BasicHandle(result->wrapper(), &(result->provenance()));
0407 }
0408
0409 BasicHandle Principal::getByToken(KindOfType,
0410 TypeID const&,
0411 ProductResolverIndex index,
0412 bool skipCurrentProcess,
0413 bool& ambiguous,
0414 SharedResourcesAcquirer* sra,
0415 ModuleCallingContext const* mcc) const {
0416 assert(index != ProductResolverIndexInvalid);
0417 auto& productResolver = productResolvers_[index];
0418 assert(nullptr != productResolver.get());
0419 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0420 if (resolution.isAmbiguous()) {
0421 ambiguous = true;
0422
0423
0424 return BasicHandle::makeInvalid();
0425 }
0426 auto productData = resolution.data();
0427 if (productData == nullptr) {
0428
0429
0430 return BasicHandle::makeInvalid();
0431 }
0432 return BasicHandle(productData->wrapper(), &(productData->provenance()));
0433 }
0434
0435 void Principal::prefetchAsync(WaitingTaskHolder task,
0436 ProductResolverIndex index,
0437 bool skipCurrentProcess,
0438 ServiceToken const& token,
0439 ModuleCallingContext const* mcc) const {
0440 auto const& productResolver = productResolvers_.at(index);
0441 assert(nullptr != productResolver.get());
0442 productResolver->prefetchAsync(task, *this, skipCurrentProcess, token, nullptr, mcc);
0443 }
0444
0445 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0446 TypeID const& typeID,
0447 InputTag const& inputTag,
0448 EDConsumerBase const* consumer,
0449 SharedResourcesAcquirer* sra,
0450 ModuleCallingContext const* mcc) const {
0451 bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
0452
0453 ProductResolverIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
0454
0455 if (index == ProductResolverIndexInvalid) {
0456 char const* processName = inputTag.process().c_str();
0457 if (skipCurrentProcess) {
0458 processName = "\0";
0459 } else if (inputTag.process() == InputTag::kCurrentProcess) {
0460 processName = processConfiguration_->processName().c_str();
0461 }
0462
0463 index =
0464 productLookup().index(kindOfType, typeID, inputTag.label().c_str(), inputTag.instance().c_str(), processName);
0465
0466 if (index == ProductResolverIndexAmbiguous) {
0467 throwAmbiguousException("findProductByLabel",
0468 typeID,
0469 inputTag.label(),
0470 inputTag.instance(),
0471 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0472 } else if (index == ProductResolverIndexInvalid) {
0473
0474 for (auto const& item : preg_->productList()) {
0475 auto const& bd = item.second;
0476 if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == inputTag.label() and
0477 bd.productInstanceName() == inputTag.instance()) {
0478 bool const inCurrentProcess = bd.processName() == processConfiguration_->processName();
0479 if (inputTag.process().empty() or bd.processName() == inputTag.process() or
0480 (skipCurrentProcess and not inCurrentProcess) or
0481 (inputTag.process() == InputTag::kCurrentProcess and inCurrentProcess)) {
0482 failedToRegisterConsumes(
0483 kindOfType,
0484 typeID,
0485 inputTag.label(),
0486 inputTag.instance(),
0487 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0488 }
0489 }
0490 }
0491 return nullptr;
0492 }
0493 inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
0494 }
0495 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
0496 failedToRegisterConsumes(kindOfType,
0497 typeID,
0498 inputTag.label(),
0499 inputTag.instance(),
0500 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0501 }
0502
0503 auto const& productResolver = productResolvers_[index];
0504
0505 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0506 if (resolution.isAmbiguous()) {
0507 throwAmbiguousException("findProductByLabel",
0508 typeID,
0509 inputTag.label(),
0510 inputTag.instance(),
0511 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0512 }
0513 return resolution.data();
0514 }
0515
0516 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0517 TypeID const& typeID,
0518 std::string const& label,
0519 std::string const& instance,
0520 std::string const& process,
0521 EDConsumerBase const* consumer,
0522 SharedResourcesAcquirer* sra,
0523 ModuleCallingContext const* mcc) const {
0524 ProductResolverIndex index =
0525 productLookup().index(kindOfType, typeID, label.c_str(), instance.c_str(), process.c_str());
0526
0527 if (index == ProductResolverIndexAmbiguous) {
0528 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0529 } else if (index == ProductResolverIndexInvalid) {
0530
0531 for (auto const& item : preg_->productList()) {
0532 auto const& bd = item.second;
0533 if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == label and
0534 bd.productInstanceName() == instance) {
0535 if (process.empty() or bd.processName() == process) {
0536 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0537 }
0538 }
0539 }
0540 return nullptr;
0541 }
0542
0543 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
0544 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0545 }
0546
0547 auto const& productResolver = productResolvers_[index];
0548
0549 auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
0550 if (resolution.isAmbiguous()) {
0551 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0552 }
0553 return resolution.data();
0554 }
0555
0556 ProductData const* Principal::findProductByTag(TypeID const& typeID,
0557 InputTag const& tag,
0558 ModuleCallingContext const* mcc) const {
0559
0560 assert(branchType_ != InProcess);
0561
0562 ProductData const* productData = findProductByLabel(PRODUCT_TYPE, typeID, tag, nullptr, nullptr, mcc);
0563 return productData;
0564 }
0565
0566 Provenance const& Principal::getProvenance(BranchID const& bid) const {
0567 ConstProductResolverPtr const phb = getProductResolver(bid);
0568 if (phb == nullptr) {
0569 throwProductNotFoundException("getProvenance", errors::ProductNotFound, bid);
0570 }
0571
0572 if (phb->unscheduledWasNotRun()) {
0573 throw edm::Exception(errors::UnimplementedFeature)
0574 << "Requesting provenance from unrun EDProducer. The requested branch ID was: " << bid;
0575 }
0576 return *phb->provenance();
0577 }
0578
0579 StableProvenance const& Principal::getStableProvenance(BranchID const& bid) const {
0580 ConstProductResolverPtr const phb = getProductResolver(bid);
0581 if (phb == nullptr) {
0582 throwProductNotFoundException("getStableProvenance", errors::ProductNotFound, bid);
0583 }
0584
0585 return *phb->stableProvenance();
0586 }
0587
0588
0589
0590
0591 void Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
0592 provenances.clear();
0593 for (auto const& productResolver : *this) {
0594 if (productResolver->singleProduct() && productResolver->provenanceAvailable() &&
0595 !productResolver->productDescription().isAnyAlias()) {
0596
0597
0598 if (productResolver->provenance()->productDescription().present()) {
0599 provenances.push_back(productResolver->provenance());
0600 }
0601 }
0602 }
0603 }
0604
0605
0606
0607
0608 void Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
0609 provenances.clear();
0610 for (auto const& productResolver : *this) {
0611 if (productResolver->singleProduct() && !productResolver->productDescription().isAnyAlias()) {
0612 if (productResolver->stableProvenance()->productDescription().present()) {
0613 provenances.push_back(productResolver->stableProvenance());
0614 }
0615 }
0616 }
0617 }
0618
0619 void Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
0620 for (auto& prod : bids) {
0621 ProductResolverIndex index = preg_->indexFrom(prod);
0622 assert(index != ProductResolverIndexInvalid);
0623 ProductResolverIndex indexO = other.preg_->indexFrom(prod);
0624 assert(indexO != ProductResolverIndexInvalid);
0625 get_underlying_safe(productResolvers_[index]).swap(get_underlying_safe(other.productResolvers_[indexO]));
0626 }
0627 reader_->mergeReaders(other.reader());
0628 }
0629
0630 WrapperBase const* Principal::getIt(ProductID const&) const {
0631 assert(false);
0632 return nullptr;
0633 }
0634
0635 std::optional<std::tuple<WrapperBase const*, unsigned int>> Principal::getThinnedProduct(ProductID const&,
0636 unsigned int) const {
0637 assert(false);
0638 return std::nullopt;
0639 }
0640
0641 void Principal::getThinnedProducts(ProductID const&,
0642 std::vector<WrapperBase const*>&,
0643 std::vector<unsigned int>&) const {
0644 assert(false);
0645 }
0646
0647 OptionalThinnedKey Principal::getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const {
0648 assert(false);
0649 return std::monostate{};
0650 }
0651
0652 void Principal::put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
0653 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(prod));
0654 }
0655
0656 void Principal::put_(ProductDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
0657 if (edp.get() == nullptr) {
0658 throw edm::Exception(edm::errors::InsertFailure, "Null Pointer")
0659 << "put: Cannot put because unique_ptr to product is null."
0660 << "\n";
0661 }
0662 auto phb = getExistingProduct(bd.branchID());
0663 assert(phb);
0664
0665 put_(std::move(edp), phb);
0666 }
0667
0668 void Principal::adjustIndexesAfterProductRegistryAddition() {
0669 if (preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
0670 bool changed = false;
0671 productResolvers_.resize(preg_->getNextIndexValue(branchType_));
0672 for (auto const& prod : preg_->productList()) {
0673 ProductDescription const& bd = prod.second;
0674 if (bd.branchType() == branchType_) {
0675 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0676 assert(index != ProductResolverIndexInvalid);
0677 if (!productResolvers_[index]) {
0678
0679 assert(!bd.produced());
0680 assert(bd.dropped());
0681
0682 addDroppedProduct(bd);
0683 changed = true;
0684 }
0685 }
0686 }
0687 if (changed) {
0688 changedIndexes_();
0689 }
0690 }
0691 assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
0692 }
0693
0694 void Principal::readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata) {
0695 if (not reader()) {
0696 return;
0697 }
0698
0699 for (auto& prod : *this) {
0700 prod->retrieveAndMerge(*this, mergeableRunProductMetadata);
0701 }
0702 }
0703 }