File indexing completed on 2025-01-14 02:38:40
0001 #include "FWCore/Framework/interface/ProductResolversFactory.h"
0002 #include "FWCore/Framework/interface/ProductResolverBase.h"
0003 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0004 #include "ProductResolvers.h"
0005
0006 #include <memory>
0007
0008 namespace edm::productResolversFactory {
0009 namespace {
0010 std::shared_ptr<ProductResolverBase> makeScheduledProduct(std::shared_ptr<BranchDescription const> bd) {
0011 return std::make_shared<PuttableProductResolver>(std::move(bd));
0012 }
0013 std::shared_ptr<ProductResolverBase> makeSourceProduct(std::shared_ptr<BranchDescription const> bd) {
0014 return std::make_shared<PuttableProductResolver>(std::move(bd));
0015 }
0016 std::shared_ptr<ProductResolverBase> makeDelayedReaderInputProduct(std::shared_ptr<BranchDescription const> bd) {
0017 return std::make_shared<DelayedReaderInputProductResolver>(std::move(bd));
0018 }
0019 std::shared_ptr<ProductResolverBase> makePutOnReadInputProduct(std::shared_ptr<BranchDescription const> bd) {
0020 return std::make_shared<PutOnReadInputProductResolver>(std::move(bd));
0021 }
0022 std::shared_ptr<ProductResolverBase> makeUnscheduledProduct(std::shared_ptr<BranchDescription const> bd) {
0023 return std::make_shared<UnscheduledProductResolver>(std::move(bd));
0024 }
0025 std::shared_ptr<ProductResolverBase> makeTransformProduct(std::shared_ptr<BranchDescription const> bd) {
0026 return std::make_shared<TransformingProductResolver>(std::move(bd));
0027 }
0028 std::shared_ptr<ProductResolverBase> makeAliasedProduct(
0029 std::shared_ptr<BranchDescription const> bd,
0030 ProductRegistry const& iReg,
0031 std::vector<std::shared_ptr<ProductResolverBase>> const& iResolvers) {
0032 ProductResolverIndex index = iReg.indexFrom(bd->originalBranchID());
0033 assert(index != ProductResolverIndexInvalid);
0034 return std::make_shared<AliasProductResolver>(
0035 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*iResolvers[index]));
0036 }
0037 std::shared_ptr<ProductResolverBase> makeSwitchProducerProduct(
0038 std::shared_ptr<BranchDescription const> bd,
0039 ProductRegistry const& iReg,
0040 std::vector<std::shared_ptr<ProductResolverBase>> const& iResolvers) {
0041 ProductResolverIndex index = iReg.indexFrom(bd->switchAliasForBranchID());
0042 assert(index != ProductResolverIndexInvalid);
0043
0044 return std::make_shared<SwitchProducerProductResolver>(
0045 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*iResolvers[index]));
0046 }
0047
0048 std::shared_ptr<ProductResolverBase> makeSwitchAliasProduct(
0049 std::shared_ptr<BranchDescription const> bd,
0050 ProductRegistry const& iReg,
0051 std::vector<std::shared_ptr<ProductResolverBase>> const& iResolvers) {
0052 ProductResolverIndex index = iReg.indexFrom(bd->switchAliasForBranchID());
0053 assert(index != ProductResolverIndexInvalid);
0054
0055 return std::make_shared<SwitchAliasProductResolver>(
0056 std::move(bd), dynamic_cast<DataManagingOrAliasProductResolver&>(*iResolvers[index]));
0057 }
0058
0059 std::shared_ptr<ProductResolverBase> makeParentProcessProduct(std::shared_ptr<BranchDescription const> bd) {
0060 return std::make_shared<ParentProcessProductResolver>(std::move(bd));
0061 }
0062
0063 void addProductOrThrow(std::shared_ptr<ProductResolverBase> iResolver,
0064 std::vector<std::shared_ptr<ProductResolverBase>>& oResolvers,
0065 ProductRegistry const& iReg) {
0066 assert(bool(iResolver));
0067 BranchDescription const& bd = iResolver->branchDescription();
0068 assert(!bd.className().empty());
0069 assert(!bd.friendlyClassName().empty());
0070 assert(!bd.moduleLabel().empty());
0071 assert(!bd.processName().empty());
0072 auto index = iReg.indexFrom(bd.branchID());
0073 if (oResolvers[index]) {
0074 throw Exception(errors::InsertFailure, "AlreadyPresent")
0075 << "Problem found while adding a new ProductResolver, "
0076 << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
0077 << bd.productInstanceName() << "," << bd.processName() << ")\n";
0078 }
0079 oResolvers[index] = std::move(iResolver);
0080 }
0081
0082 std::shared_ptr<ProductResolverBase> makeForPrimary(BranchDescription const& bd,
0083 ProductRegistry const& iReg,
0084 ProductResolverIndexHelper const& iHelper) {
0085 auto cbd = std::make_shared<BranchDescription const>(bd);
0086 if (bd.produced()) {
0087 using namespace std::literals;
0088 if (bd.moduleLabel() == "source"sv) {
0089 return makeSourceProduct(cbd);
0090 } else if (bd.onDemand()) {
0091 assert(bd.branchType() == InEvent);
0092 if (bd.isTransform()) {
0093 return makeTransformProduct(cbd);
0094 } else {
0095 return makeUnscheduledProduct(cbd);
0096 }
0097 }
0098 return makeScheduledProduct(cbd);
0099 }
0100
0101 if (bd.onDemand()) {
0102 return makeDelayedReaderInputProduct(cbd);
0103 }
0104 return makePutOnReadInputProduct(cbd);
0105 }
0106 bool isProductMadeAtEnd(edm::BranchIDList const& matchingHolders,
0107 std::vector<bool> const& ambiguous,
0108 std::vector<std::shared_ptr<edm::ProductResolverBase>> const& productResolvers) {
0109 for (unsigned int j = 0; j < matchingHolders.size(); ++j) {
0110 if ((not ambiguous[j]) and ProductResolverIndexInvalid != matchingHolders[j] and
0111 productResolvers[matchingHolders[j]]->branchDescription().availableOnlyAtEndTransition()) {
0112 return true;
0113 }
0114 }
0115 return false;
0116 }
0117 std::shared_ptr<ProductResolverBase> makeNoProcess(
0118 unsigned int numberOfMatches,
0119 ProductResolverIndex lastMatchIndex,
0120 edm::BranchIDList const& matchingHolders,
0121 std::vector<bool> const& ambiguous,
0122 std::vector<std::shared_ptr<edm::ProductResolverBase>> const& productResolvers) {
0123 if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
0124
0125 return std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
0126 }
0127
0128 bool productMadeAtEnd = isProductMadeAtEnd(matchingHolders, ambiguous, productResolvers);
0129 return std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
0130 }
0131
0132 void addUnspecifiedProcess(ProductResolverIndexHelper const& iHelper,
0133 std::vector<std::shared_ptr<ProductResolverBase>>& productResolvers) {
0134
0135
0136
0137 std::vector<std::string> const& lookupProcessNames = iHelper.lookupProcessNames();
0138 std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
0139 std::vector<bool> ambiguous(lookupProcessNames.size(), false);
0140 unsigned int beginElements = iHelper.beginElements();
0141 std::vector<TypeID> const& sortedTypeIDs = iHelper.sortedTypeIDs();
0142 std::vector<ProductResolverIndexHelper::Range> const& ranges = iHelper.ranges();
0143 std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = iHelper.indexAndNames();
0144 std::vector<char> const& processNamesCharArray = iHelper.processNames();
0145
0146 unsigned int numberOfMatches = 0;
0147 ProductResolverIndex lastMatchIndex = ProductResolverIndexInvalid;
0148 if (!sortedTypeIDs.empty()) {
0149 ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
0150 for (unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
0151 ProductResolverIndexHelper::Range const& range = ranges.at(k);
0152 for (unsigned int i = range.begin(); i < range.end(); ++i) {
0153 ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
0154 if (product.startInProcessNames() == 0) {
0155 if (productResolverIndex != ProductResolverIndexInvalid) {
0156 productResolvers.at(productResolverIndex) =
0157 makeNoProcess(numberOfMatches, lastMatchIndex, matchingHolders, ambiguous, productResolvers);
0158 matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
0159 ambiguous.assign(lookupProcessNames.size(), false);
0160 numberOfMatches = 0;
0161 lastMatchIndex = ProductResolverIndexInvalid;
0162 }
0163 productResolverIndex = product.index();
0164 } else {
0165 const std::string_view process(&processNamesCharArray.at(product.startInProcessNames()));
0166 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
0167 assert(iter != lookupProcessNames.end());
0168 ProductResolverIndex iMatchingIndex = product.index();
0169 lastMatchIndex = iMatchingIndex;
0170 assert(iMatchingIndex != ProductResolverIndexInvalid);
0171 ++numberOfMatches;
0172 if (iMatchingIndex == ProductResolverIndexAmbiguous) {
0173 assert(k >= beginElements);
0174 ambiguous.at(iter - lookupProcessNames.begin()) = true;
0175 } else {
0176 matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
0177 }
0178 }
0179 }
0180 }
0181 productResolvers.at(productResolverIndex) =
0182 makeNoProcess(numberOfMatches, lastMatchIndex, matchingHolders, ambiguous, productResolvers);
0183 }
0184 }
0185 }
0186
0187 std::vector<std::shared_ptr<ProductResolverBase>> make(BranchType bt,
0188 std::string_view iProcessName,
0189 ProductRegistry const& iReg,
0190 bool isForPrimaryProcess) {
0191 auto const& helper = iReg.productLookup(bt);
0192 std::vector<std::shared_ptr<ProductResolverBase>> productResolvers(iReg.getNextIndexValue(bt));
0193 ProductRegistry::ProductList const& prodsList = iReg.productList();
0194
0195
0196
0197 bool hasAliases = false;
0198 bool hasSwitchAliases = false;
0199 for (auto const& prod : prodsList) {
0200 BranchDescription const& bd = prod.second;
0201 if (bd.branchType() == bt) {
0202 if (isForPrimaryProcess or bd.processName() == iProcessName) {
0203 if (bd.isAlias()) {
0204 hasAliases = true;
0205 } else if (bd.isSwitchAlias()) {
0206 hasSwitchAliases = true;
0207 } else {
0208 addProductOrThrow(makeForPrimary(bd, iReg, *helper), productResolvers, iReg);
0209 }
0210 } else {
0211
0212 auto cbd = std::make_shared<BranchDescription const>(bd);
0213 addProductOrThrow(makeParentProcessProduct(cbd), productResolvers, iReg);
0214 }
0215 }
0216 }
0217
0218 if (hasAliases) {
0219 for (auto const& prod : prodsList) {
0220 BranchDescription const& bd = prod.second;
0221 if (bd.isAlias() && bd.branchType() == bt) {
0222 addProductOrThrow(makeAliasedProduct(std::make_shared<BranchDescription const>(bd), iReg, productResolvers),
0223 productResolvers,
0224 iReg);
0225 }
0226 }
0227 }
0228
0229 if (hasSwitchAliases) {
0230 for (auto const& prod : prodsList) {
0231 BranchDescription const& bd = prod.second;
0232 if (bd.isSwitchAlias() && bd.branchType() == bt) {
0233 assert(bt == InEvent);
0234 auto cbd = std::make_shared<BranchDescription const>(bd);
0235
0236
0237
0238
0239
0240 if (bd.onDemand()) {
0241 addProductOrThrow(makeSwitchAliasProduct(cbd, iReg, productResolvers), productResolvers, iReg);
0242 } else {
0243 addProductOrThrow(makeSwitchProducerProduct(cbd, iReg, productResolvers), productResolvers, iReg);
0244 }
0245 }
0246 }
0247 }
0248
0249 addUnspecifiedProcess(*helper, productResolvers);
0250
0251 return productResolvers;
0252 }
0253 }