Project
Loading...
Searching...
No Matches
GroupSlicer.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef FRAMEWORK_GROUP_SLICER_H_
13#define FRAMEWORK_GROUP_SLICER_H_
14
15#include "Framework/Pack.h"
16#include "Framework/ASoA.h"
18
19#include <arrow/util/config.h>
20#include <arrow/util/key_value_metadata.h>
21#include <type_traits>
22#include <string>
23namespace
24{
25template <typename T>
26auto getMatcherFor(std::string const& columnName, o2::header::DataOrigin newOrigin = o2::header::DataOrigin{"AOD"})
27{
28 auto matcher = o2::soa::getMatcherFromTypeForKey<std::decay_t<T>>(columnName);
29 if ((matcher.origin == o2::header::DataOrigin{"AOD"}) && (newOrigin != o2::header::DataOrigin{"AOD"})) {
30 matcher = o2::framework::replaceOrigin(matcher, newOrigin);
31 }
32 return matcher;
33}
34} // namespace
35
36namespace o2::framework
37{
38template <typename G, typename... A>
40 using grouping_t = std::decay_t<G>;
41 GroupSlicer(G& gt, std::tuple<A...>& at, ArrowTableSlicingCache& slices, header::DataOrigin newOrigin = header::DataOrigin{"AOD"})
42 : max{gt.size()},
43 mBegin{GroupSlicerIterator(gt, at, slices, newOrigin)}
44 {
45 }
46
48 int64_t position;
49 };
50
53
59
60 template <typename T>
62 {
63 }
64
65 template <soa::is_table T>
66 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<T>>() && !soa::is_smallgroups<T>)
67 auto splittingFunction(T&& table)
68 {
69 if (table.size() == 0) {
70 return;
71 }
72 sliceInfos[framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{})] = mSlices->getCacheFor(Entry("", getMatcherFor<T>(mIndexColumnName, replacementOrigin), mIndexColumnName));
73 }
74
75 template <soa::is_smallgroups T>
76 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<T>>())
77 auto splittingFunction(T&& table)
78 {
79 if (table.tableSize() == 0) {
80 return;
81 }
82 sliceInfosUnsorted[framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{})] = mSlices->getCacheUnsortedFor(Entry("", getMatcherFor<T>(mIndexColumnName, replacementOrigin), mIndexColumnName));
83 }
84
85 template <typename T>
87 {
88 }
89
90 template <soa::is_filtered_table T>
91 auto extractingFunction(T&& table)
92 {
93 constexpr auto index = framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{});
94 selections[index] = &table.getSelectedRows();
95 starts[index] = selections[index]->begin();
96 }
97
98 GroupSlicerIterator(G& gt, std::tuple<A...>& at, ArrowTableSlicingCache& slices, header::DataOrigin newOrigin = header::DataOrigin{"AOD"})
99 : mIndexColumnName{std::string("fIndex") + o2::framework::cutString(o2::soa::getLabelFromType<G>())},
100 mGt{&gt},
101 mAt{&at},
103 position{0},
104 mSlices{&slices},
105 replacementOrigin{newOrigin}
106 {
108 groupSelection = mGt->getSelectedRows();
109 }
110
114
115 [this]<size_t... Is>(std::tuple<A...>& at, std::index_sequence<Is...>) {
116 (splittingFunction(std::get<Is>(at)), ...);
117 (extractingFunction(std::get<Is>(at)), ...);
118 }(*mAt, std::make_index_sequence<sizeof...(A)>());
119 }
120
122 {
123 ++position;
125 return *this;
126 }
127
129 {
130 GroupSlicerIterator copy = *this;
131 copy.position += inc;
132 copy.mGroupingElement = copy.mGroupingElement + inc;
133 return copy;
134 }
135
137 {
138 position += inc;
139 mGroupingElement += inc;
140 return *this;
141 }
142
144 {
145 return O2_BUILTIN_UNLIKELY(position == other.position);
146 }
147
149 {
150 return O2_BUILTIN_LIKELY(position != other.position);
151 }
152
154 {
155 return mGroupingElement;
156 }
157
159 {
160 return *this;
161 }
162
164 {
165 return std::make_tuple(prepareArgument<A>()...);
166 }
167
168 template <soa::is_smallgroups A1>
169 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && soa::is_filtered_table<A1>)
171 {
172 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
173 auto& originalTable = std::get<A1>(*mAt);
174 uint64_t pos;
177 } else {
178 pos = position;
179 }
180 // generic split
181 auto selection = sliceInfosUnsorted[index].getSliceFor(pos);
182 // intersect selections
184 if (selections[index]->empty()) {
185 if (!selection.empty()) {
186 std::copy(selection.begin(), selection.end(), std::back_inserter(s));
187 }
188 } else {
189 if (!selection.empty()) {
190 if constexpr (std::decay_t<A1>::applyFilters) {
191 std::set_intersection(selection.begin(), selection.end(), selections[index]->begin(), selections[index]->end(), std::back_inserter(s));
192 } else {
193 std::copy(selection.begin(), selection.end(), std::back_inserter(s));
194 }
195 }
196 }
197 std::decay_t<A1> typedTable{{originalTable.asArrowTable()}, std::move(s)};
198 typedTable.bindInternalIndicesTo(&originalTable);
199 return typedTable;
200 }
201
202 template <soa::is_filtered_table A1>
203 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1>)
205 {
206 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
207 auto& originalTable = std::get<A1>(*mAt);
208 if (originalTable.size() == 0) {
209 return originalTable;
210 }
211 uint64_t pos;
214 } else {
215 pos = position;
216 }
217 // optimized split
218 auto oc = sliceInfos[index].getSliceFor(pos);
219 uint64_t offset = oc.first;
220 auto count = oc.second;
221 auto groupedElementsTable = originalTable.asArrowTable()->Slice(offset, count);
222 if (count == 0) {
223 return std::decay_t<A1>{{groupedElementsTable}, soa::SelectionVector{}};
224 }
225
226 // for each grouping element we need to slice the selection vector
227 auto start_iterator = std::lower_bound(starts[index], selections[index]->end(), offset);
228 auto stop_iterator = std::lower_bound(start_iterator, selections[index]->end(), offset + count);
229 starts[index] = stop_iterator;
230 soa::SelectionVector slicedSelection{start_iterator, stop_iterator};
231 std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
232 [&offset](int64_t idx) {
233 return idx - static_cast<int64_t>(offset);
234 });
235
236 std::decay_t<A1> typedTable{{groupedElementsTable}, std::move(slicedSelection), offset};
237 typedTable.bindInternalIndicesTo(&originalTable);
238 return typedTable;
239 }
240
241 template <soa::is_table A1>
242 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1> && !soa::is_filtered_table<A1>)
244 {
245 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
246 auto& originalTable = std::get<A1>(*mAt);
247 if (originalTable.size() == 0) {
248 return originalTable;
249 }
250 uint64_t pos;
253 } else {
254 pos = position;
255 }
256 // optimized split
257 auto [offset, count] = sliceInfos[index].getSliceFor(pos);
258 auto groupedElementsTable = originalTable.rawSlice(offset, offset + count - 1);
259 groupedElementsTable.bindInternalIndicesTo(&originalTable);
260 return groupedElementsTable;
261 }
262
263 template <soa::is_table A1>
264 requires(!o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1>)
266 {
267 return std::get<A1>(*mAt);
268 }
269
270 std::string mIndexColumnName;
271 G const* mGt;
272 std::tuple<A...>* mAt;
273 typename grouping_t::iterator mGroupingElement;
274 uint64_t position = 0;
275 std::span<int64_t const> groupSelection;
276 std::array<std::span<int64_t const> const*, sizeof...(A)> selections;
277 std::array<std::span<int64_t const>::iterator, sizeof...(A)> starts;
278
279 std::array<SliceInfoPtr, sizeof...(A)> sliceInfos;
280 std::array<SliceInfoUnsortedPtr, sizeof...(A)> sliceInfosUnsorted;
283 };
284
286 {
287 return mBegin;
288 }
289
291 {
292 return GroupSlicerSentinel{max};
293 }
294 int64_t max;
296};
297
298} // namespace o2::framework
299#endif // FRAMEWORK_GROUP_SLICER_H_
#define O2_BUILTIN_LIKELY(x)
#define O2_BUILTIN_UNLIKELY(x)
uint16_t pos
Definition RawData.h:3
Definition A.h:16
GLsizei const GLchar *const * string
Definition glcorearb.h:809
GLint GLsizei count
Definition glcorearb.h:399
GLsizeiptr size
Definition glcorearb.h:659
GLuint index
Definition glcorearb.h:781
GLintptr offset
Definition glcorearb.h:660
constexpr framework::ConcreteDataMatcher matcher()
Definition ASoA.h:380
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
ConfigParamSpec replaceOrigin(ConfigParamSpec &source, std::string const &originStr)
std::string cutString(std::string &&str)
Definition ASoA.cxx:276
std::vector< int64_t > SelectionVector
Definition ASoA.h:443
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void empty(int)
SliceInfoUnsortedPtr getCacheUnsortedFor(Entry const &bindingKey) const
SliceInfoPtr getCacheFor(Entry const &bindingKey) const
std::array< SliceInfoUnsortedPtr, sizeof...(A)> sliceInfosUnsorted
GroupSlicerIterator operator+(int64_t inc) const
std::array< std::span< int64_t const >::iterator, sizeof...(A)> starts
std::array< SliceInfoPtr, sizeof...(A)> sliceInfos
GroupSlicerIterator & operator=(GroupSlicerIterator const &)=default
GroupSlicerIterator(GroupSlicerIterator &&)=default
bool operator!=(GroupSlicerSentinel const &other)
GroupSlicerIterator & operator=(GroupSlicerIterator &&)=default
GroupSlicerIterator operator+=(int64_t inc)
GroupSlicerIterator(GroupSlicerIterator const &)=default
std::array< std::span< int64_t const > const *, sizeof...(A)> selections
GroupSlicerIterator(G &gt, std::tuple< A... > &at, ArrowTableSlicingCache &slices, header::DataOrigin newOrigin=header::DataOrigin{"AOD"})
Definition GroupSlicer.h:98
bool operator==(GroupSlicerSentinel const &other)
GroupSlicerSentinel end()
GroupSlicer(G &gt, std::tuple< A... > &at, ArrowTableSlicingCache &slices, header::DataOrigin newOrigin=header::DataOrigin{"AOD"})
Definition GroupSlicer.h:41
GroupSlicerIterator mBegin
std::decay_t< G > grouping_t
Definition GroupSlicer.h:40
GroupSlicerIterator & begin()
VectorOfTObjectPtrs other