From 3dda7ea9c6f1fa911a6f7a2435257cdc4df2bb91 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 8 Nov 2026 20:05:19 +0100 Subject: [PATCH 1/2] DPL Analysis: look up the CCDB output buffer only when fetching populateCacheWith created the pmr vector for the object, which matches the output route and looks up its transport, for every FetchOp. On a cache hit the vector is never used, and the analysis CCDB fetcher issues one FetchOp per column for every row of the source table. Create it only where an object is actually requested from the server. --- Framework/CCDBSupport/src/CCDBFetcherHelper.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/CCDBSupport/src/CCDBFetcherHelper.cxx b/Framework/CCDBSupport/src/CCDBFetcherHelper.cxx index e4a9556c59b17..c79f64cccbd7c 100644 --- a/Framework/CCDBSupport/src/CCDBFetcherHelper.cxx +++ b/Framework/CCDBSupport/src/CCDBFetcherHelper.cxx @@ -179,7 +179,6 @@ auto CCDBFetcherHelper::populateCacheWith(std::shared_ptr con O2_SIGNPOST_EVENT_EMIT(ccdb, sid, "populateCacheWith", "Fetching object for route %{public}s", DataSpecUtils::describe(op.spec).data()); auto concrete = DataSpecUtils::asConcreteDataMatcher(op.spec); Output output{concrete.origin, concrete.description, concrete.subSpec}; - auto&& v = allocator.makeVector(output); std::map metadata; std::map headers; std::string path = op.url; @@ -232,6 +231,7 @@ auto CCDBFetcherHelper::populateCacheWith(std::shared_ptr con const auto& api = helper->getAPI(path); if (checkValidity && (!api.isSnapshotMode() || etag.empty())) { // in the snapshot mode the object needs to be fetched only once + auto&& v = allocator.makeVector(output); LOGP(detail, "Loading {} for timestamp {}", path, timestampToUse); api.loadFileToMemory(v, path, metadata, timestampToUse, &headers, etag, helper->createdNotAfter, helper->createdNotBefore); if ((headers.count("Error") != 0) || (etag.empty() && v.empty())) { From 61435054c34a4563bf9ad2b0bf4a5e4e8850a0fa Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Sun, 8 Nov 2026 20:05:19 +0100 Subject: [PATCH 2/2] DPL Analysis: query the CCDB once per run of equal timestamps When a CCDB table has no separate uniformity column, the analysis CCDB fetcher called populateCacheWith for every row of the source table, so about 19k times per timeframe for a BC-indexed table such as the ones of propagation-service-v2, even though consecutive BCs share the same millisecond timestamp. Reuse the previous responses whenever the lookup key, the uniformity value or else the timestamp, is the same as the one of the previous row. Since the key determines every FetchOp of the row, the responses and hence the output table are unchanged. For the LHC25b4a6 AO2D of Hyperloop test 799098 this is about 350 runs of equal (millisecond) BC times over 1.17M BCs in 61 DFs, instead of one query per BC. --- Framework/CCDBSupport/src/AnalysisCCDBHelpers.cxx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Framework/CCDBSupport/src/AnalysisCCDBHelpers.cxx b/Framework/CCDBSupport/src/AnalysisCCDBHelpers.cxx index 5bd21ce6bdf3f..b5e7e9436357c 100644 --- a/Framework/CCDBSupport/src/AnalysisCCDBHelpers.cxx +++ b/Framework/CCDBSupport/src/AnalysisCCDBHelpers.cxx @@ -235,8 +235,8 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/) // Rows sharing a uniformity value resolve to the same objects, so the query is // issued once per distinct value and the resulting handles are repeated for the - // rest of the run. When uniformity is the timestamp itself (the default) this - // degenerates to the previous behaviour, one query per row. + // rest of the run. When uniformity is the timestamp itself (the default) the + // query is issued once per run of consecutive rows with the same timestamp. std::vector uniformity; bool const shortCircuit = uniformityColumn.get() != timestampColumn.get(); if (shortCircuit) { @@ -273,15 +273,13 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/) for (int64_t ri = 0; ri < chunk->data()->length; ri++) { ++row; - bool const sameAsPrevious = shortCircuit && haveResponses && uniformity[row] == previousUniformity; - if (shortCircuit) { - previousUniformity = uniformity[row]; - } ops.clear(); int64_t timestamp = timestamps[ri]; // Key the path lookup on the uniformity value; when uniformity is the // timestamp itself the mapping expresses validity intervals instead. int64_t const uniformityKey = shortCircuit ? uniformity[row] : timestamp; + bool const sameAsPrevious = haveResponses && uniformityKey == previousUniformity; + previousUniformity = uniformityKey; int fi = 0; for (auto& field : schema->fields()) { auto const& url = pathTables[i][fi++].resolve(uniformityKey, field->name());