Skip to content

Commit 13071e7

Browse files
committed
DPL: allow narrowing of large joins
This allows narrowing of large joins when they are not strictly necessary, allowing to simplify iteration and reducing the scope of helper functions and alikes.
1 parent 290b414 commit 13071e7

2 files changed

Lines changed: 86 additions & 0 deletions

File tree

Framework/Core/include/Framework/ASoA.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,6 +2308,28 @@ class Table
23082308
template <uint32_t D, soa::is_column... C>
23092309
using InPlaceTable = Table<o2::aod::Hash<"TEST"_h>, o2::aod::Hash<D>, o2::aod::Hash<"TEST"_h>, C...>;
23102310

2311+
template <typename Narrow>
2312+
std::shared_ptr<arrow::Table> projectColumns(std::shared_ptr<arrow::Table> const& src)
2313+
{
2314+
auto indices = []<typename... C>(framework::pack<C...>, std::shared_ptr<arrow::Schema> const& sch) {
2315+
return std::vector<int>{sch->GetFieldIndex(C::columnLabel())...};
2316+
}(typename Narrow::persistent_columns_t{}, src->schema());
2317+
return src->SelectColumns(indices).ValueOrDie();
2318+
}
2319+
2320+
template <typename Narrow, is_table T>
2321+
requires(!is_filtered_table<T>)
2322+
Narrow as_table(T const& wide)
2323+
{
2324+
return Narrow{projectColumns<Narrow>(wide.asArrowTable()), wide.offset()};
2325+
}
2326+
2327+
template <typename Narrow, is_filtered_table T>
2328+
soa::Filtered<Narrow> as_table(T const& wide)
2329+
{
2330+
return soa::Filtered<Narrow>({projectColumns<Narrow>(wide.asArrowTable())}, wide.getSelectedRows(), wide.offset());
2331+
}
2332+
23112333
void getterNotFound(const char* targetColumnLabel);
23122334
void emptyColumnLabel();
23132335

Framework/Core/test/test_ASoA.cxx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,70 @@ TEST_CASE("TestJoinedTables")
320320
}
321321
}
322322

323+
TEST_CASE("TestAsTableProjection")
324+
{
325+
TableBuilder builderX;
326+
auto rowWriterX = builderX.persist<int32_t>({"fX"});
327+
for (int i = 0; i < 8; ++i) {
328+
rowWriterX(0, i);
329+
}
330+
auto tableX = builderX.finalize();
331+
332+
TableBuilder builderY;
333+
auto rowWriterY = builderY.persist<int32_t>({"fY"});
334+
for (int i = 0; i < 8; ++i) {
335+
rowWriterY(0, 7 - i);
336+
}
337+
auto tableY = builderY.finalize();
338+
339+
TableBuilder builderZ;
340+
auto rowWriterZ = builderZ.persist<int32_t>({"fZ"});
341+
for (int i = 0; i < 8; ++i) {
342+
rowWriterZ(0, 8);
343+
}
344+
auto tableZ = builderZ.finalize();
345+
346+
using TestX = InPlaceTable<"A0"_h, o2::aod::test::X>;
347+
using TestY = InPlaceTable<"A1"_h, o2::aod::test::Y>;
348+
using TestZ = InPlaceTable<"A2"_h, o2::aod::test::Z>;
349+
using Wide = Join<TestX, TestY, TestZ>;
350+
351+
Wide wide{{tableX, tableY, tableZ}, 0};
352+
REQUIRE(wide.asArrowTable()->num_columns() == 3);
353+
354+
// Project the wide join onto just the X table: the resulting arrow table
355+
// shares the data but exposes a single column, and iteration sees only x.
356+
auto narrow = as_table<TestX>(wide);
357+
REQUIRE(narrow.asArrowTable()->num_columns() == 1);
358+
REQUIRE(narrow.size() == 8);
359+
int sum = 0;
360+
for (auto& r : narrow) {
361+
sum += r.x();
362+
}
363+
REQUIRE(sum == (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7));
364+
365+
// Projecting onto two of the three tables keeps two columns.
366+
auto narrow2 = as_table<Join<TestX, TestY>>(wide);
367+
REQUIRE(narrow2.asArrowTable()->num_columns() == 2);
368+
for (auto& r : narrow2) {
369+
REQUIRE(7 == r.x() + r.y());
370+
}
371+
372+
// Filtered projection: the selection carries over to the narrow table, so the
373+
// narrow view iterates exactly the selected rows of the projected column.
374+
Filtered<Wide> wideF{{tableX, tableY, tableZ}, SelectionVector{1, 3, 5}, 0};
375+
auto narrowF = as_table<TestX>(wideF);
376+
REQUIRE(narrowF.asArrowTable()->num_columns() == 1);
377+
int sumF = 0;
378+
int nF = 0;
379+
for (auto& r : narrowF) {
380+
sumF += r.x();
381+
++nF;
382+
}
383+
REQUIRE(nF == 3);
384+
REQUIRE(sumF == (1 + 3 + 5));
385+
}
386+
323387
TEST_CASE("TestConcatTables")
324388
{
325389
TableBuilder builderA;

0 commit comments

Comments
 (0)