File indexing completed on 2024-05-15 04:21:40
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 "ProductResolvers.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::shared_ptr<ProductResolverIndexHelper const> productLookup,
0120 ProcessConfiguration const& pc,
0121 BranchType bt,
0122 HistoryAppender* historyAppender,
0123 bool isForPrimaryProcess)
0124 : EDProductGetter(),
0125 processHistoryPtr_(),
0126 processHistoryID_(),
0127 processHistoryIDBeforeConfig_(),
0128 processConfiguration_(&pc),
0129 productResolvers_(),
0130 preg_(reg),
0131 productLookup_(productLookup),
0132 lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
0133 reader_(),
0134 branchType_(bt),
0135 historyAppender_(historyAppender),
0136 cacheIdentifier_(nextIdentifier()) {
0137 productResolvers_.resize(reg->getNextIndexValue(bt));
0138
0139 std::string const source("source");
0140 ProductRegistry::ProductList const& prodsList = reg->productList();
0141
0142
0143
0144 bool hasAliases = false;
0145 bool hasSwitchAliases = false;
0146 for (auto const& prod : prodsList) {
0147 BranchDescription const& bd = prod.second;
0148 if (bd.branchType() == branchType_) {
0149 if (isForPrimaryProcess or bd.processName() == pc.processName()) {
0150 if (bd.isAlias()) {
0151 hasAliases = true;
0152 } else if (bd.isSwitchAlias()) {
0153 hasSwitchAliases = true;
0154 } else {
0155 auto cbd = std::make_shared<BranchDescription const>(bd);
0156 if (bd.produced()) {
0157 if (bd.moduleLabel() == source) {
0158 addSourceProduct(cbd);
0159 } else if (bd.onDemand()) {
0160 assert(branchType_ == InEvent);
0161 if (bd.isTransform()) {
0162 addTransformProduct(cbd);
0163 } else {
0164 addUnscheduledProduct(cbd);
0165 }
0166 } else {
0167 addScheduledProduct(cbd);
0168 }
0169 } else {
0170 if (bd.onDemand()) {
0171 addDelayedReaderInputProduct(cbd);
0172 } else {
0173 addPutOnReadInputProduct(cbd);
0174 }
0175 }
0176 }
0177 } else {
0178
0179 auto cbd = std::make_shared<BranchDescription const>(bd);
0180 addParentProcessProduct(cbd);
0181 }
0182 }
0183 }
0184
0185 if (hasAliases) {
0186 for (auto const& prod : prodsList) {
0187 BranchDescription const& bd = prod.second;
0188 if (bd.isAlias() && bd.branchType() == branchType_) {
0189 addAliasedProduct(std::make_shared<BranchDescription const>(bd));
0190 }
0191 }
0192 }
0193
0194 if (hasSwitchAliases) {
0195 for (auto const& prod : prodsList) {
0196 BranchDescription const& bd = prod.second;
0197 if (bd.isSwitchAlias() && bd.branchType() == branchType_) {
0198 assert(branchType_ == InEvent);
0199 auto cbd = std::make_shared<BranchDescription const>(bd);
0200
0201
0202
0203
0204
0205 if (bd.onDemand()) {
0206 addSwitchAliasProduct(cbd);
0207 } else {
0208 addSwitchProducerProduct(cbd);
0209 }
0210 }
0211 }
0212 }
0213
0214
0215
0216
0217 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0218 std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
0219 std::vector<bool> ambiguous(lookupProcessNames.size(), false);
0220 unsigned int beginElements = productLookup_->beginElements();
0221 std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
0222 std::vector<ProductResolverIndexHelper::Range> const& ranges = productLookup_->ranges();
0223 std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
0224 std::vector<char> const& processNamesCharArray = productLookup_->processNames();
0225
0226 unsigned int numberOfMatches = 0;
0227 ProductResolverIndex lastMatchIndex = ProductResolverIndexInvalid;
0228 if (!sortedTypeIDs.empty()) {
0229 ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
0230 for (unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
0231 ProductResolverIndexHelper::Range const& range = ranges.at(k);
0232 for (unsigned int i = range.begin(); i < range.end(); ++i) {
0233 ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
0234 if (product.startInProcessNames() == 0) {
0235 if (productResolverIndex != ProductResolverIndexInvalid) {
0236 if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
0237
0238 productResolvers_.at(productResolverIndex) =
0239 std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
0240 } else {
0241 bool productMadeAtEnd = false;
0242
0243 for (unsigned int j = 0; j < matchingHolders.size(); ++j) {
0244 if ((not ambiguous[j]) and ProductResolverIndexInvalid != matchingHolders[j] and
0245 productResolvers_[matchingHolders[j]]->branchDescription().availableOnlyAtEndTransition()) {
0246 productMadeAtEnd = true;
0247 break;
0248 }
0249 }
0250 std::shared_ptr<ProductResolverBase> newHolder =
0251 std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
0252 productResolvers_.at(productResolverIndex) = newHolder;
0253 }
0254 matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
0255 ambiguous.assign(lookupProcessNames.size(), false);
0256 numberOfMatches = 0;
0257 lastMatchIndex = ProductResolverIndexInvalid;
0258 }
0259 productResolverIndex = product.index();
0260 } else {
0261 std::string process(&processNamesCharArray.at(product.startInProcessNames()));
0262 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
0263 assert(iter != lookupProcessNames.end());
0264 ProductResolverIndex iMatchingIndex = product.index();
0265 lastMatchIndex = iMatchingIndex;
0266 assert(iMatchingIndex != ProductResolverIndexInvalid);
0267 ++numberOfMatches;
0268 if (iMatchingIndex == ProductResolverIndexAmbiguous) {
0269 assert(k >= beginElements);
0270 ambiguous.at(iter - lookupProcessNames.begin()) = true;
0271 } else {
0272 matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
0273 }
0274 }
0275 }
0276 }
0277
0278 if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
0279
0280 productResolvers_.at(productResolverIndex) =
0281 std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
0282 } else {
0283 bool productMadeAtEnd = false;
0284 for (unsigned int i = 0; i < matchingHolders.size(); ++i) {
0285 if ((not ambiguous[i]) and ProductResolverIndexInvalid != matchingHolders[i] and
0286 productResolvers_[matchingHolders[i]]->branchDescription().availableOnlyAtEndTransition()) {
0287 productMadeAtEnd = true;
0288 break;
0289 }
0290 }
0291 std::shared_ptr<ProductResolverBase> newHolder =
0292 std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
0293 productResolvers_.at(productResolverIndex) = newHolder;
0294 }
0295 }
0296 }
0297
0298 Principal::~Principal() {}
0299
0300
0301
0302
0303 size_t Principal::size() const {
0304 size_t size = 0U;
0305 for (auto const& prod : *this) {
0306 if (prod->singleProduct() &&
0307 !prod->productUnavailable() && !prod->unscheduledWasNotRun() && !prod->branchDescription().dropped()) {
0308 ++size;
0309 }
0310 }
0311 return size;
0312 }
0313
0314
0315 bool Principal::adjustToNewProductRegistry(ProductRegistry const& reg) {
0316 ProductRegistry::ProductList const& prodsList = reg.productList();
0317 for (auto const& prod : prodsList) {
0318 BranchDescription const& bd = prod.second;
0319 if (!bd.produced() && (bd.branchType() == branchType_)) {
0320 auto cbd = std::make_shared<BranchDescription const>(bd);
0321 auto phb = getExistingProduct(cbd->branchID());
0322 if (phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
0323 return false;
0324 }
0325 phb->resetBranchDescription(cbd);
0326 }
0327 }
0328 return true;
0329 }
0330
0331 void Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
0332 auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
0333 addProductOrThrow(std::move(phb));
0334 }
0335
0336 void Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
0337 auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
0338 addProductOrThrow(std::move(phb));
0339 }
0340
0341 void Principal::addDelayedReaderInputProduct(std::shared_ptr<BranchDescription const> bd) {
0342 addProductOrThrow(std::make_unique<DelayedReaderInputProductResolver>(std::move(bd)));
0343 }
0344
0345 void Principal::addPutOnReadInputProduct(std::shared_ptr<BranchDescription const> bd) {
0346 addProductOrThrow(std::make_unique<PutOnReadInputProductResolver>(std::move(bd)));
0347 }
0348
0349 void Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
0350 addProductOrThrow(std::make_unique<UnscheduledProductResolver>(std::move(bd)));
0351 }
0352
0353 void Principal::addTransformProduct(std::shared_ptr<BranchDescription const> bd) {
0354 addProductOrThrow(std::make_unique<TransformingProductResolver>(std::move(bd)));
0355 }
0356
0357 void Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
0358 ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
0359 assert(index != ProductResolverIndexInvalid);
0360
0361 addProductOrThrow(std::make_unique<AliasProductResolver>(
0362 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0363 }
0364
0365 void Principal::addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd) {
0366 ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
0367 assert(index != ProductResolverIndexInvalid);
0368
0369 addProductOrThrow(std::make_unique<SwitchProducerProductResolver>(
0370 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0371 }
0372
0373 void Principal::addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd) {
0374 ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
0375 assert(index != ProductResolverIndexInvalid);
0376
0377 addProductOrThrow(std::make_unique<SwitchAliasProductResolver>(
0378 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0379 }
0380
0381 void Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
0382 addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
0383 }
0384
0385
0386 void Principal::clearPrincipal() {
0387
0388
0389
0390 reader_ = nullptr;
0391 for (auto& prod : *this) {
0392 prod->resetProductData();
0393 }
0394 }
0395
0396 void Principal::deleteProduct(BranchID const& id) const {
0397 auto phb = getExistingProduct(id);
0398 assert(nullptr != phb);
0399 phb->unsafe_deleteProduct();
0400 }
0401
0402 void Principal::setupUnscheduled(UnscheduledConfigurator const& iConfigure) {
0403 applyToResolvers([&iConfigure](ProductResolverBase* iResolver) { iResolver->setupUnscheduled(iConfigure); });
0404 }
0405
0406 void Principal::fillPrincipal(DelayedReader* reader) {
0407
0408 cacheIdentifier_ = nextIdentifier();
0409 if (reader) {
0410 reader_ = reader;
0411 }
0412 }
0413
0414
0415 void Principal::fillPrincipal(ProcessHistoryID const& hist,
0416 ProcessHistory const* processHistory,
0417 DelayedReader* reader) {
0418 fillPrincipal(reader);
0419
0420 if (historyAppender_ && productRegistry().anyProductProduced()) {
0421 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0422 processHistoryPtr_ = historyAppender_->appendToProcessHistory(hist, processHistory, *processConfiguration_);
0423 processHistoryID_ = processHistoryPtr_->id();
0424 processHistoryIDBeforeConfig_ = hist;
0425 }
0426 } else {
0427 std::shared_ptr<ProcessHistory const> inputProcessHistory;
0428 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0429 if (hist.isValid()) {
0430
0431 auto noDel = [](void const*) {};
0432 inputProcessHistory = std::shared_ptr<ProcessHistory const>(processHistory, noDel);
0433 if (inputProcessHistory.get() == nullptr) {
0434 throw Exception(errors::LogicError) << "Principal::fillPrincipal\n"
0435 << "Input ProcessHistory not found in registry\n"
0436 << "Contact a Framework developer\n";
0437 }
0438 } else {
0439
0440 inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory, [](void const*) {});
0441
0442 orderProcessHistoryID_ = hist;
0443 }
0444 processHistoryID_ = hist;
0445 processHistoryPtr_ = inputProcessHistory;
0446 processHistoryIDBeforeConfig_ = hist;
0447 }
0448 }
0449
0450 if (orderProcessHistoryID_ != processHistoryID_) {
0451 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0452 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0453 unsigned int k = 0;
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463 {
0464 auto nameIterCurrentProcess =
0465 std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processConfiguration_->processName());
0466 if (nameIterCurrentProcess != lookupProcessNames.end()) {
0467 lookupProcessOrder_.at(k) = nameIterCurrentProcess - lookupProcessNames.begin();
0468 ++k;
0469 }
0470 }
0471
0472
0473
0474 auto iter = processHistoryPtr_->rbegin();
0475 if (iter->processName() == processConfiguration_->processName()) {
0476 ++iter;
0477 }
0478
0479 for (auto iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
0480 auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
0481 if (nameIter == lookupProcessNames.end()) {
0482 continue;
0483 }
0484 lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
0485 ++k;
0486 }
0487 orderProcessHistoryID_ = processHistoryID_;
0488 }
0489 }
0490
0491
0492 void Principal::fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader) {
0493 fillPrincipal(reader);
0494
0495 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0496 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0497 if (!lookupProcessOrder_.empty()) {
0498 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processNameOfBlock);
0499 if (iter != lookupProcessNames.end()) {
0500 lookupProcessOrder_[0] = iter - lookupProcessNames.begin();
0501 }
0502 }
0503 }
0504
0505 ProductResolverBase* Principal::getExistingProduct(BranchID const& branchID) {
0506 return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getExistingProduct(branchID));
0507 }
0508
0509 ProductResolverBase const* Principal::getExistingProduct(BranchID const& branchID) const {
0510 ProductResolverIndex index = preg_->indexFrom(branchID);
0511 assert(index != ProductResolverIndexInvalid);
0512 return productResolvers_.at(index).get();
0513 }
0514
0515 ProductResolverBase const* Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
0516 auto phb = getExistingProduct(productResolver.branchDescription().branchID());
0517 if (nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
0518 BranchDescription const& newProduct = phb->branchDescription();
0519 BranchDescription const& existing = productResolver.branchDescription();
0520 if (newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
0521 throw cms::Exception("HashCollision")
0522 << "Principal::getExistingProduct\n"
0523 << " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName()
0524 << "\n"
0525 << "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
0526 } else {
0527 assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
0528 }
0529 }
0530 return phb;
0531 }
0532
0533 void Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
0534 BranchDescription const& bd = productResolver->branchDescription();
0535 assert(!bd.className().empty());
0536 assert(!bd.friendlyClassName().empty());
0537 assert(!bd.moduleLabel().empty());
0538 assert(!bd.processName().empty());
0539 SharedProductPtr phb(productResolver.release());
0540
0541 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0542 assert(index != ProductResolverIndexInvalid);
0543 productResolvers_[index] = phb;
0544 }
0545
0546 void Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
0547 ProductResolverBase const* phb = getExistingProduct(*productResolver);
0548 if (phb != nullptr) {
0549 BranchDescription const& bd = productResolver->branchDescription();
0550 throw Exception(errors::InsertFailure, "AlreadyPresent")
0551 << "addProductOrThrow: Problem found while adding product, "
0552 << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
0553 << bd.productInstanceName() << "," << bd.processName() << ")\n";
0554 }
0555 addProduct_(std::move(productResolver));
0556 }
0557
0558 Principal::ConstProductResolverPtr Principal::getProductResolver(BranchID const& bid) const {
0559 ProductResolverIndex index = preg_->indexFrom(bid);
0560 if (index == ProductResolverIndexInvalid) {
0561 return ConstProductResolverPtr();
0562 }
0563 return getProductResolverByIndex(index);
0564 }
0565
0566 Principal::ConstProductResolverPtr Principal::getProductResolverByIndex(
0567 ProductResolverIndex const& index) const noexcept {
0568 ConstProductResolverPtr const phb = productResolvers_[index].get();
0569 return phb;
0570 }
0571
0572 unsigned int Principal::processBlockIndex(std::string const&) const {
0573 throw Exception(errors::LogicError) << "Principal::processBlockIndex not implemented for this type of Principal";
0574 }
0575
0576 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0577 TypeID const& typeID,
0578 InputTag const& inputTag,
0579 EDConsumerBase const* consumer,
0580 SharedResourcesAcquirer* sra,
0581 ModuleCallingContext const* mcc) const {
0582
0583
0584 assert(branchType_ != InProcess);
0585
0586 ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
0587 if (result == nullptr) {
0588 return BasicHandle(makeHandleExceptionFactory([=, this]() -> std::shared_ptr<cms::Exception> {
0589 return makeNotFoundException(
0590 "getByLabel",
0591 kindOfType,
0592 typeID,
0593 inputTag.label(),
0594 inputTag.instance(),
0595 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0596 }));
0597 }
0598 return BasicHandle(result->wrapper(), &(result->provenance()));
0599 }
0600
0601 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0602 TypeID const& typeID,
0603 std::string const& label,
0604 std::string const& instance,
0605 std::string const& process,
0606 EDConsumerBase const* consumer,
0607 SharedResourcesAcquirer* sra,
0608 ModuleCallingContext const* mcc) const {
0609 ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process, consumer, sra, mcc);
0610 if (result == nullptr) {
0611 return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
0612 return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
0613 }));
0614 }
0615 return BasicHandle(result->wrapper(), &(result->provenance()));
0616 }
0617
0618 BasicHandle Principal::getByToken(KindOfType,
0619 TypeID const&,
0620 ProductResolverIndex index,
0621 bool skipCurrentProcess,
0622 bool& ambiguous,
0623 SharedResourcesAcquirer* sra,
0624 ModuleCallingContext const* mcc) const {
0625 assert(index != ProductResolverIndexInvalid);
0626 auto& productResolver = productResolvers_[index];
0627 assert(nullptr != productResolver.get());
0628 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0629 if (resolution.isAmbiguous()) {
0630 ambiguous = true;
0631
0632
0633 return BasicHandle::makeInvalid();
0634 }
0635 auto productData = resolution.data();
0636 if (productData == nullptr) {
0637
0638
0639 return BasicHandle::makeInvalid();
0640 }
0641 return BasicHandle(productData->wrapper(), &(productData->provenance()));
0642 }
0643
0644 void Principal::prefetchAsync(WaitingTaskHolder task,
0645 ProductResolverIndex index,
0646 bool skipCurrentProcess,
0647 ServiceToken const& token,
0648 ModuleCallingContext const* mcc) const {
0649 auto const& productResolver = productResolvers_.at(index);
0650 assert(nullptr != productResolver.get());
0651 productResolver->prefetchAsync(task, *this, skipCurrentProcess, token, nullptr, mcc);
0652 }
0653
0654 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0655 TypeID const& typeID,
0656 InputTag const& inputTag,
0657 EDConsumerBase const* consumer,
0658 SharedResourcesAcquirer* sra,
0659 ModuleCallingContext const* mcc) const {
0660 bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
0661
0662 ProductResolverIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
0663
0664 if (index == ProductResolverIndexInvalid) {
0665 char const* processName = inputTag.process().c_str();
0666 if (skipCurrentProcess) {
0667 processName = "\0";
0668 } else if (inputTag.process() == InputTag::kCurrentProcess) {
0669 processName = processConfiguration_->processName().c_str();
0670 }
0671
0672 index =
0673 productLookup().index(kindOfType, typeID, inputTag.label().c_str(), inputTag.instance().c_str(), processName);
0674
0675 if (index == ProductResolverIndexAmbiguous) {
0676 throwAmbiguousException("findProductByLabel",
0677 typeID,
0678 inputTag.label(),
0679 inputTag.instance(),
0680 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0681 } else if (index == ProductResolverIndexInvalid) {
0682
0683 for (auto const& item : preg_->productList()) {
0684 auto const& bd = item.second;
0685 if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == inputTag.label() and
0686 bd.productInstanceName() == inputTag.instance()) {
0687 bool const inCurrentProcess = bd.processName() == processConfiguration_->processName();
0688 if (inputTag.process().empty() or bd.processName() == inputTag.process() or
0689 (skipCurrentProcess and not inCurrentProcess) or
0690 (inputTag.process() == InputTag::kCurrentProcess and inCurrentProcess)) {
0691 failedToRegisterConsumes(
0692 kindOfType,
0693 typeID,
0694 inputTag.label(),
0695 inputTag.instance(),
0696 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0697 }
0698 }
0699 }
0700 return nullptr;
0701 }
0702 inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
0703 }
0704 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
0705 failedToRegisterConsumes(kindOfType,
0706 typeID,
0707 inputTag.label(),
0708 inputTag.instance(),
0709 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0710 }
0711
0712 auto const& productResolver = productResolvers_[index];
0713
0714 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0715 if (resolution.isAmbiguous()) {
0716 throwAmbiguousException("findProductByLabel",
0717 typeID,
0718 inputTag.label(),
0719 inputTag.instance(),
0720 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0721 }
0722 return resolution.data();
0723 }
0724
0725 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0726 TypeID const& typeID,
0727 std::string const& label,
0728 std::string const& instance,
0729 std::string const& process,
0730 EDConsumerBase const* consumer,
0731 SharedResourcesAcquirer* sra,
0732 ModuleCallingContext const* mcc) const {
0733 ProductResolverIndex index =
0734 productLookup().index(kindOfType, typeID, label.c_str(), instance.c_str(), process.c_str());
0735
0736 if (index == ProductResolverIndexAmbiguous) {
0737 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0738 } else if (index == ProductResolverIndexInvalid) {
0739
0740 for (auto const& item : preg_->productList()) {
0741 auto const& bd = item.second;
0742 if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == label and
0743 bd.productInstanceName() == instance) {
0744 if (process.empty() or bd.processName() == process) {
0745 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0746 }
0747 }
0748 }
0749 return nullptr;
0750 }
0751
0752 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
0753 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0754 }
0755
0756 auto const& productResolver = productResolvers_[index];
0757
0758 auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
0759 if (resolution.isAmbiguous()) {
0760 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0761 }
0762 return resolution.data();
0763 }
0764
0765 ProductData const* Principal::findProductByTag(TypeID const& typeID,
0766 InputTag const& tag,
0767 ModuleCallingContext const* mcc) const {
0768
0769 assert(branchType_ != InProcess);
0770
0771 ProductData const* productData = findProductByLabel(PRODUCT_TYPE, typeID, tag, nullptr, nullptr, mcc);
0772 return productData;
0773 }
0774
0775 Provenance const& Principal::getProvenance(BranchID const& bid) const {
0776 ConstProductResolverPtr const phb = getProductResolver(bid);
0777 if (phb == nullptr) {
0778 throwProductNotFoundException("getProvenance", errors::ProductNotFound, bid);
0779 }
0780
0781 if (phb->unscheduledWasNotRun()) {
0782 throw edm::Exception(errors::UnimplementedFeature)
0783 << "Requesting provenance from unrun EDProducer. The requested branch ID was: " << bid;
0784 }
0785 return *phb->provenance();
0786 }
0787
0788 StableProvenance const& Principal::getStableProvenance(BranchID const& bid) const {
0789 ConstProductResolverPtr const phb = getProductResolver(bid);
0790 if (phb == nullptr) {
0791 throwProductNotFoundException("getStableProvenance", errors::ProductNotFound, bid);
0792 }
0793
0794 return *phb->stableProvenance();
0795 }
0796
0797
0798
0799
0800 void Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
0801 provenances.clear();
0802 for (auto const& productResolver : *this) {
0803 if (productResolver->singleProduct() && productResolver->provenanceAvailable() &&
0804 !productResolver->branchDescription().isAnyAlias()) {
0805
0806
0807 if (productResolver->provenance()->branchDescription().present()) {
0808 provenances.push_back(productResolver->provenance());
0809 }
0810 }
0811 }
0812 }
0813
0814
0815
0816
0817 void Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
0818 provenances.clear();
0819 for (auto const& productResolver : *this) {
0820 if (productResolver->singleProduct() && !productResolver->branchDescription().isAnyAlias()) {
0821 if (productResolver->stableProvenance()->branchDescription().present()) {
0822 provenances.push_back(productResolver->stableProvenance());
0823 }
0824 }
0825 }
0826 }
0827
0828 void Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
0829 for (auto& prod : bids) {
0830 ProductResolverIndex index = preg_->indexFrom(prod);
0831 assert(index != ProductResolverIndexInvalid);
0832 ProductResolverIndex indexO = other.preg_->indexFrom(prod);
0833 assert(indexO != ProductResolverIndexInvalid);
0834 get_underlying_safe(productResolvers_[index]).swap(get_underlying_safe(other.productResolvers_[indexO]));
0835 }
0836 reader_->mergeReaders(other.reader());
0837 }
0838
0839 WrapperBase const* Principal::getIt(ProductID const&) const {
0840 assert(false);
0841 return nullptr;
0842 }
0843
0844 std::optional<std::tuple<WrapperBase const*, unsigned int>> Principal::getThinnedProduct(ProductID const&,
0845 unsigned int) const {
0846 assert(false);
0847 return std::nullopt;
0848 }
0849
0850 void Principal::getThinnedProducts(ProductID const&,
0851 std::vector<WrapperBase const*>&,
0852 std::vector<unsigned int>&) const {
0853 assert(false);
0854 }
0855
0856 OptionalThinnedKey Principal::getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const {
0857 assert(false);
0858 return std::monostate{};
0859 }
0860
0861 void Principal::put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
0862 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(prod));
0863 }
0864
0865 void Principal::put_(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
0866 if (edp.get() == nullptr) {
0867 throw edm::Exception(edm::errors::InsertFailure, "Null Pointer")
0868 << "put: Cannot put because unique_ptr to product is null."
0869 << "\n";
0870 }
0871 auto phb = getExistingProduct(bd.branchID());
0872 assert(phb);
0873
0874 put_(std::move(edp), phb);
0875 }
0876
0877 void Principal::adjustIndexesAfterProductRegistryAddition() {
0878 if (preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
0879 bool changed = false;
0880 productResolvers_.resize(preg_->getNextIndexValue(branchType_));
0881 for (auto const& prod : preg_->productList()) {
0882 BranchDescription const& bd = prod.second;
0883 if (bd.branchType() == branchType_) {
0884 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0885 assert(index != ProductResolverIndexInvalid);
0886 if (!productResolvers_[index]) {
0887
0888 assert(!bd.produced());
0889 auto cbd = std::make_shared<BranchDescription const>(bd);
0890 if (bd.onDemand()) {
0891 addDelayedReaderInputProduct(cbd);
0892 } else {
0893 addPutOnReadInputProduct(cbd);
0894 }
0895 changed = true;
0896 }
0897 }
0898 }
0899 if (changed) {
0900 changedIndexes_();
0901 }
0902 }
0903 assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
0904 }
0905
0906 void Principal::readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata) {
0907 if (not reader()) {
0908 return;
0909 }
0910
0911 for (auto& prod : *this) {
0912 prod->retrieveAndMerge(*this, mergeableRunProductMetadata);
0913 }
0914 }
0915 }