diff --git a/Framework/Core/include/Framework/GroupSlicer.h b/Framework/Core/include/Framework/GroupSlicer.h index 8fd96fb00156c..64b1d863c59e6 100644 --- a/Framework/Core/include/Framework/GroupSlicer.h +++ b/Framework/Core/include/Framework/GroupSlicer.h @@ -22,7 +22,6 @@ namespace o2::framework { - template struct GroupSlicer { using grouping_t = std::decay_t; @@ -46,34 +45,41 @@ struct GroupSlicer { GroupSlicerIterator& operator=(GroupSlicerIterator&&) = default; template + auto splittingFunction(T&&) + { + } + + template + requires(o2::soa::relatedByIndex, std::decay_t>()) auto splittingFunction(T&& table) { constexpr auto index = framework::has_type_at_v>(associated_pack_t{}); - if constexpr (o2::soa::relatedByIndex, std::decay_t>()) { - auto binding = o2::soa::getLabelFromTypeForKey>(mIndexColumnName); - auto bk = std::make_pair(binding, mIndexColumnName); - if constexpr (!o2::soa::is_smallgroups>) { - if (table.size() == 0) { - return; - } - sliceInfos[index] = mSlices->getCacheFor(bk); - } else { - if (table.tableSize() == 0) { - return; - } - sliceInfosUnsorted[index] = mSlices->getCacheUnsortedFor(bk); + auto binding = o2::soa::getLabelFromTypeForKey>(mIndexColumnName); + auto bk = std::make_pair(binding, mIndexColumnName); + if constexpr (!o2::soa::is_smallgroups>) { + if (table.size() == 0) { + return; } + sliceInfos[index] = mSlices->getCacheFor(bk); + } else { + if (table.tableSize() == 0) { + return; + } + sliceInfosUnsorted[index] = mSlices->getCacheUnsortedFor(bk); } } template + auto extractingFunction(T&&) + { + } + + template auto extractingFunction(T&& table) { - if constexpr (soa::is_filtered_table>) { - constexpr auto index = framework::has_type_at_v>(associated_pack_t{}); - selections[index] = &table.getSelectedRows(); - starts[index] = selections[index]->begin(); - } + constexpr auto index = framework::has_type_at_v>(associated_pack_t{}); + selections[index] = &table.getSelectedRows(); + starts[index] = selections[index]->begin(); } GroupSlicerIterator(G& gt, std::tuple& at, ArrowTableSlicingCache& slices) @@ -151,83 +157,108 @@ struct GroupSlicer { return std::make_tuple(prepareArgument()...); } - template + template + requires(o2::soa::relatedByIndex, std::decay_t>() && soa::is_filtered_table) auto prepareArgument() { constexpr auto index = framework::has_type_at_v(associated_pack_t{}); auto& originalTable = std::get(*mAt); - - if constexpr (o2::soa::relatedByIndex, std::decay_t>()) { - uint64_t pos; - if constexpr (soa::is_filtered_table>) { - pos = groupSelection[position]; - } else { - pos = position; + uint64_t pos; + if constexpr (soa::is_filtered_table>) { + pos = groupSelection[position]; + } else { + pos = position; + } + // generic split + auto selection = sliceInfosUnsorted[index].getSliceFor(pos); + // intersect selections + o2::soa::SelectionVector s; + if (selections[index]->empty()) { + if (!selection.empty()) { + std::copy(selection.begin(), selection.end(), std::back_inserter(s)); } - - if constexpr (!o2::soa::is_smallgroups>) { - // optimized split - if (originalTable.size() == 0) { - return originalTable; - } - auto oc = sliceInfos[index].getSliceFor(pos); - uint64_t offset = oc.first; - auto count = oc.second; - if constexpr (soa::is_filtered_table>) { - auto groupedElementsTable = originalTable.asArrowTable()->Slice(offset, count); - if (count == 0) { - return std::decay_t{{groupedElementsTable}, soa::SelectionVector{}}; - } - - // for each grouping element we need to slice the selection vector - auto start_iterator = std::lower_bound(starts[index], selections[index]->end(), offset); - auto stop_iterator = std::lower_bound(start_iterator, selections[index]->end(), offset + count); - starts[index] = stop_iterator; - soa::SelectionVector slicedSelection{start_iterator, stop_iterator}; - std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(), - [&offset](int64_t idx) { - return idx - static_cast(offset); - }); - - std::decay_t typedTable{{groupedElementsTable}, std::move(slicedSelection), offset}; - typedTable.bindInternalIndicesTo(&originalTable); - return typedTable; - - } else { - auto groupedElementsTable = originalTable.rawSlice(offset, offset + count - 1); - groupedElementsTable.bindInternalIndicesTo(&originalTable); - return groupedElementsTable; - } - } else { - // generic split - if constexpr (soa::is_filtered_table>) { - auto selection = sliceInfosUnsorted[index].getSliceFor(pos); - // intersect selections - o2::soa::SelectionVector s; - if (selections[index]->empty()) { - if (!selection.empty()) { - std::copy(selection.begin(), selection.end(), std::back_inserter(s)); - } - } else { - if (!selection.empty()) { - if constexpr (std::decay_t::applyFilters) { - std::set_intersection(selection.begin(), selection.end(), selections[index]->begin(), selections[index]->end(), std::back_inserter(s)); - } else { - std::copy(selection.begin(), selection.end(), std::back_inserter(s)); - } - } - } - std::decay_t typedTable{{originalTable.asArrowTable()}, std::move(s)}; - typedTable.bindInternalIndicesTo(&originalTable); - return typedTable; + } else { + if (!selection.empty()) { + if constexpr (std::decay_t::applyFilters) { + std::set_intersection(selection.begin(), selection.end(), selections[index]->begin(), selections[index]->end(), std::back_inserter(s)); } else { - throw runtime_error("Unsorted grouped table needs to be used with soa::SmallGroups<>"); + std::copy(selection.begin(), selection.end(), std::back_inserter(s)); } } + } + std::decay_t typedTable{{originalTable.asArrowTable()}, std::move(s)}; + typedTable.bindInternalIndicesTo(&originalTable); + return typedTable; + } + + template + requires(o2::soa::relatedByIndex, std::decay_t>() && !soa::is_smallgroups) + auto prepareArgument() + { + constexpr auto index = framework::has_type_at_v(associated_pack_t{}); + auto& originalTable = std::get(*mAt); + if (originalTable.size() == 0) { + return originalTable; + } + uint64_t pos; + if constexpr (soa::is_filtered_table>) { + pos = groupSelection[position]; } else { - static_assert(!o2::soa::is_smallgroups>, "SmallGroups used with a table that is not related by index to the gouping table"); + pos = position; + } + // optimized split + auto oc = sliceInfos[index].getSliceFor(pos); + uint64_t offset = oc.first; + auto count = oc.second; + auto groupedElementsTable = originalTable.asArrowTable()->Slice(offset, count); + if (count == 0) { + return std::decay_t{{groupedElementsTable}, soa::SelectionVector{}}; + } + + // for each grouping element we need to slice the selection vector + auto start_iterator = std::lower_bound(starts[index], selections[index]->end(), offset); + auto stop_iterator = std::lower_bound(start_iterator, selections[index]->end(), offset + count); + starts[index] = stop_iterator; + soa::SelectionVector slicedSelection{start_iterator, stop_iterator}; + std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(), + [&offset](int64_t idx) { + return idx - static_cast(offset); + }); + + std::decay_t typedTable{{groupedElementsTable}, std::move(slicedSelection), offset}; + typedTable.bindInternalIndicesTo(&originalTable); + return typedTable; + } + + template + requires(o2::soa::relatedByIndex, std::decay_t>() && !soa::is_smallgroups && !soa::is_filtered_table) + auto prepareArgument() + { + constexpr auto index = framework::has_type_at_v(associated_pack_t{}); + auto& originalTable = std::get(*mAt); + if (originalTable.size() == 0) { return originalTable; } + uint64_t pos; + if constexpr (soa::is_filtered_table>) { + pos = groupSelection[position]; + } else { + pos = position; + } + // optimized split + auto oc = sliceInfos[index].getSliceFor(pos); + uint64_t offset = oc.first; + auto count = oc.second; + auto groupedElementsTable = originalTable.rawSlice(offset, offset + count - 1); + groupedElementsTable.bindInternalIndicesTo(&originalTable); + return groupedElementsTable; + } + + template + requires(!o2::soa::relatedByIndex, std::decay_t>() && !soa::is_smallgroups) + auto prepareArgument() + { + return std::get(*mAt); } std::string mIndexColumnName;