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,49 @@ 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+ #if (FAIRMQ_VERSION_DEC >= 111000)
124+ std::vector<std::pair<uint32_t , std::shared_ptr<arrow::FixedSizeListBuilder>>> allbuilders;
125+ #else
126+ std::vector<std::pair<uint32_t , std::shared_ptr<arrow::BinaryViewBuilder>>> allbuilders;
127+ #endif
128+ allbuilders.resize ([&schemas]() { size_t size = 0 ; for (auto & schema : schemas) { size += schema->num_fields (); }; return size; }());
129+ auto * pool = arrow::default_memory_pool ();
130+
131+ int idx = 0 ;
132+ int sidx = 0 ;
133+ for (auto const & schema : schemas) {
134+ for (auto const & _ : schema->fields ()) {
135+ #if (FAIRMQ_VERSION_DEC >= 111000)
136+ auto value_builder = std::make_shared<arrow::Int64Builder>();
137+ allbuilders[idx] = std::make_pair (sidx, std::make_shared<arrow::FixedSizeListBuilder>(pool, std::move (value_builder), 3 ));
138+ #else
139+ allbuilders[idx] = std::make_pair (sidx, std::make_shared<arrow::BinaryViewBuilder>());
140+ #endif
141+ ++idx;
142+ }
143+ ++sidx;
144+ }
145+
117146 std::shared_ptr<CCDBFetcherHelper> helper = std::make_shared<CCDBFetcherHelper>();
118147 CCDBFetcherHelper::initialiseHelper (*helper, options);
119148 std::unordered_map<std::string, int > bindings;
120149 fillValidRoutes (*helper, spec.outputs , bindings);
121150
122- return adaptStateless ([schemas, bindings, helper](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
151+ return adaptStateless ([schemas, bindings, helper, allbuilders ](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
123152 O2_SIGNPOST_ID_GENERATE (sid, ccdb);
124153 O2_SIGNPOST_START (ccdb, sid, " fetchFromAnalysisCCDB" , " Fetching CCDB objects for analysis%" PRIu64, (uint64_t )timingInfo.timeslice );
125- for (auto & schema : schemas) {
154+ std::ranges::for_each (allbuilders, [](auto & builder) { builder.second ->Reset (); });
155+ for (auto i = 0U ; i < schemas.size (); ++i) {
156+ auto & schema = schemas[i];
126157 std::vector<CCDBFetcherHelper::FetchOp> ops;
127158 auto inputBinding = *schema->metadata ()->Get (" sourceTable" );
128159 auto inputMatcher = DataSpecUtils::fromString (*schema->metadata ()->Get (" sourceMatcher" ));
@@ -134,6 +165,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
134165 auto table = inputs.get <TableConsumer>(inputMatcher)->asArrowTable ();
135166 // FIXME: make the fTimestamp column configurable.
136167 auto timestampColumn = table->GetColumnByName (" fTimestamp" );
168+ auto reserveSize = timestampColumn->length ();
137169 O2_SIGNPOST_EVENT_EMIT_INFO (ccdb, sid, " fetchFromAnalysisCCDB" ,
138170 " There are %zu bindings available" , bindings.size ());
139171 for (auto & binding : bindings) {
@@ -143,9 +175,16 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
143175 }
144176 int outputRouteIndex = bindings.at (outRouteDesc);
145177 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>());
178+ auto builders = allbuilders | std::views::filter ([&i](auto const & builder) { return builder.first == i; });
179+ unsigned int numBuilders = std::ranges::count_if (allbuilders, [&i](auto const & builder) { return builder.first == i; });
180+ arrow::Status status;
181+ std::ranges::for_each (builders, [&status, &reserveSize](auto & builder) {
182+ if (reserveSize > builder.second ->capacity ()) {
183+ status &= builder.second ->Reserve (reserveSize - builder.second ->capacity ());
184+ }
185+ });
186+ if (!status.ok ()) {
187+ throw framework::runtime_error_f (" Failed to reserve arrays: " , status.ToString ().c_str ());
149188 }
150189
151190 for (auto ci = 0 ; ci < timestampColumn->num_chunks (); ++ci) {
@@ -171,15 +210,25 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
171210 O2_SIGNPOST_START (ccdb, sid, " handlingResponses" ,
172211 " Got %zu responses from server." ,
173212 responses.size ());
174- if (builders. size () != responses.size ()) {
175- LOGP (fatal, " Not enough responses (expected {}, found {})" , builders. size () , responses.size ());
213+ if (numBuilders != responses.size ()) {
214+ LOGP (fatal, " Not enough responses (expected {}, found {})" , numBuilders , responses.size ());
176215 }
177216 arrow::Status result;
178- for (size_t bi = 0 ; bi < responses.size (); bi++) {
179- auto & builder = builders[bi];
217+
218+ int bi = 0 ;
219+ for (auto & builder : builders) {
180220 auto & response = responses[bi];
221+ #if (FAIRMQ_VERSION_DEC >= 111000)
222+ result &= builder.second ->Append ();
223+ auto * value_builder = dynamic_cast <arrow::Int64Builder*>(builder.second ->value_builder ());
224+ result &= value_builder->Append (response.id .handle );
225+ result &= value_builder->Append (response.id .segment );
226+ result &= value_builder->Append (response.size );
227+ #else
181228 char const * address = reinterpret_cast <char const *>(response.id .value );
182- result &= builder->Append (std::string_view (address, response.size ));
229+ result &= builder.second ->Append (std::string_view (address, response.size ));
230+ #endif
231+ ++bi;
183232 }
184233 if (!result.ok ()) {
185234 LOGP (fatal, " Error adding results from CCDB" );
@@ -188,9 +237,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
188237 }
189238 }
190239 arrow::ArrayVector arrays;
191- for (auto & builder : builders) {
192- arrays.push_back (*builder->Finish ());
193- }
240+ std::ranges::for_each (builders, [&arrays](auto & builder) { arrays.push_back (*builder.second ->Finish ()); });
194241 auto outTable = arrow::Table::Make (schema, arrays);
195242 auto concrete = DataSpecUtils::asConcreteDataMatcher (spec);
196243 allocator.adopt (Output{concrete.origin , concrete.description , concrete.subSpec }, outTable);
0 commit comments