From 2e401ed1edbde52df7f8ae100ecd0fcd4b596832 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Fri, 8 Aug 2025 09:16:26 +0200 Subject: [PATCH 1/2] WIP DPL Analysis: support BinaryView The idea is to be able to have BinaryViews on top of the CCDB object blobs which are already cached in shared memory, so that we can have a simple table with rows of the kind: (timestamp, blob-requested-ccdb-object-2, blob-requested-ccdb-object-2) which then can be joined via the timestamp to provide access to the requested CCDB Object. Filling of the table via TableBuilder seems to work, retrieving the blobs currently crashes. --- Framework/Core/include/Framework/ArrowTypes.h | 5 +++ .../Core/include/Framework/TableBuilder.h | 34 ++++++++++++++++++- Framework/Core/test/test_TableBuilder.cxx | 32 +++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/ArrowTypes.h b/Framework/Core/include/Framework/ArrowTypes.h index 69946b6f35a50..6fd70113fede7 100644 --- a/Framework/Core/include/Framework/ArrowTypes.h +++ b/Framework/Core/include/Framework/ArrowTypes.h @@ -12,6 +12,7 @@ #ifndef O2_FRAMEWORK_ARROWTYPES_H #define O2_FRAMEWORK_ARROWTYPES_H #include "arrow/type_fwd.h" +#include namespace o2::soa { @@ -62,6 +63,10 @@ template <> struct arrow_array_for { using type = arrow::DoubleArray; }; +template <> +struct arrow_array_for> { + using type = arrow::BinaryViewArray; +}; template struct arrow_array_for { using type = arrow::FixedSizeListArray; diff --git a/Framework/Core/include/Framework/TableBuilder.h b/Framework/Core/include/Framework/TableBuilder.h index eb56791acfd3c..0eaaa2bc1f949 100644 --- a/Framework/Core/include/Framework/TableBuilder.h +++ b/Framework/Core/include/Framework/TableBuilder.h @@ -98,6 +98,7 @@ O2_ARROW_STL_CONVERSION(long unsigned, UInt64Type) O2_ARROW_STL_CONVERSION(float, FloatType) O2_ARROW_STL_CONVERSION(double, DoubleType) O2_ARROW_STL_CONVERSION(std::string, StringType) +O2_ARROW_STL_CONVERSION(std::span, BinaryViewType) } // namespace detail void addLabelToSchema(std::shared_ptr& schema, const char* label); @@ -274,6 +275,29 @@ struct BuilderMaker { } }; +template <> +struct BuilderMaker> { + using FillType = std::span; + using STLValueType = std::span; + using ArrowType = typename detail::ConversionTraits>::ArrowType; + using BuilderType = typename arrow::TypeTraits::BuilderType; + + static std::unique_ptr make(arrow::MemoryPool* pool) + { + return std::make_unique(pool); + } + + static std::shared_ptr make_datatype() + { + return arrow::TypeTraits::type_singleton(); + } + + static arrow::Status append(BuilderType& builder, std::span value) + { + return builder.Append((char*)value.data(), (int64_t)value.size()); + } +}; + template struct BuilderMaker> { using FillType = std::pair; @@ -338,6 +362,7 @@ struct BuilderMaker { } }; + template struct BuilderMaker> { using FillType = T*; @@ -422,6 +447,13 @@ struct DirectInsertion { return builder->Append(value); } + template + requires std::same_as, T> + arrow::Status append(BUILDER& builder, T value) + { + return builder->Append((char*)value.data(), (int64_t)value.size()); + } + template arrow::Status flush(BUILDER&) { @@ -569,7 +601,7 @@ template using IndexedHoldersTuple = decltype(makeHolderTypes()); template -concept ShouldNotDeconstruct = std::is_bounded_array_v || std::is_arithmetic_v || framework::is_base_of_template_v; +concept ShouldNotDeconstruct = std::is_bounded_array_v || std::is_arithmetic_v || framework::is_base_of_template_v || std::same_as, T>; /// Helper class which creates a lambda suitable for building /// an arrow table from a tuple. This can be used, for example diff --git a/Framework/Core/test/test_TableBuilder.cxx b/Framework/Core/test/test_TableBuilder.cxx index 00cbbbc59b725..a42fe01511892 100644 --- a/Framework/Core/test/test_TableBuilder.cxx +++ b/Framework/Core/test/test_TableBuilder.cxx @@ -19,6 +19,9 @@ #include #include +#include +#include + using namespace o2::framework; // We use a different namespace to avoid clashes with the @@ -27,10 +30,12 @@ namespace test2 { DECLARE_SOA_COLUMN_FULL(X, x, uint64_t, "x"); DECLARE_SOA_COLUMN_FULL(Y, y, uint64_t, "y"); +DECLARE_SOA_COLUMN_FULL(Blob, blob, std::span, "blob"); DECLARE_SOA_COLUMN_FULL(Pos, pos, int[4], "pos"); } // namespace test2 using TestTable = o2::soa::InPlaceTable<0, test2::X, test2::Y>; +using SpanTable = o2::soa::InPlaceTable<0, test2::Blob>; using ArrayTable = o2::soa::InPlaceTable<0, test2::Pos>; TEST_CASE("TestTableBuilder") @@ -189,6 +194,32 @@ TEST_CASE("TestTableBuilderMore") REQUIRE(table->schema()->field(3)->type()->id() == arrow::boolean()->id()); } +TEST_CASE("TestSpan") +{ + TableBuilder builder; + std::vector buffer{10, std::byte{'c'}}; + std::vector buffer1{10, std::byte{'a'}}; + + auto rowWriter = builder.persist>({"blob"}); + rowWriter(0, std::span(buffer)); + rowWriter(0, std::span(buffer)); + rowWriter(0, std::span(buffer1.data(), 3)); + rowWriter(0, std::span(buffer1.data(), 1)); + auto table = builder.finalize(); + + REQUIRE(table->num_columns() == 1); + REQUIRE(table->num_rows() == 4); + REQUIRE(table->schema()->field(0)->name() == "blob"); + REQUIRE(table->schema()->field(0)->type()->id() == arrow::binary_view()->id()); + + std::cout << table->ToString() << std::endl; + + auto readBack = SpanTable{table}; + for (auto& row : readBack) { + std::cout << row.blob().size() << std::endl; + } +} + TEST_CASE("TestSoAIntegration") { TableBuilder builder; @@ -240,6 +271,7 @@ TEST_CASE("TestPodInjestion") } } + TEST_CASE("TestColumnCount") { struct Foo { From 6ea5056f061db7d42a58cf5cc20464ead20a72a8 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Fri, 8 Aug 2025 07:20:23 +0000 Subject: [PATCH 2/2] Please consider the following formatting changes --- Framework/Core/include/Framework/TableBuilder.h | 1 - Framework/Core/test/test_TableBuilder.cxx | 1 - 2 files changed, 2 deletions(-) diff --git a/Framework/Core/include/Framework/TableBuilder.h b/Framework/Core/include/Framework/TableBuilder.h index 0eaaa2bc1f949..74395a2680077 100644 --- a/Framework/Core/include/Framework/TableBuilder.h +++ b/Framework/Core/include/Framework/TableBuilder.h @@ -362,7 +362,6 @@ struct BuilderMaker { } }; - template struct BuilderMaker> { using FillType = T*; diff --git a/Framework/Core/test/test_TableBuilder.cxx b/Framework/Core/test/test_TableBuilder.cxx index a42fe01511892..b6fc96e377fdb 100644 --- a/Framework/Core/test/test_TableBuilder.cxx +++ b/Framework/Core/test/test_TableBuilder.cxx @@ -271,7 +271,6 @@ TEST_CASE("TestPodInjestion") } } - TEST_CASE("TestColumnCount") { struct Foo {