1111
1212#include " AnalysisCCDBHelpers.h"
1313#include " CCDBFetcherHelper.h"
14+ #include " Framework/ArrowTypes.h"
1415#include " Framework/DataProcessingStats.h"
1516#include " Framework/DeviceSpec.h"
1617#include " Framework/TimingInfo.h"
2223#include " Framework/DanglingEdgesContext.h"
2324#include " Framework/ConfigContext.h"
2425#include " Framework/ConfigParamsHelper.h"
26+ #include < fairmq/Version.h>
2527#include < arrow/array/builder_binary.h>
2628#include < arrow/type.h>
2729#include < arrow/type_fwd.h>
@@ -109,20 +111,45 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
109111 auto it = ccdbUrls.find (m.name );
110112 fieldMetadata->Append (" url" , it != ccdbUrls.end () ? it->second : m.defaultValue .asString ());
111113 auto columnName = m.name .substr (strlen (" ccdb:" ));
114+ #if (FAIRMQ_VERSION_DEC >= 111000)
115+ fields.emplace_back (std::make_shared<arrow::Field>(columnName, soa::asArrowDataType<int64_t [3 ]>(), false , fieldMetadata));
116+ #else
112117 fields.emplace_back (std::make_shared<arrow::Field>(columnName, arrow::binary_view (), false , fieldMetadata));
118+ #endif
113119 }
114120 schemas.emplace_back (std::make_shared<arrow::Schema>(fields, schemaMetadata));
115121 }
116122
123+ std::vector<std::pair<uint32_t , std::shared_ptr<arrow::FixedSizeListBuilder>>> allbuilders;
124+ allbuilders.resize ([&schemas]() { size_t size = 0 ; for (auto & schema : schemas) { size += schema->num_fields (); }; return size; }());
125+ auto * pool = arrow::default_memory_pool ();
126+
127+ int idx = 0 ;
128+ int sidx = 0 ;
129+ for (auto const & schema : schemas) {
130+ for (auto const & _ : schema->fields ()) {
131+ #if (FAIRMQ_VERSION_DEC >= 111000)
132+ auto value_builder = std::make_shared<arrow::Int64Builder>();
133+ allbuilders[idx] = std::make_pair (sidx, std::make_shared<arrow::FixedSizeListBuilder>(pool, std::move (value_builder), 3 ));
134+ #else
135+ allbuilders[idx] = std::make_pair (sidx, std::make_shared<arrow::BinaryViewBuilder>());
136+ #endif
137+ ++idx;
138+ }
139+ ++sidx;
140+ }
141+
117142 std::shared_ptr<CCDBFetcherHelper> helper = std::make_shared<CCDBFetcherHelper>();
118143 CCDBFetcherHelper::initialiseHelper (*helper, options);
119144 std::unordered_map<std::string, int > bindings;
120145 fillValidRoutes (*helper, spec.outputs , bindings);
121146
122- return adaptStateless ([schemas, bindings, helper](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
147+ return adaptStateless ([schemas, bindings, helper, allbuilders ](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
123148 O2_SIGNPOST_ID_GENERATE (sid, ccdb);
124149 O2_SIGNPOST_START (ccdb, sid, " fetchFromAnalysisCCDB" , " Fetching CCDB objects for analysis%" PRIu64, (uint64_t )timingInfo.timeslice );
125- for (auto & schema : schemas) {
150+ std::ranges::for_each (allbuilders, [](auto & builder) { builder.second ->Reset (); });
151+ for (auto i = 0U ; i < schemas.size (); ++i) {
152+ auto & schema = schemas[i];
126153 std::vector<CCDBFetcherHelper::FetchOp> ops;
127154 auto inputBinding = *schema->metadata ()->Get (" sourceTable" );
128155 auto inputMatcher = DataSpecUtils::fromString (*schema->metadata ()->Get (" sourceMatcher" ));
@@ -134,6 +161,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
134161 auto table = inputs.get <TableConsumer>(inputMatcher)->asArrowTable ();
135162 // FIXME: make the fTimestamp column configurable.
136163 auto timestampColumn = table->GetColumnByName (" fTimestamp" );
164+ auto reserveSize = timestampColumn->length ();
137165 O2_SIGNPOST_EVENT_EMIT_INFO (ccdb, sid, " fetchFromAnalysisCCDB" ,
138166 " There are %zu bindings available" , bindings.size ());
139167 for (auto & binding : bindings) {
@@ -143,9 +171,16 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
143171 }
144172 int outputRouteIndex = bindings.at (outRouteDesc);
145173 auto & spec = helper->routes [outputRouteIndex].matcher ;
146- std::vector<std::shared_ptr<arrow::BinaryViewBuilder>> builders;
147- for (auto const & _ : schema->fields ()) {
148- builders.emplace_back (std::make_shared<arrow::BinaryViewBuilder>());
174+ auto builders = allbuilders | std::views::filter ([&i](auto const & builder) { return builder.first == i; });
175+ unsigned int numBuilders = std::ranges::count_if (allbuilders, [&i](auto const & builder) { return builder.first == i; });
176+ arrow::Status status;
177+ std::ranges::for_each (builders, [&status, &reserveSize](auto & builder) {
178+ if (reserveSize > builder.second ->capacity ()) {
179+ status &= builder.second ->Reserve (reserveSize - builder.second ->capacity ());
180+ }
181+ });
182+ if (!status.ok ()) {
183+ throw framework::runtime_error_f (" Failed to reserve arrays: " , status.ToString ().c_str ());
149184 }
150185
151186 for (auto ci = 0 ; ci < timestampColumn->num_chunks (); ++ci) {
@@ -171,15 +206,25 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
171206 O2_SIGNPOST_START (ccdb, sid, " handlingResponses" ,
172207 " Got %zu responses from server." ,
173208 responses.size ());
174- if (builders. size () != responses.size ()) {
175- LOGP (fatal, " Not enough responses (expected {}, found {})" , builders. size () , responses.size ());
209+ if (numBuilders != responses.size ()) {
210+ LOGP (fatal, " Not enough responses (expected {}, found {})" , numBuilders , responses.size ());
176211 }
177212 arrow::Status result;
178- for (size_t bi = 0 ; bi < responses.size (); bi++) {
179- auto & builder = builders[bi];
213+
214+ int bi = 0 ;
215+ for (auto & builder : builders) {
180216 auto & response = responses[bi];
217+ #if (FAIRMQ_VERSION_DEC >= 111000)
218+ result &= builder.second ->Append ();
219+ auto * value_builder = dynamic_cast <arrow::Int64Builder*>(builder.second ->value_builder ());
220+ result &= value_builder->Append (response.id .handle );
221+ result &= value_builder->Append (response.id .segment );
222+ result &= value_builder->Append (response.size );
223+ #else
181224 char const * address = reinterpret_cast <char const *>(response.id .value );
182225 result &= builder->Append (std::string_view (address, response.size ));
226+ #endif
227+ ++bi;
183228 }
184229 if (!result.ok ()) {
185230 LOGP (fatal, " Error adding results from CCDB" );
@@ -188,9 +233,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
188233 }
189234 }
190235 arrow::ArrayVector arrays;
191- for (auto & builder : builders) {
192- arrays.push_back (*builder->Finish ());
193- }
236+ std::ranges::for_each (builders, [&arrays](auto & builder) { arrays.push_back (*builder.second ->Finish ()); });
194237 auto outTable = arrow::Table::Make (schema, arrays);
195238 auto concrete = DataSpecUtils::asConcreteDataMatcher (spec);
196239 allocator.adopt (Output{concrete.origin , concrete.description , concrete.subSpec }, outTable);
0 commit comments