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"
@@ -109,20 +110,37 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
109110 auto it = ccdbUrls.find (m.name );
110111 fieldMetadata->Append (" url" , it != ccdbUrls.end () ? it->second : m.defaultValue .asString ());
111112 auto columnName = m.name .substr (strlen (" ccdb:" ));
112- fields.emplace_back (std::make_shared<arrow::Field>(columnName, arrow::binary_view (), false , fieldMetadata));
113+ fields.emplace_back (std::make_shared<arrow::Field>(columnName, soa::asArrowDataType< int64_t [ 3 ]> (), false , fieldMetadata));
113114 }
114115 schemas.emplace_back (std::make_shared<arrow::Schema>(fields, schemaMetadata));
115116 }
116117
118+ std::vector<std::pair<uint32_t , std::shared_ptr<arrow::FixedSizeListBuilder>>> allbuilders;
119+ allbuilders.resize ([&schemas]() { size_t size = 0 ; for (auto & schema : schemas) { size += schema->num_fields (); }; return size; }());
120+ auto * pool = arrow::default_memory_pool ();
121+
122+ int idx = 0 ;
123+ int sidx = 0 ;
124+ for (auto const & schema : schemas) {
125+ for (auto const & _ : schema->fields ()) {
126+ auto value_builder = std::make_shared<arrow::Int64Builder>();
127+ allbuilders[idx] = std::make_pair (sidx, std::make_shared<arrow::FixedSizeListBuilder>(pool, std::move (value_builder), 3 ));
128+ ++idx;
129+ }
130+ ++sidx;
131+ }
132+
117133 std::shared_ptr<CCDBFetcherHelper> helper = std::make_shared<CCDBFetcherHelper>();
118134 CCDBFetcherHelper::initialiseHelper (*helper, options);
119135 std::unordered_map<std::string, int > bindings;
120136 fillValidRoutes (*helper, spec.outputs , bindings);
121137
122- return adaptStateless ([schemas, bindings, helper](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
138+ return adaptStateless ([schemas, bindings, helper, allbuilders ](InputRecord& inputs, DataTakingContext& dtc, DataAllocator& allocator, TimingInfo& timingInfo, DataProcessingStats& stats) {
123139 O2_SIGNPOST_ID_GENERATE (sid, ccdb);
124140 O2_SIGNPOST_START (ccdb, sid, " fetchFromAnalysisCCDB" , " Fetching CCDB objects for analysis%" PRIu64, (uint64_t )timingInfo.timeslice );
125- for (auto & schema : schemas) {
141+ std::ranges::for_each (allbuilders, [](auto & builder) { builder.second ->Reset (); });
142+ for (auto i = 0U ; i < schemas.size (); ++i) {
143+ auto & schema = schemas[i];
126144 std::vector<CCDBFetcherHelper::FetchOp> ops;
127145 auto inputBinding = *schema->metadata ()->Get (" sourceTable" );
128146 auto inputMatcher = DataSpecUtils::fromString (*schema->metadata ()->Get (" sourceMatcher" ));
@@ -134,6 +152,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
134152 auto table = inputs.get <TableConsumer>(inputMatcher)->asArrowTable ();
135153 // FIXME: make the fTimestamp column configurable.
136154 auto timestampColumn = table->GetColumnByName (" fTimestamp" );
155+ auto reserveSize = timestampColumn->length ();
137156 O2_SIGNPOST_EVENT_EMIT_INFO (ccdb, sid, " fetchFromAnalysisCCDB" ,
138157 " There are %zu bindings available" , bindings.size ());
139158 for (auto & binding : bindings) {
@@ -143,9 +162,16 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
143162 }
144163 int outputRouteIndex = bindings.at (outRouteDesc);
145164 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>());
165+ auto builders = allbuilders | std::views::filter ([&i](auto const & builder) { return builder.first == i; });
166+ unsigned int numBuilders = std::ranges::count_if (allbuilders, [&i](auto const & builder) { return builder.first == i; });
167+ arrow::Status status;
168+ std::ranges::for_each (builders, [&status, &reserveSize](auto & builder) {
169+ if (reserveSize > builder.second ->capacity ()) {
170+ status &= builder.second ->Reserve (reserveSize - builder.second ->capacity ());
171+ }
172+ });
173+ if (!status.ok ()) {
174+ throw framework::runtime_error_f (" Failed to reserve arrays: " , status.ToString ().c_str ());
149175 }
150176
151177 for (auto ci = 0 ; ci < timestampColumn->num_chunks (); ++ci) {
@@ -171,15 +197,20 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
171197 O2_SIGNPOST_START (ccdb, sid, " handlingResponses" ,
172198 " Got %zu responses from server." ,
173199 responses.size ());
174- if (builders. size () != responses.size ()) {
175- LOGP (fatal, " Not enough responses (expected {}, found {})" , builders. size () , responses.size ());
200+ if (numBuilders != responses.size ()) {
201+ LOGP (fatal, " Not enough responses (expected {}, found {})" , numBuilders , responses.size ());
176202 }
177203 arrow::Status result;
178- for (size_t bi = 0 ; bi < responses.size (); bi++) {
179- auto & builder = builders[bi];
204+
205+ int bi = 0 ;
206+ for (auto & builder : builders) {
180207 auto & response = responses[bi];
181- char const * address = reinterpret_cast <char const *>(response.id .value );
182- result &= builder->Append (std::string_view (address, response.size ));
208+ result &= builder.second ->Append ();
209+ auto * value_builder = dynamic_cast <arrow::Int64Builder*>(builder.second ->value_builder ());
210+ result &= value_builder->Append (response.id .handle );
211+ result &= value_builder->Append (response.id .segment );
212+ result &= value_builder->Append (response.size );
213+ ++bi;
183214 }
184215 if (!result.ok ()) {
185216 LOGP (fatal, " Error adding results from CCDB" );
@@ -188,9 +219,7 @@ AlgorithmSpec AnalysisCCDBHelpers::fetchFromCCDB(ConfigContext const& /*ctx*/)
188219 }
189220 }
190221 arrow::ArrayVector arrays;
191- for (auto & builder : builders) {
192- arrays.push_back (*builder->Finish ());
193- }
222+ std::ranges::for_each (builders, [&arrays](auto & builder) { arrays.push_back (*builder.second ->Finish ()); });
194223 auto outTable = arrow::Table::Make (schema, arrays);
195224 auto concrete = DataSpecUtils::asConcreteDataMatcher (spec);
196225 allocator.adopt (Output{concrete.origin , concrete.description , concrete.subSpec }, outTable);
0 commit comments