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