Skip to content

Commit 2cfdca7

Browse files
committed
DPL Analysis: consolidate slicing methods
1 parent 42a8244 commit 2cfdca7

1 file changed

Lines changed: 117 additions & 167 deletions

File tree

  • Framework/Core/include/Framework

Framework/Core/include/Framework/ASoA.h

Lines changed: 117 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,106 @@ class Filtered;
11781178

11791179
SelectionVector selectionToVector(gandiva::Selection const& sel);
11801180

1181+
template <typename T, typename C>
1182+
auto doSliceBy(T const* table, o2::framework::Preslice<C> const& container, int value)
1183+
{
1184+
if constexpr (o2::soa::is_binding_compatible_v<C, T>()) {
1185+
std::shared_ptr<arrow::Table> out;
1186+
uint64_t offset = 0;
1187+
auto status = container.getSliceFor(value, table->asArrowTable(), out, offset);
1188+
auto t = typename T::self_t({out}, offset);
1189+
table->copyIndexBindings(t);
1190+
t.bindInternalIndicesTo(table);
1191+
return t;
1192+
} else {
1193+
static_assert(o2::framework::always_static_assert_v<C>, "Wrong Preslice<> entry used: incompatible type");
1194+
}
1195+
}
1196+
1197+
template <typename T, typename C>
1198+
auto doSliceBy(T const* table, o2::framework::PresliceUnsorted<C> const& container, int value)
1199+
{
1200+
if constexpr (o2::soa::is_binding_compatible_v<C, T>()) {
1201+
auto selection = container.getSliceFor(value);
1202+
auto t = soa::Filtered<T>({table->asArrowTable()}, selection);
1203+
table->copyIndexBindings(t);
1204+
t.bindInternalIndicesTo(table);
1205+
return t;
1206+
} else {
1207+
static_assert(o2::framework::always_static_assert_v<C>, "Wrong Preslice<> entry used: incompatible type");
1208+
}
1209+
}
1210+
1211+
template <typename T>
1212+
auto makeEmptyFiltered(std::shared_ptr<arrow::Table> slice, T const* original)
1213+
{
1214+
typename T::self_t fresult{{slice}, SelectionVector{}, 0};
1215+
original->copyIndexBindings(fresult);
1216+
return fresult;
1217+
}
1218+
1219+
template <typename T>
1220+
auto prepareFilteredSlice(T const* table, std::shared_ptr<arrow::Table> slice, uint64_t offset)
1221+
{
1222+
if (offset >= table->tableSize()) {
1223+
return makeEmptyFiltered(slice, table);
1224+
}
1225+
auto start = offset;
1226+
auto end = start + slice->num_rows();
1227+
auto mSelectedRows = table->getSelectedRows();
1228+
auto start_iterator = std::lower_bound(mSelectedRows.begin(), mSelectedRows.end(), start);
1229+
auto stop_iterator = std::lower_bound(start_iterator, mSelectedRows.end(), end);
1230+
SelectionVector slicedSelection{start_iterator, stop_iterator};
1231+
std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
1232+
[&start](int64_t idx) {
1233+
return idx - static_cast<int64_t>(start);
1234+
});
1235+
typename T::self_t fresult{{slice}, std::move(slicedSelection), start};
1236+
table->copyIndexBindings(fresult);
1237+
return fresult;
1238+
}
1239+
1240+
template <typename T, typename C>
1241+
auto doFilteredSliceBy(T const* table, o2::framework::Preslice<C> const& container, int value)
1242+
{
1243+
if constexpr (o2::soa::is_binding_compatible_v<C, T>()) {
1244+
uint64_t offset = 0;
1245+
std::shared_ptr<arrow::Table> slice = nullptr;
1246+
auto status = container.getSliceFor(value, table->asArrowTable(), slice, offset);
1247+
return prepareFilteredSlice(table, slice, offset);
1248+
} else {
1249+
static_assert(o2::framework::always_static_assert_v<C>, "Wrong Preslice<> entry used: incompatible type");
1250+
}
1251+
}
1252+
1253+
template <typename T>
1254+
auto doSliceByCached(T const* table, framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache)
1255+
{
1256+
auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<T>(node.name), node.name});
1257+
auto [offset, count] = localCache.getSliceFor(value);
1258+
auto t = typename T::self_t({table->asArrowTable()->Slice(static_cast<uint64_t>(offset), count)}, static_cast<uint64_t>(offset));
1259+
table->copyIndexBindings(t);
1260+
return t;
1261+
}
1262+
1263+
template <typename T>
1264+
auto doFilteredSliceByCached(T const* table, framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache)
1265+
{
1266+
auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<T>(node.name), node.name});
1267+
auto [offset, count] = localCache.getSliceFor(value);
1268+
auto slice = table->asArrowTable()->Slice(static_cast<uint64_t>(offset), count);
1269+
return prepareFilteredSlice(table, slice, offset);
1270+
}
1271+
1272+
template <typename T>
1273+
auto doSliceByCachedUnsorted(T const* table, framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache)
1274+
{
1275+
auto localCache = cache.ptr->getCacheUnsortedFor({o2::soa::getLabelFromTypeForKey<T>(node.name), node.name});
1276+
auto t = Filtered<T>({table->asArrowTable()}, localCache.getSliceFor(value));
1277+
table->copyIndexBindings(t);
1278+
return t;
1279+
}
1280+
11811281
template <typename T>
11821282
auto select(T const& t, framework::expressions::Filter const& f)
11831283
{
@@ -1480,36 +1580,13 @@ class Table
14801580
template <typename T1>
14811581
auto sliceBy(o2::framework::Preslice<T1> const& container, int value) const
14821582
{
1483-
if constexpr (o2::soa::is_binding_compatible_v<T1, std::decay_t<decltype(*this)>>()) {
1484-
std::shared_ptr<arrow::Table> out;
1485-
uint64_t offset = 0;
1486-
auto status = container.getSliceFor(value, mTable, out, offset);
1487-
auto t = table_t({out}, offset);
1488-
copyIndexBindings(t);
1489-
t.bindInternalIndicesTo(this);
1490-
return t;
1491-
} else {
1492-
static_assert(o2::framework::always_static_assert_v<T1>, "Wrong Preslice<> entry used: incompatible type");
1493-
}
1583+
return doSliceBy(this, container, value);
14941584
}
14951585

14961586
template <typename T1>
14971587
auto sliceBy(o2::framework::PresliceUnsorted<T1> const& container, int value) const
14981588
{
1499-
if constexpr (o2::soa::is_binding_compatible_v<T1, std::decay_t<decltype(*this)>>()) {
1500-
auto selection = container.getSliceFor(value);
1501-
auto t = soa::Filtered<table_t>({this->asArrowTable()}, selection);
1502-
copyIndexBindings(t);
1503-
t.bindInternalIndicesTo(this);
1504-
return t;
1505-
} else {
1506-
static_assert(o2::framework::always_static_assert_v<T1>, "Wrong Preslice<> entry used: incompatible type");
1507-
}
1508-
}
1509-
1510-
auto slice(uint64_t start, uint64_t end) const
1511-
{
1512-
return rawSlice(start, end);
1589+
return doSliceBy(this, container, value);
15131590
}
15141591

15151592
auto rawSlice(uint64_t start, uint64_t end) const
@@ -2483,6 +2560,7 @@ struct Join : JoinBase<Ts...> {
24832560
using base::bindExternalIndices;
24842561
using base::bindInternalIndicesTo;
24852562

2563+
using self_t = Join<Ts...>;
24862564
using table_t = base;
24872565
using persistent_columns_t = typename table_t::persistent_columns_t;
24882566
using iterator = typename table_t::template RowView<Join<Ts...>, Ts...>;
@@ -2492,49 +2570,24 @@ struct Join : JoinBase<Ts...> {
24922570

24932571
auto sliceByCached(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
24942572
{
2495-
auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
2496-
auto [offset, count] = localCache.getSliceFor(value);
2497-
auto t = Join<Ts...>({this->asArrowTable()->Slice(static_cast<uint64_t>(offset), count)}, static_cast<uint64_t>(offset));
2498-
this->copyIndexBindings(t);
2499-
return t;
2573+
return doSliceByCached(this, node, value, cache);
25002574
}
25012575

25022576
auto sliceByCachedUnsorted(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
25032577
{
2504-
auto localCache = cache.ptr->getCacheUnsortedFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
2505-
auto t = Filtered<Join<Ts...>>({this->asArrowTable()}, localCache.getSliceFor(value));
2506-
this->copyIndexBindings(t);
2507-
return t;
2578+
return doSliceByCachedUnsorted(this, node, value, cache);
25082579
}
25092580

25102581
template <typename T1>
25112582
auto sliceBy(o2::framework::Preslice<T1> const& container, int value) const
25122583
{
2513-
if constexpr (o2::soa::is_binding_compatible_v<T1, std::decay_t<decltype(*this)>>()) {
2514-
std::shared_ptr<arrow::Table> out;
2515-
uint64_t offset = 0;
2516-
auto status = container.getSliceFor(value, this->asArrowTable(), out, offset);
2517-
auto t = table_t({out}, offset);
2518-
this->copyIndexBindings(t);
2519-
t.bindInternalIndicesTo(this);
2520-
return t;
2521-
} else {
2522-
static_assert(o2::framework::always_static_assert_v<T1>, "Wrong Preslice<> entry used: incompatible type");
2523-
}
2584+
return doSliceBy(this, container, value);
25242585
}
25252586

25262587
template <typename T1>
25272588
auto sliceBy(o2::framework::PresliceUnsorted<T1> const& container, int value) const
25282589
{
2529-
if constexpr (o2::soa::is_binding_compatible_v<T1, std::decay_t<decltype(*this)>>()) {
2530-
auto selection = container.getSliceFor(value);
2531-
auto t = soa::Filtered<std::decay_t<decltype(*this)>>({this->asArrowTable()}, selection);
2532-
this->copyIndexBindings(t);
2533-
t.bindInternalIndicesTo(this);
2534-
return t;
2535-
} else {
2536-
static_assert(o2::framework::always_static_assert_v<T1>, "Wrong Preslice<> entry used: incompatible type");
2537-
}
2590+
return doSliceBy(this, container, value);
25382591
}
25392592

25402593
template <typename T>
@@ -2753,78 +2806,28 @@ class FilteredBase : public T
27532806

27542807
auto sliceByCached(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
27552808
{
2756-
auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
2757-
auto [offset, count] = localCache.getSliceFor(value);
2758-
auto slice = this->asArrowTable()->Slice(static_cast<uint64_t>(offset), count);
2759-
if (offset >= this->tableSize()) {
2760-
self_t fresult{{slice}, SelectionVector{}, 0}; // empty slice
2761-
this->copyIndexBindings(fresult);
2762-
return fresult;
2763-
}
2764-
auto start = static_cast<uint64_t>(offset);
2765-
auto end = start + slice->num_rows();
2766-
auto start_iterator = std::lower_bound(mSelectedRows.begin(), mSelectedRows.end(), start);
2767-
auto stop_iterator = std::lower_bound(start_iterator, mSelectedRows.end(), end);
2768-
SelectionVector slicedSelection{start_iterator, stop_iterator};
2769-
std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
2770-
[&start](int64_t idx) {
2771-
return idx - static_cast<int64_t>(start);
2772-
});
2773-
self_t fresult{{slice}, std::move(slicedSelection), start};
2774-
this->copyIndexBindings(fresult);
2775-
return fresult;
2809+
return doFilteredSliceByCached(this, node, value, cache);
27762810
}
27772811

27782812
auto sliceByCachedUnsorted(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
27792813
{
2780-
auto localCache = cache.ptr->getCacheUnsortedFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
2781-
auto t = std::decay_t<decltype(*this)>{{this->asArrowTable()}, localCache.getSliceFor(value)};
2814+
auto t = doSliceByCachedUnsorted(this, node, value, cache);
27822815
t.intersectWithSelection(this->getSelectedRows());
2783-
this->copyIndexBindings(t);
27842816
return t;
27852817
}
27862818

27872819
template <typename T1>
27882820
auto sliceBy(o2::framework::Preslice<T1> const& container, int value) const
27892821
{
2790-
if constexpr (o2::soa::is_binding_compatible_v<T1, std::decay_t<decltype(*this)>>()) {
2791-
uint64_t offset = 0;
2792-
std::shared_ptr<arrow::Table> result = nullptr;
2793-
auto status = container.getSliceFor(value, this->asArrowTable(), result, offset);
2794-
if (offset >= static_cast<uint64_t>(this->tableSize())) {
2795-
self_t fresult{{result}, SelectionVector{}, 0}; // empty slice
2796-
this->copyIndexBindings(fresult);
2797-
return fresult;
2798-
}
2799-
auto start = offset;
2800-
auto end = start + result->num_rows();
2801-
auto start_iterator = std::lower_bound(mSelectedRows.begin(), mSelectedRows.end(), start);
2802-
auto stop_iterator = std::lower_bound(start_iterator, mSelectedRows.end(), end);
2803-
SelectionVector slicedSelection{start_iterator, stop_iterator};
2804-
std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
2805-
[&start](int64_t idx) {
2806-
return idx - static_cast<int64_t>(start);
2807-
});
2808-
self_t fresult{{result}, std::move(slicedSelection), start};
2809-
this->copyIndexBindings(fresult);
2810-
return fresult;
2811-
} else {
2812-
static_assert(o2::framework::always_static_assert_v<T1>, "Wrong Preslice<> entry used: incompatible type");
2813-
}
2822+
return doFilteredSliceBy(this, container, value);
28142823
}
28152824

28162825
template <typename T1>
28172826
auto sliceBy(o2::framework::PresliceUnsorted<T1> const& container, int value) const
28182827
{
2819-
if constexpr (o2::soa::is_binding_compatible_v<T1, std::decay_t<decltype(*this)>>()) {
2820-
auto selection = container.getSliceFor(value);
2821-
auto t = std::decay_t<decltype(*this)>{{this->asArrowTable()}, selection};
2822-
t.intersectWithSelection(this->getSelectedRows());
2823-
this->copyIndexBindings(t);
2824-
return t;
2825-
} else {
2826-
static_assert(o2::framework::always_static_assert_v<T1>, "Wrong Preslice<> entry used: incompatible type");
2827-
}
2828+
auto t = doSliceBy(this, container, value);
2829+
t.intersectWithSelection(this->getSelectedRows());
2830+
return t;
28282831
}
28292832

28302833
auto select(framework::expressions::Filter const& f) const
@@ -2844,18 +2847,6 @@ class FilteredBase : public T
28442847
}
28452848

28462849
protected:
2847-
auto slice(uint64_t start, uint64_t end)
2848-
{
2849-
auto start_iterator = std::lower_bound(mSelectedRows.begin(), mSelectedRows.end(), start);
2850-
auto stop_iterator = std::lower_bound(start_iterator, mSelectedRows.end(), end);
2851-
SelectionVector slicedSelection{start_iterator, stop_iterator};
2852-
std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
2853-
[&](int64_t idx) {
2854-
return idx - static_cast<int64_t>(start);
2855-
});
2856-
return self_t{{this->asArrowTable()->Slice(start, end - start + 1)}, std::move(slicedSelection), start};
2857-
}
2858-
28592850
void sumWithSelection(SelectionVector const& selection)
28602851
{
28612852
mCached = true;
@@ -3008,34 +2999,13 @@ class Filtered : public FilteredBase<T>
30082999

30093000
auto sliceByCached(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
30103001
{
3011-
auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
3012-
auto [offset, count] = localCache.getSliceFor(value);
3013-
auto slice = this->asArrowTable()->Slice(offset, count);
3014-
if (offset >= this->tableSize()) {
3015-
self_t fresult{{slice}, SelectionVector{}, 0}; // empty slice
3016-
this->copyIndexBindings(fresult);
3017-
return fresult;
3018-
}
3019-
auto start = offset;
3020-
auto end = start + slice->num_rows();
3021-
auto start_iterator = std::lower_bound(this->getSelectedRows().begin(), this->getSelectedRows().end(), start);
3022-
auto stop_iterator = std::lower_bound(start_iterator, this->getSelectedRows().end(), end);
3023-
SelectionVector slicedSelection{start_iterator, stop_iterator};
3024-
std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
3025-
[&start](int64_t idx) {
3026-
return idx - static_cast<int64_t>(start);
3027-
});
3028-
self_t fresult{{slice}, std::move(slicedSelection), static_cast<uint64_t>(start)};
3029-
this->copyIndexBindings(fresult);
3030-
return fresult;
3002+
return doFilteredSliceByCached(this, node, value, cache);
30313003
}
30323004

30333005
auto sliceByCachedUnsorted(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
30343006
{
3035-
auto localCache = cache.ptr->getCacheUnsortedFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
3036-
auto t = std::decay_t<decltype(*this)>{{this->asArrowTable()}, localCache.getSliceFor(value)};
3007+
auto t = doSliceByCachedUnsorted(this, node, value, cache);
30373008
t.intersectWithSelection(this->getSelectedRows());
3038-
this->copyIndexBindings(t);
30393009
return t;
30403010
}
30413011
};
@@ -3146,33 +3116,13 @@ class Filtered<Filtered<T>> : public FilteredBase<typename T::table_t>
31463116

31473117
auto sliceByCached(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
31483118
{
3149-
auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
3150-
auto [offset, count] = localCache.getSliceFor(value);
3151-
auto start = static_cast<uint64_t>(offset);
3152-
auto slice = this->asArrowTable()->Slice(start, count);
3153-
auto end = start + slice->num_rows();
3154-
auto start_iterator = std::lower_bound(this->getSelectedRows().begin(), this->getSelectedRows().end(), start);
3155-
auto stop_iterator = std::lower_bound(start_iterator, this->getSelectedRows().end(), end);
3156-
SelectionVector slicedSelection{start_iterator, stop_iterator};
3157-
std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
3158-
[&start](int64_t idx) {
3159-
return idx - static_cast<int64_t>(start);
3160-
});
3161-
SelectionVector copy = slicedSelection;
3162-
Filtered<T> filteredTable{{slice}, std::move(slicedSelection), start};
3163-
std::vector<Filtered<T>> filtered{filteredTable};
3164-
self_t fresult{std::move(filtered), std::move(copy), start};
3165-
this->copyIndexBindings(fresult);
3166-
return fresult;
3119+
return doFilteredSliceByCached(this, node, value, cache);
31673120
}
31683121

31693122
auto sliceByCachedUnsorted(framework::expressions::BindingNode const& node, int value, o2::framework::SliceCache& cache) const
31703123
{
3171-
auto localCache = cache.ptr->getCacheUnsortedFor({o2::soa::getLabelFromTypeForKey<std::decay_t<decltype(*this)>>(node.name), node.name});
3172-
std::vector<Filtered<T>> filtered{Filtered<T>{{this->asArrowTable()}, localCache.getSliceFor(value)}};
3173-
auto t = std::decay_t<decltype(*this)>{std::move(filtered), localCache.getSliceFor(value)};
3124+
auto t = doSliceByCachedUnsorted(this, node, value, cache);
31743125
t.intersectWithSelection(this->getSelectedRows());
3175-
this->copyIndexBindings(t);
31763126
return t;
31773127
}
31783128

0 commit comments

Comments
 (0)