File indexing completed on 2025-03-13 02:31:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0011
0012 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0013
0014 #include "FWCore/Utilities/interface/Algorithms.h"
0015 #include "FWCore/Utilities/interface/EDMException.h"
0016 #include "FWCore/Reflection/interface/DictionaryTools.h"
0017 #include "FWCore/Utilities/interface/TypeID.h"
0018 #include "FWCore/Reflection/interface/TypeWithDict.h"
0019 #include "FWCore/Utilities/interface/WrappedClassName.h"
0020
0021 #include "TDictAttributeMap.h"
0022
0023 #include <cassert>
0024 #include <iterator>
0025 #include <limits>
0026 #include <set>
0027 #include <sstream>
0028 #include <ostream>
0029
0030 namespace edm {
0031
0032 ProductRegistry::Transients::Transients()
0033 : frozen_(false),
0034 productProduced_(),
0035 anyProductProduced_(false),
0036 productLookups_{{std::make_unique<ProductResolverIndexHelper>(),
0037 std::make_unique<ProductResolverIndexHelper>(),
0038 std::make_unique<ProductResolverIndexHelper>(),
0039 std::make_unique<ProductResolverIndexHelper>()}},
0040 nextIndexValues_(),
0041 branchIDToIndex_() {
0042 for (bool& isProduced : productProduced_)
0043 isProduced = false;
0044 }
0045
0046 void ProductRegistry::Transients::reset() {
0047 frozen_ = false;
0048 for (bool& isProduced : productProduced_)
0049 isProduced = false;
0050 anyProductProduced_ = false;
0051
0052
0053 for (auto& iterProductLookup : productLookups_) {
0054 iterProductLookup = std::make_unique<ProductResolverIndexHelper>();
0055 }
0056 nextIndexValues_.fill(0);
0057
0058 branchIDToIndex_.clear();
0059 }
0060
0061 ProductRegistry::ProductRegistry(ProductList const& productList, bool toBeFrozen)
0062 : productList_(productList), transient_() {
0063 freezeIt(toBeFrozen);
0064 }
0065
0066 void ProductRegistry::addProduct_(ProductDescription const& productDesc) {
0067 assert(productDesc.produced());
0068 throwIfFrozen();
0069 std::pair<ProductList::iterator, bool> ret =
0070 productList_.insert(std::make_pair(BranchKey(productDesc), productDesc));
0071 if (!ret.second) {
0072 auto const& previous = *productList_.find(BranchKey(productDesc));
0073 if (previous.second.produced()) {
0074
0075 throw Exception(errors::LogicError, "Duplicate Product Identifier")
0076 << "\nThe Framework requires a unique branch name for each product\n"
0077 << "which consists of four parts: a friendly class name, module label,\n"
0078 << "product instance name, and process name. A product has been\n"
0079 << "registered with a duplicate branch name. The most common way\n"
0080 << "to fix this error is to modify the product instance name in\n"
0081 << "one of the offending 'produces' function calls. Another fix\n"
0082 << "would be to delete one of them if they are for the same product.\n\n"
0083 << " friendly class name = " << previous.second.friendlyClassName() << "\n"
0084 << " module label = " << previous.second.moduleLabel() << "\n"
0085 << " product instance name = " << previous.second.productInstanceName() << "\n"
0086 << " process name = " << previous.second.processName() << "\n\n"
0087 << "The following additional information is not used as part of\n"
0088 << "the unique branch identifier.\n\n"
0089 << " branch types = " << previous.second.branchType() << " " << productDesc.branchType() << "\n"
0090 << " class name = " << previous.second.fullClassName() << "\n\n"
0091 << "Note that if the four parts of the branch name are the same,\n"
0092 << "then this error will occur even if the branch types differ!\n\n";
0093 } else {
0094
0095 throw Exception(errors::Configuration, "Duplicate Process Name.\n")
0096 << "The process name " << productDesc.processName() << " was previously used for products in the input.\n"
0097 << "This has caused branch name conflicts between input products and new products.\n"
0098 << "Please modify the configuration file to use a distinct process name.\n"
0099 << "Alternately, drop all input products using that process name and the\n"
0100 << "descendants of those products.\n";
0101 }
0102 }
0103 }
0104
0105 ProductDescription const& ProductRegistry::addLabelAlias_(ProductDescription const& productDesc,
0106 std::string const& labelAlias,
0107 std::string const& instanceAlias) {
0108 assert(productDesc.produced());
0109 assert(productDesc.branchID().isValid());
0110 throwIfFrozen();
0111 ProductDescription bd(productDesc, labelAlias, instanceAlias);
0112 std::pair<ProductList::iterator, bool> ret = productList_.insert(std::make_pair(BranchKey(bd), bd));
0113 assert(ret.second);
0114 transient_.aliasToOriginal_.emplace_back(
0115 PRODUCT_TYPE, productDesc.unwrappedTypeID(), labelAlias, instanceAlias, productDesc.moduleLabel());
0116 return ret.first->second;
0117 }
0118
0119 void ProductRegistry::copyProduct(ProductDescription const& productDesc) {
0120 assert(!productDesc.produced());
0121 throwIfFrozen();
0122 BranchKey k = BranchKey(productDesc);
0123 ProductList::iterator iter = productList_.find(k);
0124 if (iter == productList_.end()) {
0125 productList_.insert(std::make_pair(k, productDesc));
0126 } else {
0127 assert(combinable(iter->second, productDesc));
0128 iter->second.merge(productDesc);
0129 }
0130 }
0131
0132 bool ProductRegistry::anyProducts(BranchType brType) const {
0133 throwIfNotFrozen();
0134 for (ProductList::const_iterator it = productList_.begin(), itEnd = productList_.end(); it != itEnd; ++it) {
0135 if (it->second.branchType() == brType) {
0136 return true;
0137 }
0138 }
0139 return false;
0140 }
0141
0142 std::shared_ptr<ProductResolverIndexHelper const> ProductRegistry::productLookup(BranchType branchType) const {
0143 return transient_.productLookups_[branchType];
0144 }
0145
0146 void ProductRegistry::setFrozen(bool initializeLookupInfo) {
0147 if (frozen())
0148 return;
0149 freezeIt();
0150 if (initializeLookupInfo) {
0151 initializeLookupTables(nullptr, nullptr, nullptr);
0152 }
0153 sort_all(transient_.aliasToOriginal_);
0154 }
0155
0156 void ProductRegistry::setFrozen(std::set<TypeID> const& productTypesConsumed,
0157 std::set<TypeID> const& elementTypesConsumed,
0158 std::string const& processName) {
0159 if (frozen())
0160 return;
0161 freezeIt();
0162 initializeLookupTables(&productTypesConsumed, &elementTypesConsumed, &processName);
0163 sort_all(transient_.aliasToOriginal_);
0164 }
0165
0166 void ProductRegistry::throwIfFrozen() const {
0167 if (frozen()) {
0168 throw cms::Exception("ProductRegistry", "throwIfFrozen")
0169 << "cannot modify the ProductRegistry because it is frozen\n";
0170 }
0171 }
0172
0173 void ProductRegistry::throwIfNotFrozen() const {
0174 if (!frozen()) {
0175 throw cms::Exception("ProductRegistry", "throwIfNotFrozen")
0176 << "cannot read the ProductRegistry because it is not yet frozen\n";
0177 }
0178 }
0179
0180 std::vector<std::string> ProductRegistry::allBranchNames() const {
0181 std::vector<std::string> result;
0182 result.reserve(productList().size());
0183
0184 for (auto const& product : productList()) {
0185 result.push_back(product.second.branchName());
0186 }
0187 return result;
0188 }
0189
0190 std::vector<ProductDescription const*> ProductRegistry::allProductDescriptions() const {
0191 std::vector<ProductDescription const*> result;
0192 result.reserve(productList().size());
0193
0194 for (auto const& product : productList()) {
0195 result.push_back(&product.second);
0196 }
0197 return result;
0198 }
0199
0200 void ProductRegistry::updateFromInput(ProductList const& other) {
0201 for (auto const& product : other) {
0202 copyProduct(product.second);
0203 }
0204 }
0205
0206 void ProductRegistry::updateFromInput(std::vector<ProductDescription> const& other) {
0207 for (ProductDescription const& productDescription : other) {
0208 copyProduct(productDescription);
0209 }
0210 }
0211
0212 void ProductRegistry::setUnscheduledProducts(std::set<std::string> const& unscheduledLabels) {
0213 throwIfFrozen();
0214
0215 bool hasAliases = false;
0216 std::vector<BranchID> onDemandIDs;
0217 for (auto& prod : productList_) {
0218 if (prod.second.produced() && prod.second.branchType() == InEvent &&
0219 unscheduledLabels.end() != unscheduledLabels.find(prod.second.moduleLabel())) {
0220 prod.second.setOnDemand(true);
0221 onDemandIDs.push_back(prod.second.branchID());
0222 }
0223 if (prod.second.produced() && prod.second.isAlias()) {
0224 hasAliases = true;
0225 }
0226 }
0227
0228
0229 if (hasAliases) {
0230 std::sort(onDemandIDs.begin(), onDemandIDs.end());
0231 for (auto& prod : productList_) {
0232 if (prod.second.isAlias()) {
0233 if (std::binary_search(onDemandIDs.begin(), onDemandIDs.end(), prod.second.aliasForBranchID())) {
0234 prod.second.setOnDemand(true);
0235 }
0236 }
0237 }
0238 }
0239 }
0240
0241 std::string ProductRegistry::merge(ProductRegistry const& other,
0242 std::string const& fileName,
0243 ProductDescription::MatchMode branchesMustMatch) {
0244 std::ostringstream differences;
0245
0246 ProductRegistry::ProductList::iterator j = productList_.begin();
0247 ProductRegistry::ProductList::iterator s = productList_.end();
0248 ProductRegistry::ProductList::const_iterator i = other.productList().begin();
0249 ProductRegistry::ProductList::const_iterator e = other.productList().end();
0250
0251
0252 while (j != s || i != e) {
0253 if (j != s && j->second.produced()) {
0254
0255 ++j;
0256 } else if (j == s || (i != e && i->first < j->first)) {
0257 if (i->second.present()) {
0258 differences << "Branch '" << i->second.branchName() << "' is in file '" << fileName << "'\n";
0259 differences << " but not in previous files.\n";
0260 } else {
0261 productList_.insert(*i);
0262 transient_.branchIDToIndex_[i->second.branchID()] = getNextIndexValue(i->second.branchType());
0263 ++nextIndexValue(i->second.branchType());
0264 }
0265 ++i;
0266 } else if (i == e || (j != s && j->first < i->first)) {
0267 if (j->second.present() &&
0268 (branchesMustMatch == ProductDescription::Strict || j->second.branchType() == InProcess)) {
0269 differences << "Branch '" << j->second.branchName() << "' is in previous files\n";
0270 differences << " but not in file '" << fileName << "'.\n";
0271 }
0272 ++j;
0273 } else {
0274 std::string difs = match(j->second, i->second, fileName);
0275 if (difs.empty()) {
0276 j->second.merge(i->second);
0277 } else {
0278 differences << difs;
0279 }
0280 ++i;
0281 ++j;
0282 }
0283 }
0284 return differences.str();
0285 }
0286
0287 void ProductRegistry::initializeLookupTables(std::set<TypeID> const* productTypesConsumed,
0288 std::set<TypeID> const* elementTypesConsumed,
0289 std::string const* processName) {
0290 std::map<TypeID, TypeID> containedTypeMap;
0291 std::map<TypeID, std::vector<TypeID>> containedTypeToBaseTypesMap;
0292
0293 std::vector<std::string> missingDictionaries;
0294 std::vector<std::string> branchNamesForMissing;
0295 std::vector<std::string> producedTypes;
0296
0297 transient_.branchIDToIndex_.clear();
0298
0299 std::array<std::shared_ptr<ProductResolverIndexHelper>, NumBranchTypes> new_productLookups{
0300 {std::make_shared<ProductResolverIndexHelper>(),
0301 std::make_shared<ProductResolverIndexHelper>(),
0302 std::make_shared<ProductResolverIndexHelper>(),
0303 std::make_shared<ProductResolverIndexHelper>()}};
0304 for (auto const& product : productList_) {
0305 auto const& desc = product.second;
0306
0307 checkForDuplicateProcessName(desc, processName);
0308
0309 if (desc.produced() && !desc.transient()) {
0310 setProductProduced(desc.branchType());
0311 }
0312
0313
0314 if (desc.present()) {
0315
0316
0317
0318
0319 if (!desc.produced()) {
0320 if (!checkDictionary(missingDictionaries, desc.className(), desc.unwrappedType())) {
0321 checkDictionaryOfWrappedType(missingDictionaries, desc.className());
0322 branchNamesForMissing.emplace_back(desc.branchName());
0323 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0324 continue;
0325 }
0326 }
0327 TypeID typeID(desc.unwrappedType().typeInfo());
0328
0329 auto iterContainedType = containedTypeMap.find(typeID);
0330 bool alreadySawThisType = (iterContainedType != containedTypeMap.end());
0331
0332 if (!desc.produced() && !alreadySawThisType) {
0333 if (!checkDictionary(missingDictionaries, desc.wrappedName(), desc.wrappedType())) {
0334 branchNamesForMissing.emplace_back(desc.branchName());
0335 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0336 continue;
0337 }
0338 }
0339
0340 TypeID wrappedTypeID(desc.wrappedType().typeInfo());
0341
0342 TypeID containedTypeID;
0343 if (alreadySawThisType) {
0344 containedTypeID = iterContainedType->second;
0345 } else {
0346 containedTypeID = productholderindexhelper::getContainedTypeFromWrapper(wrappedTypeID, typeID.className());
0347 }
0348 bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0349
0350 std::vector<TypeID>* baseTypesOfContainedType = nullptr;
0351
0352 if (!alreadySawThisType) {
0353 bool alreadyCheckedConstituents = desc.produced() && !desc.transient();
0354 if (!alreadyCheckedConstituents && !desc.transient()) {
0355
0356 if (!checkClassDictionaries(missingDictionaries, desc.wrappedName(), desc.wrappedType())) {
0357 branchNamesForMissing.emplace_back(desc.branchName());
0358 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0359 continue;
0360 }
0361 }
0362
0363 if (hasContainedType) {
0364 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
0365 if (iterBaseTypes == containedTypeToBaseTypesMap.end()) {
0366 std::vector<TypeID> baseTypes;
0367 if (!public_base_classes(missingDictionaries, containedTypeID, baseTypes)) {
0368 branchNamesForMissing.emplace_back(desc.branchName());
0369 if (desc.produced()) {
0370 producedTypes.emplace_back(desc.className() + std::string(" (produced in current process)"));
0371 } else {
0372 producedTypes.emplace_back(desc.className() + std::string(" (read from input)"));
0373 }
0374 continue;
0375 }
0376 iterBaseTypes = containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, baseTypes)).first;
0377 }
0378 baseTypesOfContainedType = &iterBaseTypes->second;
0379 }
0380
0381
0382
0383 containedTypeMap.emplace(typeID, containedTypeID);
0384 } else {
0385 if (hasContainedType) {
0386 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
0387 if (iterBaseTypes != containedTypeToBaseTypesMap.end()) {
0388 baseTypesOfContainedType = &iterBaseTypes->second;
0389 }
0390 }
0391 }
0392
0393 if (productTypesConsumed != nullptr && !desc.produced()) {
0394 bool mainTypeConsumed = (productTypesConsumed->find(typeID) != productTypesConsumed->end());
0395 bool containedTypeConsumed =
0396 hasContainedType && (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end());
0397 if (hasContainedType && !containedTypeConsumed && baseTypesOfContainedType != nullptr) {
0398 for (TypeID const& baseType : *baseTypesOfContainedType) {
0399 if (elementTypesConsumed->find(TypeID(baseType.typeInfo())) != elementTypesConsumed->end()) {
0400 containedTypeConsumed = true;
0401 break;
0402 }
0403 }
0404 }
0405 if (!containedTypeConsumed) {
0406 if (mainTypeConsumed) {
0407
0408
0409
0410
0411 if (hasContainedType) {
0412 containedTypeID = TypeID(typeid(void));
0413 }
0414 } else {
0415
0416
0417
0418
0419 continue;
0420 }
0421 }
0422 }
0423 ProductResolverIndex index = new_productLookups[desc.branchType()]->insert(typeID,
0424 desc.moduleLabel().c_str(),
0425 desc.productInstanceName().c_str(),
0426 desc.processName().c_str(),
0427 containedTypeID,
0428 baseTypesOfContainedType);
0429
0430 transient_.branchIDToIndex_[desc.branchID()] = index;
0431 }
0432 }
0433 if (!missingDictionaries.empty()) {
0434 std::string context("Calling ProductRegistry::initializeLookupTables");
0435 throwMissingDictionariesException(missingDictionaries, context, producedTypes, branchNamesForMissing);
0436 }
0437
0438 for (auto& iterProductLookup : new_productLookups) {
0439 iterProductLookup->setFrozen();
0440 }
0441 for (size_t i = 0; i < new_productLookups.size(); ++i) {
0442 transient_.productLookups_[i] = std::move(new_productLookups[i]);
0443 }
0444
0445 unsigned int indexIntoNextIndexValue = 0;
0446 for (auto const& iterProductLookup : transient_.productLookups_) {
0447 transient_.nextIndexValues_[indexIntoNextIndexValue] = iterProductLookup->nextIndexValue();
0448 ++indexIntoNextIndexValue;
0449 }
0450
0451 for (auto const& product : productList_) {
0452 auto const& desc = product.second;
0453 if (transient_.branchIDToIndex_.find(desc.branchID()) == transient_.branchIDToIndex_.end()) {
0454 transient_.branchIDToIndex_[desc.branchID()] = getNextIndexValue(desc.branchType());
0455 ++nextIndexValue(desc.branchType());
0456 }
0457 }
0458 checkDictionariesOfConsumedTypes(
0459 productTypesConsumed, elementTypesConsumed, containedTypeMap, containedTypeToBaseTypesMap);
0460
0461 addElementTypesForAliases(elementTypesConsumed, containedTypeMap, containedTypeToBaseTypesMap);
0462 }
0463
0464 void ProductRegistry::addElementTypesForAliases(
0465 std::set<TypeID> const* elementTypesConsumed,
0466 std::map<TypeID, TypeID> const& containedTypeMap,
0467 std::map<TypeID, std::vector<TypeID>> const& containedTypeToBaseTypesMap) {
0468 Transients::AliasToOriginalVector elementAliases;
0469 for (auto& item : transient_.aliasToOriginal_) {
0470 auto iterContainedType = containedTypeMap.find(std::get<Transients::kType>(item));
0471 if (iterContainedType == containedTypeMap.end()) {
0472 edm::Exception ex(errors::LogicError);
0473 ex << "containedTypeMap did not contain " << std::get<Transients::kType>(item).className()
0474 << " that is used in EDAlias " << std::get<Transients::kModuleLabel>(item)
0475 << ".\nThis should not happen, contact framework developers";
0476 ex.addContext("Calling ProductRegistry::initializeLookupTables()");
0477 throw ex;
0478 }
0479 auto const& containedTypeID = iterContainedType->second;
0480 bool const hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0481 if (not hasContainedType) {
0482 continue;
0483 }
0484
0485 if (elementTypesConsumed->find(containedTypeID) != elementTypesConsumed->end()) {
0486 elementAliases.emplace_back(ELEMENT_TYPE,
0487 containedTypeID,
0488 std::get<Transients::kModuleLabel>(item),
0489 std::get<Transients::kProductInstanceName>(item),
0490 std::get<Transients::kAliasForModuleLabel>(item));
0491 }
0492
0493 auto iterBaseTypes = containedTypeToBaseTypesMap.find(containedTypeID);
0494 if (iterBaseTypes == containedTypeToBaseTypesMap.end()) {
0495 continue;
0496 }
0497 for (TypeID const& baseTypeID : iterBaseTypes->second) {
0498 if (elementTypesConsumed->find(baseTypeID) != elementTypesConsumed->end()) {
0499 elementAliases.emplace_back(ELEMENT_TYPE,
0500 baseTypeID,
0501 std::get<Transients::kModuleLabel>(item),
0502 std::get<Transients::kProductInstanceName>(item),
0503 std::get<Transients::kAliasForModuleLabel>(item));
0504 }
0505 }
0506 }
0507 transient_.aliasToOriginal_.insert(transient_.aliasToOriginal_.end(),
0508 std::make_move_iterator(elementAliases.begin()),
0509 std::make_move_iterator(elementAliases.end()));
0510 }
0511
0512 void ProductRegistry::checkDictionariesOfConsumedTypes(
0513 std::set<TypeID> const* productTypesConsumed,
0514 std::set<TypeID> const* elementTypesConsumed,
0515 std::map<TypeID, TypeID> const& containedTypeMap,
0516 std::map<TypeID, std::vector<TypeID>>& containedTypeToBaseTypesMap) {
0517 std::vector<std::string> missingDictionaries;
0518 std::set<std::string> consumedTypesWithMissingDictionaries;
0519
0520 if (productTypesConsumed) {
0521
0522 for (auto const& consumedTypeID : *productTypesConsumed) {
0523
0524
0525
0526 if (containedTypeMap.find(consumedTypeID) == containedTypeMap.end()) {
0527 std::string wrappedName = wrappedClassName(consumedTypeID.className());
0528 TypeWithDict wrappedType = TypeWithDict::byName(wrappedName);
0529 if (!checkDictionary(missingDictionaries, wrappedName, wrappedType)) {
0530 checkDictionary(missingDictionaries, consumedTypeID);
0531 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0532 continue;
0533 }
0534 bool transient = false;
0535 TDictAttributeMap* wp = wrappedType.getClass()->GetAttributeMap();
0536 if (wp && wp->HasKey("persistent") && !strcmp(wp->GetPropertyAsString("persistent"), "false")) {
0537 transient = true;
0538 }
0539 if (transient) {
0540 if (!checkDictionary(missingDictionaries, consumedTypeID)) {
0541 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0542 }
0543
0544 TypeID containedTypeID = productholderindexhelper::getContainedTypeFromWrapper(
0545 TypeID(wrappedType.typeInfo()), consumedTypeID.className());
0546 bool hasContainedType = (containedTypeID != TypeID(typeid(void)) && containedTypeID != TypeID());
0547 if (hasContainedType) {
0548 if (containedTypeToBaseTypesMap.find(containedTypeID) == containedTypeToBaseTypesMap.end()) {
0549 std::vector<TypeID> bases;
0550
0551 if (!public_base_classes(missingDictionaries, containedTypeID, bases)) {
0552 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0553 }
0554 containedTypeToBaseTypesMap.insert(std::make_pair(containedTypeID, bases));
0555 }
0556 }
0557 } else {
0558 if (!checkClassDictionaries(missingDictionaries, wrappedName, wrappedType)) {
0559 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0560 }
0561 }
0562 }
0563 }
0564 if (!missingDictionaries.empty()) {
0565 std::string context(
0566 "Calling ProductRegistry::initializeLookupTables, checking dictionaries for consumed products");
0567 throwMissingDictionariesException(missingDictionaries, context, consumedTypesWithMissingDictionaries, false);
0568 }
0569 }
0570
0571 if (elementTypesConsumed) {
0572 missingDictionaries.clear();
0573 consumedTypesWithMissingDictionaries.clear();
0574 for (auto const& consumedTypeID : *elementTypesConsumed) {
0575 if (containedTypeToBaseTypesMap.find(consumedTypeID) == containedTypeToBaseTypesMap.end()) {
0576 std::vector<TypeID> bases;
0577
0578 if (!public_base_classes(missingDictionaries, consumedTypeID, bases)) {
0579 consumedTypesWithMissingDictionaries.emplace(consumedTypeID.className());
0580 }
0581 }
0582 }
0583 if (!missingDictionaries.empty()) {
0584 std::string context(
0585 "Calling ProductRegistry::initializeLookupTables, checking dictionaries for elements of products consumed "
0586 "using View");
0587 throwMissingDictionariesException(missingDictionaries, context, consumedTypesWithMissingDictionaries, true);
0588 }
0589 }
0590 }
0591
0592 void ProductRegistry::checkForDuplicateProcessName(ProductDescription const& desc,
0593 std::string const* processName) const {
0594 if (processName && !desc.produced() && (*processName == desc.processName())) {
0595 throw Exception(errors::Configuration, "Duplicate Process Name.\n")
0596 << "The process name " << *processName << " was previously used for products in the input.\n"
0597 << "Please modify the configuration file to use a distinct process name.\n"
0598 << "Alternately, drop all input products using that process name and the\n"
0599 << "descendants of those products.\n";
0600 }
0601 }
0602
0603 ProductResolverIndex ProductRegistry::indexFrom(BranchID const& iID) const {
0604 std::map<BranchID, ProductResolverIndex>::const_iterator itFind = transient_.branchIDToIndex_.find(iID);
0605 if (itFind == transient_.branchIDToIndex_.end()) {
0606 return ProductResolverIndexInvalid;
0607 }
0608 return itFind->second;
0609 }
0610
0611 std::vector<std::string> ProductRegistry::aliasToModules(KindOfType kindOfType,
0612 TypeID const& type,
0613 std::string_view moduleLabel,
0614 std::string_view productInstanceName) const {
0615 auto aliasFields = [](auto const& item) {
0616 return std::tie(std::get<Transients::kKind>(item),
0617 std::get<Transients::kType>(item),
0618 std::get<Transients::kModuleLabel>(item),
0619 std::get<Transients::kProductInstanceName>(item));
0620 };
0621 auto const target = std::tuple(kindOfType, type, moduleLabel, productInstanceName);
0622 auto found =
0623 std::lower_bound(transient_.aliasToOriginal_.begin(),
0624 transient_.aliasToOriginal_.end(),
0625 target,
0626 [aliasFields](auto const& item, auto const& target) { return aliasFields(item) < target; });
0627 std::vector<std::string> ret;
0628 for (; found != transient_.aliasToOriginal_.end() and aliasFields(*found) == target; ++found) {
0629 ret.emplace_back(std::get<Transients::kAliasForModuleLabel>(*found));
0630 }
0631 return ret;
0632 }
0633
0634 void ProductRegistry::print(std::ostream& os) const {
0635 for (auto const& product : productList_) {
0636 os << product.second << "\n-----\n";
0637 }
0638 }
0639
0640 ProductResolverIndex const& ProductRegistry::getNextIndexValue(BranchType branchType) const {
0641 return transient_.nextIndexValues_[branchType];
0642 }
0643
0644 ProductResolverIndex& ProductRegistry::nextIndexValue(BranchType branchType) {
0645 return transient_.nextIndexValues_[branchType];
0646 }
0647 }