File indexing completed on 2021-08-18 22:30:21
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 addUnscheduledProduct(cbd);
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::addAliasedProduct(std::shared_ptr<BranchDescription const> bd) {
0354 ProductResolverIndex index = preg_->indexFrom(bd->originalBranchID());
0355 assert(index != ProductResolverIndexInvalid);
0356
0357 addProductOrThrow(std::make_unique<AliasProductResolver>(
0358 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0359 }
0360
0361 void Principal::addSwitchProducerProduct(std::shared_ptr<BranchDescription const> bd) {
0362 ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
0363 assert(index != ProductResolverIndexInvalid);
0364
0365 addProductOrThrow(std::make_unique<SwitchProducerProductResolver>(
0366 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0367 }
0368
0369 void Principal::addSwitchAliasProduct(std::shared_ptr<BranchDescription const> bd) {
0370 ProductResolverIndex index = preg_->indexFrom(bd->switchAliasForBranchID());
0371 assert(index != ProductResolverIndexInvalid);
0372
0373 addProductOrThrow(std::make_unique<SwitchAliasProductResolver>(
0374 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*productResolvers_[index])));
0375 }
0376
0377 void Principal::addParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
0378 addProductOrThrow(std::make_unique<ParentProcessProductResolver>(std::move(bd)));
0379 }
0380
0381
0382 void Principal::clearPrincipal() {
0383
0384
0385
0386 reader_ = nullptr;
0387 for (auto& prod : *this) {
0388 prod->resetProductData();
0389 }
0390 }
0391
0392 void Principal::deleteProduct(BranchID const& id) const {
0393 auto phb = getExistingProduct(id);
0394 assert(nullptr != phb);
0395 phb->unsafe_deleteProduct();
0396 }
0397
0398 void Principal::setupUnscheduled(UnscheduledConfigurator const& iConfigure) {
0399 applyToResolvers([&iConfigure](ProductResolverBase* iResolver) { iResolver->setupUnscheduled(iConfigure); });
0400 }
0401
0402 void Principal::fillPrincipal(DelayedReader* reader) {
0403
0404 cacheIdentifier_ = nextIdentifier();
0405 if (reader) {
0406 reader_ = reader;
0407 }
0408 }
0409
0410
0411 void Principal::fillPrincipal(ProcessHistoryID const& hist,
0412 ProcessHistory const* processHistory,
0413 DelayedReader* reader) {
0414 fillPrincipal(reader);
0415
0416 if (historyAppender_ && productRegistry().anyProductProduced()) {
0417 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0418 processHistoryPtr_ = historyAppender_->appendToProcessHistory(hist, processHistory, *processConfiguration_);
0419 processHistoryID_ = processHistoryPtr_->id();
0420 processHistoryIDBeforeConfig_ = hist;
0421 }
0422 } else {
0423 std::shared_ptr<ProcessHistory const> inputProcessHistory;
0424 if ((not processHistoryPtr_) || (processHistoryIDBeforeConfig_ != hist)) {
0425 if (hist.isValid()) {
0426
0427 auto noDel = [](void const*) {};
0428 inputProcessHistory = std::shared_ptr<ProcessHistory const>(processHistory, noDel);
0429 if (inputProcessHistory.get() == nullptr) {
0430 throw Exception(errors::LogicError) << "Principal::fillPrincipal\n"
0431 << "Input ProcessHistory not found in registry\n"
0432 << "Contact a Framework developer\n";
0433 }
0434 } else {
0435
0436 inputProcessHistory = std::shared_ptr<ProcessHistory const>(&s_emptyProcessHistory, [](void const*) {});
0437
0438 orderProcessHistoryID_ = hist;
0439 }
0440 processHistoryID_ = hist;
0441 processHistoryPtr_ = inputProcessHistory;
0442 processHistoryIDBeforeConfig_ = hist;
0443 }
0444 }
0445
0446 if (orderProcessHistoryID_ != processHistoryID_) {
0447 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0448 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0449 unsigned int k = 0;
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 {
0460 auto nameIterCurrentProcess =
0461 std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processConfiguration_->processName());
0462 if (nameIterCurrentProcess != lookupProcessNames.end()) {
0463 lookupProcessOrder_.at(k) = nameIterCurrentProcess - lookupProcessNames.begin();
0464 ++k;
0465 }
0466 }
0467
0468
0469
0470 auto iter = processHistoryPtr_->rbegin();
0471 if (iter->processName() == processConfiguration_->processName()) {
0472 ++iter;
0473 }
0474
0475 for (auto iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
0476 auto nameIter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), iter->processName());
0477 if (nameIter == lookupProcessNames.end()) {
0478 continue;
0479 }
0480 lookupProcessOrder_.at(k) = nameIter - lookupProcessNames.begin();
0481 ++k;
0482 }
0483 orderProcessHistoryID_ = processHistoryID_;
0484 }
0485 }
0486
0487
0488 void Principal::fillPrincipal(std::string const& processNameOfBlock, DelayedReader* reader) {
0489 fillPrincipal(reader);
0490
0491 std::vector<std::string> const& lookupProcessNames = productLookup_->lookupProcessNames();
0492 lookupProcessOrder_.assign(lookupProcessNames.size(), 0);
0493 if (!lookupProcessOrder_.empty()) {
0494 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), processNameOfBlock);
0495 if (iter != lookupProcessNames.end()) {
0496 lookupProcessOrder_[0] = iter - lookupProcessNames.begin();
0497 }
0498 }
0499 }
0500
0501 ProductResolverBase* Principal::getExistingProduct(BranchID const& branchID) {
0502 return const_cast<ProductResolverBase*>(const_cast<const Principal*>(this)->getExistingProduct(branchID));
0503 }
0504
0505 ProductResolverBase const* Principal::getExistingProduct(BranchID const& branchID) const {
0506 ProductResolverIndex index = preg_->indexFrom(branchID);
0507 assert(index != ProductResolverIndexInvalid);
0508 return productResolvers_.at(index).get();
0509 }
0510
0511 ProductResolverBase const* Principal::getExistingProduct(ProductResolverBase const& productResolver) const {
0512 auto phb = getExistingProduct(productResolver.branchDescription().branchID());
0513 if (nullptr != phb && BranchKey(productResolver.branchDescription()) != BranchKey(phb->branchDescription())) {
0514 BranchDescription const& newProduct = phb->branchDescription();
0515 BranchDescription const& existing = productResolver.branchDescription();
0516 if (newProduct.branchName() != existing.branchName() && newProduct.branchID() == existing.branchID()) {
0517 throw cms::Exception("HashCollision")
0518 << "Principal::getExistingProduct\n"
0519 << " Branch " << newProduct.branchName() << " has same branch ID as branch " << existing.branchName()
0520 << "\n"
0521 << "Workaround: change process name or product instance name of " << newProduct.branchName() << "\n";
0522 } else {
0523 assert(nullptr == phb || BranchKey(productResolver.branchDescription()) == BranchKey(phb->branchDescription()));
0524 }
0525 }
0526 return phb;
0527 }
0528
0529 void Principal::addProduct_(std::unique_ptr<ProductResolverBase> productResolver) {
0530 BranchDescription const& bd = productResolver->branchDescription();
0531 assert(!bd.className().empty());
0532 assert(!bd.friendlyClassName().empty());
0533 assert(!bd.moduleLabel().empty());
0534 assert(!bd.processName().empty());
0535 SharedProductPtr phb(productResolver.release());
0536
0537 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0538 assert(index != ProductResolverIndexInvalid);
0539 productResolvers_[index] = phb;
0540 }
0541
0542 void Principal::addProductOrThrow(std::unique_ptr<ProductResolverBase> productResolver) {
0543 ProductResolverBase const* phb = getExistingProduct(*productResolver);
0544 if (phb != nullptr) {
0545 BranchDescription const& bd = productResolver->branchDescription();
0546 throw Exception(errors::InsertFailure, "AlreadyPresent")
0547 << "addProductOrThrow: Problem found while adding product, "
0548 << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
0549 << bd.productInstanceName() << "," << bd.processName() << ")\n";
0550 }
0551 addProduct_(std::move(productResolver));
0552 }
0553
0554 Principal::ConstProductResolverPtr Principal::getProductResolver(BranchID const& bid) const {
0555 ProductResolverIndex index = preg_->indexFrom(bid);
0556 if (index == ProductResolverIndexInvalid) {
0557 return ConstProductResolverPtr();
0558 }
0559 return getProductResolverByIndex(index);
0560 }
0561
0562 Principal::ConstProductResolverPtr Principal::getProductResolverByIndex(ProductResolverIndex const& index) const {
0563 ConstProductResolverPtr const phb = productResolvers_[index].get();
0564 return phb;
0565 }
0566
0567 unsigned int Principal::processBlockIndex(std::string const&) const {
0568 throw Exception(errors::LogicError) << "Principal::processBlockIndex not implemented for this type of Principal";
0569 }
0570
0571 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0572 TypeID const& typeID,
0573 InputTag const& inputTag,
0574 EDConsumerBase const* consumer,
0575 SharedResourcesAcquirer* sra,
0576 ModuleCallingContext const* mcc) const {
0577
0578
0579 assert(branchType_ != InProcess);
0580
0581 ProductData const* result = findProductByLabel(kindOfType, typeID, inputTag, consumer, sra, mcc);
0582 if (result == nullptr) {
0583 return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
0584 return makeNotFoundException(
0585 "getByLabel",
0586 kindOfType,
0587 typeID,
0588 inputTag.label(),
0589 inputTag.instance(),
0590 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0591 }));
0592 }
0593 return BasicHandle(result->wrapper(), &(result->provenance()));
0594 }
0595
0596 BasicHandle Principal::getByLabel(KindOfType kindOfType,
0597 TypeID const& typeID,
0598 std::string const& label,
0599 std::string const& instance,
0600 std::string const& process,
0601 EDConsumerBase const* consumer,
0602 SharedResourcesAcquirer* sra,
0603 ModuleCallingContext const* mcc) const {
0604 ProductData const* result = findProductByLabel(kindOfType, typeID, label, instance, process, consumer, sra, mcc);
0605 if (result == nullptr) {
0606 return BasicHandle(makeHandleExceptionFactory([=]() -> std::shared_ptr<cms::Exception> {
0607 return makeNotFoundException("getByLabel", kindOfType, typeID, label, instance, process);
0608 }));
0609 }
0610 return BasicHandle(result->wrapper(), &(result->provenance()));
0611 }
0612
0613 BasicHandle Principal::getByToken(KindOfType,
0614 TypeID const&,
0615 ProductResolverIndex index,
0616 bool skipCurrentProcess,
0617 bool& ambiguous,
0618 SharedResourcesAcquirer* sra,
0619 ModuleCallingContext const* mcc) const {
0620 assert(index != ProductResolverIndexInvalid);
0621 auto& productResolver = productResolvers_[index];
0622 assert(nullptr != productResolver.get());
0623 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0624 if (resolution.isAmbiguous()) {
0625 ambiguous = true;
0626
0627
0628 return BasicHandle::makeInvalid();
0629 }
0630 auto productData = resolution.data();
0631 if (productData == nullptr) {
0632
0633
0634 return BasicHandle::makeInvalid();
0635 }
0636 return BasicHandle(productData->wrapper(), &(productData->provenance()));
0637 }
0638
0639 void Principal::prefetchAsync(WaitingTaskHolder task,
0640 ProductResolverIndex index,
0641 bool skipCurrentProcess,
0642 ServiceToken const& token,
0643 ModuleCallingContext const* mcc) const {
0644 auto const& productResolver = productResolvers_.at(index);
0645 assert(nullptr != productResolver.get());
0646 productResolver->prefetchAsync(task, *this, skipCurrentProcess, token, nullptr, mcc);
0647 }
0648
0649 void Principal::getManyByType(TypeID const& typeID,
0650 BasicHandleVec& results,
0651 EDConsumerBase const* consumer,
0652 SharedResourcesAcquirer* sra,
0653 ModuleCallingContext const* mcc) const {
0654
0655 assert(branchType_ != InProcess);
0656
0657 assert(results.empty());
0658
0659 if (UNLIKELY(consumer and (not consumer->registeredToConsumeMany(typeID, branchType())))) {
0660 failedToRegisterConsumesMany(typeID);
0661 }
0662
0663
0664 ProductResolverIndexHelper::Matches matches = productLookup().relatedIndexes(PRODUCT_TYPE, typeID);
0665
0666 if (matches.numberOfMatches() == 0) {
0667 return;
0668 }
0669
0670 results.reserve(matches.numberOfMatches());
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695 std::vector<ProductResolverBase const*> holders;
0696
0697 for (unsigned int i = 0; i < matches.numberOfMatches(); ++i) {
0698 ProductResolverIndex index = matches.index(i);
0699
0700 if (!matches.isFullyResolved(i)) {
0701 if (!holders.empty()) {
0702
0703 findProducts(holders, typeID, results, sra, mcc);
0704 holders.clear();
0705 }
0706 } else {
0707 ProductResolverBase const* productResolver = productResolvers_.at(index).get();
0708 assert(productResolver);
0709 holders.push_back(productResolver);
0710 }
0711 }
0712
0713 if (!holders.empty()) {
0714 findProducts(holders, typeID, results, sra, mcc);
0715 }
0716 return;
0717 }
0718
0719 void Principal::findProducts(std::vector<ProductResolverBase const*> const& holders,
0720 TypeID const&,
0721 BasicHandleVec& results,
0722 SharedResourcesAcquirer* sra,
0723 ModuleCallingContext const* mcc) const {
0724 for (auto iter = processHistoryPtr_->rbegin(), iEnd = processHistoryPtr_->rend(); iter != iEnd; ++iter) {
0725 std::string const& process = iter->processName();
0726 for (auto productResolver : holders) {
0727 BranchDescription const& bd = productResolver->branchDescription();
0728 if (process == bd.processName()) {
0729
0730 if (bd.isAnyAlias()) {
0731 continue;
0732 }
0733
0734 ProductData const* productData = productResolver->resolveProduct(*this, false, sra, mcc).data();
0735 if (productData) {
0736
0737 results.emplace_back(productData->wrapper(), &(productData->provenance()));
0738 }
0739 }
0740 }
0741 }
0742 }
0743
0744 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0745 TypeID const& typeID,
0746 InputTag const& inputTag,
0747 EDConsumerBase const* consumer,
0748 SharedResourcesAcquirer* sra,
0749 ModuleCallingContext const* mcc) const {
0750 bool skipCurrentProcess = inputTag.willSkipCurrentProcess();
0751
0752 ProductResolverIndex index = inputTag.indexFor(typeID, branchType(), &productRegistry());
0753
0754 if (index == ProductResolverIndexInvalid) {
0755 char const* processName = inputTag.process().c_str();
0756 if (skipCurrentProcess) {
0757 processName = "\0";
0758 } else if (inputTag.process() == InputTag::kCurrentProcess) {
0759 processName = processConfiguration_->processName().c_str();
0760 }
0761
0762 index =
0763 productLookup().index(kindOfType, typeID, inputTag.label().c_str(), inputTag.instance().c_str(), processName);
0764
0765 if (index == ProductResolverIndexAmbiguous) {
0766 throwAmbiguousException("findProductByLabel",
0767 typeID,
0768 inputTag.label(),
0769 inputTag.instance(),
0770 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0771 } else if (index == ProductResolverIndexInvalid) {
0772 return nullptr;
0773 }
0774 inputTag.tryToCacheIndex(index, typeID, branchType(), &productRegistry());
0775 }
0776 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, skipCurrentProcess, branchType())))) {
0777 failedToRegisterConsumes(kindOfType,
0778 typeID,
0779 inputTag.label(),
0780 inputTag.instance(),
0781 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0782 }
0783
0784 auto const& productResolver = productResolvers_[index];
0785
0786 auto resolution = productResolver->resolveProduct(*this, skipCurrentProcess, sra, mcc);
0787 if (resolution.isAmbiguous()) {
0788 throwAmbiguousException("findProductByLabel",
0789 typeID,
0790 inputTag.label(),
0791 inputTag.instance(),
0792 appendCurrentProcessIfAlias(inputTag.process(), processConfiguration_->processName()));
0793 }
0794 return resolution.data();
0795 }
0796
0797 ProductData const* Principal::findProductByLabel(KindOfType kindOfType,
0798 TypeID const& typeID,
0799 std::string const& label,
0800 std::string const& instance,
0801 std::string const& process,
0802 EDConsumerBase const* consumer,
0803 SharedResourcesAcquirer* sra,
0804 ModuleCallingContext const* mcc) const {
0805 ProductResolverIndex index =
0806 productLookup().index(kindOfType, typeID, label.c_str(), instance.c_str(), process.c_str());
0807
0808 if (index == ProductResolverIndexAmbiguous) {
0809 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0810 } else if (index == ProductResolverIndexInvalid) {
0811 return nullptr;
0812 }
0813
0814 if (UNLIKELY(consumer and (not consumer->registeredToConsume(index, false, branchType())))) {
0815 failedToRegisterConsumes(kindOfType, typeID, label, instance, process);
0816 }
0817
0818 auto const& productResolver = productResolvers_[index];
0819
0820 auto resolution = productResolver->resolveProduct(*this, false, sra, mcc);
0821 if (resolution.isAmbiguous()) {
0822 throwAmbiguousException("findProductByLabel", typeID, label, instance, process);
0823 }
0824 return resolution.data();
0825 }
0826
0827 ProductData const* Principal::findProductByTag(TypeID const& typeID,
0828 InputTag const& tag,
0829 ModuleCallingContext const* mcc) const {
0830
0831 assert(branchType_ != InProcess);
0832
0833 ProductData const* productData = findProductByLabel(PRODUCT_TYPE, typeID, tag, nullptr, nullptr, mcc);
0834 return productData;
0835 }
0836
0837 Provenance const& Principal::getProvenance(BranchID const& bid) const {
0838 ConstProductResolverPtr const phb = getProductResolver(bid);
0839 if (phb == nullptr) {
0840 throwProductNotFoundException("getProvenance", errors::ProductNotFound, bid);
0841 }
0842
0843 if (phb->unscheduledWasNotRun()) {
0844 throw edm::Exception(errors::UnimplementedFeature)
0845 << "Requesting provenance from unrun EDProducer. The requested branch ID was: " << bid;
0846 }
0847 return *phb->provenance();
0848 }
0849
0850 StableProvenance const& Principal::getStableProvenance(BranchID const& bid) const {
0851 ConstProductResolverPtr const phb = getProductResolver(bid);
0852 if (phb == nullptr) {
0853 throwProductNotFoundException("getStableProvenance", errors::ProductNotFound, bid);
0854 }
0855
0856 return *phb->stableProvenance();
0857 }
0858
0859
0860
0861
0862 void Principal::getAllProvenance(std::vector<Provenance const*>& provenances) const {
0863 provenances.clear();
0864 for (auto const& productResolver : *this) {
0865 if (productResolver->singleProduct() && productResolver->provenanceAvailable() &&
0866 !productResolver->branchDescription().isAnyAlias()) {
0867
0868
0869 if (productResolver->provenance()->branchDescription().present()) {
0870 provenances.push_back(productResolver->provenance());
0871 }
0872 }
0873 }
0874 }
0875
0876
0877
0878
0879 void Principal::getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const {
0880 provenances.clear();
0881 for (auto const& productResolver : *this) {
0882 if (productResolver->singleProduct() && !productResolver->branchDescription().isAnyAlias()) {
0883 if (productResolver->stableProvenance()->branchDescription().present()) {
0884 provenances.push_back(productResolver->stableProvenance());
0885 }
0886 }
0887 }
0888 }
0889
0890 void Principal::recombine(Principal& other, std::vector<BranchID> const& bids) {
0891 for (auto& prod : bids) {
0892 ProductResolverIndex index = preg_->indexFrom(prod);
0893 assert(index != ProductResolverIndexInvalid);
0894 ProductResolverIndex indexO = other.preg_->indexFrom(prod);
0895 assert(indexO != ProductResolverIndexInvalid);
0896 get_underlying_safe(productResolvers_[index]).swap(get_underlying_safe(other.productResolvers_[indexO]));
0897 }
0898 reader_->mergeReaders(other.reader());
0899 }
0900
0901 WrapperBase const* Principal::getIt(ProductID const&) const {
0902 assert(false);
0903 return nullptr;
0904 }
0905
0906 std::optional<std::tuple<WrapperBase const*, unsigned int>> Principal::getThinnedProduct(ProductID const&,
0907 unsigned int) const {
0908 assert(false);
0909 return std::nullopt;
0910 }
0911
0912 void Principal::getThinnedProducts(ProductID const&,
0913 std::vector<WrapperBase const*>&,
0914 std::vector<unsigned int>&) const {
0915 assert(false);
0916 }
0917
0918 OptionalThinnedKey Principal::getThinnedKeyFrom(ProductID const&, unsigned int, ProductID const&) const {
0919 assert(false);
0920 return std::monostate{};
0921 }
0922
0923 void Principal::put_(std::unique_ptr<WrapperBase> prod, ProductResolverBase const* phb) const {
0924 dynamic_cast<ProductPutterBase const*>(phb)->putProduct(std::move(prod));
0925 }
0926
0927 void Principal::put_(BranchDescription const& bd, std::unique_ptr<WrapperBase> edp) const {
0928 if (edp.get() == nullptr) {
0929 throw edm::Exception(edm::errors::InsertFailure, "Null Pointer")
0930 << "put: Cannot put because unique_ptr to product is null."
0931 << "\n";
0932 }
0933 auto phb = getExistingProduct(bd.branchID());
0934 assert(phb);
0935
0936 put_(std::move(edp), phb);
0937 }
0938
0939 void Principal::adjustIndexesAfterProductRegistryAddition() {
0940 if (preg_->getNextIndexValue(branchType_) != productResolvers_.size()) {
0941 bool changed = false;
0942 productResolvers_.resize(preg_->getNextIndexValue(branchType_));
0943 for (auto const& prod : preg_->productList()) {
0944 BranchDescription const& bd = prod.second;
0945 if (bd.branchType() == branchType_) {
0946 ProductResolverIndex index = preg_->indexFrom(bd.branchID());
0947 assert(index != ProductResolverIndexInvalid);
0948 if (!productResolvers_[index]) {
0949
0950 assert(!bd.produced());
0951 auto cbd = std::make_shared<BranchDescription const>(bd);
0952 if (bd.onDemand()) {
0953 addDelayedReaderInputProduct(cbd);
0954 } else {
0955 addPutOnReadInputProduct(cbd);
0956 }
0957 changed = true;
0958 }
0959 }
0960 }
0961 if (changed) {
0962 changedIndexes_();
0963 }
0964 }
0965 assert(preg_->getNextIndexValue(branchType_) == productResolvers_.size());
0966 }
0967
0968 void Principal::readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const* mergeableRunProductMetadata) {
0969 if (not reader()) {
0970 return;
0971 }
0972
0973 for (auto& prod : *this) {
0974 prod->retrieveAndMerge(*this, mergeableRunProductMetadata);
0975 }
0976 }
0977 }