Skip to content

Commit 72641e8

Browse files
committed
Allow lookup of paths based on the run / uniformity
1 parent b439f58 commit 72641e8

2 files changed

Lines changed: 112 additions & 2 deletions

File tree

Framework/CCDBSupport/src/AnalysisCCDBHelpers.cxx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,16 @@
3434
#include <fmt/base.h>
3535
#include <ctime>
3636
#include <memory>
37+
#include "CCDBPathTable.h"
38+
39+
#include <string>
3740
#include <unordered_map>
41+
#include <vector>
3842

3943
O2_DECLARE_DYNAMIC_LOG(ccdb);
4044

45+
46+
4147
namespace o2::framework
4248
{
4349
// Fill valid routes. Notice that for analysis the timestamps are associated to
@@ -120,6 +126,15 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
120126
schemas.emplace_back(std::make_shared<arrow::Schema>(fields, schemaMetadata));
121127
}
122128

129+
// Parse the declared path mappings once; they are fixed for the run of the workflow.
130+
std::vector<std::vector<PathTable>> pathTables;
131+
for (auto const& schema : schemas) {
132+
auto& tables = pathTables.emplace_back();
133+
for (auto const& field : schema->fields()) {
134+
tables.push_back(PathTable::parse(*field->metadata()->Get("url")));
135+
}
136+
}
137+
123138
std::vector<std::pair<uint32_t, std::shared_ptr<arrow::FixedSizeListBuilder>>> allbuilders;
124139
allbuilders.resize([&schemas]() { size_t size = 0; for (auto& schema : schemas) { size += schema->num_fields(); }; return size; }());
125140
auto* pool = arrow::default_memory_pool();
@@ -140,7 +155,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
140155
std::unordered_map<std::string, int> bindings;
141156
fillValidRoutes(*helper, spec.outputs, bindings);
142157

143-
return adaptStateless([schemas, bindings, helper, allbuilders](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
158+
return adaptStateless([schemas, bindings, helper, allbuilders, pathTables](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
144159
O2_SIGNPOST_ID_GENERATE(sid, ccdb);
145160
O2_SIGNPOST_START(ccdb, sid, "fetchFromAnalysisCCDB", "Fetching CCDB objects for analysis%" PRIu64, (uint64_t)timingInfo.timeslice);
146161
std::ranges::for_each(allbuilders, [](auto& builder) { builder.second->Reset(); });
@@ -258,8 +273,12 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
258273
}
259274
ops.clear();
260275
int64_t timestamp = timestamps[ri];
276+
// Key the path lookup on the uniformity value; when uniformity is the
277+
// timestamp itself the mapping expresses validity intervals instead.
278+
int64_t const uniformityKey = shortCircuit ? uniformity[row] : timestamp;
279+
int fi = 0;
261280
for (auto& field : schema->fields()) {
262-
auto url = *field->metadata()->Get("url");
281+
auto const& url = pathTables[i][fi++].resolve(uniformityKey, field->name());
263282
// Time to actually populate the blob
264283
ops.push_back({
265284
.spec = spec,
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
#ifndef O2_FRAMEWORK_CCDBPATHTABLE_H_
12+
#define O2_FRAMEWORK_CCDBPATHTABLE_H_
13+
14+
#include <Framework/Logger.h>
15+
16+
#include <cstdint>
17+
#include <limits>
18+
#include <string>
19+
#include <vector>
20+
21+
namespace o2::framework
22+
{
23+
// A CCDB path may be declared either as a plain path, or as a mapping from uniformity
24+
// value to path: "lo-hi=path;lo-hi=path;fallback". Ranges are inclusive and either bound
25+
// may be omitted ("-hi=path", "lo-=path"). An entry without '=' is an explicit fallback;
26+
// without one, a value matching no range is an error rather than a silent guess.
27+
// The mapping is data, carried in the schema metadata, so the fetcher needs no code from
28+
// the task that declared the column.
29+
struct PathTable {
30+
struct Range {
31+
int64_t lo;
32+
int64_t hi;
33+
std::string path;
34+
};
35+
std::vector<Range> ranges;
36+
std::string fallback;
37+
bool hasFallback = false;
38+
39+
static PathTable parse(std::string const& spec)
40+
{
41+
PathTable table;
42+
if (spec.find('=') == std::string::npos) { // plain path, the common case
43+
table.fallback = spec;
44+
table.hasFallback = true;
45+
return table;
46+
}
47+
size_t pos = 0;
48+
while (pos <= spec.size()) {
49+
auto end = spec.find(';', pos);
50+
auto entry = spec.substr(pos, end == std::string::npos ? std::string::npos : end - pos);
51+
pos = (end == std::string::npos) ? spec.size() + 1 : end + 1;
52+
if (entry.empty()) {
53+
continue;
54+
}
55+
auto eq = entry.find('=');
56+
if (eq == std::string::npos) {
57+
table.fallback = entry;
58+
table.hasFallback = true;
59+
continue;
60+
}
61+
auto bounds = entry.substr(0, eq);
62+
auto dash = bounds.find('-');
63+
if (dash == std::string::npos) {
64+
LOGP(fatal, R"(Malformed CCDB path mapping "{}": expected "lo-hi=path")", entry);
65+
}
66+
auto loStr = bounds.substr(0, dash);
67+
auto hiStr = bounds.substr(dash + 1);
68+
table.ranges.push_back({loStr.empty() ? std::numeric_limits<int64_t>::min() : std::stoll(loStr),
69+
hiStr.empty() ? std::numeric_limits<int64_t>::max() : std::stoll(hiStr),
70+
entry.substr(eq + 1)});
71+
}
72+
return table;
73+
}
74+
75+
std::string const& resolve(int64_t key, std::string const& column) const
76+
{
77+
for (auto const& range : ranges) {
78+
if (key >= range.lo && key <= range.hi) {
79+
return range.path;
80+
}
81+
}
82+
if (!hasFallback) {
83+
LOGP(fatal, R"(No CCDB path declared for {} at uniformity value {}; the declared mapping covers no such value and has no fallback entry)",
84+
column, key);
85+
}
86+
return fallback;
87+
}
88+
};
89+
} // namespace o2::framework
90+
91+
#endif // O2_FRAMEWORK_CCDBPATHTABLE_H_

0 commit comments

Comments
 (0)