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