File indexing completed on 2025-03-14 23:36:16
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 std::shared_ptr<ProductResolverBase> makeParentProcessProduct(std::shared_ptr<ProductDescription const> bd) {
0066 return std::make_shared<ParentProcessProductResolver>(std::move(bd));
0067 }
0068
0069 void addProductOrThrow(std::shared_ptr<ProductResolverBase> iResolver,
0070 std::vector<std::shared_ptr<ProductResolverBase>>& oResolvers,
0071 ProductRegistry const& iReg) {
0072 assert(bool(iResolver));
0073 ProductDescription const& bd = iResolver->productDescription();
0074 assert(!bd.className().empty());
0075 assert(!bd.friendlyClassName().empty());
0076 assert(!bd.moduleLabel().empty());
0077 assert(!bd.processName().empty());
0078 auto index = iReg.indexFrom(bd.branchID());
0079 if (oResolvers[index]) {
0080 throw Exception(errors::InsertFailure, "AlreadyPresent")
0081 << "Problem found while adding a new ProductResolver, "
0082 << "product already exists for (" << bd.friendlyClassName() << "," << bd.moduleLabel() << ","
0083 << bd.productInstanceName() << "," << bd.processName() << ")\n";
0084 }
0085 oResolvers[index] = std::move(iResolver);
0086 }
0087
0088 std::shared_ptr<ProductResolverBase> makeForPrimary(ProductDescription const& bd,
0089 ProductRegistry const& iReg,
0090 ProductResolverIndexHelper const& iHelper) {
0091 auto cbd = std::make_shared<ProductDescription const>(bd);
0092 if (bd.produced()) {
0093 using namespace std::literals;
0094 if (bd.moduleLabel() == "source"sv) {
0095 return makeSourceProduct(cbd);
0096 } else if (bd.onDemand()) {
0097 assert(bd.branchType() == InEvent);
0098 if (bd.isTransform()) {
0099 return makeTransformProduct(cbd);
0100 } else {
0101 return makeUnscheduledProduct(cbd);
0102 }
0103 }
0104 return makeScheduledProduct(cbd);
0105 }
0106
0107 if (bd.dropped()) {
0108
0109 return makeDroppedProduct(cbd);
0110 }
0111 if (bd.onDemand()) {
0112 return makeDelayedReaderInputProduct(cbd);
0113 }
0114 return makePutOnReadInputProduct(cbd);
0115 }
0116 bool isProductMadeAtEnd(edm::BranchIDList const& matchingHolders,
0117 std::vector<bool> const& ambiguous,
0118 std::vector<std::shared_ptr<edm::ProductResolverBase>> const& productResolvers) {
0119 for (unsigned int j = 0; j < matchingHolders.size(); ++j) {
0120 if ((not ambiguous[j]) and ProductResolverIndexInvalid != matchingHolders[j] and
0121 productResolvers[matchingHolders[j]]->productDescription().availableOnlyAtEndTransition()) {
0122 return true;
0123 }
0124 }
0125 return false;
0126 }
0127 std::shared_ptr<ProductResolverBase> makeNoProcess(
0128 unsigned int numberOfMatches,
0129 ProductResolverIndex lastMatchIndex,
0130 edm::BranchIDList const& matchingHolders,
0131 std::vector<bool> const& ambiguous,
0132 std::vector<std::shared_ptr<edm::ProductResolverBase>> const& productResolvers) {
0133 if ((numberOfMatches == 1) and (lastMatchIndex != ProductResolverIndexAmbiguous)) {
0134
0135 return std::make_shared<SingleChoiceNoProcessProductResolver>(lastMatchIndex);
0136 }
0137
0138 bool productMadeAtEnd = isProductMadeAtEnd(matchingHolders, ambiguous, productResolvers);
0139 return std::make_shared<NoProcessProductResolver>(matchingHolders, ambiguous, productMadeAtEnd);
0140 }
0141
0142 void addUnspecifiedProcess(ProductResolverIndexHelper const& iHelper,
0143 std::vector<std::shared_ptr<ProductResolverBase>>& productResolvers) {
0144
0145
0146
0147 std::vector<std::string> const& lookupProcessNames = iHelper.lookupProcessNames();
0148 std::vector<ProductResolverIndex> matchingHolders(lookupProcessNames.size(), ProductResolverIndexInvalid);
0149 std::vector<bool> ambiguous(lookupProcessNames.size(), false);
0150 unsigned int beginElements = iHelper.beginElements();
0151 std::vector<TypeID> const& sortedTypeIDs = iHelper.sortedTypeIDs();
0152 std::vector<ProductResolverIndexHelper::Range> const& ranges = iHelper.ranges();
0153 std::vector<ProductResolverIndexHelper::IndexAndNames> const& indexAndNames = iHelper.indexAndNames();
0154 std::vector<char> const& processNamesCharArray = iHelper.processNames();
0155
0156 unsigned int numberOfMatches = 0;
0157 ProductResolverIndex lastMatchIndex = ProductResolverIndexInvalid;
0158 if (!sortedTypeIDs.empty()) {
0159 ProductResolverIndex productResolverIndex = ProductResolverIndexInvalid;
0160 for (unsigned int k = 0, kEnd = sortedTypeIDs.size(); k < kEnd; ++k) {
0161 ProductResolverIndexHelper::Range const& range = ranges.at(k);
0162 for (unsigned int i = range.begin(); i < range.end(); ++i) {
0163 ProductResolverIndexHelper::IndexAndNames const& product = indexAndNames.at(i);
0164 if (product.startInProcessNames() == 0) {
0165 if (productResolverIndex != ProductResolverIndexInvalid) {
0166 productResolvers.at(productResolverIndex) =
0167 makeNoProcess(numberOfMatches, lastMatchIndex, matchingHolders, ambiguous, productResolvers);
0168 matchingHolders.assign(lookupProcessNames.size(), ProductResolverIndexInvalid);
0169 ambiguous.assign(lookupProcessNames.size(), false);
0170 numberOfMatches = 0;
0171 lastMatchIndex = ProductResolverIndexInvalid;
0172 }
0173 productResolverIndex = product.index();
0174 } else {
0175 const std::string_view process(&processNamesCharArray.at(product.startInProcessNames()));
0176 auto iter = std::find(lookupProcessNames.begin(), lookupProcessNames.end(), process);
0177 assert(iter != lookupProcessNames.end());
0178 ProductResolverIndex iMatchingIndex = product.index();
0179 lastMatchIndex = iMatchingIndex;
0180 assert(iMatchingIndex != ProductResolverIndexInvalid);
0181 ++numberOfMatches;
0182 if (iMatchingIndex == ProductResolverIndexAmbiguous) {
0183 assert(k >= beginElements);
0184 ambiguous.at(iter - lookupProcessNames.begin()) = true;
0185 } else {
0186 matchingHolders.at(iter - lookupProcessNames.begin()) = iMatchingIndex;
0187 }
0188 }
0189 }
0190 }
0191 productResolvers.at(productResolverIndex) =
0192 makeNoProcess(numberOfMatches, lastMatchIndex, matchingHolders, ambiguous, productResolvers);
0193 }
0194 }
0195 }
0196
0197 std::vector<std::shared_ptr<ProductResolverBase>> make(BranchType bt,
0198 std::string_view iProcessName,
0199 ProductRegistry const& iReg,
0200 bool isForPrimaryProcess) {
0201 auto const& helper = iReg.productLookup(bt);
0202 std::vector<std::shared_ptr<ProductResolverBase>> productResolvers(iReg.getNextIndexValue(bt));
0203 ProductRegistry::ProductList const& prodsList = iReg.productList();
0204
0205
0206
0207 bool hasAliases = false;
0208 bool hasSwitchAliases = false;
0209 for (auto const& prod : prodsList) {
0210 ProductDescription const& bd = prod.second;
0211 if (bd.branchType() == bt) {
0212 if (isForPrimaryProcess or bd.processName() == iProcessName) {
0213 if (bd.isAlias()) {
0214 hasAliases = true;
0215 } else if (bd.isSwitchAlias()) {
0216 hasSwitchAliases = true;
0217 } else {
0218 addProductOrThrow(makeForPrimary(bd, iReg, *helper), productResolvers, iReg);
0219 }
0220 } else {
0221
0222 auto cbd = std::make_shared<ProductDescription const>(bd);
0223 if (bd.dropped()) {
0224 addProductOrThrow(makeDroppedProduct(cbd), productResolvers, iReg);
0225 } else {
0226 addProductOrThrow(makeParentProcessProduct(cbd), productResolvers, iReg);
0227 }
0228 }
0229 }
0230 }
0231
0232 if (hasAliases) {
0233 for (auto const& prod : prodsList) {
0234 ProductDescription const& bd = prod.second;
0235 if (bd.isAlias() && bd.branchType() == bt) {
0236 addProductOrThrow(makeAliasedProduct(std::make_shared<ProductDescription const>(bd), iReg, productResolvers),
0237 productResolvers,
0238 iReg);
0239 }
0240 }
0241 }
0242
0243 if (hasSwitchAliases) {
0244 for (auto const& prod : prodsList) {
0245 ProductDescription const& bd = prod.second;
0246 if (bd.isSwitchAlias() && bd.branchType() == bt) {
0247 assert(bt == InEvent);
0248 auto cbd = std::make_shared<ProductDescription const>(bd);
0249
0250
0251
0252
0253
0254 if (bd.onDemand()) {
0255 addProductOrThrow(makeSwitchAliasProduct(cbd, iReg, productResolvers), productResolvers, iReg);
0256 } else {
0257 addProductOrThrow(makeSwitchProducerProduct(cbd, iReg, productResolvers), productResolvers, iReg);
0258 }
0259 }
0260 }
0261 }
0262
0263 addUnspecifiedProcess(*helper, productResolvers);
0264
0265 return productResolvers;
0266 }
0267 }