File indexing completed on 2023-03-17 11:02:18
0001
0002
0003
0004 #include "FWCore/Framework/interface/Principal.h"
0005
0006 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0007 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0008 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0009 #include "DataFormats/Common/interface/FunctorHandleExceptionFactory.h"
0010 #include "FWCore/Framework/interface/DelayedReader.h"
0011 #include "FWCore/Framework/interface/HistoryAppender.h"
0012 #include "FWCore/Framework/src/ProductDeletedException.h"
0013 #include "FWCore/Framework/interface/ProductPutterBase.h"
0014 #include "FWCore/Framework/interface/EDConsumerBase.h"
0015 #include "ProductResolvers.h"
0016 #include "FWCore/Utilities/interface/EDMException.h"
0017 #include "FWCore/Utilities/interface/ProductResolverIndex.h"
0018 #include "FWCore/Utilities/interface/TypeID.h"
0019 #include "FWCore/Utilities/interface/WrappedClassName.h"
0020 #include "FWCore/Utilities/interface/Likely.h"
0021
0022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0023
0024 #include <algorithm>
0025 #include <cstring>
0026 #include <limits>
0027 #include <sstream>
0028 #include <stdexcept>
0029 #include <typeinfo>
0030 #include <atomic>
0031
0032 namespace edm {
0033
0034 static ProcessHistory const s_emptyProcessHistory;
0035
0036 static std::string appendCurrentProcessIfAlias(std::string const& processFromInputTag,
0037 std::string const& currentProcess) {
0038 if (processFromInputTag == InputTag::kCurrentProcess) {
0039 std::string returnValue = processFromInputTag;
0040 returnValue += " (";
0041 returnValue += currentProcess;
0042 returnValue += ")";
0043 return returnValue;
0044 }
0045 return processFromInputTag;
0046 }
0047
0048 static void throwProductNotFoundException(char const* where, errors::ErrorCodes error, BranchID const& bid) {
0049 throw Exception(error, "InvalidID") << "Principal::" << where << ": no product with given branch id: " << bid
0050 << "\n";
0051 }
0052
0053 static std::shared_ptr<cms::Exception> makeNotFoundException(char const* where,
0054 KindOfType kindOfType,
0055 TypeID const& productType,
0056 std::string const& label,
0057 std::string const& instance,
0058 std::string const& process) {
0059 std::shared_ptr<cms::Exception> exception = std::make_shared<Exception>(errors::ProductNotFound);
0060 if (kindOfType == PRODUCT_TYPE) {
0061 *exception << "Principal::" << where
0062 << ": Found zero products matching all criteria\nLooking for type: " << productType << "\n"
0063 << "Looking for module label: " << label << "\n"
0064 << "Looking for productInstanceName: " << instance << "\n"
0065 << (process.empty() ? "" : "Looking for process: ") << process << "\n";
0066 } else {
0067 *exception << "Principal::" << where
0068 << ": Found zero products matching all criteria\nLooking for a container with elements of type: "
0069 << productType << "\n"
0070 << "Looking for module label: " << label << "\n"
0071 << "Looking for productInstanceName: " << instance << "\n"
0072 << (process.empty() ? "" : "Looking for process: ") << process << "\n";
0073 }
0074 return exception;
0075 }
0076
0077 static void throwAmbiguousException(const char* where,
0078 TypeID const& productType,
0079 std::string const& label,
0080 std::string const& instance,
0081 std::string const& process) {
0082 cms::Exception exception("AmbiguousProduct");
0083 exception << "Principal::" << where
0084 << ": More than 1 product matches all criteria\nLooking for type: " << productType << "\n"
0085 << "Looking for module label: " << label << "\n"
0086 << "Looking for productInstanceName: " << instance << "\n"
0087 << (process.empty() ? "" : "Looking for process: ") << process << "\n"
0088 << "This can only occur with get function calls using a Handle<View> argument.\n"
0089 << "Try a get not using a View or change the instance name of one of the products";
0090 throw exception;
0091 }
0092
0093 namespace {
0094 void failedToRegisterConsumesMany(edm::TypeID const& iType) {
0095 cms::Exception exception("GetManyWithoutRegistration");
0096 exception << "::getManyByType called for " << iType
0097 << " without a corresponding consumesMany being called for this module. \n";
0098 throw exception;
0099 }
0100
0101 void failedToRegisterConsumes(KindOfType kindOfType,
0102 TypeID const& productType,
0103 std::string const& moduleLabel,
0104 std::string const& productInstanceName,
0105 std::string const& processName) {
0106 cms::Exception exception("GetByLabelWithoutRegistration");
0107 exception << "::getByLabel without corresponding call to consumes or mayConsumes for this module.\n"
0108 << (kindOfType == PRODUCT_TYPE ? " type: " : " type: edm::View<") << productType
0109 << (kindOfType == PRODUCT_TYPE ? "\n module label: " : ">\n module label: ") << moduleLabel
0110 << "\n product instance name: '" << productInstanceName << "'\n process name: '" << processName
0111 << "'\n";
0112 throw exception;
0113 }
0114 }
0115
0116
0117 static std::atomic<Principal::CacheIdentifier_t> s_nextIdentifier{1};
0118 static inline Principal::CacheIdentifier_t nextIdentifier() {
0119 return s_nextIdentifier.fetch_add(1, std::memory_order_acq_rel);
0120 }
0121
0122 Principal::Principal(std::shared_ptr<ProductRegistry const> reg,
0123 std::shared_ptr<ProductResolverIndexHelper const> productLookup,
0124 ProcessConfiguration const& pc,
0125 BranchType bt,
0126 HistoryAppender* historyAppender,
0127 bool isForPrimaryProcess)
0128 : EDProductGetter(),
0129 processHistoryPtr_(),
0130 processHistoryID_(),
0131 processHistoryIDBeforeConfig_(),
0132 processConfiguration_(&pc),
0133 productResolvers_(),
0134 preg_(reg),
0135 productLookup_(productLookup),
0136 lookupProcessOrder_(productLookup->lookupProcessNames().size(), 0),
0137 reader_(),
0138 branchType_(bt),
0139 historyAppender_(historyAppender),
0140 cacheIdentifier_(nextIdentifier()) {
0141 productResolvers_.resize(reg->getNextIndexValue(bt));
0142
0143 std::string const source("source");
0144 ProductRegistry::ProductList const& prodsList = reg->productList();
0145
0146
0147
0148 bool hasAliases = false;
0149 bool hasSwitchAliases = false;
0150 for (auto const& prod : prodsList) {
0151 BranchDescription const& bd = prod.second;
0152 if (bd.branchType() == branchType_) {
0153 if (isForPrimaryProcess or bd.processName() == pc.processName()) {
0154 if (bd.isAlias()) {
0155 hasAliases = true;
0156 } else if (bd.isSwitchAlias()) {
0157 hasSwitchAliases = true;
0158 } else {
0159 auto cbd = std::make_shared<BranchDescription const>(bd);
0160 if (bd.produced()) {
0161 if (bd.moduleLabel() == source) {
0162 addSourceProduct(cbd);
0163 } else if (bd.onDemand()) {
0164 assert(branchType_ == InEvent);
0165 if (bd.isTransform()) {
0166 addTransformProduct(cbd);
0167 } else {
0168 addUnscheduledProduct(cbd);
0169 }
0170 } else {
0171 addScheduledProduct(cbd);
0172 }
0173 } else {
0174 if (bd.onDemand()) {
0175 addDelayedReaderInputProduct(cbd);
0176 } else {
0177 addPutOnReadInputProduct(cbd);
0178 }
0179 }
0180 }
0181 } else {
0182
0183 auto cbd = std::make_shared<BranchDescription const>(bd);
0184 addParentProcessProduct(cbd);
0185 }
0186 }
0187 }
0188
0189 if (hasAliases) {
0190 for (auto const& prod : prodsList) {
0191 BranchDescription const& bd = prod.second;
0192 if (bd.isAlias() && bd.branchType() == branchType_) {
0193 addAliasedProduct(std::make_shared<BranchDescription const>(bd));
0194 }
0195 }
0196 }
0197
0198 if (hasSwitchAliases) {
0199 for (auto const& prod : prodsList) {
0200 BranchDescription const& bd = prod.second;
0201 if (bd.isSwitchAlias() && bd.branchType() == branchType_) {
0202 assert(branchType_ == InEvent);
0203 auto cbd = std::make_shared<BranchDescription const>(bd);
0204
0205
0206
0207
0208
0209 if (bd.onDemand()) {
0210 addSwitchAliasProduct(cbd);
0211 } else {
0212 addSwitchProducerProduct(cbd);
0213 }
0214 }
0215 }
0216 }
0217
0218
0219
0220
0221 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0222 std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
0223 std::vector<bool> ambiguous(lookupProcessNames.size(), false);
0224 unsigned int beginElements = productLookup_->beginElements();
0225 std::vector<TypeID> const& sortedTypeIDs = productLookup_->sortedTypeIDs();
0226 std::vector<ProductResolverIndexHelper::Range> const& ranges = productLookup_->ranges();
0227 std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = productLookup_->indexAndNames();
0228 std::vector<char> const& processNamesCharArray = productLookup_->processNames();
0229
0230 unsigned int numberOfMatches = 0;
0231 ProductResolverIndex lastMatchIndex = ProductResolverIndexInvalid;
0232 if (!sortedTypeIDs.empty()) {
0233 ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
0234 for (unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
0235 ProductResolverIndexHelper::Range const& range = ranges.at(k);
0236 for (unsigned int i = range.begin(); i < range.end(); ++i) {
0237 ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
0238 if (product.startInProcessNames() == 0) {
0239 if (productResolverIndex != ProductResolverIndexInvalid) {
0240 if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
0241
0242 productResolvers_.at(productResolverIndex) =
0243 std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
0244 } else {
0245 bool productMadeAtEnd = false;
0246
0247 for (unsigned int j = 0; j < matchingHolders.size(); ++j) {
0248 if ((not ambiguous[j]) and ProductResolverIndexInvalid != matchingHolders[j] and
0249 productResolvers_[matchingHolders[j]]->branchDescription().availableOnlyAtEndTransition()) {
0250 productMadeAtEnd = true;
0251 break;
0252 }
0253 }
0254 std::shared_ptr<ProductResolverBase> newHolder =
0255 std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
0256 productResolvers_.at(productResolverIndex) = newHolder;
0257 }
0258 matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
0259 ambiguous.assign(lookupProcessNames.size(), false);
0260 numberOfMatches = 0;
0261 lastMatchIndex = ProductResolverIndexInvalid;
0262 }
0263 productResolverIndex = product.index();
0264 } else {
0265 std::string process(&processNamesCharArray.at(product.startInProcessNames()));
0266 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
0267 assert(iter != lookupProcessNames.end());
0268 ProductResolverIndex iMatchingIndex = product.index();
0269 lastMatchIndex = iMatchingIndex;
0270 assert(iMatchingIndex != ProductResolverIndexInvalid);
0271 ++numberOfMatches;
0272 if (iMatchingIndex == ProductResolverIndexAmbiguous) {
0273 assert(k >= beginElements);
0274 ambiguous.at(iter - lookupProcessNames.begin()) = true;
0275 } else {
0276 matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
0277 }
0278 }
0279 }
0280 }
0281
0282 if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
0283
0284 productResolvers_.at(productResolverIndex) =
0285 std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
0286 } else {
0287 bool productMadeAtEnd = false;
0288 for (unsigned int i = 0; i < matchingHolders.size(); ++i) {
0289 if ((not ambiguous[i]) and ProductResolverIndexInvalid != matchingHolders[i] and
0290 productResolvers_[matchingHolders[i]]->branchDescription().availableOnlyAtEndTransition()) {
0291 productMadeAtEnd = true;
0292 break;
0293 }
0294 }
0295 std::shared_ptr<ProductResolverBase> newHolder =
0296 std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
0297 productResolvers_.at(productResolverIndex) = newHolder;
0298 }
0299 }
0300 }
0301
0302 Principal::~Principal() {}
0303
0304
0305
0306
0307 size_t Principal::size() const {
0308 size_t size = 0U;
0309 for (auto const& prod : *this) {
0310 if (prod->singleProduct() &&
0311 !prod->productUnavailable() && !prod->unscheduledWasNotRun() && !prod->branchDescription().dropped()) {
0312 ++size;
0313 }
0314 }
0315 return size;
0316 }
0317
0318
0319 bool Principal::adjustToNewProductRegistry(ProductRegistry const& reg) {
0320 ProductRegistry::ProductList const& prodsList = reg.productList();
0321 for (auto const& prod : prodsList) {
0322 BranchDescription const& bd = prod.second;
0323 if (!bd.produced() && (bd.branchType() == branchType_)) {
0324 auto cbd = std::make_shared<BranchDescription const>(bd);
0325 auto phb = getExistingProduct(cbd->branchID());
0326 if (phb == nullptr || phb->branchDescription().branchName() != cbd->branchName()) {
0327 return false;
0328 }
0329 phb->resetBranchDescription(cbd);
0330 }
0331 }
0332 return true;
0333 }
0334
0335 void Principal::addScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
0336 auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
0337 addProductOrThrow(std::move(phb));
0338 }
0339
0340 void Principal::addSourceProduct(std::shared_ptr<BranchDescription const> bd) {
0341 auto phb = std::make_unique<PuttableProductResolver>(std::move(bd));
0342 addProductOrThrow(std::move(phb));
0343 }
0344
0345 void Principal::addDelayedReaderInputProduct(std::shared_ptr<BranchDescription const> bd) {
0346 addProductOrThrow(std::make_unique<DelayedReaderInputProductResolver>(std::move(bd)));
0347 }
0348
0349 void Principal::addPutOnReadInputProduct(std::shared_ptr<BranchDescription const> bd) {
0350 addProductOrThrow(std::make_unique<PutOnReadInputProductResolver>(std::move(bd)));
0351 }
0352
0353 void Principal::addUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
0354 addProductOrThrow(std::make_unique<UnscheduledProductResolver>(std::move(bd)));
0355 }
0356
0357 void Principal::addTransformProduct(std::shared_ptr<BranchDescription const> bd) {
0358 addProductOrThrow(std::make_unique<TransformingProductResolver>(std::move(bd)));
0359 }
0360
0361 void Principal::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
0362 ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
0363 assert(index != ProductResolverIndexInvalid);
0364
0365 addProductOrThrow(std::make_unique<AliasProductResolver>(
0366 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0367 }
0368
0369 void Principal::addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd) {
0370 ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
0371 assert(index != ProductResolverIndexInvalid);
0372
0373 addProductOrThrow(std::make_unique<SwitchProducerProductResolver>(
0374 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0375 }
0376
0377 void Principal::addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd) {
0378 ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
0379 assert(index != ProductResolverIndexInvalid);
0380
0381 addProductOrThrow(std::make_unique<SwitchAliasProductResolver>(
0382 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0383 }
0384
0385 void Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
0386 addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
0387 }
0388
0389
0390 void Principal::clearPrincipal() {
0391
0392
0393
0394 reader_ = nullptr;
0395 for (auto& prod : *this) {
0396 prod->resetProductData();
0397 }
0398 }
0399
0400 void Principal::deleteProduct(BranchID const& id) const {
0401 auto phb = getExistingProduct(id);
0402 assert(nullptr != phb);
0403 phb->unsafe_deleteProduct();
0404 }
0405
0406 void Principal::setupUnscheduled(UnscheduledConfigurator const& iConfigure) {
0407 applyToResolvers([&iConfigure](ProductResolverBase* iResolver) { iResolver->setupUnscheduled(iConfigure); });
0408 }
0409
0410 void Principal::fillPrincipal(DelayedReader* reader) {
0411
0412 cacheIdentifier_ = nextIdentifier();
0413 if (reader) {
0414 reader_ = reader;
0415 }
0416 }
0417
0418
0419 void Principal::fillPrincipal(ProcessHistoryID const& hist,
0420 ProcessHistory const* processHistory,
0421 DelayedReader* reader) {
0422 fillPrincipal(reader);
0423
0424 if (historyAppender_ && productRegistry().anyProductProduced()) {
0425 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0426 processHistoryPtr_ = historyAppender_->appendToProcessHistory(hist, processHistory, *processConfiguration_);
0427 processHistoryID_ = processHistoryPtr_->id();
0428 processHistoryIDBeforeConfig_ = hist;
0429 }
0430 } else {
0431 std::shared_ptr<ProcessHistory const> inputProcessHistory;
0432 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0433 if (hist.isValid()) {
0434
0435 auto noDel = [](void const*) {};
0436 inputProcessHistory = std::shared_ptr<ProcessHistory const>(processHistory, noDel);
0437 if (inputProcessHistory.get() == nullptr) {
0438 throw Exception(errors::LogicError) << "Principal::fillPrincipal\n"
0439 << "Input ProcessHistory not found in registry\n"
0440 << "Contact a Framework developer\n";
0441 }
0442 } else {
0443
0444 inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory, [](void const*) {});
0445
0446 orderProcessHistoryID_ = hist;
0447 }
0448 processHistoryID_ = hist;
0449 processHistoryPtr_ = inputProcessHistory;
0450 processHistoryIDBeforeConfig_ = hist;
0451 }
0452 }
0453
0454 if (orderProcessHistoryID_ != processHistoryID_) {
0455 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0456 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0457 unsigned int k = 0;
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467 {
0468 auto nameIterCurrentProcess =
0469 std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processConfiguration_->processName());
0470 if (nameIterCurrentProcess != lookupProcessNames.end()) {
0471 lookupProcessOrder_.at(k) = nameIterCurrentProcess - lookupProcessNames.begin();
0472 ++k;
0473 }
0474 }
0475
0476
0477
0478 auto iter = processHistoryPtr_->rbegin();
0479 if (iter->processName() == processConfiguration_->processName()) {
0480 ++iter;
0481 }
0482
0483 for (auto iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
0484 auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
0485 if (nameIter == lookupProcessNames.end()) {
0486 continue;
0487 }
0488 lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
0489 ++k;
0490 }
0491 orderProcessHistoryID_ = processHistoryID_;
0492 }
0493 }
0494
0495
0496 void Principal::fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader) {
0497 fillPrincipal(reader);
0498
0499 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0500 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0501 if (!lookupProcessOrder_.empty()) {
0502 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processNameOfBlock);
0503 if (iter != lookupProcessNames.end()) {
0504 lookupProcessOrder_[0] = iter - lookupProcessNames.begin();
0505 }
0506 }
0507 }
0508
0509 ProductResolverBase* Principal::getExistingProduct(BranchID const& branchID) {
0510 return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getExistingProduct(branchID));
0511 }
0512
0513 ProductResolverBase const* Principal::getExistingProduct(BranchID const& branchID) const {
0514 ProductResolverIndex index = preg_->indexFrom(branchID);
0515 assert(index != ProductResolverIndexInvalid);
0516 return productResolvers_.at(index).get();
0517 }
0518
0519 ProductResolverBase const* Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
0520 auto phb = getExistingProduct(productResolver.branchDescription().branchID());
0521 if (nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
0522 BranchDescription const& newProduct = phb->branchDescription();
0523 BranchDescription const& existing = productResolver.branchDescription();
0524 if (newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
0525 throw cms::Exception("HashCollision")
0526 << "Principal::getExistingProduct\n"
0527 << " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName()
0528 << "\n"
0529 << "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
0530 } else {
0531 assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
0532 }
0533 }
0534 return phb;
0535 }
0536
0537 void Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
0538 BranchDescription const& bd = productResolver->branchDescription();
0539 assert(!bd.className().empty());
0540 assert(!bd.friendlyClassName().empty());
0541 assert(!bd.moduleLabel().empty());
0542 assert(!bd.processName().empty());
0543 SharedProductPtr phb(productResolver.release());
0544
0545 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0546 assert(index != ProductResolverIndexInvalid);
0547 productResolvers_[index] = phb;
0548 }
0549
0550 void Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
0551 ProductResolverBase const* phb = getExistingProduct(*productResolver);
0552 if (phb != nullptr) {
0553 BranchDescription const& bd = productResolver->branchDescription();
0554 throw Exception(errors::InsertFailure, "AlreadyPresent")
0555 << "addProductOrThrow: Problem found while adding product, "
0556 << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
0557 << bd.productInstanceName() << "," << bd.processName() << ")\n";
0558 }
0559 addProduct_(std::move(productResolver));
0560 }
0561
0562 Principal::ConstProductResolverPtr Principal::getProductResolver(BranchID const& bid) const {
0563 ProductResolverIndex index = preg_->indexFrom(bid);
0564 if (index == ProductResolverIndexInvalid) {
0565 return ConstProductResolverPtr();
0566 }
0567 return getProductResolverByIndex(index);
0568 }
0569
0570 Principal::ConstProductResolverPtr Principal::getProductResolverByIndex(ProductResolverIndex const& index) const {
0571 ConstProductResolverPtr const phb = productResolvers_[index].get();
0572 return phb;
0573 }
0574
0575 unsigned int Principal::processBlockIndex(std::string const&) const {
0576 throw Exception(errors::LogicError) << "Principal::processBlockIndex not implemented for this type of Principal";
0577 }
0578
0579 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0580 TypeID const& typeID,
0581 InputTag const& inputTag,
0582 EDConsumerBase const* consumer,
0583 SharedResourcesAcquirer* sra,
0584 ModuleCallingContext const* mcc) const {
0585
0586
0587 assert(branchType_ != InProcess);
0588
0589 ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
0590 if (result == nullptr) {
0591 return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
0592 return makeNotFoundException(
0593 "getByLabel",
0594 kindOfType,
0595 typeID,
0596 inputTag.label(),
0597 inputTag.instance(),
0598 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0599 }));
0600 }
0601 return BasicHandle(result->wrapper(), &(result->provenance()));
0602 }
0603
0604 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0605 TypeID const& typeID,
0606 std::string const& label,
0607 std::string const& instance,
0608 std::string const& process,
0609 EDConsumerBase const* consumer,
0610 SharedResourcesAcquirer* sra,
0611 ModuleCallingContext const* mcc) const {
0612 ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process, consumer, sra, mcc);
0613 if (result == nullptr) {
0614 return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
0615 return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
0616 }));
0617 }
0618 return BasicHandle(result->wrapper(), &(result->provenance()));
0619 }
0620
0621 BasicHandle Principal::getByToken(KindOfType,
0622 TypeID const&,
0623 ProductResolverIndex index,
0624 bool skipCurrentProcess,
0625 bool& ambiguous,
0626 SharedResourcesAcquirer* sra,
0627 ModuleCallingContext const* mcc) const {
0628 assert(index != ProductResolverIndexInvalid);
0629 auto& productResolver = productResolvers_[index];
0630 assert(nullptr != productResolver.get());
0631 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0632 if (resolution.isAmbiguous()) {
0633 ambiguous = true;
0634
0635
0636 return BasicHandle::makeInvalid();
0637 }
0638 auto productData = resolution.data();
0639 if (productData == nullptr) {
0640
0641
0642 return BasicHandle::makeInvalid();
0643 }
0644 return BasicHandle(productData->wrapper(), &(productData->provenance()));
0645 }
0646
0647 void Principal::prefetchAsync(WaitingTaskHolder task,
0648 ProductResolverIndex index,
0649 bool skipCurrentProcess,
0650 ServiceToken const& token,
0651 ModuleCallingContext const* mcc) const {
0652 auto const& productResolver = productResolvers_.at(index);
0653 assert(nullptr != productResolver.get());
0654 productResolver->prefetchAsync(task, *this, skipCurrentProcess, token, nullptr, mcc);
0655 }
0656
0657 void Principal::getManyByType(TypeID const& typeID,
0658 BasicHandleVec& results,
0659 EDConsumerBase const* consumer,
0660 SharedResourcesAcquirer* sra,
0661 ModuleCallingContext const* mcc) const {
0662
0663 assert(branchType_ != InProcess);
0664
0665 assert(results.empty());
0666
0667 if (UNLIKELY(consumer and (not consumer->registeredToConsumeMany(typeID, branchType())))) {
0668 failedToRegisterConsumesMany(typeID);
0669 }
0670
0671
0672 ProductResolverIndexHelper::Matches matches = productLookup().relatedIndexes(PRODUCT_TYPE, typeID);
0673
0674 if (matches.numberOfMatches() == 0) {
0675 return;
0676 }
0677
0678 results.reserve(matches.numberOfMatches());
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703 std::vector<ProductResolverBase const*> holders;
0704
0705 for (unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
0706 ProductResolverIndex index = matches.index(i);
0707
0708 if (!matches.isFullyResolved(i)) {
0709 if (!holders.empty()) {
0710
0711 findProducts(holders, typeID, results, sra, mcc);
0712 holders.clear();
0713 }
0714 } else {
0715 ProductResolverBase const* productResolver = productResolvers_.at(index).get();
0716 assert(productResolver);
0717 holders.push_back(productResolver);
0718 }
0719 }
0720
0721 if (!holders.empty()) {
0722 findProducts(holders, typeID, results, sra, mcc);
0723 }
0724 return;
0725 }
0726
0727 void Principal::findProducts(std::vector<ProductResolverBase const*> const& holders,
0728 TypeID const&,
0729 BasicHandleVec& results,
0730 SharedResourcesAcquirer* sra,
0731 ModuleCallingContext const* mcc) const {
0732 for (auto iter = processHistoryPtr_->rbegin(), iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
0733 std::string const& process = iter->processName();
0734 for (auto productResolver : holders) {
0735 BranchDescription const& bd = productResolver->branchDescription();
0736 if (process == bd.processName()) {
0737
0738 if (bd.isAnyAlias()) {
0739 continue;
0740 }
0741
0742 ProductData const* productData = productResolver->resolveProduct(*this, false, sra, mcc).data();
0743 if (productData) {
0744
0745 results.emplace_back(productData->wrapper(), &(productData->provenance()));
0746 }
0747 }
0748 }
0749 }
0750 }
0751
0752 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0753 TypeID const& typeID,
0754 InputTag const& inputTag,
0755 EDConsumerBase const* consumer,
0756 SharedResourcesAcquirer* sra,
0757 ModuleCallingContext const* mcc) const {
0758 bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
0759
0760 ProductResolverIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
0761
0762 if (index == ProductResolverIndexInvalid) {
0763 char const* processName = inputTag.process().c_str();
0764 if (skipCurrentProcess) {
0765 processName = "\0";
0766 } else if (inputTag.process() == InputTag::kCurrentProcess) {
0767 processName = processConfiguration_->processName().c_str();
0768 }
0769
0770 index =
0771 productLookup().index(kindOfType, typeID, inputTag.label().c_str(), inputTag.instance().c_str(), processName);
0772
0773 if (index == ProductResolverIndexAmbiguous) {
0774 throwAmbiguousException("findProductByLabel",
0775 typeID,
0776 inputTag.label(),
0777 inputTag.instance(),
0778 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0779 } else if (index == ProductResolverIndexInvalid) {
0780
0781 for (auto const& item : preg_->productList()) {
0782 auto const& bd = item.second;
0783 if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == inputTag.label() and
0784 bd.productInstanceName() == inputTag.instance()) {
0785 bool const inCurrentProcess = bd.processName() == processConfiguration_->processName();
0786 if (inputTag.process().empty() or bd.processName() == inputTag.process() or
0787 (skipCurrentProcess and not inCurrentProcess) or
0788 (inputTag.process() == InputTag::kCurrentProcess and inCurrentProcess)) {
0789 failedToRegisterConsumes(
0790 kindOfType,
0791 typeID,
0792 inputTag.label(),
0793 inputTag.instance(),
0794 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0795 }
0796 }
0797 }
0798 return nullptr;
0799 }
0800 inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
0801 }
0802 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
0803 failedToRegisterConsumes(kindOfType,
0804 typeID,
0805 inputTag.label(),
0806 inputTag.instance(),
0807 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0808 }
0809
0810 auto const& productResolver = productResolvers_[index];
0811
0812 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0813 if (resolution.isAmbiguous()) {
0814 throwAmbiguousException("findProductByLabel",
0815 typeID,
0816 inputTag.label(),
0817 inputTag.instance(),
0818 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0819 }
0820 return resolution.data();
0821 }
0822
0823 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0824 TypeID const& typeID,
0825 std::string const& label,
0826 std::string const& instance,
0827 std::string const& process,
0828 EDConsumerBase const* consumer,
0829 SharedResourcesAcquirer* sra,
0830 ModuleCallingContext const* mcc) const {
0831 ProductResolverIndex index =
0832 productLookup().index(kindOfType, typeID, label.c_str(), instance.c_str(), process.c_str());
0833
0834 if (index == ProductResolverIndexAmbiguous) {
0835 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0836 } else if (index == ProductResolverIndexInvalid) {
0837
0838 for (auto const& item : preg_->productList()) {
0839 auto const& bd = item.second;
0840 if (bd.present() and bd.unwrappedTypeID() == typeID and bd.moduleLabel() == label and
0841 bd.productInstanceName() == instance) {
0842 if (process.empty() or bd.processName() == process) {
0843 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0844 }
0845 }
0846 }
0847 return nullptr;
0848 }
0849
0850 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
0851 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0852 }
0853
0854 auto const& productResolver = productResolvers_[index];
0855
0856 auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
0857 if (resolution.isAmbiguous()) {
0858 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0859 }
0860 return resolution.data();
0861 }
0862
0863 ProductData const* Principal::findProductByTag(TypeID const& typeID,
0864 InputTag const& tag,
0865 ModuleCallingContext const* mcc) const {
0866
0867 assert(branchType_ != InProcess);
0868
0869 ProductData const* productData = findProductByLabel(PRODUCT_TYPE, typeID, tag, nullptr, nullptr, mcc);
0870 return productData;
0871 }
0872
0873 Provenance const& Principal::getProvenance(BranchID const& bid) const {
0874 ConstProductResolverPtr const phb = getProductResolver(bid);
0875 if (phb == nullptr) {
0876 throwProductNotFoundException("getProvenance", errors::ProductNotFound, bid);
0877 }
0878
0879 if (phb->unscheduledWasNotRun()) {
0880 throw edm::Exception(errors::UnimplementedFeature)
0881 << "Requesting provenance from unrun EDProducer. The requested branch ID was: " << bid;
0882 }
0883 return *phb->provenance();
0884 }
0885
0886 StableProvenance const& Principal::getStableProvenance(BranchID const& bid) const {
0887 ConstProductResolverPtr const phb = getProductResolver(bid);
0888 if (phb == nullptr) {
0889 throwProductNotFoundException("getStableProvenance", errors::ProductNotFound, bid);
0890 }
0891
0892 return *phb->stableProvenance();
0893 }
0894
0895
0896
0897
0898 void Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
0899 provenances.clear();
0900 for (auto const& productResolver : *this) {
0901 if (productResolver->singleProduct() && productResolver->provenanceAvailable() &&
0902 !productResolver->branchDescription().isAnyAlias()) {
0903
0904
0905 if (productResolver->provenance()->branchDescription().present()) {
0906 provenances.push_back(productResolver->provenance());
0907 }
0908 }
0909 }
0910 }
0911
0912
0913
0914
0915 void Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
0916 provenances.clear();
0917 for (auto const& productResolver : *this) {
0918 if (productResolver->singleProduct() && !productResolver->branchDescription().isAnyAlias()) {
0919 if (productResolver->stableProvenance()->branchDescription().present()) {
0920 provenances.push_back(productResolver->stableProvenance());
0921 }
0922 }
0923 }
0924 }
0925
0926 void Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
0927 for (auto& prod : bids) {
0928 ProductResolverIndex index = preg_->indexFrom(prod);
0929 assert(index != ProductResolverIndexInvalid);
0930 ProductResolverIndex indexO = other.preg_->indexFrom(prod);
0931 assert(indexO != ProductResolverIndexInvalid);
0932 get_underlying_safe(productResolvers_[index]).swap(get_underlying_safe(other.productResolvers_[indexO]));
0933 }
0934 reader_->mergeReaders(other.reader());
0935 }
0936
0937 WrapperBase const* Principal::getIt(ProductID const&) const {
0938 assert(false);
0939 return nullptr;
0940 }
0941
0942 std::optional<std::tuple<WrapperBase const*, unsigned int>> Principal::getThinnedProduct(ProductID const&,
0943 unsigned int) const {
0944 assert(false);
0945 return std::nullopt;
0946 }
0947
0948 void Principal::getThinnedProducts(ProductID const&,
0949 std::vector<WrapperBase const*>&,
0950 std::vector<unsigned int>&) const {
0951 assert(false);
0952 }
0953
0954 OptionalThinnedKey Principal::getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const {
0955 assert(false);
0956 return std::monostate{};
0957 }
0958
0959 void Principal::put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
0960 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(prod));
0961 }
0962
0963 void Principal::put_(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
0964 if (edp.get() == nullptr) {
0965 throw edm::Exception(edm::errors::InsertFailure, "Null Pointer")
0966 << "put: Cannot put because unique_ptr to product is null."
0967 << "\n";
0968 }
0969 auto phb = getExistingProduct(bd.branchID());
0970 assert(phb);
0971
0972 put_(std::move(edp), phb);
0973 }
0974
0975 void Principal::adjustIndexesAfterProductRegistryAddition() {
0976 if (preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
0977 bool changed = false;
0978 productResolvers_.resize(preg_->getNextIndexValue(branchType_));
0979 for (auto const& prod : preg_->productList()) {
0980 BranchDescription const& bd = prod.second;
0981 if (bd.branchType() == branchType_) {
0982 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0983 assert(index != ProductResolverIndexInvalid);
0984 if (!productResolvers_[index]) {
0985
0986 assert(!bd.produced());
0987 auto cbd = std::make_shared<BranchDescription const>(bd);
0988 if (bd.onDemand()) {
0989 addDelayedReaderInputProduct(cbd);
0990 } else {
0991 addPutOnReadInputProduct(cbd);
0992 }
0993 changed = true;
0994 }
0995 }
0996 }
0997 if (changed) {
0998 changedIndexes_();
0999 }
1000 }
1001 assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
1002 }
1003
1004 void Principal::readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata) {
1005 if (not reader()) {
1006 return;
1007 }
1008
1009 for (auto& prod : *this) {
1010 prod->retrieveAndMerge(*this, mergeableRunProductMetadata);
1011 }
1012 }
1013 }