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"
17
18#include <arrow/util/config.h>
19#include <arrow/util/key_value_metadata.h>
20#include <type_traits>
21#include <string>
22
23namespace o2::framework
24{
25template <typename G, typename... A>
27 using grouping_t = std::decay_t<G>;
28 GroupSlicer(G& gt, std::tuple<A...>& at, ArrowTableSlicingCache& slices)
29 : max{gt.size()},
30 mBegin{GroupSlicerIterator(gt, at, slices)}
31 {
32 }
33
35 int64_t position;
36 };
37
40
46
47 template <typename T>
49 {
50 }
51
52 template <typename T>
53 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<T>>())
54 auto splittingFunction(T&& table)
55 {
56 constexpr auto index = framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{});
57 auto binding = o2::soa::getLabelFromTypeForKey<std::decay_t<T>>(mIndexColumnName);
58 auto bk = std::make_pair(binding, mIndexColumnName);
60 if (table.size() == 0) {
61 return;
62 }
64 } else {
65 if (table.tableSize() == 0) {
66 return;
67 }
69 }
70 }
71
72 template <typename T>
74 {
75 }
76
77 template <soa::is_filtered_table T>
78 auto extractingFunction(T&& table)
79 {
80 constexpr auto index = framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{});
81 selections[index] = &table.getSelectedRows();
82 starts[index] = selections[index]->begin();
83 }
84
85 GroupSlicerIterator(G& gt, std::tuple<A...>& at, ArrowTableSlicingCache& slices)
86 : mIndexColumnName{std::string("fIndex") + o2::framework::cutString(o2::soa::getLabelFromType<G>())},
87 mGt{&gt},
88 mAt{&at},
90 position{0},
91 mSlices{&slices}
92 {
94 groupSelection = mGt->getSelectedRows();
95 }
96
100 std::apply(
101 [&](auto&&... x) -> void {
102 (splittingFunction(x), ...);
103 },
104 at);
106 std::apply(
107 [&](auto&&... x) -> void {
108 (extractingFunction(x), ...);
109 },
110 at);
111 }
112
114 {
115 ++position;
117 return *this;
118 }
119
121 {
122 GroupSlicerIterator copy = *this;
123 copy.position += inc;
124 copy.mGroupingElement = copy.mGroupingElement + inc;
125 return copy;
126 }
127
129 {
130 position += inc;
131 mGroupingElement += inc;
132 return *this;
133 }
134
136 {
137 return O2_BUILTIN_UNLIKELY(position == other.position);
138 }
139
141 {
142 return O2_BUILTIN_LIKELY(position != other.position);
143 }
144
146 {
147 return mGroupingElement;
148 }
149
151 {
152 return *this;
153 }
154
156 {
157 return std::make_tuple(prepareArgument<A>()...);
158 }
159
160 template <soa::is_smallgroups A1>
161 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && soa::is_filtered_table<A1>)
163 {
164 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
165 auto& originalTable = std::get<A1>(*mAt);
166 uint64_t pos;
169 } else {
170 pos = position;
171 }
172 // generic split
173 auto selection = sliceInfosUnsorted[index].getSliceFor(pos);
174 // intersect selections
176 if (selections[index]->empty()) {
177 if (!selection.empty()) {
178 std::copy(selection.begin(), selection.end(), std::back_inserter(s));
179 }
180 } else {
181 if (!selection.empty()) {
182 if constexpr (std::decay_t<A1>::applyFilters) {
183 std::set_intersection(selection.begin(), selection.end(), selections[index]->begin(), selections[index]->end(), std::back_inserter(s));
184 } else {
185 std::copy(selection.begin(), selection.end(), std::back_inserter(s));
186 }
187 }
188 }
189 std::decay_t<A1> typedTable{{originalTable.asArrowTable()}, std::move(s)};
190 typedTable.bindInternalIndicesTo(&originalTable);
191 return typedTable;
192 }
193
194 template <soa::is_filtered_table A1>
195 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1>)
197 {
198 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
199 auto& originalTable = std::get<A1>(*mAt);
200 if (originalTable.size() == 0) {
201 return originalTable;
202 }
203 uint64_t pos;
206 } else {
207 pos = position;
208 }
209 // optimized split
210 auto oc = sliceInfos[index].getSliceFor(pos);
211 uint64_t offset = oc.first;
212 auto count = oc.second;
213 auto groupedElementsTable = originalTable.asArrowTable()->Slice(offset, count);
214 if (count == 0) {
215 return std::decay_t<A1>{{groupedElementsTable}, soa::SelectionVector{}};
216 }
217
218 // for each grouping element we need to slice the selection vector
219 auto start_iterator = std::lower_bound(starts[index], selections[index]->end(), offset);
220 auto stop_iterator = std::lower_bound(start_iterator, selections[index]->end(), offset + count);
221 starts[index] = stop_iterator;
222 soa::SelectionVector slicedSelection{start_iterator, stop_iterator};
223 std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
224 [&offset](int64_t idx) {
225 return idx - static_cast<int64_t>(offset);
226 });
227
228 std::decay_t<A1> typedTable{{groupedElementsTable}, std::move(slicedSelection), offset};
229 typedTable.bindInternalIndicesTo(&originalTable);
230 return typedTable;
231 }
232
233 template <soa::is_table A1>
234 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1> && !soa::is_filtered_table<A1>)
236 {
237 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
238 auto& originalTable = std::get<A1>(*mAt);
239 if (originalTable.size() == 0) {
240 return originalTable;
241 }
242 uint64_t pos;
245 } else {
246 pos = position;
247 }
248 // optimized split
249 auto oc = sliceInfos[index].getSliceFor(pos);
250 uint64_t offset = oc.first;
251 auto count = oc.second;
252 auto groupedElementsTable = originalTable.rawSlice(offset, offset + count - 1);
253 groupedElementsTable.bindInternalIndicesTo(&originalTable);
254 return groupedElementsTable;
255 }
256
257 template <soa::is_table A1>
258 requires(!o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1>)
260 {
261 return std::get<A1>(*mAt);
262 }
263
264 std::string mIndexColumnName;
265 G const* mGt;
266 std::tuple<A...>* mAt;
267 typename grouping_t::iterator mGroupingElement;
268 uint64_t position = 0;
269 gsl::span<int64_t const> groupSelection;
270 std::array<gsl::span<int64_t const> const*, sizeof...(A)> selections;
271 std::array<gsl::span<int64_t const>::iterator, sizeof...(A)> starts;
272
273 std::array<SliceInfoPtr, sizeof...(A)> sliceInfos;
274 std::array<SliceInfoUnsortedPtr, sizeof...(A)> sliceInfosUnsorted;
276 };
277
279 {
280 return mBegin;
281 }
282
284 {
285 return GroupSlicerSentinel{max};
286 }
287 int64_t max;
289};
290
291} // namespace o2::framework
292#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 GLenum GLint x
Definition glcorearb.h:403
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
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::string cutString(std::string &&str)
Definition ASoA.cxx:180
std::vector< int64_t > SelectionVector
Definition ASoA.h:406
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
void empty(int)
SliceInfoPtr getCacheFor(StringPair const &bindingKey) const
SliceInfoUnsortedPtr getCacheUnsortedFor(StringPair const &bindingKey) const
std::array< SliceInfoUnsortedPtr, sizeof...(A)> sliceInfosUnsorted
GroupSlicerIterator(G &gt, std::tuple< A... > &at, ArrowTableSlicingCache &slices)
Definition GroupSlicer.h:85
GroupSlicerIterator operator+(int64_t inc) const
std::array< SliceInfoPtr, sizeof...(A)> sliceInfos
GroupSlicerIterator & operator=(GroupSlicerIterator const &)=default
GroupSlicerIterator(GroupSlicerIterator &&)=default
bool operator!=(GroupSlicerSentinel const &other)
std::array< gsl::span< int64_t const > const *, sizeof...(A)> selections
GroupSlicerIterator & operator=(GroupSlicerIterator &&)=default
std::array< gsl::span< int64_t const >::iterator, sizeof...(A)> starts
GroupSlicerIterator operator+=(int64_t inc)
GroupSlicerIterator(GroupSlicerIterator const &)=default
bool operator==(GroupSlicerSentinel const &other)
GroupSlicerSentinel end()
GroupSlicerIterator mBegin
GroupSlicer(G &gt, std::tuple< A... > &at, ArrowTableSlicingCache &slices)
Definition GroupSlicer.h:28
std::decay_t< G > grouping_t
Definition GroupSlicer.h:27
GroupSlicerIterator & begin()
VectorOfTObjectPtrs other