Project
Loading...
Searching...
No Matches
ASoA.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 O2_FRAMEWORK_ASOA_H_
13#define O2_FRAMEWORK_ASOA_H_
14
15#include "Framework/Pack.h" // IWYU pragma: export
16#include "Framework/FunctionalHelpers.h" // IWYU pragma: export
17#include "Headers/DataHeader.h" // IWYU pragma: export
18#include "Headers/DataHeaderHelpers.h" // IWYU pragma: export
19#include "Framework/CompilerBuiltins.h" // IWYU pragma: export
20#include "Framework/Traits.h" // IWYU pragma: export
21#include "Framework/Expressions.h" // IWYU pragma: export
22#include "Framework/ArrowTypes.h" // IWYU pragma: export
23#include "Framework/ArrowTableSlicingCache.h" // IWYU pragma: export
24#include "Framework/SliceCache.h" // IWYU pragma: export
25#include "Framework/VariantHelpers.h" // IWYU pragma: export
26#include <arrow/array/array_binary.h>
27#include <arrow/table.h> // IWYU pragma: export
28#include <arrow/array.h> // IWYU pragma: export
29#include <arrow/util/config.h> // IWYU pragma: export
30#include <gandiva/selection_vector.h> // IWYU pragma: export
31#include <array> // IWYU pragma: export
32#include <cassert>
33#include <fmt/format.h>
34#include <concepts>
35#include <cstring>
36#include <gsl/span> // IWYU pragma: export
37#include <limits>
38
39namespace o2::framework
40{
41using ListVector = std::vector<std::vector<int64_t>>;
42
43std::string cutString(std::string&& str);
44std::string strToUpper(std::string&& str);
45} // namespace o2::framework
46
47namespace o2::soa
48{
49void accessingInvalidIndexFor(const char* getter);
50void dereferenceWithWrongType(const char* getter, const char* target);
51void missingFilterDeclaration(int hash, int ai);
52void notBoundTable(const char* tableName);
53} // namespace o2::soa
54
55namespace o2::soa
56{
58struct TableRef {
59 consteval TableRef()
60 : label_hash{0},
61 desc_hash{0},
62 origin_hash{0},
63 version{0}
64 {
65 }
66 consteval TableRef(uint32_t _label, uint32_t _desc, uint32_t _origin, uint32_t _version)
67 : label_hash{_label},
68 desc_hash{_desc},
69 origin_hash{_origin},
70 version{_version}
71 {
72 }
73 uint32_t label_hash;
74 uint32_t desc_hash;
75 uint32_t origin_hash;
76 uint32_t version;
77
78 constexpr bool operator==(TableRef const& other) const noexcept
79 {
80 return (this->label_hash == other.label_hash) &&
81 (this->desc_hash == other.desc_hash) &&
82 (this->origin_hash == other.origin_hash) &&
83 (this->version == other.version);
84 }
85
86 constexpr bool descriptionCompatible(TableRef const& other) const noexcept
87 {
88 return this->desc_hash == other.desc_hash;
89 }
90
91 constexpr bool descriptionCompatible(uint32_t _desc_hash) const noexcept
92 {
93 return this->desc_hash == _desc_hash;
94 }
95
96 constexpr TableRef(TableRef const&) = default;
97 constexpr TableRef& operator=(TableRef const&) = default;
98 constexpr TableRef(TableRef&&) = default;
99 constexpr TableRef& operator=(TableRef&&) = default;
100};
101
103template <size_t N1, size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2>
104consteval auto merge()
105{
106 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](TableRef const& a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
107 std::array<TableRef, N1 + N2 - duplicates> out;
108
109 auto pos = std::copy(ar1.begin(), ar1.end(), out.begin());
110 std::copy_if(ar2.begin(), ar2.end(), pos, [&](TableRef const& a) { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
111 return out;
112}
113
114template <size_t N1, size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2, typename L>
115consteval auto merge_if(L l)
116{
117 constexpr const int to_remove = std::ranges::count_if(ar1.begin(), ar1.end(), [&](TableRef const& a) { return !l(a); });
118 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](TableRef const& a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) || !l(a); });
119 std::array<TableRef, N1 + N2 - duplicates - to_remove> out;
120
121 auto pos = std::copy_if(ar1.begin(), ar1.end(), out.begin(), [&](TableRef const& a) { return l(a); });
122 std::copy_if(ar2.begin(), ar2.end(), pos, [&](TableRef const& a) { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) && l(a); });
123 return out;
124}
125
126template <size_t N, std::array<TableRef, N> ar, typename L>
127consteval auto remove_if(L l)
128{
129 constexpr const int to_remove = std::ranges::count_if(ar.begin(), ar.end(), [&l](TableRef const& e) { return l(e); });
130 std::array<TableRef, N - to_remove> out;
131 std::copy_if(ar.begin(), ar.end(), out.begin(), [&l](TableRef const& e) { return !l(e); });
132 return out;
133}
134
135template <size_t N1, size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2>
136consteval auto intersect()
137{
138 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](TableRef const& a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
139 std::array<TableRef, duplicates> out;
140 std::copy_if(ar1.begin(), ar1.end(), out.begin(), [](TableRef const& a) { return std::find(ar2.begin(), ar2.end(), a) != ar2.end(); });
141 return out;
142}
143
144template <typename T, typename... Ts>
145consteval auto mergeOriginals()
146 requires(sizeof...(Ts) == 1)
147{
149 return merge<T::originals.size(), T1::originals.size(), T::originals, T1::originals>();
150}
151
152template <typename T, typename... Ts>
153consteval auto mergeOriginals()
154 requires(sizeof...(Ts) > 1)
155{
156 constexpr auto tail = mergeOriginals<Ts...>();
157 return merge<T::originals.size(), tail.size(), T::originals, tail>();
158}
159
160template <typename T, typename... Ts>
161 requires(sizeof...(Ts) == 1)
162consteval auto intersectOriginals()
163{
165 return intersect<T::originals.size(), T1::originals.size(), T::originals, T1::originals>();
166}
167
168template <typename T, typename... Ts>
169 requires(sizeof...(Ts) > 1)
170consteval auto intersectOriginals()
171{
172 constexpr auto tail = intersectOriginals<Ts...>();
173 return intersect<T::originals.size(), tail.size(), T::originals, tail>();
174}
175} // namespace o2::soa
176
177namespace o2::soa
178{
179struct Binding;
180
181template <typename T>
182concept not_void = requires { !std::same_as<T, void>; };
183
185template <typename C>
186concept is_persistent_column = requires(C c) { c.mColumnIterator; };
187
188template <typename C>
190
191template <typename C>
192using is_persistent_column_t = std::conditional_t<is_persistent_column<C>, std::true_type, std::false_type>;
193
194template <typename C>
195concept is_self_index_column = not_void<typename C::self_index_t> && std::same_as<typename C::self_index_t, std::true_type>;
196
197template <typename C>
199 { c.setCurrentRaw(b) } -> std::same_as<bool>;
200 requires std::same_as<decltype(c.mBinding), o2::soa::Binding>;
201};
202
203template <typename C>
204using is_external_index_t = typename std::conditional_t<is_index_column<C>, std::true_type, std::false_type>;
205
206template <typename C>
207using is_self_index_t = typename std::conditional_t<is_self_index_column<C>, std::true_type, std::false_type>;
208} // namespace o2::soa
209
210namespace o2::aod
211{
213template <typename D, typename... Cs>
215 using columns = framework::pack<Cs...>;
219
220 template <typename Key, typename... PCs>
221 static consteval std::array<bool, sizeof...(PCs)> getMap(framework::pack<PCs...>)
222 {
223 return std::array<bool, sizeof...(PCs)>{[]() {
224 if constexpr (requires { PCs::index_targets.size(); }) {
225 return Key::template isIndexTargetOf<PCs::index_targets.size(), PCs::index_targets>();
226 } else {
227 return false;
228 }
229 }()...};
230 }
231
232 template <typename Key>
233 static consteval int getIndexPosToKey()
234 {
236 }
237
238 template <typename Key, size_t N, std::array<bool, N> map>
239 static consteval int getIndexPosToKey_impl()
240 {
241 constexpr const auto pos = std::find(map.begin(), map.end(), true);
242 if constexpr (pos != map.end()) {
243 return std::distance(map.begin(), pos);
244 } else {
245 return -1;
246 }
247 }
248};
249
250template <typename D>
252 using metadata = void;
253};
254
257template <uint32_t H>
258struct Hash {
259 static constexpr uint32_t hash = H;
260 static constexpr char const* const str{""};
261};
262
264template <size_t N, std::array<soa::TableRef, N> ar, typename Key>
265consteval auto filterForKey()
266{
267 constexpr std::array<bool, N> test = []<size_t... Is>(std::index_sequence<Is...>) {
268 return std::array<bool, N>{(Key::template hasOriginal<ar[Is]>() || (o2::aod::MetadataTrait<o2::aod::Hash<ar[Is].desc_hash>>::metadata::template getIndexPosToKey<Key>() >= 0))...};
269 }(std::make_index_sequence<N>());
270 constexpr int correct = std::ranges::count(test.begin(), test.end(), true);
271 std::array<soa::TableRef, correct> out;
272 std::ranges::copy_if(ar.begin(), ar.end(), out.begin(), [&test](soa::TableRef const& r) { return test[std::distance(ar.begin(), std::find(ar.begin(), ar.end(), r))]; });
273 return out;
274}
275
277#define O2HASH(_Str_) \
278 template <> \
279 struct Hash<_Str_ ""_h> { \
280 static constexpr uint32_t hash = _Str_ ""_h; \
281 static constexpr char const* const str{_Str_}; \
282 };
283
285#define O2ORIGIN(_Str_) \
286 template <> \
287 struct Hash<_Str_ ""_h> { \
288 static constexpr header::DataOrigin origin{_Str_}; \
289 static constexpr uint32_t hash = _Str_ ""_h; \
290 static constexpr char const* const str{_Str_}; \
291 };
292
294static inline constexpr uint32_t version(const char* const str)
295{
296 if (str[0] == '\0') {
297 return 0;
298 }
299 size_t len = 0;
300 uint32_t res = 0;
301 while (str[len] != '/' && str[len] != '\0') {
302 ++len;
303 }
304 if (str[len - 1] == '\0') {
305 return -1;
306 }
307 for (auto i = len + 1; str[i] != '\0'; ++i) {
308 res = res * 10 + (int)(str[i] - '0');
309 }
310 return res;
311}
312
314static inline constexpr std::string_view description_str(const char* const str)
315{
316 size_t len = 0;
317 while (len < 15 && str[len] != '/') {
318 ++len;
319 }
320 return std::string_view{str, len};
321}
322
323static inline constexpr header::DataDescription description(const char* const str)
324{
325 size_t len = 0;
326 while (len < 15 && str[len] != '/') {
327 ++len;
328 }
329 char out[16];
330 for (auto i = 0; i < 16; ++i) {
331 out[i] = 0;
332 }
333 std::memcpy(out, str, len);
334 return {out};
335}
336
337// Helpers to get strings from TableRef
338template <soa::TableRef R>
339consteval const char* label()
340{
341 return o2::aod::Hash<R.label_hash>::str;
342}
343
344template <soa::TableRef R>
345consteval const char* origin_str()
346{
347 return o2::aod::Hash<R.origin_hash>::str;
348}
349
350template <soa::TableRef R>
352{
353 return o2::aod::Hash<R.origin_hash>::origin;
354}
355
356template <soa::TableRef R>
357consteval const char* signature()
358{
359 return o2::aod::Hash<R.desc_hash>::str;
360}
361
363template <typename T>
364concept is_aod_hash = requires(T t) { t.hash; t.str; };
365
366template <typename T>
367concept is_origin_hash = is_aod_hash<T> && requires(T t) { t.origin; };
368
370template <soa::TableRef R>
371static constexpr auto sourceSpec()
372{
373 return fmt::format("{}/{}/{}/{}", label<R>(), origin_str<R>(), description_str(signature<R>()), R.version);
374}
375} // namespace o2::aod
376
377namespace o2::soa
378{
379template <aod::is_aod_hash L, aod::is_aod_hash D, aod::is_origin_hash O, typename... Ts>
380class Table;
381
383struct Binding {
384 void const* ptr = nullptr;
385 size_t hash = 0;
386 std::span<TableRef const> refs;
387
388 template <typename T>
389 void bind(T const* table)
390 {
391 ptr = table;
392 hash = o2::framework::TypeIdHelpers::uniqueId<T>();
393 refs = std::span{T::originals};
394 }
395
396 template <typename T>
397 T const* get() const
398 {
399 if (hash == o2::framework::TypeIdHelpers::uniqueId<T>()) {
400 return static_cast<T const*>(ptr);
401 }
402 return nullptr;
403 }
404};
405
406template <typename... C>
408{
409 return std::vector<std::shared_ptr<arrow::Field>>{C::asArrowField()...};
410}
411
412using SelectionVector = std::vector<int64_t>;
413
414template <typename T>
416
417template <typename T>
419
420template <typename T>
422
423template <typename T>
425
426template <typename T>
428
429template <typename T>
430concept has_configurable_extension = has_extension<T> && requires(T t) { typename T::configurable_t; requires std::same_as<std::true_type, typename T::configurable_t>; };
431
432template <typename T>
433concept is_spawnable_column = std::same_as<typename T::spawnable_t, std::true_type>;
434
435template <typename B, typename E>
437 constexpr static bool value = false;
438};
439
440template <aod::is_aod_hash A, aod::is_aod_hash B>
442 constexpr static bool value = false;
443};
444
445template <typename B, typename E>
447
448template <aod::is_aod_hash A, aod::is_aod_hash B>
450
454struct Chunked {
455 constexpr static bool chunked = true;
456};
457
460struct Flat {
461 constexpr static bool chunked = false;
462};
463
465template <typename T>
466struct unwrap {
467 using type = T;
468};
469
470template <typename T>
471struct unwrap<std::vector<T>> {
472 using type = T;
473};
474
475template <>
476struct unwrap<bool> {
477 using type = char;
478};
479
480template <typename T>
481using unwrap_t = typename unwrap<T>::type;
482
487template <typename T, typename ChunkingPolicy = Chunked>
488class ColumnIterator : ChunkingPolicy
489{
490 static constexpr char SCALE_FACTOR = std::same_as<std::decay_t<T>, bool> ? 3 : 0;
491
492 public:
497 ColumnIterator(arrow::ChunkedArray const* column)
498 : mColumn{column},
499 mCurrent{nullptr},
500 mCurrentPos{nullptr},
501 mLast{nullptr},
502 mFirstIndex{0},
503 mCurrentChunk{0},
504 mOffset{0}
505 {
506 auto array = getCurrentArray();
507 mCurrent = reinterpret_cast<unwrap_t<T> const*>(array->values()->data()) + (mOffset >> SCALE_FACTOR);
508 mLast = mCurrent + array->length();
509 }
510
511 ColumnIterator() = default;
514
517
519 void nextChunk() const
520 {
521 auto previousArray = getCurrentArray();
522 mFirstIndex += previousArray->length();
523
525 auto array = getCurrentArray();
526 mCurrent = reinterpret_cast<unwrap_t<T> const*>(array->values()->data()) + (mOffset >> SCALE_FACTOR) - (mFirstIndex >> SCALE_FACTOR);
527 mLast = mCurrent + array->length() + (mFirstIndex >> SCALE_FACTOR);
528 }
529
530 void prevChunk() const
531 {
532 auto previousArray = getCurrentArray();
533 mFirstIndex -= previousArray->length();
534
536 auto array = getCurrentArray();
537 mCurrent = reinterpret_cast<unwrap_t<T> const*>(array->values()->data()) + (mOffset >> SCALE_FACTOR) - (mFirstIndex >> SCALE_FACTOR);
538 mLast = mCurrent + array->length() + (mFirstIndex >> SCALE_FACTOR);
539 }
540
541 void moveToChunk(int chunk)
542 {
543 if (mCurrentChunk < chunk) {
544 while (mCurrentChunk != chunk) {
545 nextChunk();
546 }
547 } else {
548 while (mCurrentChunk != chunk) {
549 prevChunk();
550 }
551 }
552 }
553
556 {
557 mCurrentChunk = mColumn->num_chunks() - 1;
558 auto array = getCurrentArray();
559 mFirstIndex = mColumn->length() - array->length();
560 mCurrent = reinterpret_cast<unwrap_t<T> const*>(array->values()->data()) + (mOffset >> SCALE_FACTOR) - (mFirstIndex >> SCALE_FACTOR);
561 mLast = mCurrent + array->length() + (mFirstIndex >> SCALE_FACTOR);
562 }
563
564 decltype(auto) operator*() const
565 requires std::same_as<bool, std::decay_t<T>>
566 {
567 checkSkipChunk();
568 return (*(mCurrent - (mOffset >> SCALE_FACTOR) + ((*mCurrentPos + mOffset) >> SCALE_FACTOR)) & (1 << ((*mCurrentPos + mOffset) & 0x7))) != 0;
569 }
570
571 decltype(auto) operator*() const
572 requires((!std::same_as<bool, std::decay_t<T>>) && std::same_as<arrow_array_for_t<T>, arrow::ListArray>)
573 {
574 checkSkipChunk();
575 auto list = std::static_pointer_cast<arrow::ListArray>(mColumn->chunk(mCurrentChunk));
576 auto offset = list->value_offset(*mCurrentPos - mFirstIndex);
577 auto length = list->value_length(*mCurrentPos - mFirstIndex);
578 return gsl::span{mCurrent + mFirstIndex + offset, mCurrent + mFirstIndex + (offset + length)};
579 }
580
581 decltype(auto) operator*() const
582 requires((!std::same_as<bool, std::decay_t<T>>) && std::same_as<arrow_array_for_t<T>, arrow::BinaryViewArray>)
583 {
584 checkSkipChunk();
585 auto array = std::static_pointer_cast<arrow::BinaryViewArray>(mColumn->chunk(mCurrentChunk));
586 return array->GetView(*mCurrentPos - mFirstIndex);
587 }
588
589 decltype(auto) operator*() const
590 requires((!std::same_as<bool, std::decay_t<T>>) && !std::same_as<arrow_array_for_t<T>, arrow::ListArray> && !std::same_as<arrow_array_for_t<T>, arrow::BinaryViewArray>)
591 {
592 checkSkipChunk();
593 return *(mCurrent + (*mCurrentPos >> SCALE_FACTOR));
594 }
595
596 // Move to the chunk which containts element pos
598 {
599 checkSkipChunk();
600 return *this;
601 }
602
603 mutable unwrap_t<T> const* mCurrent;
604 int64_t const* mCurrentPos;
605 mutable unwrap_t<T> const* mLast;
606 arrow::ChunkedArray const* mColumn;
607 mutable int mFirstIndex;
608 mutable int mCurrentChunk;
609 mutable int mOffset;
610
611 private:
612 void checkSkipChunk() const
613 requires((ChunkingPolicy::chunked == true) && std::same_as<arrow_array_for_t<T>, arrow::ListArray>)
614 {
615 auto list = std::static_pointer_cast<arrow::ListArray>(mColumn->chunk(mCurrentChunk));
616 if (O2_BUILTIN_UNLIKELY(*mCurrentPos - mFirstIndex >= list->length())) {
617 nextChunk();
618 }
619 }
620
621 void checkSkipChunk() const
622 requires((ChunkingPolicy::chunked == true) && !std::same_as<arrow_array_for_t<T>, arrow::ListArray>)
623 {
624 if (O2_BUILTIN_UNLIKELY(((mCurrent + (*mCurrentPos >> SCALE_FACTOR)) >= mLast))) {
625 nextChunk();
626 }
627 }
628
629 void checkSkipChunk() const
630 requires(ChunkingPolicy::chunked == false)
631 {
632 }
634 auto getCurrentArray() const
635 requires(std::same_as<arrow_array_for_t<T>, arrow::FixedSizeListArray>)
636 {
637 std::shared_ptr<arrow::Array> chunkToUse = mColumn->chunk(mCurrentChunk);
638 mOffset = chunkToUse->offset();
639 chunkToUse = std::dynamic_pointer_cast<arrow::FixedSizeListArray>(chunkToUse)->values();
640 return std::static_pointer_cast<arrow_array_for_t<value_for_t<T>>>(chunkToUse);
641 }
642
643 auto getCurrentArray() const
644 requires(std::same_as<arrow_array_for_t<T>, arrow::ListArray>)
645 {
646 std::shared_ptr<arrow::Array> chunkToUse = mColumn->chunk(mCurrentChunk);
647 mOffset = chunkToUse->offset();
648 chunkToUse = std::dynamic_pointer_cast<arrow::ListArray>(chunkToUse)->values();
649 mOffset = chunkToUse->offset();
650 return std::static_pointer_cast<arrow_array_for_t<value_for_t<T>>>(chunkToUse);
651 }
652
653 auto getCurrentArray() const
654 requires(!std::same_as<arrow_array_for_t<T>, arrow::FixedSizeListArray> && !std::same_as<arrow_array_for_t<T>, arrow::ListArray>)
655 {
656 std::shared_ptr<arrow::Array> chunkToUse = mColumn->chunk(mCurrentChunk);
657 mOffset = chunkToUse->offset();
658 return std::static_pointer_cast<arrow_array_for_t<T>>(chunkToUse);
659 }
660};
661
662template <typename T, typename INHERIT>
663struct Column {
664 using inherited_t = INHERIT;
666 : mColumnIterator{it}
667 {
668 }
669
670 Column() = default;
671 Column(Column const&) = default;
672 Column& operator=(Column const&) = default;
673
674 Column(Column&&) = default;
675 Column& operator=(Column&&) = default;
676
677 using type = T;
678 static constexpr const char* const& columnLabel() { return INHERIT::mLabel; }
680 {
681 return mColumnIterator;
682 }
683
684 static auto asArrowField()
685 {
686 return std::make_shared<arrow::Field>(inherited_t::mLabel, framework::expressions::concreteArrowType(framework::expressions::selectArrowType<type>()));
687 }
688
692};
693
696template <typename F, typename INHERIT>
698 using inherited_t = INHERIT;
699
700 static constexpr const char* const& columnLabel() { return INHERIT::mLabel; }
701};
702
703template <typename INHERIT>
705 using inherited_t = INHERIT;
706 static constexpr const uint32_t hash = 0;
707
708 static constexpr const char* const& columnLabel() { return INHERIT::mLabel; }
709};
710
711template <typename INHERIT>
713 using inherited_t = INHERIT;
714 static constexpr const uint32_t hash = 0;
715
716 static constexpr const char* const& columnLabel() { return INHERIT::mLabel; }
717};
718
719template <size_t M = 0>
720struct Marker : o2::soa::MarkerColumn<Marker<M>> {
721 using type = size_t;
723 constexpr inline static auto value = M;
724
725 Marker() = default;
726 Marker(Marker const&) = default;
727 Marker(Marker&&) = default;
728
729 Marker& operator=(Marker const&) = default;
730 Marker& operator=(Marker&&) = default;
731
732 Marker(arrow::ChunkedArray const*) {}
733 constexpr inline auto mark()
734 {
735 return value;
736 }
737
738 static constexpr const char* mLabel = "Marker";
739};
740
741template <int64_t START = 0, int64_t END = -1>
742struct Index : o2::soa::IndexColumn<Index<START, END>> {
744 constexpr inline static int64_t start = START;
745 constexpr inline static int64_t end = END;
746
747 Index() = default;
748 Index(Index const&) = default;
749 Index(Index&&) = default;
750
751 Index& operator=(Index const&) = default;
752 Index& operator=(Index&&) = default;
753
754 Index(arrow::ChunkedArray const*)
755 {
756 }
757
758 constexpr inline int64_t rangeStart()
759 {
760 return START;
761 }
762
763 constexpr inline int64_t rangeEnd()
764 {
765 return END;
766 }
767
768 [[nodiscard]] int64_t index() const
769 {
770 return index<0>();
771 }
772
773 [[nodiscard]] int64_t filteredIndex() const
774 {
775 return index<1>();
776 }
777
778 [[nodiscard]] int64_t globalIndex() const
779 {
780 return index<0>() + offsets<0>();
781 }
782
783 template <int N = 0>
784 [[nodiscard]] int64_t index() const
785 {
786 return *std::get<N>(rowIndices);
787 }
788
789 template <int N = 0>
790 [[nodiscard]] int64_t offsets() const
791 {
792 return *std::get<N>(rowOffsets);
793 }
794
795 void setIndices(std::tuple<int64_t const*, int64_t const*> indices)
796 {
798 }
799
800 void setOffsets(std::tuple<uint64_t const*> offsets)
801 {
803 }
804
805 static constexpr const char* mLabel = "Index";
806 using type = int64_t;
807
808 std::tuple<int64_t const*, int64_t const*> rowIndices;
811 std::tuple<uint64_t const*> rowOffsets;
812};
813
814template <typename C>
815concept is_indexing_column = requires(C& c) {
816 c.rowIndices;
817 c.rowOffsets;
818};
819
820template <typename C>
821concept is_dynamic_column = requires(C& c) {
822 c.boundIterators;
823};
824
825template <typename C>
826concept is_marker_column = requires { &C::mark; };
827
828template <typename T>
829using is_dynamic_t = std::conditional_t<is_dynamic_column<T>, std::true_type, std::false_type>;
830
831template <typename T>
833
834template <typename T>
835using is_indexing_t = std::conditional_t<is_indexing_column<T>, std::true_type, std::false_type>;
836
839 int64_t mRowIndex = 0;
841 uint64_t mOffset = 0;
842};
843
845 int64_t const index;
846};
847
849 // We use -1 in the IndexPolicyBase to indicate that the index is
850 // invalid. What will validate the index is the this->setCursor()
851 // which happens below which will properly setup the first index
852 // by remapping the filtered index 0 to whatever unfiltered index
853 // it belongs to.
854 FilteredIndexPolicy(gsl::span<int64_t const> selection, int64_t rows, uint64_t offset = 0)
855 : IndexPolicyBase{-1, offset},
856 mSelectedRows(selection),
857 mMaxSelection(selection.size()),
858 nRows{rows}
859 {
860 this->setCursor(0);
861 }
862
863 void resetSelection(gsl::span<int64_t const> selection)
864 {
865 mSelectedRows = selection;
866 mMaxSelection = selection.size();
867 this->setCursor(0);
868 }
869
875
876 [[nodiscard]] std::tuple<int64_t const*, int64_t const*>
878 {
879 return std::make_tuple(&mRowIndex, &mSelectionRow);
880 }
881
882 [[nodiscard]] std::tuple<uint64_t const*>
884 {
885 return std::make_tuple(&mOffset);
886 }
887
888 void limitRange(int64_t start, int64_t end)
889 {
890 this->setCursor(start);
891 if (end >= 0) {
892 mMaxSelection = std::min(end, mMaxSelection);
893 }
894 }
895
896 void setCursor(int64_t i)
897 {
898 mSelectionRow = i;
899 updateRow();
900 }
901
902 void moveByIndex(int64_t i)
903 {
904 mSelectionRow += i;
905 updateRow();
906 }
907
908 friend bool operator==(FilteredIndexPolicy const& lh, FilteredIndexPolicy const& rh)
909 {
910 return lh.mSelectionRow == rh.mSelectionRow;
911 }
912
913 bool operator==(RowViewSentinel const& sentinel) const
914 {
915 return O2_BUILTIN_UNLIKELY(mSelectionRow == sentinel.index);
916 }
917
922 {
923 this->mSelectionRow = this->mMaxSelection;
924 this->mRowIndex = -1;
925 }
926
927 [[nodiscard]] auto getSelectionRow() const
928 {
929 return mSelectionRow;
930 }
931
932 [[nodiscard]] auto size() const
933 {
934 return mMaxSelection;
935 }
936
937 [[nodiscard]] auto raw_size() const
938 {
939 return nRows;
940 }
941
942 private:
943 inline void updateRow()
944 {
945 this->mRowIndex = O2_BUILTIN_LIKELY(mSelectionRow < mMaxSelection) ? mSelectedRows[mSelectionRow] : -1;
946 }
947 gsl::span<int64_t const> mSelectedRows;
948 int64_t mSelectionRow = 0;
949 int64_t mMaxSelection = 0;
950 int64_t nRows = 0;
951};
952
960
964 DefaultIndexPolicy(int64_t nRows, uint64_t offset)
966 mMaxRow(nRows)
967 {
968 }
969
975
976 void limitRange(int64_t start, int64_t end)
977 {
978 this->setCursor(start);
979 if (end >= 0) {
980 mMaxRow = std::min(end, mMaxRow);
981 }
982 }
983
984 [[nodiscard]] std::tuple<int64_t const*, int64_t const*>
986 {
987 return std::make_tuple(&mRowIndex, &mRowIndex);
988 }
989
990 [[nodiscard]] std::tuple<uint64_t const*>
992 {
993 return std::make_tuple(&mOffset);
994 }
995
996 void setCursor(int64_t i)
997 {
998 this->mRowIndex = i;
999 }
1000 void moveByIndex(int64_t i)
1001 {
1002 this->mRowIndex += i;
1003 }
1004
1006 {
1007 this->setCursor(mMaxRow);
1008 }
1009
1010 friend bool operator==(DefaultIndexPolicy const& lh, DefaultIndexPolicy const& rh)
1011 {
1012 return lh.mRowIndex == rh.mRowIndex;
1013 }
1014
1015 bool operator==(RowViewSentinel const& sentinel) const
1016 {
1017 return O2_BUILTIN_UNLIKELY(this->mRowIndex == sentinel.index);
1018 }
1019
1020 [[nodiscard]] auto size() const
1021 {
1022 return mMaxRow;
1023 }
1024
1025 int64_t mMaxRow = 0;
1026};
1027
1028// template <OriginEnc ORIGIN, typename... C>
1029// class Table;
1030
1031template <aod::is_aod_hash L, aod::is_aod_hash D, aod::is_origin_hash O, typename... T>
1032class Table;
1033
1034template <typename T>
1036
1039template <typename C>
1042 arrow::ChunkedArray* second;
1043};
1044
1045template <typename T, typename B>
1046concept can_bind = requires(T&& t) {
1047 { t.B::mColumnIterator };
1048};
1049
1050template <typename... C>
1052
1053template <typename D, typename O, typename IP, typename... C>
1054struct TableIterator : IP, C... {
1055 public:
1056 using self_t = TableIterator<D, O, IP, C...>;
1057 using policy_t = IP;
1062 using bindings_pack_t = decltype([]<typename... Cs>(framework::pack<Cs...>) -> framework::pack<typename Cs::binding_t...> {}(external_index_columns_t{})); // decltype(extractBindings(external_index_columns_t{}));
1063
1064 TableIterator(arrow::ChunkedArray* columnData[sizeof...(C)], IP&& policy)
1065 : IP{policy},
1066 C(columnData[framework::has_type_at_v<C>(all_columns{})])...
1067 {
1068 bind();
1069 }
1070
1071 TableIterator(arrow::ChunkedArray* columnData[sizeof...(C)], IP&& policy)
1072 requires(has_index<C...>)
1073 : IP{policy},
1074 C(columnData[framework::has_type_at_v<C>(all_columns{})])...
1075 {
1076 bind();
1077 // In case we have an index column might need to constrain the actual
1078 // number of rows in the view to the range provided by the index.
1079 // FIXME: we should really understand what happens to an index when we
1080 // have a RowViewFiltered.
1081 this->limitRange(this->rangeStart(), this->rangeEnd());
1082 }
1083
1084 TableIterator() = default;
1086 : IP{static_cast<IP const&>(other)},
1087 C(static_cast<C const&>(other))...
1088 {
1089 bind();
1090 }
1091
1093 {
1094 IP::operator=(static_cast<IP const&>(other));
1095 (void(static_cast<C&>(*this) = static_cast<C>(other)), ...);
1096 bind();
1097 return *this;
1098 }
1099
1101 requires std::same_as<IP, DefaultIndexPolicy>
1102 : IP{static_cast<IP const&>(other)},
1103 C(static_cast<C const&>(other))...
1104 {
1105 bind();
1106 }
1107
1109 {
1110 this->moveByIndex(1);
1111 return *this;
1112 }
1113
1115 {
1116 self_t copy = *this;
1117 this->operator++();
1118 return copy;
1119 }
1120
1122 {
1123 this->moveByIndex(-1);
1124 return *this;
1125 }
1126
1128 {
1129 self_t copy = *this;
1130 this->operator--();
1131 return copy;
1132 }
1133
1135 TableIterator operator+(int64_t inc) const
1136 {
1137 TableIterator copy = *this;
1138 copy.moveByIndex(inc);
1139 return copy;
1140 }
1141
1142 TableIterator operator-(int64_t dec) const
1143 {
1144 return operator+(-dec);
1145 }
1146
1148 {
1149 return *this;
1150 }
1151
1152 template <typename... CL, typename TA>
1154 {
1155 (CL::setCurrent(current), ...);
1156 }
1157
1158 template <typename CL>
1159 auto getCurrent() const
1160 {
1161 return CL::getCurrentRaw();
1162 }
1163
1164 template <typename... Cs>
1166 {
1167 return std::vector<o2::soa::Binding>{static_cast<Cs const&>(*this).getCurrentRaw()...};
1168 }
1169
1170 auto getIndexBindings() const
1171 {
1173 }
1174
1175 template <typename... TA>
1176 void bindExternalIndices(TA*... current)
1177 {
1179 }
1180
1181 template <typename... Cs>
1182 void doSetCurrentIndexRaw(framework::pack<Cs...> p, std::vector<o2::soa::Binding>&& ptrs)
1183 {
1184 (Cs::setCurrentRaw(ptrs[framework::has_type_at_v<Cs>(p)]), ...);
1185 }
1186
1187 template <typename... Cs, typename I>
1189 {
1191 b.bind(ptr);
1192 (Cs::setCurrentRaw(b), ...);
1193 }
1194
1195 void bindExternalIndicesRaw(std::vector<o2::soa::Binding>&& ptrs)
1196 {
1197 doSetCurrentIndexRaw(external_index_columns_t{}, std::forward<std::vector<o2::soa::Binding>>(ptrs));
1198 }
1199
1200 template <typename I>
1201 void bindInternalIndices(I const* table)
1202 {
1204 }
1205
1206 private:
1208 template <typename... PC>
1209 void doMoveToEnd(framework::pack<PC...>)
1210 {
1211 (PC::mColumnIterator.moveToEnd(), ...);
1212 }
1213
1216 void bind()
1217 {
1218 using namespace o2::soa;
1219 auto f = framework::overloaded{
1220 [this]<soa::is_persistent_column T>(T*) -> void { T::mColumnIterator.mCurrentPos = &this->mRowIndex; },
1221 [this]<soa::is_dynamic_column T>(T*) -> void { bindDynamicColumn<T>(typename T::bindings_t{}); },
1222 [this]<typename T>(T*) -> void {},
1223 };
1224 (f(static_cast<C*>(nullptr)), ...);
1225 if constexpr (has_index<C...>) {
1226 this->setIndices(this->getIndices());
1227 this->setOffsets(this->getOffsets());
1228 }
1229 }
1230
1231 template <typename DC, typename... B>
1232 auto bindDynamicColumn(framework::pack<B...>)
1233 {
1234 DC::boundIterators = std::make_tuple(getDynamicBinding<B>()...);
1235 }
1236
1237 // Sometimes dynamic columns are defined for tables in
1238 // the hope that it will be joined / extended with another one which provides
1239 // the full set of bindings. This is to avoid a compilation
1240 // error if constructor for the table or any other thing involving a missing
1241 // binding is preinstanciated.
1242 template <typename B>
1243 requires(can_bind<self_t, B>)
1244 decltype(auto) getDynamicBinding()
1245 {
1246 static_assert(std::same_as<decltype(&(static_cast<B*>(this)->mColumnIterator)), std::decay_t<decltype(B::mColumnIterator)>*>, "foo");
1247 return &(static_cast<B*>(this)->mColumnIterator);
1248 // return static_cast<std::decay_t<decltype(B::mColumnIterator)>*>(nullptr);
1249 }
1250
1251 template <typename B>
1252 decltype(auto) getDynamicBinding()
1253 {
1254 return static_cast<std::decay_t<decltype(B::mColumnIterator)>*>(nullptr);
1255 }
1256};
1257
1259 static std::shared_ptr<arrow::Table> joinTables(std::vector<std::shared_ptr<arrow::Table>>&& tables, std::span<const char* const> labels);
1260 static std::shared_ptr<arrow::Table> concatTables(std::vector<std::shared_ptr<arrow::Table>>&& tables);
1261};
1262
1264template <typename T>
1266
1267template <typename T>
1268concept with_originals = requires {
1269 T::originals.size();
1270};
1271
1272template <typename T>
1273concept with_sources = requires {
1274 T::sources.size();
1275};
1276
1277template <typename T>
1278concept with_base_table = not_void<typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata::base_table_t>;
1279
1280template <size_t N1, std::array<TableRef, N1> os1, size_t N2, std::array<TableRef, N2> os2>
1281consteval bool is_compatible()
1282{
1283 return []<size_t... Is>(std::index_sequence<Is...>) {
1284 return ([]<size_t... Ks>(std::index_sequence<Ks...>) {
1285 constexpr auto h = os1[Is].desc_hash;
1286 using H = o2::aod::Hash<h>;
1287 return (((h == os2[Ks].desc_hash) || is_ng_index_equivalent_v<H, o2::aod::Hash<os2[Ks].desc_hash>>) || ...);
1288 }(std::make_index_sequence<N2>()) ||
1289 ...);
1290 }(std::make_index_sequence<N1>());
1291}
1292
1293template <with_originals T, with_originals B>
1295{
1296 return is_compatible<T::originals.size(), T::originals, B::originals.size(), B::originals>();
1297}
1298
1299template <typename T, typename B>
1300using is_binding_compatible = std::conditional_t<is_binding_compatible_v<T, typename B::binding_t>(), std::true_type, std::false_type>;
1301
1302template <typename L, typename D, typename O, typename Key, typename H, typename... Ts>
1303struct IndexTable;
1304
1305template <typename T>
1307
1308template <soa::is_table T>
1309static constexpr std::string getLabelForTable()
1310{
1311 return std::string{aod::label<std::decay_t<T>::originals[0]>()};
1312}
1313
1314template <soa::is_table T>
1316static constexpr std::string getLabelFromType()
1317{
1318 return getLabelForTable<T>();
1319}
1320
1321template <soa::is_iterator T>
1322static constexpr std::string getLabelFromType()
1323{
1324 return getLabelForTable<typename std::decay_t<T>::parent_t>();
1325}
1326
1327template <soa::is_index_table T>
1328static constexpr std::string getLabelFromType()
1329{
1330 return getLabelForTable<typename std::decay_t<T>::first_t>();
1331}
1332template <soa::with_base_table T>
1333static constexpr std::string getLabelFromType()
1334{
1335 return getLabelForTable<typename aod::MetadataTrait<o2::aod::Hash<T::ref.desc_hash>>::metadata::base_table_t>();
1336}
1337
1338template <typename... C>
1339static constexpr auto hasColumnForKey(framework::pack<C...>, std::string const& key)
1340{
1341 return ((C::inherited_t::mLabel == key) || ...);
1342}
1343
1344template <TableRef ref>
1345static constexpr std::pair<bool, std::string> hasKey(std::string const& key)
1346{
1347 return {hasColumnForKey(typename aod::MetadataTrait<o2::aod::Hash<ref.desc_hash>>::metadata::columns{}, key), aod::label<ref>()};
1348}
1349
1350template <typename... C>
1351static constexpr auto haveKey(framework::pack<C...>, std::string const& key)
1352{
1353 return std::vector{hasKey<C>(key)...};
1354}
1355
1356void notFoundColumn(const char* label, const char* key);
1357void missingOptionalPreslice(const char* label, const char* key);
1358
1359template <with_originals T, bool OPT = false>
1360static constexpr std::string getLabelFromTypeForKey(std::string const& key)
1361{
1362 if constexpr (T::originals.size() == 1) {
1363 auto locate = hasKey<T::originals[0]>(key);
1364 if (locate.first) {
1365 return locate.second;
1366 }
1367 } else {
1368 auto locate = [&]<size_t... Is>(std::index_sequence<Is...>) {
1369 return std::vector{hasKey<T::originals[Is]>(key)...};
1370 }(std::make_index_sequence<T::originals.size()>{});
1371 auto it = std::find_if(locate.begin(), locate.end(), [](auto const& x) { return x.first; });
1372 if (it != locate.end()) {
1373 return it->second;
1374 }
1375 }
1376 if constexpr (!OPT) {
1377 notFoundColumn(getLabelFromType<std::decay_t<T>>().data(), key.data());
1378 } else {
1379 return "[MISSING]";
1380 }
1382}
1383
1384template <typename B, typename... C>
1385consteval static bool hasIndexTo(framework::pack<C...>&&)
1386{
1387 return (o2::soa::is_binding_compatible_v<B, typename C::binding_t>() || ...);
1388}
1389
1390template <typename B, typename... C>
1391consteval static bool hasSortedIndexTo(framework::pack<C...>&&)
1392{
1393 return ((C::sorted && o2::soa::is_binding_compatible_v<B, typename C::binding_t>()) || ...);
1394}
1395
1396template <typename B, typename Z>
1397consteval static bool relatedByIndex()
1398{
1399 return hasIndexTo<B>(typename Z::table_t::external_index_columns_t{});
1400}
1401
1402template <typename B, typename Z>
1403consteval static bool relatedBySortedIndex()
1404{
1405 return hasSortedIndexTo<B>(typename Z::table_t::external_index_columns_t{});
1406}
1407} // namespace o2::soa
1408
1409namespace o2::framework
1410{
1411
1413 const std::string binding;
1415
1416 bool isMissing() const;
1417 Entry const& getBindingKey() const;
1418};
1419
1421 void updateSliceInfo(SliceInfoPtr&& si);
1422
1424 std::shared_ptr<arrow::Table> getSliceFor(int value, std::shared_ptr<arrow::Table> const& input, uint64_t& offset) const;
1425};
1426
1429
1431 gsl::span<const int64_t> getSliceFor(int value) const;
1432};
1433
1434template <typename T, typename Policy, bool OPT = false>
1435struct PresliceBase : public Policy {
1436 constexpr static bool optional = OPT;
1437 using target_t = T;
1438 using policy_t = Policy;
1439 const std::string binding;
1440
1442 : Policy{PreslicePolicyBase{{o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name})}, Entry(o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name}), std::string{index_.name})}, {}}
1443 {
1444 }
1445
1446 std::shared_ptr<arrow::Table> getSliceFor(int value, std::shared_ptr<arrow::Table> const& input, uint64_t& offset) const
1447 {
1448 if constexpr (OPT) {
1449 if (Policy::isMissing()) {
1450 return nullptr;
1451 }
1452 }
1453 return Policy::getSliceFor(value, input, offset);
1454 }
1455
1456 gsl::span<const int64_t> getSliceFor(int value) const
1457 {
1458 if constexpr (OPT) {
1459 if (Policy::isMissing()) {
1460 return {};
1461 }
1462 }
1463 return Policy::getSliceFor(value);
1464 }
1465};
1466
1467template <typename T>
1469template <typename T>
1471template <typename T>
1473template <typename T>
1475
1476template <typename T>
1477concept is_preslice = std::derived_from<T, PreslicePolicyBase>;
1478
1492};
1493
1494template <typename T>
1495concept is_preslice_group = std::derived_from<T, PresliceGroup>;
1496
1497} // namespace o2::framework
1498
1499namespace o2::soa
1500{
1501template <soa::is_table T>
1502class FilteredBase;
1503template <typename T>
1504class Filtered;
1505
1506template <typename T>
1507concept has_filtered_policy = not_void<typename T::policy_t> && std::same_as<typename T::policy_t, soa::FilteredIndexPolicy>;
1508
1509template <typename T>
1511
1512template <typename T>
1514
1515// FIXME: compatbility declaration to be removed
1516template <typename T>
1518
1519template <typename T>
1521
1522template <typename T>
1524
1526template <typename... Is>
1527static consteval auto extractBindings(framework::pack<Is...>)
1528{
1529 return framework::pack<typename Is::binding_t...>{};
1530}
1531
1533
1534template <typename T, typename C, typename Policy, bool OPT>
1535 requires std::same_as<Policy, framework::PreslicePolicySorted> && (o2::soa::is_binding_compatible_v<C, T>())
1536auto doSliceBy(T const* table, o2::framework::PresliceBase<C, Policy, OPT> const& container, int value)
1537{
1538 if constexpr (OPT) {
1539 if (container.isMissing()) {
1540 missingOptionalPreslice(getLabelFromType<std::decay_t<T>>().data(), container.bindingKey.key.c_str());
1541 }
1542 }
1543 uint64_t offset = 0;
1544 auto out = container.getSliceFor(value, table->asArrowTable(), offset);
1545 auto t = typename T::self_t({out}, offset);
1546 table->copyIndexBindings(t);
1547 t.bindInternalIndicesTo(table);
1548 return t;
1549}
1550
1551template <soa::is_filtered_table T>
1552auto doSliceByHelper(T const* table, gsl::span<const int64_t> const& selection)
1553{
1554 auto t = soa::Filtered<typename T::base_t>({table->asArrowTable()}, selection);
1555 table->copyIndexBindings(t);
1556 t.bindInternalIndicesTo(table);
1557 t.intersectWithSelection(table->getSelectedRows()); // intersect filters
1558 return t;
1559}
1560
1561template <soa::is_table T>
1562 requires(!soa::is_filtered_table<T>)
1563auto doSliceByHelper(T const* table, gsl::span<const int64_t> const& selection)
1564{
1565 auto t = soa::Filtered<T>({table->asArrowTable()}, selection);
1566 table->copyIndexBindings(t);
1567 t.bindInternalIndicesTo(table);
1568 return t;
1569}
1570
1571template <typename T, typename C, typename Policy, bool OPT>
1572 requires std::same_as<Policy, framework::PreslicePolicyGeneral> && (o2::soa::is_binding_compatible_v<C, T>())
1573auto doSliceBy(T const* table, o2::framework::PresliceBase<C, Policy, OPT> const& container, int value)
1574{
1575 if constexpr (OPT) {
1576 if (container.isMissing()) {
1577 missingOptionalPreslice(getLabelFromType<std::decay_t<T>>().data(), container.bindingKey.key.c_str());
1578 }
1579 }
1580 auto selection = container.getSliceFor(value);
1581 return doSliceByHelper(table, selection);
1582}
1583
1584SelectionVector sliceSelection(gsl::span<int64_t const> const& mSelectedRows, int64_t nrows, uint64_t offset);
1585
1586template <soa::is_filtered_table T>
1587auto prepareFilteredSlice(T const* table, std::shared_ptr<arrow::Table> slice, uint64_t offset)
1588{
1589 if (offset >= static_cast<uint64_t>(table->tableSize())) {
1590 Filtered<typename T::base_t> fresult{{{slice}}, SelectionVector{}, 0};
1591 table->copyIndexBindings(fresult);
1592 return fresult;
1593 }
1594 auto slicedSelection = sliceSelection(table->getSelectedRows(), slice->num_rows(), offset);
1595 Filtered<typename T::base_t> fresult{{{slice}}, std::move(slicedSelection), offset};
1596 table->copyIndexBindings(fresult);
1597 return fresult;
1598}
1599
1600template <soa::is_filtered_table T, typename C, bool OPT>
1601 requires(o2::soa::is_binding_compatible_v<C, T>())
1603{
1604 if constexpr (OPT) {
1605 if (container.isMissing()) {
1606 missingOptionalPreslice(getLabelFromType<T>().data(), container.bindingKey.key.c_str());
1607 }
1608 }
1609 uint64_t offset = 0;
1610 auto slice = container.getSliceFor(value, table->asArrowTable(), offset);
1611 return prepareFilteredSlice(table, slice, offset);
1612}
1613
1614template <typename T>
1616{
1617 auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<T>(node.name), node.name});
1618 auto [offset, count] = localCache.getSliceFor(value);
1619 auto t = typename T::self_t({table->asArrowTable()->Slice(static_cast<uint64_t>(offset), count)}, static_cast<uint64_t>(offset));
1620 table->copyIndexBindings(t);
1621 return t;
1622}
1623
1624template <typename T>
1626{
1627 auto localCache = cache.ptr->getCacheFor({o2::soa::getLabelFromTypeForKey<T>(node.name), node.name});
1628 auto [offset, count] = localCache.getSliceFor(value);
1629 auto slice = table->asArrowTable()->Slice(static_cast<uint64_t>(offset), count);
1630 return prepareFilteredSlice(table, slice, offset);
1631}
1632
1633template <typename T>
1635{
1636 auto localCache = cache.ptr->getCacheUnsortedFor({o2::soa::getLabelFromTypeForKey<T>(node.name), node.name});
1637 if constexpr (soa::is_filtered_table<T>) {
1638 auto t = typename T::self_t({table->asArrowTable()}, localCache.getSliceFor(value));
1639 t.intersectWithSelection(table->getSelectedRows());
1640 table->copyIndexBindings(t);
1641 return t;
1642 } else {
1643 auto t = Filtered<T>({table->asArrowTable()}, localCache.getSliceFor(value));
1644 table->copyIndexBindings(t);
1645 return t;
1646 }
1647}
1648
1649template <with_originals T>
1651{
1652 return Filtered<T>({t.asArrowTable()}, selectionToVector(framework::expressions::createSelection(t.asArrowTable(), f)));
1653}
1654
1655arrow::ChunkedArray* getIndexFromLabel(arrow::Table* table, std::string_view label);
1656
1657template <typename D, typename O, typename IP, typename... C>
1658consteval auto base_iter(framework::pack<C...>&&) -> TableIterator<D, O, IP, C...>
1659{
1660}
1661
1662template <TableRef ref, typename... Ts>
1663 requires((sizeof...(Ts) > 0) && (soa::is_column<Ts> && ...))
1664consteval auto getColumns()
1665{
1666 return framework::pack<Ts...>{};
1667}
1668
1669template <TableRef ref, typename... Ts>
1670 requires((sizeof...(Ts) > 0) && !(soa::is_column<Ts> || ...) && (ref.origin_hash == "CONC"_h))
1671consteval auto getColumns()
1672{
1673 return framework::full_intersected_pack_t<typename Ts::columns_t...>{};
1674}
1675
1676template <TableRef ref, typename... Ts>
1677 requires((sizeof...(Ts) > 0) && !(soa::is_column<Ts> || ...) && (ref.origin_hash != "CONC"_h))
1678consteval auto getColumns()
1679{
1680 return framework::concatenated_pack_unique_t<typename Ts::columns_t...>{};
1681}
1682
1683template <TableRef ref, typename... Ts>
1684 requires(sizeof...(Ts) == 0 && soa::has_metadata<aod::MetadataTrait<o2::aod::Hash<ref.desc_hash>>>)
1685consteval auto getColumns()
1686{
1687 return typename aod::MetadataTrait<o2::aod::Hash<ref.desc_hash>>::metadata::columns{};
1688}
1689
1690template <TableRef ref, typename... Ts>
1691 requires((sizeof...(Ts) == 0) || (o2::soa::is_column<Ts> && ...))
1692consteval auto computeOriginals()
1693{
1694 return std::array<TableRef, 1>{ref};
1695}
1696
1697template <TableRef ref, typename... Ts>
1698 requires((sizeof...(Ts) > 0) && (!o2::soa::is_column<Ts> || ...))
1699consteval auto computeOriginals()
1700{
1701 return o2::soa::mergeOriginals<Ts...>();
1702}
1703
1706template <aod::is_aod_hash L, aod::is_aod_hash D, aod::is_origin_hash O, typename... Ts>
1708{
1709 public:
1710 static constexpr const auto ref = TableRef{L::hash, D::hash, O::hash, o2::aod::version(D::str)};
1711 using self_t = Table<L, D, O, Ts...>;
1713
1714 static constexpr const auto originals = computeOriginals<ref, Ts...>();
1715 static constexpr const auto originalLabels = []<size_t N, std::array<TableRef, N> refs, size_t... Is>(std::index_sequence<Is...>) { return std::array<const char*, N>{o2::aod::label<refs[Is]>()...}; }.template operator()<originals.size(), originals>(std::make_index_sequence<originals.size()>());
1716
1717 template <size_t N, std::array<TableRef, N> bindings>
1718 requires(ref.origin_hash == "CONC"_h)
1719 static consteval auto isIndexTargetOf()
1720 {
1721 return false;
1722 }
1723
1724 template <size_t N, std::array<TableRef, N> bindings>
1725 requires(ref.origin_hash == "JOIN"_h)
1726 static consteval auto isIndexTargetOf()
1727 {
1728 return std::find_if(self_t::originals.begin(), self_t::originals.end(),
1729 [](TableRef const& r) {
1730 return std::find(bindings.begin(), bindings.end(), r) != bindings.end();
1731 }) != self_t::originals.end();
1732 }
1733
1734 template <size_t N, std::array<TableRef, N> bindings>
1735 requires(!(ref.origin_hash == "CONC"_h || ref.origin_hash == "JOIN"_h))
1736 static consteval auto isIndexTargetOf()
1737 {
1738 return std::find(bindings.begin(), bindings.end(), self_t::ref) != bindings.end();
1739 }
1740
1741 template <TableRef r>
1742 static consteval bool hasOriginal()
1743 {
1744 return std::find_if(originals.begin(), originals.end(), [](TableRef const& o) { return o.desc_hash == r.desc_hash; }) != originals.end();
1745 }
1746
1747 using columns_t = decltype(getColumns<ref, Ts...>());
1748
1751
1754 template <typename IP>
1755 using base_iterator = decltype(base_iter<D, O, IP>(columns_t{}));
1756
1757 template <typename IP, typename Parent, typename... T>
1759 using columns_t = typename Parent::columns_t;
1760 using external_index_columns_t = typename Parent::external_index_columns_t;
1762 // static constexpr const std::array<TableRef, sizeof...(T)> originals{T::ref...};
1763 static constexpr auto originals = Parent::originals;
1764 using policy_t = IP;
1765 using parent_t = Parent;
1766
1768
1769 TableIteratorBase(arrow::ChunkedArray* columnData[framework::pack_size(columns_t{})], IP&& policy)
1770 : base_iterator<IP>(columnData, std::forward<decltype(policy)>(policy))
1771 {
1772 }
1773
1774 template <typename P, typename... Os>
1776 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1777 {
1778 static_cast<base_iterator<IP>&>(*this) = static_cast<base_iterator<IP>>(other);
1779 return *this;
1780 }
1781
1782 template <typename P>
1784 {
1785 static_cast<base_iterator<IP>&>(*this) = static_cast<base_iterator<IP>>(other);
1786 return *this;
1787 }
1788
1789 template <typename P>
1791 requires std::same_as<IP, DefaultIndexPolicy>
1792 {
1793 static_cast<base_iterator<IP>&>(*this) = static_cast<base_iterator<FilteredIndexPolicy>>(other);
1794 return *this;
1795 }
1796
1797 template <typename P, typename O1, typename... Os>
1799 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1800 {
1801 *this = other;
1802 }
1803
1804 template <typename P, typename O1, typename... Os>
1806 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1807 {
1808 *this = other;
1809 }
1810
1811 template <typename P>
1816
1817 template <typename P>
1819 {
1820 *this = other;
1821 }
1822
1823 template <typename P>
1825 requires std::same_as<IP, DefaultIndexPolicy>
1826 {
1827 *this = other;
1828 }
1829
1831 {
1832 this->mRowIndex = other.index;
1833 return *this;
1834 }
1835 template <typename P>
1837 {
1838 this->mRowIndex = other.mRowIndex;
1839 }
1840
1841 template <typename P, typename... Os>
1843 requires std::same_as<typename P::table_t, typename Parent::table_t>
1844 {
1845 this->mRowIndex = other.mRowIndex;
1846 }
1847
1848 template <typename TI>
1849 auto getId() const
1850 {
1851 using decayed = std::decay_t<TI>;
1852 if constexpr (framework::has_type<decayed>(bindings_pack_t{})) { // index to another table
1853 constexpr auto idx = framework::has_type_at_v<decayed>(bindings_pack_t{});
1855 } else if constexpr (std::same_as<decayed, Parent>) { // self index
1856 return this->globalIndex();
1857 } else if constexpr (is_indexing_column<decayed>) { // soa::Index<>
1858 return this->globalIndex();
1859 } else {
1860 return static_cast<int32_t>(-1);
1861 }
1862 }
1863
1864 template <typename CD, typename... CDArgs>
1865 auto getDynamicColumn() const
1866 {
1867 using decayed = std::decay_t<CD>;
1868 static_assert(is_dynamic_t<decayed>(), "Requested column is not a dynamic column");
1869 return static_cast<decayed>(*this).template getDynamicValue<CDArgs...>();
1870 }
1871
1872 template <typename B, typename CC>
1873 auto getValue() const
1874 {
1875 using COL = std::decay_t<CC>;
1876 static_assert(is_dynamic_t<COL>() || soa::is_persistent_column<COL>, "Should be persistent or dynamic column with no argument that has a return type convertable to float");
1877 return static_cast<B>(static_cast<COL>(*this).get());
1878 }
1879
1880 template <typename B, typename... CCs>
1881 std::array<B, sizeof...(CCs)> getValues() const
1882 {
1883 static_assert(std::same_as<B, float> || std::same_as<B, double>, "The common return type should be float or double");
1884 return {getValue<B, CCs>()...};
1885 }
1886
1887 using IP::size;
1888
1889 using base_iterator<IP>::operator++;
1890
1892 TableIteratorBase operator+(int64_t inc) const
1893 {
1894 TableIteratorBase copy = *this;
1895 copy.moveByIndex(inc);
1896 return copy;
1897 }
1898
1899 TableIteratorBase operator-(int64_t dec) const
1900 {
1901 return operator+(-dec);
1902 }
1903
1905 {
1906 return *this;
1907 }
1908 };
1909
1910 template <typename IP, typename Parent, typename... T>
1912
1913 template <typename IP, typename Parent>
1914 static consteval auto full_iter()
1915 {
1916 if constexpr (sizeof...(Ts) == 0) {
1918 } else {
1919 if constexpr ((o2::soa::is_column<Ts> && ...)) {
1921 } else {
1922 return iterator_template<IP, Parent, Ts...>{};
1923 }
1924 }
1925 }
1926
1927 template <typename IP, typename Parent>
1928 using iterator_template_o = decltype(full_iter<IP, Parent>());
1929
1932
1936
1937 static constexpr auto hashes()
1938 {
1939 return []<typename... C>(framework::pack<C...>) { return std::set{{C::hash...}}; }(columns_t{});
1940 }
1941
1942 Table(std::shared_ptr<arrow::Table> table, uint64_t offset = 0)
1943 : mTable(table),
1944 mEnd{table->num_rows()},
1945 mOffset(offset)
1946 {
1947 if (mTable->num_rows() == 0) {
1948 for (size_t ci = 0; ci < framework::pack_size(columns_t{}); ++ci) {
1949 mColumnChunks[ci] = nullptr;
1950 }
1951 mBegin = mEnd;
1952 } else {
1953 auto lookups = [this]<typename... C>(framework::pack<C...>) -> std::array<arrow::ChunkedArray*, framework::pack_size(columns_t{})> { return {lookupColumn<C>()...}; }(columns_t{});
1954 for (size_t ci = 0; ci < framework::pack_size(columns_t{}); ++ci) {
1955 mColumnChunks[ci] = lookups[ci];
1956 }
1957 mBegin = unfiltered_iterator{mColumnChunks, {table->num_rows(), offset}};
1958 mBegin.bindInternalIndices(this);
1959 }
1960 }
1961
1962 Table(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t offset = 0)
1963 requires(ref.origin_hash != "CONC"_h)
1964 : Table(ArrowHelpers::joinTables(std::move(tables), std::span{originalLabels}), offset)
1965 {
1966 }
1967
1968 Table(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t offset = 0)
1969 requires(ref.origin_hash == "CONC"_h)
1970 : Table(ArrowHelpers::concatTables(std::move(tables)), offset)
1971 {
1972 }
1973
1974 template <typename Key>
1975 inline arrow::ChunkedArray* getIndexToKey()
1976 {
1977 constexpr auto map = []<typename... Cs>(framework::pack<Cs...>) {
1978 return std::array<bool, sizeof...(Cs)>{[]() {
1979 if constexpr (requires { Cs::index_targets.size(); }) {
1980 return Key::template isIndexTargetOf<Cs::index_targets.size(), Cs::index_targets>();
1981 } else {
1982 return false;
1983 }
1984 }()...};
1986 constexpr auto pos = std::find(map.begin(), map.end(), true);
1987 if constexpr (pos != map.end()) {
1988 return mColumnChunks[std::distance(map.begin(), pos)];
1989 } else {
1990 static_assert(framework::always_static_assert_v<Key>, "This table does not have an index to given Key");
1991 }
1992 }
1993
1995 {
1996 return mBegin;
1997 }
1998
1999 auto const& cached_begin() const
2000 {
2001 return mBegin;
2002 }
2003
2005 {
2006 return unfiltered_iterator(mBegin);
2007 }
2008
2010 {
2011 return RowViewSentinel{mEnd};
2012 }
2013
2014 filtered_iterator filtered_begin(gsl::span<int64_t const> selection)
2015 {
2016 // Note that the FilteredIndexPolicy will never outlive the selection which
2017 // is held by the table, so we are safe passing the bare pointer. If it does it
2018 // means that the iterator on a table is outliving the table itself, which is
2019 // a bad idea.
2020 return filtered_iterator(mColumnChunks, {selection, mTable->num_rows(), mOffset});
2021 }
2022
2023 iterator iteratorAt(uint64_t i) const
2024 {
2025 return rawIteratorAt(i);
2026 }
2027
2029 {
2030 auto it = mBegin;
2031 it.setCursor(i);
2032 return it;
2033 }
2034
2036 {
2037 return unfiltered_const_iterator(mBegin);
2038 }
2039
2040 [[nodiscard]] RowViewSentinel end() const
2041 {
2042 return RowViewSentinel{mEnd};
2043 }
2044
2046 [[nodiscard]] std::shared_ptr<arrow::Table> asArrowTable() const
2047 {
2048 return mTable;
2049 }
2051 auto offset() const
2052 {
2053 return mOffset;
2054 }
2056 [[nodiscard]] int64_t size() const
2057 {
2058 return mTable->num_rows();
2059 }
2060
2061 [[nodiscard]] int64_t tableSize() const
2062 {
2063 return size();
2064 }
2065
2068 template <typename... TA>
2069 void bindExternalIndices(TA*... current)
2070 {
2071 mBegin.bindExternalIndices(current...);
2072 }
2073
2074 template <typename I>
2076 {
2077 mBegin.bindInternalIndices(ptr);
2078 }
2079
2084
2085 template <typename... Cs>
2087 {
2088 (static_cast<Cs>(mBegin).setCurrentRaw(binding), ...);
2089 }
2090
2091 void bindExternalIndicesRaw(std::vector<o2::soa::Binding>&& ptrs)
2092 {
2093 mBegin.bindExternalIndicesRaw(std::forward<std::vector<o2::soa::Binding>>(ptrs));
2094 }
2095
2096 template <typename T, typename... Cs>
2098 {
2099 dest.bindExternalIndicesRaw(mBegin.getIndexBindings());
2100 }
2101
2102 template <typename T>
2103 void copyIndexBindings(T& dest) const
2104 {
2106 }
2107
2109 {
2110 auto t = o2::soa::select(*this, f);
2112 return t;
2113 }
2114
2116 {
2117 return doSliceByCached(this, node, value, cache);
2118 }
2119
2121 {
2122 return doSliceByCachedUnsorted(this, node, value, cache);
2123 }
2124
2125 template <typename T1, typename Policy, bool OPT>
2127 {
2128 return doSliceBy(this, container, value);
2129 }
2130
2131 auto rawSlice(uint64_t start, uint64_t end) const
2132 {
2133 return self_t{mTable->Slice(start, end - start + 1), start};
2134 }
2135
2136 auto emptySlice() const
2137 {
2138 return self_t{mTable->Slice(0, 0), 0};
2139 }
2140
2141 private:
2142 template <typename T>
2143 arrow::ChunkedArray* lookupColumn()
2144 {
2145 if constexpr (soa::is_persistent_column<T>) {
2146 auto label = T::columnLabel();
2147 return getIndexFromLabel(mTable.get(), label);
2148 } else {
2149 return nullptr;
2150 }
2151 }
2152 std::shared_ptr<arrow::Table> mTable = nullptr;
2153 uint64_t mOffset = 0;
2154 // Cached pointers to the ChunkedArray associated to a column
2155 arrow::ChunkedArray* mColumnChunks[framework::pack_size(columns_t{})];
2156 RowViewSentinel mEnd;
2157 iterator mBegin;
2158};
2159
2160template <uint32_t D, soa::is_column... C>
2162
2163void getterNotFound(const char* targetColumnLabel);
2164void emptyColumnLabel();
2165
2166namespace row_helpers
2167{
2168template <typename R, typename T, typename C>
2169R getColumnValue(const T& rowIterator)
2170{
2171 return static_cast<R>(static_cast<C>(rowIterator).get());
2172}
2173
2174namespace
2175{
2176template <typename R, typename T>
2177using ColumnGetterFunction = R (*)(const T&);
2178
2179template <typename T, typename R>
2181 // lambda is callable without additional free args
2182 framework::pack_size(typename T::bindings_t{}) == framework::pack_size(typename T::callable_t::args{}) &&
2183 requires(T t) {
2184 { t.get() } -> std::convertible_to<R>;
2185 };
2186
2187template <typename T, typename R>
2188concept persistent_with_common_getter = is_persistent_v<T> && requires(T t) {
2189 { t.get() } -> std::convertible_to<R>;
2190};
2191
2192template <typename R, typename T, persistent_with_common_getter<R> C>
2193ColumnGetterFunction<R, T> createGetterPtr(const std::string_view& targetColumnLabel)
2194{
2195 return targetColumnLabel == C::columnLabel() ? &getColumnValue<R, T, C> : nullptr;
2196}
2197
2198template <typename R, typename T, dynamic_with_common_getter<R> C>
2199ColumnGetterFunction<R, T> createGetterPtr(const std::string_view& targetColumnLabel)
2200{
2201 std::string_view columnLabel(C::columnLabel());
2202
2203 // allows user to use consistent formatting (with prefix) of all column labels
2204 // by default there isn't 'f' prefix for dynamic column labels
2205 if (targetColumnLabel.starts_with("f") && targetColumnLabel.substr(1) == columnLabel) {
2206 return &getColumnValue<R, T, C>;
2207 }
2208
2209 // check also exact match if user is aware of prefix missing
2210 if (targetColumnLabel == columnLabel) {
2211 return &getColumnValue<R, T, C>;
2212 }
2213
2214 return nullptr;
2215}
2216
2217template <typename R, typename T, typename... Cs>
2218ColumnGetterFunction<R, T> getColumnGetterByLabel(o2::framework::pack<Cs...>, const std::string_view& targetColumnLabel)
2219{
2220 ColumnGetterFunction<R, T> func;
2221
2222 (void)((func = createGetterPtr<R, T, Cs>(targetColumnLabel), func) || ...);
2223
2224 if (!func) {
2225 getterNotFound(targetColumnLabel.data());
2226 }
2227
2228 return func;
2229}
2230
2231template <typename T, typename R>
2232using with_common_getter_t = typename std::conditional<persistent_with_common_getter<T, R> || dynamic_with_common_getter<T, R>, std::true_type, std::false_type>::type;
2233} // namespace
2234
2235template <typename R, typename T>
2236ColumnGetterFunction<R, typename T::iterator> getColumnGetterByLabel(const std::string_view& targetColumnLabel)
2237{
2238 using TypesWithCommonGetter = o2::framework::selected_pack_multicondition<with_common_getter_t, framework::pack<R>, typename T::columns_t>;
2239
2240 if (targetColumnLabel.size() == 0) {
2242 }
2243
2244 return getColumnGetterByLabel<R, typename T::iterator>(TypesWithCommonGetter{}, targetColumnLabel);
2245}
2246} // namespace row_helpers
2247} // namespace o2::soa
2248
2249namespace o2::aod
2250{
2252O2ORIGIN("AOD1");
2253O2ORIGIN("AOD2");
2256O2ORIGIN("JOIN");
2257O2HASH("JOIN/0");
2258O2ORIGIN("CONC");
2259O2HASH("CONC/0");
2260O2ORIGIN("TEST");
2261O2HASH("TEST/0");
2262} // namespace o2::aod
2263
2264namespace
2265{
2266template <typename T>
2267consteval static std::string_view namespace_prefix()
2268{
2269 constexpr auto name = o2::framework::type_name<T>();
2270 const auto pos = name.rfind(std::string_view{":"});
2271 return name.substr(0, pos + 1);
2272}
2273} // namespace
2274
2275#define DECLARE_EQUIVALENT_FOR_INDEX(_Base_, _Equiv_) \
2276 template <> \
2277 struct EquivalentIndexNG<o2::aod::Hash<_Base_::ref.desc_hash>, o2::aod::Hash<_Equiv_::ref.desc_hash>> { \
2278 constexpr static bool value = true; \
2279 }
2280
2281#define DECLARE_EQUIVALENT_FOR_INDEX_NG(_Base_, _Equiv_) \
2282 template <> \
2283 struct EquivalentIndexNG<o2::aod::Hash<_Base_ ""_h>, o2::aod::Hash<_Equiv_ ""_h>> { \
2284 constexpr static bool value = true; \
2285 }
2286
2287#define DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) \
2288 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2289 static constexpr const char* mLabel = _Label_; \
2290 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2291 static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \
2292 using base = o2::soa::Column<_Type_, _Name_>; \
2293 using type = _Type_; \
2294 using column_t = _Name_; \
2295 _Name_(arrow::ChunkedArray const* column) \
2296 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2297 { \
2298 } \
2299 \
2300 _Name_() = default; \
2301 _Name_(_Name_ const& other) = default; \
2302 _Name_& operator=(_Name_ const& other) = default; \
2303 \
2304 decltype(auto) _Getter_() const \
2305 { \
2306 return *mColumnIterator; \
2307 } \
2308 \
2309 decltype(auto) get() const \
2310 { \
2311 return _Getter_(); \
2312 } \
2313 }; \
2314 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2315
2316#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_) \
2317 DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, "f" #_Name_)
2318
2321#define MAKEINT(_Size_) uint##_Size_##_t
2322
2323#define DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, _Label_) \
2324 struct _Name_ : o2::soa::Column<MAKEINT(_Size_), _Name_> { \
2325 static constexpr const char* mLabel = _Label_; \
2326 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2327 static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \
2328 using base = o2::soa::Column<MAKEINT(_Size_), _Name_>; \
2329 using type = MAKEINT(_Size_); \
2330 _Name_(arrow::ChunkedArray const* column) \
2331 : o2::soa::Column<type, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2332 { \
2333 } \
2334 \
2335 _Name_() = default; \
2336 _Name_(_Name_ const& other) = default; \
2337 _Name_& operator=(_Name_ const& other) = default; \
2338 \
2339 decltype(auto) _Getter_##_raw() const \
2340 { \
2341 return *mColumnIterator; \
2342 } \
2343 \
2344 bool _Getter_##_bit(int bit) const \
2345 { \
2346 return (*mColumnIterator & (static_cast<type>(1) << bit)) >> bit; \
2347 } \
2348 }; \
2349 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<MAKEINT(_Size_)>() }
2350
2351#define DECLARE_SOA_BITMAP_COLUMN(_Name_, _Getter_, _Size_) \
2352 DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, "f" #_Name_)
2353
2356#define DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_, _Expression_) \
2357 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2358 static constexpr const char* mLabel = _Label_; \
2359 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2360 using base = o2::soa::Column<_Type_, _Name_>; \
2361 using type = _Type_; \
2362 using column_t = _Name_; \
2363 using spawnable_t = std::true_type; \
2364 _Name_(arrow::ChunkedArray const* column) \
2365 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2366 { \
2367 } \
2368 \
2369 _Name_() = default; \
2370 _Name_(_Name_ const& other) = default; \
2371 _Name_& operator=(_Name_ const& other) = default; \
2372 \
2373 decltype(auto) _Getter_() const \
2374 { \
2375 return *mColumnIterator; \
2376 } \
2377 \
2378 decltype(auto) get() const \
2379 { \
2380 return _Getter_(); \
2381 } \
2382 \
2383 static o2::framework::expressions::Projector Projector() \
2384 { \
2385 return _Expression_; \
2386 } \
2387 }; \
2388 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2389
2390#define DECLARE_SOA_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Expression_) \
2391 DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, "f" #_Name_, _Expression_);
2392
2395#define DECLARE_SOA_CONFIGURABLE_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Label_) \
2396 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2397 static constexpr const char* mLabel = _Label_; \
2398 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2399 static constexpr const int32_t mHash = _Label_ ""_h; \
2400 using base = o2::soa::Column<_Type_, _Name_>; \
2401 using type = _Type_; \
2402 using column_t = _Name_; \
2403 using spawnable_t = std::true_type; \
2404 _Name_(arrow::ChunkedArray const* column) \
2405 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2406 { \
2407 } \
2408 \
2409 _Name_() = default; \
2410 _Name_(_Name_ const& other) = default; \
2411 _Name_& operator=(_Name_ const& other) = default; \
2412 \
2413 decltype(auto) _Getter_() const \
2414 { \
2415 return *mColumnIterator; \
2416 } \
2417 \
2418 decltype(auto) get() const \
2419 { \
2420 return _Getter_(); \
2421 } \
2422 }; \
2423 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2424
2443
2445
2446template <o2::soa::is_table T>
2447consteval auto getIndexTargets()
2448{
2449 return T::originals;
2450}
2451
2452#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2453 struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \
2454 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2455 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2456 static constexpr const char* mLabel = "fIndexSlice" _Label_ _Suffix_; \
2457 static constexpr const uint32_t hash = 0; \
2458 using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \
2459 using type = _Type_[2]; \
2460 using column_t = _Name_##IdSlice; \
2461 using binding_t = _Table_; \
2462 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2463 _Name_##IdSlice(arrow::ChunkedArray const* column) \
2464 : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator<type>(column)) \
2465 { \
2466 } \
2467 \
2468 _Name_##IdSlice() = default; \
2469 _Name_##IdSlice(_Name_##IdSlice const& other) = default; \
2470 _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \
2471 std::array<_Type_, 2> inline getIds() const \
2472 { \
2473 return _Getter_##Ids(); \
2474 } \
2475 \
2476 bool has_##_Getter_() const \
2477 { \
2478 auto a = *mColumnIterator; \
2479 return a[0] >= 0 && a[1] >= 0; \
2480 } \
2481 \
2482 std::array<_Type_, 2> _Getter_##Ids() const \
2483 { \
2484 auto a = *mColumnIterator; \
2485 return std::array{a[0], a[1]}; \
2486 } \
2487 \
2488 template <typename T> \
2489 auto _Getter_##_as() const \
2490 { \
2491 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2492 o2::soa::notBoundTable(#_Table_); \
2493 } \
2494 auto t = mBinding.get<T>(); \
2495 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2496 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2497 } \
2498 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2499 return t->emptySlice(); \
2500 } \
2501 auto a = *mColumnIterator; \
2502 auto r = t->rawSlice(a[0], a[1]); \
2503 t->copyIndexBindings(r); \
2504 r.bindInternalIndicesTo(t); \
2505 return r; \
2506 } \
2507 \
2508 auto _Getter_() const \
2509 { \
2510 return _Getter_##_as<binding_t>(); \
2511 } \
2512 \
2513 template <typename T> \
2514 bool setCurrent(T const* current) \
2515 { \
2516 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2517 assert(current != nullptr); \
2518 this->mBinding.bind(current); \
2519 return true; \
2520 } \
2521 return false; \
2522 } \
2523 \
2524 bool setCurrentRaw(o2::soa::Binding current) \
2525 { \
2526 this->mBinding = current; \
2527 return true; \
2528 } \
2529 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2530 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2531 o2::soa::Binding mBinding; \
2532 };
2533
2534#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2535#define DECLARE_SOA_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2536#define DECLARE_SOA_SLICE_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2537
2539#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2540 struct _Name_##Ids : o2::soa::Column<std::vector<_Type_>, _Name_##Ids> { \
2541 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2542 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2543 static constexpr const char* mLabel = "fIndexArray" _Label_ _Suffix_; \
2544 static constexpr const uint32_t hash = 0; \
2545 using base = o2::soa::Column<std::vector<_Type_>, _Name_##Ids>; \
2546 using type = std::vector<_Type_>; \
2547 using column_t = _Name_##Ids; \
2548 using binding_t = _Table_; \
2549 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2550 _Name_##Ids(arrow::ChunkedArray const* column) \
2551 : o2::soa::Column<std::vector<_Type_>, _Name_##Ids>(o2::soa::ColumnIterator<type>(column)) \
2552 { \
2553 } \
2554 \
2555 _Name_##Ids() = default; \
2556 _Name_##Ids(_Name_##Ids const& other) = default; \
2557 _Name_##Ids& operator=(_Name_##Ids const& other) = default; \
2558 \
2559 gsl::span<const _Type_> inline getIds() const \
2560 { \
2561 return _Getter_##Ids(); \
2562 } \
2563 \
2564 gsl::span<const _Type_> _Getter_##Ids() const \
2565 { \
2566 return *mColumnIterator; \
2567 } \
2568 \
2569 bool has_##_Getter_() const \
2570 { \
2571 return !(*mColumnIterator).empty(); \
2572 } \
2573 \
2574 template <typename T> \
2575 auto _Getter_##_as() const \
2576 { \
2577 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2578 o2::soa::notBoundTable(#_Table_); \
2579 } \
2580 auto t = mBinding.get<T>(); \
2581 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2582 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2583 } \
2584 return getIterators<T>(); \
2585 } \
2586 \
2587 template <typename T> \
2588 auto filtered_##_Getter_##_as() const \
2589 { \
2590 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2591 o2::soa::notBoundTable(#_Table_); \
2592 } \
2593 auto t = mBinding.get<T>(); \
2594 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2595 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2596 } \
2597 return getFilteredIterators<T>(); \
2598 } \
2599 \
2600 template <typename T> \
2601 auto getIterators() const \
2602 { \
2603 auto result = std::vector<typename T::unfiltered_iterator>(); \
2604 for (auto& i : *mColumnIterator) { \
2605 result.push_back(mBinding.get<T>()->rawIteratorAt(i)); \
2606 } \
2607 return result; \
2608 } \
2609 \
2610 template <typename T> \
2611 std::vector<typename T::iterator> getFilteredIterators() const \
2612 { \
2613 if constexpr (o2::soa::is_filtered_table<T>) { \
2614 auto result = std::vector<typename T::iterator>(); \
2615 for (auto const& i : *mColumnIterator) { \
2616 auto pos = mBinding.get<T>()->isInSelectedRows(i); \
2617 if (pos > 0) { \
2618 result.emplace_back(mBinding.get<T>()->iteratorAt(pos)); \
2619 } \
2620 } \
2621 return result; \
2622 } else { \
2623 static_assert(o2::framework::always_static_assert_v<T>, "T is not a Filtered type"); \
2624 } \
2625 return {}; \
2626 } \
2627 \
2628 auto _Getter_() const \
2629 { \
2630 return _Getter_##_as<binding_t>(); \
2631 } \
2632 \
2633 template <typename T> \
2634 auto _Getter_##_first_as() const \
2635 { \
2636 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2637 o2::soa::notBoundTable(#_Table_); \
2638 } \
2639 auto t = mBinding.get<T>(); \
2640 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2641 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2642 } \
2643 return t->rawIteratorAt((*mColumnIterator)[0]); \
2644 } \
2645 \
2646 template <typename T> \
2647 auto _Getter_##_last_as() const \
2648 { \
2649 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2650 o2::soa::notBoundTable(#_Table_); \
2651 } \
2652 auto t = mBinding.get<T>(); \
2653 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2654 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2655 } \
2656 return t->rawIteratorAt((*mColumnIterator).back()); \
2657 } \
2658 \
2659 auto _Getter_first() const \
2660 { \
2661 return _Getter_##_first_as<binding_t>(); \
2662 } \
2663 \
2664 auto _Getter_last() const \
2665 { \
2666 return _Getter_##_last_as<binding_t>(); \
2667 } \
2668 \
2669 template <typename T> \
2670 bool setCurrent(T const* current) \
2671 { \
2672 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2673 assert(current != nullptr); \
2674 this->mBinding.bind(current); \
2675 return true; \
2676 } \
2677 return false; \
2678 } \
2679 \
2680 bool setCurrentRaw(o2::soa::Binding current) \
2681 { \
2682 this->mBinding = current; \
2683 return true; \
2684 } \
2685 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2686 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2687 o2::soa::Binding mBinding; \
2688 };
2689
2690#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2691#define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2692#define DECLARE_SOA_ARRAY_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2693
2695#define DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2696 struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \
2697 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2698 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2699 static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \
2700 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_##Id>(), std::string_view{#_Getter_ "Id"}); \
2701 using base = o2::soa::Column<_Type_, _Name_##Id>; \
2702 using type = _Type_; \
2703 using column_t = _Name_##Id; \
2704 using binding_t = _Table_; \
2705 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2706 _Name_##Id(arrow::ChunkedArray const* column) \
2707 : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator<type>(column)) \
2708 { \
2709 } \
2710 \
2711 _Name_##Id() = default; \
2712 _Name_##Id(_Name_##Id const& other) = default; \
2713 _Name_##Id& operator=(_Name_##Id const& other) = default; \
2714 type inline getId() const \
2715 { \
2716 return _Getter_##Id(); \
2717 } \
2718 \
2719 type _Getter_##Id() const \
2720 { \
2721 return *mColumnIterator; \
2722 } \
2723 \
2724 bool has_##_Getter_() const \
2725 { \
2726 return *mColumnIterator >= 0; \
2727 } \
2728 \
2729 template <typename T> \
2730 auto _Getter_##_as() const \
2731 { \
2732 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2733 o2::soa::notBoundTable(#_Table_); \
2734 } \
2735 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2736 o2::soa::accessingInvalidIndexFor(#_Getter_); \
2737 } \
2738 auto t = mBinding.get<T>(); \
2739 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2740 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2741 } \
2742 return t->rawIteratorAt(*mColumnIterator); \
2743 } \
2744 \
2745 auto _Getter_() const \
2746 { \
2747 return _Getter_##_as<binding_t>(); \
2748 } \
2749 \
2750 template <typename T> \
2751 bool setCurrent(T* current) \
2752 { \
2753 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2754 assert(current != nullptr); \
2755 this->mBinding.bind(current); \
2756 return true; \
2757 } \
2758 return false; \
2759 } \
2760 \
2761 bool setCurrentRaw(o2::soa::Binding current) \
2762 { \
2763 this->mBinding = current; \
2764 return true; \
2765 } \
2766 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2767 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2768 o2::soa::Binding mBinding; \
2769 }; \
2770 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" #_Table_ _Suffix_, _Name_##Id::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2771
2772#define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2773#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2774#define DECLARE_SOA_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2775
2777#define DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2778 struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \
2779 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2780 static constexpr const char* mLabel = "fIndex" _Label_; \
2781 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_##Id>(), std::string_view{#_Getter_ "Id"}); \
2782 using base = o2::soa::Column<_Type_, _Name_##Id>; \
2783 using type = _Type_; \
2784 using column_t = _Name_##Id; \
2785 using self_index_t = std::true_type; \
2786 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2787 _Name_##Id(arrow::ChunkedArray const* column) \
2788 : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator<type>(column)) \
2789 { \
2790 } \
2791 \
2792 _Name_##Id() = default; \
2793 _Name_##Id(_Name_##Id const& other) = default; \
2794 _Name_##Id& operator=(_Name_##Id const& other) = default; \
2795 type inline getId() const \
2796 { \
2797 return _Getter_##Id(); \
2798 } \
2799 \
2800 type _Getter_##Id() const \
2801 { \
2802 return *mColumnIterator; \
2803 } \
2804 \
2805 bool has_##_Getter_() const \
2806 { \
2807 return *mColumnIterator >= 0; \
2808 } \
2809 \
2810 template <typename T> \
2811 auto _Getter_##_as() const \
2812 { \
2813 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2814 o2::soa::accessingInvalidIndexFor(#_Getter_); \
2815 } \
2816 auto t = mBinding.get<T>(); \
2817 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2818 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2819 } \
2820 return t->rawIteratorAt(*mColumnIterator); \
2821 } \
2822 \
2823 bool setCurrentRaw(o2::soa::Binding current) \
2824 { \
2825 this->mBinding = current; \
2826 return true; \
2827 } \
2828 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2829 o2::soa::Binding mBinding; \
2830 }; \
2831 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" _Label_, _Name_##Id::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2832
2833#define DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2834#define DECLARE_SOA_SELF_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, #_Name_)
2836#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2837 struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \
2838 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2839 static constexpr const char* mLabel = "fIndexSlice" _Label_; \
2840 static constexpr const uint32_t hash = 0; \
2841 using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \
2842 using type = _Type_[2]; \
2843 using column_t = _Name_##IdSlice; \
2844 using self_index_t = std::true_type; \
2845 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2846 _Name_##IdSlice(arrow::ChunkedArray const* column) \
2847 : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator<type>(column)) \
2848 { \
2849 } \
2850 \
2851 _Name_##IdSlice() = default; \
2852 _Name_##IdSlice(_Name_##IdSlice const& other) = default; \
2853 _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \
2854 std::array<_Type_, 2> inline getIds() const \
2855 { \
2856 return _Getter_##Ids(); \
2857 } \
2858 \
2859 bool has_##_Getter_() const \
2860 { \
2861 auto a = *mColumnIterator; \
2862 return a[0] >= 0 && a[1] >= 0; \
2863 } \
2864 \
2865 std::array<_Type_, 2> _Getter_##Ids() const \
2866 { \
2867 auto a = *mColumnIterator; \
2868 return std::array{a[0], a[1]}; \
2869 } \
2870 \
2871 template <typename T> \
2872 auto _Getter_##_as() const \
2873 { \
2874 auto t = mBinding.get<T>(); \
2875 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2876 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2877 } \
2878 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2879 return t->emptySlice(); \
2880 } \
2881 auto a = *mColumnIterator; \
2882 auto r = t->rawSlice(a[0], a[1]); \
2883 t->copyIndexBindings(r); \
2884 r.bindInternalIndicesTo(t); \
2885 return r; \
2886 } \
2887 \
2888 bool setCurrentRaw(o2::soa::Binding current) \
2889 { \
2890 this->mBinding = current; \
2891 return true; \
2892 } \
2893 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2894 o2::soa::Binding mBinding; \
2895 };
2896
2897#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2898#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_)
2900#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2901 struct _Name_##Ids : o2::soa::Column<std::vector<_Type_>, _Name_##Ids> { \
2902 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2903 static constexpr const char* mLabel = "fIndexArray" _Label_; \
2904 static constexpr const uint32_t hash = 0; \
2905 using base = o2::soa::Column<std::vector<_Type_>, _Name_##Ids>; \
2906 using type = std::vector<_Type_>; \
2907 using column_t = _Name_##Ids; \
2908 using self_index_t = std::true_type; \
2909 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2910 _Name_##Ids(arrow::ChunkedArray const* column) \
2911 : o2::soa::Column<std::vector<_Type_>, _Name_##Ids>(o2::soa::ColumnIterator<type>(column)) \
2912 { \
2913 } \
2914 \
2915 _Name_##Ids() = default; \
2916 _Name_##Ids(_Name_##Ids const& other) = default; \
2917 _Name_##Ids& operator=(_Name_##Ids const& other) = default; \
2918 gsl::span<const _Type_> inline getIds() const \
2919 { \
2920 return _Getter_##Ids(); \
2921 } \
2922 \
2923 gsl::span<const _Type_> _Getter_##Ids() const \
2924 { \
2925 return *mColumnIterator; \
2926 } \
2927 \
2928 bool has_##_Getter_() const \
2929 { \
2930 return !(*mColumnIterator).empty(); \
2931 } \
2932 \
2933 template <typename T> \
2934 auto _Getter_##_as() const \
2935 { \
2936 auto t = mBinding.get<T>(); \
2937 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2938 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2939 } \
2940 return getIterators<T>(); \
2941 } \
2942 \
2943 template <typename T> \
2944 auto getIterators() const \
2945 { \
2946 auto result = std::vector<typename T::unfiltered_iterator>(); \
2947 for (auto& i : *mColumnIterator) { \
2948 result.push_back(mBinding.get<T>()->rawIteratorAt(i)); \
2949 } \
2950 return result; \
2951 } \
2952 \
2953 template <typename T> \
2954 auto _Getter_##_first_as() const \
2955 { \
2956 return mBinding.get<T>()->rawIteratorAt((*mColumnIterator)[0]); \
2957 } \
2958 \
2959 template <typename T> \
2960 auto _Getter_##_last_as() const \
2961 { \
2962 return mBinding.get<T>()->rawIteratorAt((*mColumnIterator).back()); \
2963 } \
2964 \
2965 bool setCurrentRaw(o2::soa::Binding current) \
2966 { \
2967 this->mBinding = current; \
2968 return true; \
2969 } \
2970 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2971 o2::soa::Binding mBinding; \
2972 };
2973
2974#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2975#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_)
2976
3005#define DECLARE_SOA_DYNAMIC_COLUMN(_Name_, _Getter_, ...) \
3006 struct _Name_##Callback { \
3007 static inline constexpr auto getLambda() { return __VA_ARGS__; } \
3008 }; \
3009 \
3010 struct _Name_##Helper { \
3011 using callable_t = decltype(o2::framework::FunctionMetadata(std::declval<decltype(_Name_##Callback::getLambda())>())); \
3012 using return_type = typename callable_t::return_type; \
3013 }; \
3014 template <typename... Bindings> \
3015 struct _Name_ : o2::soa::DynamicColumn<typename _Name_##Helper::callable_t::type, _Name_<Bindings...>> { \
3016 using base = o2::soa::DynamicColumn<typename _Name_##Helper::callable_t::type, _Name_<Bindings...>>; \
3017 using helper = _Name_##Helper; \
3018 using callback_holder_t = _Name_##Callback; \
3019 using callable_t = helper::callable_t; \
3020 using callback_t = callable_t::type; \
3021 static constexpr const uint32_t hash = 0; \
3022 \
3023 _Name_(arrow::ChunkedArray const*) \
3024 { \
3025 } \
3026 _Name_() = default; \
3027 _Name_(_Name_ const& other) = default; \
3028 _Name_& operator=(_Name_ const& other) = default; \
3029 static constexpr const char* mLabel = #_Name_; \
3030 using type = typename callable_t::return_type; \
3031 \
3032 template <typename... FreeArgs> \
3033 type _Getter_(FreeArgs... freeArgs) const \
3034 { \
3035 return boundGetter(std::make_index_sequence<std::tuple_size_v<decltype(boundIterators)>>{}, freeArgs...); \
3036 } \
3037 template <typename... FreeArgs> \
3038 type getDynamicValue(FreeArgs... freeArgs) const \
3039 { \
3040 return boundGetter(std::make_index_sequence<std::tuple_size_v<decltype(boundIterators)>>{}, freeArgs...); \
3041 } \
3042 \
3043 type get() const \
3044 { \
3045 return _Getter_(); \
3046 } \
3047 \
3048 template <size_t... Is, typename... FreeArgs> \
3049 type boundGetter(std::integer_sequence<size_t, Is...>&&, FreeArgs... freeArgs) const \
3050 { \
3051 return __VA_ARGS__((**std::get<Is>(boundIterators))..., freeArgs...); \
3052 } \
3053 \
3054 using bindings_t = typename o2::framework::pack<Bindings...>; \
3055 std::tuple<o2::soa::ColumnIterator<typename Bindings::type> const*...> boundIterators; \
3056 }
3057
3058#define DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, ...) \
3059 using _Name_##Metadata = TableMetadata<Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__>;
3060
3061#define DECLARE_SOA_TABLE_METADATA_TRAIT(_Name_, _Desc_, _Version_) \
3062 template <> \
3063 struct MetadataTrait<Hash<_Desc_ "/" #_Version_ ""_h>> { \
3064 using metadata = _Name_##Metadata; \
3065 };
3066
3067#define DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, _Version_) \
3068 O2HASH(_Desc_ "/" #_Version_); \
3069 template <typename O> \
3070 using _Name_##From = o2::soa::Table<Hash<_Label_ ""_h>, Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3071 using _Name_ = _Name_##From<Hash<_Origin_ ""_h>>; \
3072 template <> \
3073 struct MetadataTrait<Hash<_Desc_ "/" #_Version_ ""_h>> { \
3074 using metadata = _Name_##Metadata; \
3075 };
3076
3077#define DECLARE_SOA_STAGE(_Name_, _Origin_, _Desc_, _Version_) \
3078 template <typename O> \
3079 using _Name_##From = o2::soa::Table<Hash<#_Name_ ""_h>, Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3080 using _Name_ = _Name_##From<Hash<_Origin_ ""_h>>;
3081
3082#define DECLARE_SOA_TABLE_FULL_VERSIONED(_Name_, _Label_, _Origin_, _Desc_, _Version_, ...) \
3083 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, __VA_ARGS__); \
3084 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, _Version_);
3085
3086#define DECLARE_SOA_TABLE_FULL(_Name_, _Label_, _Origin_, _Desc_, ...) \
3087 O2HASH(_Label_); \
3088 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, 0, __VA_ARGS__); \
3089 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, 0)
3090
3091#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_, ...) \
3092 DECLARE_SOA_TABLE_FULL(_Name_, #_Name_, _Origin_, _Desc_, __VA_ARGS__)
3093
3094#define DECLARE_SOA_TABLE_VERSIONED(_Name_, _Origin_, _Desc_, _Version_, ...) \
3095 O2HASH(#_Name_); \
3096 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, __VA_ARGS__); \
3097 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, #_Name_, _Origin_, _Desc_, _Version_)
3098
3099#define DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Desc_, _Version_, ...) \
3100 O2HASH(_Desc_ "/" #_Version_); \
3101 O2HASH(#_BaseName_); \
3102 O2HASH("Stored" #_BaseName_); \
3103 DECLARE_SOA_TABLE_METADATA(_BaseName_, _Desc_, _Version_, __VA_ARGS__); \
3104 using Stored##_BaseName_##Metadata = _BaseName_##Metadata; \
3105 DECLARE_SOA_TABLE_METADATA_TRAIT(_BaseName_, _Desc_, _Version_); \
3106 DECLARE_SOA_STAGE(_BaseName_, "AOD", _Desc_, _Version_); \
3107 DECLARE_SOA_STAGE(Stored##_BaseName_, "AOD1", _Desc_, _Version_);
3108
3109#define DECLARE_SOA_TABLE_STAGED(_BaseName_, _Desc_, ...) \
3110 DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Desc_, 0, __VA_ARGS__);
3111
3112#define DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, _Label_, _OriginalTable_, _Origin_, _Desc_, _Version_, ...) \
3113 O2HASH(_Desc_ "/" #_Version_); \
3114 template <typename O> \
3115 using _Name_##ExtensionFrom = soa::Table<o2::aod::Hash<_Label_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3116 using _Name_##Extension = _Name_##ExtensionFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3117 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3118 struct _Name_##ExtensionMetadataFrom : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3119 using base_table_t = _OriginalTable_; \
3120 using extension_table_t = _Name_##ExtensionFrom<O>; \
3121 using expression_pack_t = framework::pack<__VA_ARGS__>; \
3122 static constexpr auto sources = _OriginalTable_::originals; \
3123 }; \
3124 using _Name_##ExtensionMetadata = _Name_##ExtensionMetadataFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3125 template <> \
3126 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3127 using metadata = _Name_##ExtensionMetadata; \
3128 }; \
3129 template <typename O> \
3130 using _Name_##From = o2::soa::JoinFull<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, _OriginalTable_, _Name_##ExtensionFrom<O>>; \
3131 using _Name_ = _Name_##From<o2::aod::Hash<_Origin_ ""_h>>;
3132
3133#define DECLARE_SOA_EXTENDED_TABLE(_Name_, _Table_, _Description_, _Version_, ...) \
3134 O2HASH(#_Name_ "Extension"); \
3135 DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, #_Name_ "Extension", _Table_, "DYN", _Description_, _Version_, __VA_ARGS__)
3136
3137#define DECLARE_SOA_EXTENDED_TABLE_USER(_Name_, _Table_, _Description_, ...) \
3138 O2HASH(#_Name_ "Extension"); \
3139 DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, #_Name_ "Extension", _Table_, "AOD", "EX" _Description_, 0, __VA_ARGS__)
3140
3141#define DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE_FULL(_Name_, _Label_, _OriginalTable_, _Origin_, _Desc_, _Version_, ...) \
3142 O2HASH(_Desc_ "/" #_Version_); \
3143 template <typename O> \
3144 using _Name_##CfgExtensionFrom = soa::Table<o2::aod::Hash<_Label_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3145 using _Name_##CfgExtension = _Name_##CfgExtensionFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3146 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3147 struct _Name_##CfgExtensionMetadataFrom : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3148 using base_table_t = _OriginalTable_; \
3149 using extension_table_t = _Name_##CfgExtensionFrom<O>; \
3150 using placeholders_pack_t = framework::pack<__VA_ARGS__>; \
3151 using configurable_t = std::true_type; \
3152 static constexpr auto sources = _OriginalTable_::originals; \
3153 }; \
3154 using _Name_##CfgExtensionMetadata = _Name_##CfgExtensionMetadataFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3155 template <> \
3156 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3157 using metadata = _Name_##CfgExtensionMetadata; \
3158 }; \
3159 template <typename O> \
3160 using _Name_##From = o2::soa::JoinFull<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, _OriginalTable_, _Name_##CfgExtensionFrom<O>>; \
3161 using _Name_ = _Name_##From<o2::aod::Hash<_Origin_ ""_h>>;
3162
3163#define DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE(_Name_, _Table_, _Description_, ...) \
3164 O2HASH(#_Name_ "CfgExtension"); \
3165 DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE_FULL(_Name_, #_Name_ "CfgExtension", _Table_, "AOD", "EX" _Description_, 0, __VA_ARGS__)
3166
3167#define DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, _Origin_, _Version_, _Desc_, _Exclusive_, ...) \
3168 O2HASH(#_Name_); \
3169 O2HASH(_Desc_ "/" #_Version_); \
3170 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3171 struct _Name_##MetadataFrom : o2::aod::TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, soa::Index<>, __VA_ARGS__> { \
3172 static constexpr bool exclusive = _Exclusive_; \
3173 using Key = _Key_; \
3174 using index_pack_t = framework::pack<__VA_ARGS__>; \
3175 static constexpr const auto sources = []<typename... Cs>(framework::pack<Cs...>) { \
3176 constexpr auto a = o2::soa::mergeOriginals<typename Cs::binding_t...>(); \
3177 return o2::aod::filterForKey<a.size(), a, Key>(); \
3178 }(framework::pack<__VA_ARGS__>{}); \
3179 }; \
3180 using _Name_##Metadata = _Name_##MetadataFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3181 \
3182 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3183 using _Name_##From = o2::soa::IndexTable<o2::aod::Hash<#_Name_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O, _Key_, __VA_ARGS__>; \
3184 using _Name_ = _Name_##From<o2::aod::Hash<_Origin_ ""_h>>; \
3185 \
3186 template <> \
3187 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3188 using metadata = _Name_##Metadata; \
3189 };
3190
3191#define DECLARE_SOA_INDEX_TABLE(_Name_, _Key_, _Description_, ...) \
3192 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "IDX", 0, _Description_, false, __VA_ARGS__)
3193
3194#define DECLARE_SOA_INDEX_TABLE_EXCLUSIVE(_Name_, _Key_, _Description_, ...) \
3195 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "IDX", 0, _Description_, true, __VA_ARGS__)
3196
3197#define DECLARE_SOA_INDEX_TABLE_USER(_Name_, _Key_, _Description_, ...) \
3198 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "AOD", 0, _Description_, false, __VA_ARGS__)
3199
3200#define DECLARE_SOA_INDEX_TABLE_EXCLUSIVE_USER(_Name_, _Key_, _Description_, ...) \
3201 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "AOD", 0, _Description_, true, __VA_ARGS__)
3202
3203namespace o2::soa
3204{
3205template <typename D, typename... Ts>
3206struct JoinFull : Table<o2::aod::Hash<"JOIN"_h>, D, o2::aod::Hash<"JOIN"_h>, Ts...> {
3207 using base = Table<o2::aod::Hash<"JOIN"_h>, D, o2::aod::Hash<"JOIN"_h>, Ts...>;
3208
3209 JoinFull(std::shared_ptr<arrow::Table>&& table, uint64_t offset = 0)
3210 : base{std::move(table), offset}
3211 {
3213 }
3214 JoinFull(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t offset = 0)
3215 : base{ArrowHelpers::joinTables(std::move(tables), std::span{base::originalLabels}), offset}
3216 {
3218 }
3221
3222 using self_t = JoinFull<D, Ts...>;
3223 using table_t = base;
3224 static constexpr const auto originals = base::originals;
3225 static constexpr const auto originalLabels = base::originalLabels;
3228 using iterator = table_t::template iterator_template<DefaultIndexPolicy, self_t, Ts...>;
3234
3236 {
3237 return iterator{this->cached_begin()};
3238 }
3239
3241 {
3242 return const_iterator{this->cached_begin()};
3243 }
3244
3246 {
3247 return doSliceByCached(this, node, value, cache);
3248 }
3249
3251 {
3252 return doSliceByCachedUnsorted(this, node, value, cache);
3253 }
3254
3255 template <typename T1, typename Policy, bool OPT>
3257 {
3258 return doSliceBy(this, container, value);
3259 }
3260
3261 iterator rawIteratorAt(uint64_t i) const
3262 {
3263 auto it = iterator{this->cached_begin()};
3264 it.setCursor(i);
3265 return it;
3266 }
3267
3268 iterator iteratorAt(uint64_t i) const
3269 {
3270 return rawIteratorAt(i);
3271 }
3272
3273 auto rawSlice(uint64_t start, uint64_t end) const
3274 {
3275 return self_t{{this->asArrowTable()->Slice(start, end - start + 1)}, start};
3276 }
3277
3278 auto emptySlice() const
3279 {
3280 return self_t{{this->asArrowTable()->Slice(0, 0)}, 0};
3281 }
3282
3283 template <typename T>
3284 static consteval bool contains()
3285 {
3286 return std::find_if(originals.begin(), originals.end(), [](TableRef const& ref) { return ref.desc_hash == T::ref.desc_hash; }) != originals.end();
3287 }
3288};
3289
3290template <typename... Ts>
3291using Join = JoinFull<o2::aod::Hash<"JOIN/0"_h>, Ts...>;
3292
3293template <typename... Ts>
3294constexpr auto join(Ts const&... t)
3295{
3296 return Join<Ts...>(ArrowHelpers::joinTables({t.asArrowTable()...}, std::span{Join<Ts...>::base::originalLabels}));
3297}
3298
3299template <typename T>
3301
3302template <typename T>
3303constexpr bool is_soa_join_v = is_join<T>;
3304
3305template <typename... Ts>
3306struct Concat : Table<o2::aod::Hash<"CONC"_h>, o2::aod::Hash<"CONC/0"_h>, o2::aod::Hash<"CONC"_h>, Ts...> {
3307 using base = Table<o2::aod::Hash<"CONC"_h>, o2::aod::Hash<"CONC/0"_h>, o2::aod::Hash<"CONC"_h>, Ts...>;
3308 using self_t = Concat<Ts...>;
3309 Concat(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t offset = 0)
3310 : base{ArrowHelpers::concatTables(std::move(tables)), offset}
3311 {
3313 }
3314 Concat(Ts const&... t, uint64_t offset = 0)
3315 : base{ArrowHelpers::concatTables({t.asArrowTable()...}), offset}
3316 {
3317 bindInternalIndicesTo(this);
3318 }
3319
3320 using base::originals;
3321
3322 using base::bindExternalIndices;
3323 using base::bindInternalIndicesTo;
3324
3325 using table_t = base;
3328
3329 using iterator = table_t::template iterator_template<DefaultIndexPolicy, self_t, Ts...>;
3335};
3336
3337template <typename... Ts>
3338constexpr auto concat(Ts const&... t)
3339{
3340 return Concat<Ts...>{t...};
3341}
3342
3343template <soa::is_table T>
3344class FilteredBase : public T
3345{
3346 public:
3348 using table_t = typename T::table_t;
3349 using T::originals;
3350 using columns_t = typename T::columns_t;
3351 using persistent_columns_t = typename T::persistent_columns_t;
3352 using external_index_columns_t = typename T::external_index_columns_t;
3353
3354 using iterator = T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3355 using unfiltered_iterator = T::template iterator_template_o<DefaultIndexPolicy, self_t>;
3357
3358 FilteredBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, gandiva::Selection const& selection, uint64_t offset = 0)
3359 : T{std::move(tables), offset},
3360 mSelectedRows{getSpan(selection)}
3361 {
3362 if (this->tableSize() != 0) {
3363 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3364 }
3365 resetRanges();
3366 mFilteredBegin.bindInternalIndices(this);
3367 }
3368
3369 FilteredBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, SelectionVector&& selection, uint64_t offset = 0)
3370 : T{std::move(tables), offset},
3371 mSelectedRowsCache{std::move(selection)},
3372 mCached{true}
3373 {
3374 mSelectedRows = gsl::span{mSelectedRowsCache};
3375 if (this->tableSize() != 0) {
3376 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3377 }
3378 resetRanges();
3379 mFilteredBegin.bindInternalIndices(this);
3380 }
3381
3382 FilteredBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, gsl::span<int64_t const> const& selection, uint64_t offset = 0)
3383 : T{std::move(tables), offset},
3384 mSelectedRows{selection}
3385 {
3386 if (this->tableSize() != 0) {
3387 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3388 }
3389 resetRanges();
3390 mFilteredBegin.bindInternalIndices(this);
3391 }
3392
3394 {
3395 return iterator(mFilteredBegin);
3396 }
3397
3399 {
3400 return const_iterator(mFilteredBegin);
3401 }
3402
3404 {
3405 auto it = unfiltered_iterator{mFilteredBegin};
3406 it.setCursor(i);
3407 return it;
3408 }
3409
3410 [[nodiscard]] RowViewSentinel end() const
3411 {
3412 return RowViewSentinel{*mFilteredEnd};
3413 }
3414
3416 {
3417 return mFilteredBegin;
3418 }
3419
3420 auto const& cached_begin() const
3421 {
3422 return mFilteredBegin;
3423 }
3424
3425 iterator iteratorAt(uint64_t i) const
3426 {
3427 return mFilteredBegin + i;
3428 }
3429
3430 [[nodiscard]] int64_t size() const
3431 {
3432 return mSelectedRows.size();
3433 }
3434
3435 [[nodiscard]] int64_t tableSize() const
3436 {
3437 return table_t::asArrowTable()->num_rows();
3438 }
3439
3440 auto const& getSelectedRows() const
3441 {
3442 return mSelectedRows;
3443 }
3444
3445 auto rawSlice(uint64_t start, uint64_t end) const
3446 {
3447 SelectionVector newSelection;
3448 newSelection.resize(static_cast<int64_t>(end - start + 1));
3449 std::iota(newSelection.begin(), newSelection.end(), start);
3450 return self_t{{this->asArrowTable()}, std::move(newSelection), 0};
3451 }
3452
3453 auto emptySlice() const
3454 {
3455 return self_t{{this->asArrowTable()}, SelectionVector{}, 0};
3456 }
3457
3458 static inline auto getSpan(gandiva::Selection const& sel)
3459 {
3460 if (sel == nullptr) {
3461 return gsl::span<int64_t const>{};
3462 }
3463 auto array = std::static_pointer_cast<arrow::Int64Array>(sel->ToArray());
3464 auto start = array->raw_values();
3465 auto stop = start + array->length();
3466 return gsl::span{start, stop};
3467 }
3468
3471 template <typename... TA>
3472 void bindExternalIndices(TA*... current)
3473 {
3474 table_t::bindExternalIndices(current...);
3475 mFilteredBegin.bindExternalIndices(current...);
3476 }
3477
3478 void bindExternalIndicesRaw(std::vector<o2::soa::Binding>&& ptrs)
3479 {
3480 mFilteredBegin.bindExternalIndicesRaw(std::forward<std::vector<o2::soa::Binding>>(ptrs));
3481 }
3482
3483 template <typename I>
3485 {
3486 mFilteredBegin.bindInternalIndices(ptr);
3487 }
3488
3489 template <typename T1, typename... Cs>
3491 {
3492 dest.bindExternalIndicesRaw(mFilteredBegin.getIndexBindings());
3493 }
3494
3495 template <typename T1>
3496 void copyIndexBindings(T1& dest) const
3497 {
3498 doCopyIndexBindings(external_index_columns_t{}, dest);
3499 }
3500
3501 template <typename T1>
3502 auto rawSliceBy(o2::framework::Preslice<T1> const& container, int value) const
3503 {
3504 return (table_t)this->sliceBy(container, value);
3505 }
3506
3508 {
3509 return doFilteredSliceByCached(this, node, value, cache);
3510 }
3511
3513 {
3514 return doSliceByCachedUnsorted(this, node, value, cache);
3515 }
3516
3517 template <typename T1, bool OPT>
3519 {
3520 return doFilteredSliceBy(this, container, value);
3521 }
3522
3523 template <typename T1, bool OPT>
3525 {
3526 return doSliceBy(this, container, value);
3527 }
3528
3530 {
3531 auto t = o2::soa::select(*this, f);
3532 copyIndexBindings(t);
3533 return t;
3534 }
3535
3536 int isInSelectedRows(int i) const
3537 {
3538 auto locate = std::find(mSelectedRows.begin(), mSelectedRows.end(), i);
3539 if (locate == mSelectedRows.end()) {
3540 return -1;
3541 }
3542 return static_cast<int>(std::distance(mSelectedRows.begin(), locate));
3543 }
3544
3545 void sumWithSelection(SelectionVector const& selection)
3546 {
3547 mCached = true;
3548 SelectionVector rowsUnion;
3549 std::set_union(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(rowsUnion));
3550 mSelectedRowsCache.clear();
3551 mSelectedRowsCache = rowsUnion;
3552 resetRanges();
3553 }
3554
3556 {
3557 mCached = true;
3558 SelectionVector intersection;
3559 std::set_intersection(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(intersection));
3560 mSelectedRowsCache.clear();
3561 mSelectedRowsCache = intersection;
3562 resetRanges();
3563 }
3564
3565 void sumWithSelection(gsl::span<int64_t const> const& selection)
3566 {
3567 mCached = true;
3568 SelectionVector rowsUnion;
3569 std::set_union(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(rowsUnion));
3570 mSelectedRowsCache.clear();
3571 mSelectedRowsCache = rowsUnion;
3572 resetRanges();
3573 }
3574
3575 void intersectWithSelection(gsl::span<int64_t const> const& selection)
3576 {
3577 mCached = true;
3578 SelectionVector intersection;
3579 std::set_intersection(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(intersection));
3580 mSelectedRowsCache.clear();
3581 mSelectedRowsCache = intersection;
3582 resetRanges();
3583 }
3584
3585 bool isCached() const
3586 {
3587 return mCached;
3588 }
3589
3590 private:
3591 void resetRanges()
3592 {
3593 if (mCached) {
3594 mSelectedRows = gsl::span{mSelectedRowsCache};
3595 }
3596 mFilteredEnd.reset(new RowViewSentinel{static_cast<int64_t>(mSelectedRows.size())});
3597 if (tableSize() == 0) {
3598 mFilteredBegin = *mFilteredEnd;
3599 } else {
3600 mFilteredBegin.resetSelection(mSelectedRows);
3601 }
3602 }
3603
3604 gsl::span<int64_t const> mSelectedRows;
3605 SelectionVector mSelectedRowsCache;
3606 bool mCached = false;
3607 iterator mFilteredBegin;
3608 std::shared_ptr<RowViewSentinel> mFilteredEnd;
3609};
3610
3611template <typename T>
3612class Filtered : public FilteredBase<T>
3613{
3614 public:
3615 using base_t = T;
3617 using table_t = typename T::table_t;
3618 using columns_t = typename T::columns_t;
3619
3620 using iterator = T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3621 using unfiltered_iterator = T::template iterator_template_o<DefaultIndexPolicy, self_t>;
3623
3625 {
3626 return iterator(this->cached_begin());
3627 }
3628
3630 {
3631 return const_iterator(this->cached_begin());
3632 }
3633
3634 Filtered(std::vector<std::shared_ptr<arrow::Table>>&& tables, gandiva::Selection const& selection, uint64_t offset = 0)
3635 : FilteredBase<T>(std::move(tables), selection, offset) {}
3636
3637 Filtered(std::vector<std::shared_ptr<arrow::Table>>&& tables, SelectionVector&& selection, uint64_t offset = 0)
3638 : FilteredBase<T>(std::move(tables), std::forward<SelectionVector>(selection), offset) {}
3639
3640 Filtered(std::vector<std::shared_ptr<arrow::Table>>&& tables, gsl::span<int64_t const> const& selection, uint64_t offset = 0)
3641 : FilteredBase<T>(std::move(tables), selection, offset) {}
3642
3644 {
3645 Filtered<T> copy(*this);
3646 copy.sumWithSelection(selection);
3647 return copy;
3648 }
3649
3650 Filtered<T> operator+(gsl::span<int64_t const> const& selection)
3651 {
3652 Filtered<T> copy(*this);
3653 copy.sumWithSelection(selection);
3654 return copy;
3655 }
3656
3658 {
3659 return operator+(other.getSelectedRows());
3660 }
3661
3663 {
3664 this->sumWithSelection(selection);
3665 return *this;
3666 }
3667
3668 Filtered<T> operator+=(gsl::span<int64_t const> const& selection)
3669 {
3670 this->sumWithSelection(selection);
3671 return *this;
3672 }
3673
3675 {
3676 return operator+=(other.getSelectedRows());
3677 }
3678
3680 {
3681 Filtered<T> copy(*this);
3682 copy.intersectWithSelection(selection);
3683 return copy;
3684 }
3685
3686 Filtered<T> operator*(gsl::span<int64_t const> const& selection)
3687 {
3688 Filtered<T> copy(*this);
3689 copy.intersectWithSelection(selection);
3690 return copy;
3691 }
3692
3694 {
3695 return operator*(other.getSelectedRows());
3696 }
3697
3699 {
3700 this->intersectWithSelection(selection);
3701 return *this;
3702 }
3703
3704 Filtered<T> operator*=(gsl::span<int64_t const> const& selection)
3705 {
3706 this->intersectWithSelection(selection);
3707 return *this;
3708 }
3709
3711 {
3712 return operator*=(other.getSelectedRows());
3713 }
3714
3716 {
3717 auto it = unfiltered_iterator{this->cached_begin()};
3718 it.setCursor(i);
3719 return it;
3720 }
3721
3722 using FilteredBase<T>::getSelectedRows;
3723
3724 auto rawSlice(uint64_t start, uint64_t end) const
3725 {
3726 SelectionVector newSelection;
3727 newSelection.resize(static_cast<int64_t>(end - start + 1));
3728 std::iota(newSelection.begin(), newSelection.end(), start);
3729 return self_t{{this->asArrowTable()}, std::move(newSelection), 0};
3730 }
3731
3732 auto emptySlice() const
3733 {
3734 return self_t{{this->asArrowTable()}, SelectionVector{}, 0};
3735 }
3736
3737 template <typename T1>
3738 auto rawSliceBy(o2::framework::Preslice<T1> const& container, int value) const
3739 {
3740 return (table_t)this->sliceBy(container, value);
3741 }
3742
3744 {
3745 return doFilteredSliceByCached(this, node, value, cache);
3746 }
3747
3749 {
3750 return doSliceByCachedUnsorted(this, node, value, cache);
3751 }
3752
3753 template <typename T1, bool OPT>
3755 {
3756 return doFilteredSliceBy(this, container, value);
3757 }
3758
3759 template <typename T1, bool OPT>
3761 {
3762 return doSliceBy(this, container, value);
3763 }
3764
3766 {
3767 auto t = o2::soa::select(*this, f);
3768 copyIndexBindings(t);
3769 return t;
3770 }
3771};
3772
3773template <typename T>
3774class Filtered<Filtered<T>> : public FilteredBase<typename T::table_t>
3775{
3776 public:
3778 using base_t = T;
3780 using columns_t = typename T::columns_t;
3781
3782 using iterator = typename T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3783 using unfiltered_iterator = typename T::template iterator_template_o<DefaultIndexPolicy, self_t>;
3785
3787 {
3788 return iterator(this->cached_begin());
3789 }
3790
3792 {
3793 return const_iterator(this->cached_begin());
3794 }
3795
3796 Filtered(std::vector<Filtered<T>>&& tables, gandiva::Selection const& selection, uint64_t offset = 0)
3797 : FilteredBase<typename T::table_t>(std::move(extractTablesFromFiltered(tables)), selection, offset)
3798 {
3799 for (auto& table : tables) {
3800 *this *= table;
3801 }
3802 }
3803
3804 Filtered(std::vector<Filtered<T>>&& tables, SelectionVector&& selection, uint64_t offset = 0)
3805 : FilteredBase<typename T::table_t>(std::move(extractTablesFromFiltered(tables)), std::forward<SelectionVector>(selection), offset)
3806 {
3807 for (auto& table : tables) {
3808 *this *= table;
3809 }
3810 }
3811
3812 Filtered(std::vector<Filtered<T>>&& tables, gsl::span<int64_t const> const& selection, uint64_t offset = 0)
3813 : FilteredBase<typename T::table_t>(std::move(extractTablesFromFiltered(tables)), selection, offset)
3814 {
3815 for (auto& table : tables) {
3816 *this *= table;
3817 }
3818 }
3819
3821 {
3822 Filtered<Filtered<T>> copy(*this);
3823 copy.sumWithSelection(selection);
3824 return copy;
3825 }
3826
3827 Filtered<Filtered<T>> operator+(gsl::span<int64_t const> const& selection)
3828 {
3829 Filtered<Filtered<T>> copy(*this);
3830 copy.sumWithSelection(selection);
3831 return copy;
3832 }
3833
3835 {
3836 return operator+(other.getSelectedRows());
3837 }
3838
3840 {
3841 this->sumWithSelection(selection);
3842 return *this;
3843 }
3844
3845 Filtered<Filtered<T>> operator+=(gsl::span<int64_t const> const& selection)
3846 {
3847 this->sumWithSelection(selection);
3848 return *this;
3849 }
3850
3852 {
3853 return operator+=(other.getSelectedRows());
3854 }
3855
3857 {
3858 Filtered<Filtered<T>> copy(*this);
3859 copy.intersectionWithSelection(selection);
3860 return copy;
3861 }
3862
3863 Filtered<Filtered<T>> operator*(gsl::span<int64_t const> const& selection)
3864 {
3865 Filtered<Filtered<T>> copy(*this);
3866 copy.intersectionWithSelection(selection);
3867 return copy;
3868 }
3869
3871 {
3872 return operator*(other.getSelectedRows());
3873 }
3874
3876 {
3877 this->intersectWithSelection(selection);
3878 return *this;
3879 }
3880
3881 Filtered<Filtered<T>> operator*=(gsl::span<int64_t const> const& selection)
3882 {
3883 this->intersectWithSelection(selection);
3884 return *this;
3885 }
3886
3888 {
3889 return operator*=(other.getSelectedRows());
3890 }
3891
3893 {
3894 auto it = unfiltered_iterator{this->cached_begin()};
3895 it.setCursor(i);
3896 return it;
3897 }
3898
3899 auto rawSlice(uint64_t start, uint64_t end) const
3900 {
3901 SelectionVector newSelection;
3902 newSelection.resize(static_cast<int64_t>(end - start + 1));
3903 std::iota(newSelection.begin(), newSelection.end(), start);
3904 return self_t{{this->asArrowTable()}, std::move(newSelection), 0};
3905 }
3906
3907 auto emptySlice() const
3908 {
3909 return self_t{{this->asArrowTable()}, SelectionVector{}, 0};
3910 }
3911
3913 {
3914 return doFilteredSliceByCached(this, node, value, cache);
3915 }
3916
3918 {
3919 return doSliceByCachedUnsorted(this, node, value, cache);
3920 }
3921
3922 template <typename T1, bool OPT>
3924 {
3925 return doFilteredSliceBy(this, container, value);
3926 }
3927
3928 template <typename T1, bool OPT>
3930 {
3931 return doSliceBy(this, container, value);
3932 }
3933
3934 private:
3935 std::vector<std::shared_ptr<arrow::Table>> extractTablesFromFiltered(std::vector<Filtered<T>>& tables)
3936 {
3937 std::vector<std::shared_ptr<arrow::Table>> outTables;
3938 for (auto& table : tables) {
3939 outTables.push_back(table.asArrowTable());
3940 }
3941 return outTables;
3942 }
3943};
3944
3950template <typename L, typename D, typename O, typename Key, typename H, typename... Ts>
3951struct IndexTable : Table<L, D, O> {
3952 using self_t = IndexTable<L, D, O, Key, H, Ts...>;
3957 using first_t = typename H::binding_t;
3958 using rest_t = framework::pack<typename Ts::binding_t...>;
3959
3960 IndexTable(std::shared_ptr<arrow::Table> table, uint64_t offset = 0)
3961 : base_t{table, offset}
3962 {
3963 }
3964
3965 IndexTable(std::vector<std::shared_ptr<arrow::Table>> tables, uint64_t offset = 0)
3966 : base_t{tables[0], offset}
3967 {
3968 }
3969
3970 IndexTable(IndexTable const&) = default;
3972 IndexTable& operator=(IndexTable const&) = default;
3974
3979};
3980
3981template <typename T, bool APPLY>
3982struct SmallGroupsBase : public Filtered<T> {
3983 static constexpr bool applyFilters = APPLY;
3984 SmallGroupsBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, gandiva::Selection const& selection, uint64_t offset = 0)
3985 : Filtered<T>(std::move(tables), selection, offset) {}
3986
3987 SmallGroupsBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, SelectionVector&& selection, uint64_t offset = 0)
3988 : Filtered<T>(std::move(tables), std::forward<SelectionVector>(selection), offset) {}
3989
3990 SmallGroupsBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, gsl::span<int64_t const> const& selection, uint64_t offset = 0)
3991 : Filtered<T>(std::move(tables), selection, offset) {}
3992};
3993
3994template <typename T>
3996
3997template <typename T>
3999
4000template <typename T>
4001concept is_smallgroups = requires {
4002 []<typename B, bool A>(SmallGroupsBase<B, A>*) {}(std::declval<T*>());
4003};
4004} // namespace o2::soa
4005
4006#endif // O2_FRAMEWORK_ASOA_H_
#define O2HASH(_Str_)
Pre-declare Hash specialization for a generic string.
Definition ASoA.h:277
#define O2ORIGIN(_Str_)
Pre-declare Hash specialization for an origin string.
Definition ASoA.h:285
consteval auto getIndexTargets()
SLICE.
Definition ASoA.h:2447
o2::monitoring::tags::Key Key
#define O2_BUILTIN_UNREACHABLE
#define O2_BUILTIN_LIKELY(x)
#define O2_BUILTIN_UNLIKELY(x)
Hit operator+(const Hit &lhs, const Hit &rhs)
Definition Hit.cxx:46
int32_t i
bool o
uint16_t pos
Definition RawData.h:3
uint32_t res
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
uint32_t version
Definition RawData.h:8
TBranch * ptr
void merge(Options const &options)
StringRef key
Definition A.h:16
Definition B.h:16
Class for time synchronization of RawReader instances.
int64_t const * mCurrentPos
Definition ASoA.h:604
ColumnIterator(arrow::ChunkedArray const *column)
Definition ASoA.h:497
ColumnIterator(ColumnIterator< T, ChunkingPolicy > const &)=default
void moveToEnd()
Move the iterator to the end of the column.
Definition ASoA.h:555
ColumnIterator< T > & moveToPos()
Definition ASoA.h:597
ColumnIterator< T, ChunkingPolicy > & operator=(ColumnIterator< T, ChunkingPolicy > const &)=default
unwrap_t< T > const * mCurrent
Definition ASoA.h:603
unwrap_t< T > const * mLast
Definition ASoA.h:605
ColumnIterator(ColumnIterator< T, ChunkingPolicy > &&)=default
void prevChunk() const
Definition ASoA.h:530
arrow::ChunkedArray const * mColumn
Definition ASoA.h:606
ColumnIterator< T, ChunkingPolicy > & operator=(ColumnIterator< T, ChunkingPolicy > &&)=default
void moveToChunk(int chunk)
Definition ASoA.h:541
void nextChunk() const
Move the iterator to the next chunk.
Definition ASoA.h:519
bool isCached() const
Definition ASoA.h:3585
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3512
FilteredBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
Definition ASoA.h:3382
int64_t tableSize() const
Definition ASoA.h:3435
FilteredBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
Definition ASoA.h:3358
auto & cached_begin()
Definition ASoA.h:3415
typename T::external_index_columns_t external_index_columns_t
Definition ASoA.h:3352
auto select(framework::expressions::Filter const &f) const
Definition ASoA.h:3529
static auto getSpan(gandiva::Selection const &sel)
Definition ASoA.h:3458
int64_t size() const
Definition ASoA.h:3430
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Definition ASoA.h:3354
auto rawSliceBy(o2::framework::Preslice< T1 > const &container, int value) const
Definition ASoA.h:3502
T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
Definition ASoA.h:3355
void copyIndexBindings(T1 &dest) const
Definition ASoA.h:3496
auto const & getSelectedRows() const
Definition ASoA.h:3440
typename T::columns_t columns_t
Definition ASoA.h:3350
auto emptySlice() const
Definition ASoA.h:3453
void bindExternalIndices(TA *... current)
Definition ASoA.h:3472
void sumWithSelection(SelectionVector const &selection)
Definition ASoA.h:3545
void bindInternalIndicesTo(I const *ptr)
Definition ASoA.h:3484
void intersectWithSelection(SelectionVector const &selection)
Definition ASoA.h:3555
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
Definition ASoA.h:3524
auto rawSlice(uint64_t start, uint64_t end) const
Definition ASoA.h:3445
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
Definition ASoA.h:3518
iterator iteratorAt(uint64_t i) const
Definition ASoA.h:3425
iterator const_iterator
Definition ASoA.h:3356
typename T::table_t table_t
Definition ASoA.h:3348
typename T::persistent_columns_t persistent_columns_t
Definition ASoA.h:3351
RowViewSentinel end() const
Definition ASoA.h:3410
void intersectWithSelection(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3575
FilteredBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, SelectionVector &&selection, uint64_t offset=0)
Definition ASoA.h:3369
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
Definition ASoA.h:3478
const_iterator begin() const
Definition ASoA.h:3398
unfiltered_iterator rawIteratorAt(uint64_t i) const
Definition ASoA.h:3403
int isInSelectedRows(int i) const
Definition ASoA.h:3536
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3507
void doCopyIndexBindings(framework::pack< Cs... >, T1 &dest) const
Definition ASoA.h:3490
void sumWithSelection(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3565
iterator begin()
Definition ASoA.h:3393
auto const & cached_begin() const
Definition ASoA.h:3420
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
Definition ASoA.h:3923
typename FilteredBase< typename T::table_t >::table_t table_t
Definition ASoA.h:3779
Filtered< Filtered< T > > operator+=(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3845
typename T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
Definition ASoA.h:3783
Filtered< Filtered< T > > operator+(SelectionVector const &selection)
Definition ASoA.h:3820
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
Definition ASoA.h:3929
Filtered< Filtered< T > > operator*(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3863
typename T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Definition ASoA.h:3782
typename T::columns_t columns_t
Definition ASoA.h:3780
const_iterator begin() const
Definition ASoA.h:3791
Filtered(std::vector< Filtered< T > > &&tables, SelectionVector &&selection, uint64_t offset=0)
Definition ASoA.h:3804
unfiltered_iterator rawIteratorAt(uint64_t i) const
Definition ASoA.h:3892
Filtered< Filtered< T > > operator+=(Filtered< T > const &other)
Definition ASoA.h:3851
Filtered< Filtered< T > > operator+=(SelectionVector const &selection)
Definition ASoA.h:3839
Filtered< Filtered< T > > operator*=(SelectionVector const &selection)
Definition ASoA.h:3875
auto rawSlice(uint64_t start, uint64_t end) const
Definition ASoA.h:3899
Filtered< Filtered< T > > operator+(Filtered< T > const &other)
Definition ASoA.h:3834
Filtered(std::vector< Filtered< T > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
Definition ASoA.h:3796
Filtered< Filtered< T > > operator*=(Filtered< T > const &other)
Definition ASoA.h:3887
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3912
Filtered< Filtered< T > > operator*=(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3881
Filtered< Filtered< T > > operator*(Filtered< T > const &other)
Definition ASoA.h:3870
Filtered< Filtered< T > > operator+(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3827
Filtered< Filtered< T > > operator*(SelectionVector const &selection)
Definition ASoA.h:3856
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3917
Filtered(std::vector< Filtered< T > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
Definition ASoA.h:3812
Filtered< T > operator+=(Filtered< T > const &other)
Definition ASoA.h:3674
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
Definition ASoA.h:3760
Filtered(std::vector< std::shared_ptr< arrow::Table > > &&tables, SelectionVector &&selection, uint64_t offset=0)
Definition ASoA.h:3637
iterator const_iterator
Definition ASoA.h:3622
Filtered(std::vector< std::shared_ptr< arrow::Table > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
Definition ASoA.h:3640
iterator begin()
Definition ASoA.h:3624
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3748
Filtered< T > operator+(Filtered< T > const &other)
Definition ASoA.h:3657
Filtered< T > operator*=(SelectionVector const &selection)
Definition ASoA.h:3698
auto emptySlice() const
Definition ASoA.h:3732
const_iterator begin() const
Definition ASoA.h:3629
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
Definition ASoA.h:3620
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3743
auto select(framework::expressions::Filter const &f) const
Definition ASoA.h:3765
Filtered< T > operator+(SelectionVector const &selection)
Definition ASoA.h:3643
Filtered< T > operator*(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3686
T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
Definition ASoA.h:3621
unfiltered_iterator rawIteratorAt(uint64_t i) const
Definition ASoA.h:3715
Filtered< T > operator*(SelectionVector const &selection)
Definition ASoA.h:3679
Filtered< T > operator*=(Filtered< T > const &other)
Definition ASoA.h:3710
Filtered< T > operator*(Filtered< T > const &other)
Definition ASoA.h:3693
auto rawSliceBy(o2::framework::Preslice< T1 > const &container, int value) const
Definition ASoA.h:3738
Filtered< T > operator+=(SelectionVector const &selection)
Definition ASoA.h:3662
Filtered< T > operator*=(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3704
Filtered< T > operator+(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3650
Filtered< T > operator+=(gsl::span< int64_t const > const &selection)
Definition ASoA.h:3668
auto rawSlice(uint64_t start, uint64_t end) const
Definition ASoA.h:3724
Filtered(std::vector< std::shared_ptr< arrow::Table > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
Definition ASoA.h:3634
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
Definition ASoA.h:3754
typename T::table_t table_t
Definition ASoA.h:3617
typename T::columns_t columns_t
Definition ASoA.h:3618
decltype([]< typename... C >(framework::pack< C... > &&) -> framework::selected_pack< soa::is_self_index_t, C... > {}(columns_t{})) internal_index_columns_t
Definition ASoA.h:1753
void bindInternalIndicesExplicit(o2::soa::Binding binding)
Definition ASoA.h:2080
auto & cached_begin()
Definition ASoA.h:1994
iterator iteratorAt(uint64_t i) const
Definition ASoA.h:2023
decltype([]< typename... C >(framework::pack< C... > &&) -> framework::selected_pack< soa::is_persistent_column_t, C... > {}(columns_t{})) persistent_columns_t
Definition ASoA.h:1749
static constexpr const auto ref
Definition ASoA.h:1710
auto offset() const
Return offset.
Definition ASoA.h:2051
static consteval bool hasOriginal()
Definition ASoA.h:1742
unfiltered_iterator begin()
Definition ASoA.h:2004
int64_t tableSize() const
Definition ASoA.h:2061
auto rawSlice(uint64_t start, uint64_t end) const
Definition ASoA.h:2131
void bindExternalIndices(TA *... current)
Definition ASoA.h:2069
auto select(framework::expressions::Filter const &f) const
Definition ASoA.h:2108
unfiltered_iterator unfiltered_const_iterator
Definition ASoA.h:1935
static consteval auto full_iter()
Definition ASoA.h:1914
auto const & cached_begin() const
Definition ASoA.h:1999
auto emptySlice() const
Definition ASoA.h:2136
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:2120
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
Definition ASoA.h:2091
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
Definition ASoA.h:2126
static constexpr auto hashes()
Definition ASoA.h:1937
iterator unfiltered_iterator
Definition ASoA.h:1933
std::shared_ptr< arrow::Table > asArrowTable() const
Return a type erased arrow table backing store for / the type safe table.
Definition ASoA.h:2046
void doCopyIndexBindings(framework::pack< Cs... >, T &dest) const
Definition ASoA.h:2097
int64_t size() const
Size of the table, in rows.
Definition ASoA.h:2056
Table(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
Definition ASoA.h:1968
decltype(getColumns< ref, Ts... >()) columns_t
Definition ASoA.h:1747
arrow::ChunkedArray * getIndexToKey()
Definition ASoA.h:1975
RowViewSentinel end()
Definition ASoA.h:2009
decltype([]< typename... C >(framework::pack< C... >) -> framework::pack< typename C::type... > {}(persistent_columns_t{})) column_types
Definition ASoA.h:1750
static consteval auto isIndexTargetOf()
Definition ASoA.h:1719
iterator_template_o< FilteredIndexPolicy, table_t > filtered_iterator
Definition ASoA.h:1931
unfiltered_const_iterator begin() const
Definition ASoA.h:2035
void copyIndexBindings(T &dest) const
Definition ASoA.h:2103
static constexpr const auto originalLabels
Definition ASoA.h:1715
Table(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
Definition ASoA.h:1962
Table< L, D, O, Ts... > self_t
Definition ASoA.h:1711
static consteval auto isIndexTargetOf()
Definition ASoA.h:1726
decltype(full_iter< IP, Parent >()) iterator_template_o
Definition ASoA.h:1928
void doBindInternalIndicesExplicit(framework::pack< Cs... >, o2::soa::Binding binding)
Definition ASoA.h:2086
static constexpr const auto originals
Definition ASoA.h:1714
decltype([]< typename... C >(framework::pack< C... > &&) -> framework::selected_pack< soa::is_external_index_t, C... > {}(columns_t{})) external_index_columns_t
Definition ASoA.h:1752
Table(std::shared_ptr< arrow::Table > table, uint64_t offset=0)
Definition ASoA.h:1942
RowViewSentinel end() const
Definition ASoA.h:2040
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:2115
void bindInternalIndicesTo(I const *ptr)
Definition ASoA.h:2075
unfiltered_iterator rawIteratorAt(uint64_t i) const
Definition ASoA.h:2028
filtered_iterator filtered_begin(gsl::span< int64_t const > selection)
Definition ASoA.h:2014
iterator_template_o< DefaultIndexPolicy, table_t > iterator
Definition ASoA.h:1930
hash identification concepts
Definition ASoA.h:364
Helper to check if a type T is an iterator.
Definition ASoA.h:1265
column identification concepts
Definition ASoA.h:186
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum func
Definition glcorearb.h:778
GLint GLsizei count
Definition glcorearb.h:399
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLsizei const GLuint const GLintptr * offsets
Definition glcorearb.h:2595
GLuint GLuint end
Definition glcorearb.h:469
GLenum array
Definition glcorearb.h:4274
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum target
Definition glcorearb.h:1641
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLboolean * data
Definition glcorearb.h:298
GLintptr offset
Definition glcorearb.h:660
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
GLsizei GLenum const void * indices
Definition glcorearb.h:400
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean r
Definition glcorearb.h:1233
GLuint start
Definition glcorearb.h:469
GLenum GLenum GLsizei len
Definition glcorearb.h:4232
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLint ref
Definition glcorearb.h:291
std::shared_ptr< gandiva::SelectionVector > Selection
Definition Expressions.h:46
consteval const char * origin_str()
Definition ASoA.h:345
consteval const char * signature()
Definition ASoA.h:357
consteval auto filterForKey()
Filter TableRef array for compatibility with Key table.
Definition ASoA.h:265
consteval const char * label()
Definition ASoA.h:339
consteval header::DataOrigin origin()
Definition ASoA.h:351
std::shared_ptr< arrow::DataType > concreteArrowType(atype::type type)
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::decay_t< decltype(select_pack< Condition >(pack<>{}, Pack{}, CondPack{}))> selected_pack_multicondition
Definition Pack.h:181
std::decay_t< decltype(prune_voids_pack(pack<>{}, with_condition_pack< Condition, Types... >{}))> selected_pack
Definition Pack.h:179
decltype(intersected_pack(Ps{}...)) full_intersected_pack_t
Definition Pack.h:283
typename pack_element< I, T >::type pack_element_t
Definition Pack.h:56
consteval size_t has_type_at_v(pack< Ts... >)
Definition Pack.h:228
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
Definition Pack.h:28
decltype(concatenate_pack_unique(Ps{}...)) concatenated_pack_unique_t
Definition Pack.h:319
std::string strToUpper(std::string &&str)
Definition ASoA.cxx:186
typename pack_element< 0, T >::type pack_head_t
Definition Pack.h:59
std::string cutString(std::string &&str)
Definition ASoA.cxx:177
std::vector< std::vector< int64_t > > ListVector
Descriptor< gSizeDataDescriptionString > DataDescription
Definition DataHeader.h:551
R getColumnValue(const T &rowIterator)
Definition ASoA.h:2169
ColumnGetterFunction< R, typename T::iterator > getColumnGetterByLabel(const std::string_view &targetColumnLabel)
Definition ASoA.h:2236
consteval auto computeOriginals()
Definition ASoA.h:1692
auto createFieldsFromColumns(framework::pack< C... >)
Definition ASoA.h:407
SelectionVector selectionToVector(gandiva::Selection const &sel)
Definition ASoA.cxx:43
constexpr bool is_persistent_v
Definition ASoA.h:189
constexpr bool is_ng_index_equivalent_v
Definition ASoA.h:449
consteval auto remove_if(L l)
Definition ASoA.h:127
constexpr auto join(Ts const &... t)
Definition ASoA.h:3294
auto doSliceBy(T const *table, o2::framework::PresliceBase< C, Policy, OPT > const &container, int value)
Definition ASoA.h:1536
SelectionVector sliceSelection(gsl::span< int64_t const > const &mSelectedRows, int64_t nrows, uint64_t offset)
Definition ASoA.cxx:53
void notBoundTable(const char *tableName)
Definition ASoA.cxx:158
auto doFilteredSliceBy(T const *table, o2::framework::PresliceBase< C, framework::PreslicePolicySorted, OPT > const &container, int value)
Definition ASoA.h:1602
constexpr auto concat(Ts const &... t)
Definition ASoA.h:3338
consteval auto intersectOriginals()
Definition ASoA.h:162
consteval auto getColumns()
Definition ASoA.h:1664
std::vector< int64_t > SelectionVector
Definition ASoA.h:412
std::conditional_t< is_binding_compatible_v< T, typename B::binding_t >(), std::true_type, std::false_type > is_binding_compatible
Definition ASoA.h:1300
consteval auto mergeOriginals()
Definition ASoA.h:145
constexpr bool is_soa_filtered_v
Definition ASoA.h:1517
typename std::conditional_t< is_index_column< C >, std::true_type, std::false_type > is_external_index_t
Definition ASoA.h:204
void missingFilterDeclaration(int hash, int ai)
Definition ASoA.cxx:28
auto doSliceByCachedUnsorted(T const *table, framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache)
Definition ASoA.h:1634
auto doSliceByCached(T const *table, framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache)
Definition ASoA.h:1615
void accessingInvalidIndexFor(const char *getter)
Definition ASoA.cxx:20
auto select(T const &t, framework::expressions::Filter const &f)
Definition ASoA.h:1650
consteval auto base_iter(framework::pack< C... > &&) -> TableIterator< D, O, IP, C... >
Definition ASoA.h:1658
constexpr bool is_index_equivalent_v
Definition ASoA.h:446
constexpr bool is_soa_join_v
Definition ASoA.h:3303
void dereferenceWithWrongType(const char *getter, const char *target)
Definition ASoA.cxx:24
std::conditional_t< is_indexing_column< T >, std::true_type, std::false_type > is_indexing_t
Definition ASoA.h:835
auto doSliceByHelper(T const *table, gsl::span< const int64_t > const &selection)
Definition ASoA.h:1552
consteval bool is_binding_compatible_v()
Definition ASoA.h:1294
auto prepareFilteredSlice(T const *table, std::shared_ptr< arrow::Table > slice, uint64_t offset)
Definition ASoA.h:1587
void emptyColumnLabel()
Definition ASoA.cxx:38
typename unwrap< T >::type unwrap_t
Definition ASoA.h:481
void getterNotFound(const char *targetColumnLabel)
Definition ASoA.cxx:33
auto doFilteredSliceByCached(T const *table, framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache)
Definition ASoA.h:1625
void missingOptionalPreslice(const char *label, const char *key)
Definition ASoA.cxx:168
consteval bool is_compatible()
Definition ASoA.h:1281
arrow::ChunkedArray * getIndexFromLabel(arrow::Table *table, std::string_view label)
Definition ASoA.cxx:137
consteval auto merge()
Helpers to manipulate TableRef arrays.
Definition ASoA.h:104
consteval auto merge_if(L l)
Definition ASoA.h:115
std::conditional_t< is_persistent_column< C >, std::true_type, std::false_type > is_persistent_column_t
Definition ASoA.h:192
typename arrow_array_for< T >::type arrow_array_for_t
Definition ArrowTypes.h:117
void notFoundColumn(const char *label, const char *key)
Definition ASoA.cxx:163
std::conditional_t< is_dynamic_column< T >, std::true_type, std::false_type > is_dynamic_t
Definition ASoA.h:829
typename std::conditional_t< is_self_index_column< C >, std::true_type, std::false_type > is_self_index_t
Definition ASoA.h:207
Defining DataPointCompositeObject explicitly as copiable.
FIXME: do not use data model tables.
Definition list.h:40
static constexpr uint32_t hash
Definition ASoA.h:259
static constexpr char const *const str
Definition ASoA.h:260
Base type for table metadata.
Definition ASoA.h:214
static consteval int getIndexPosToKey()
Definition ASoA.h:233
static consteval int getIndexPosToKey_impl()
Definition ASoA.h:239
framework::selected_pack< soa::is_self_index_t, Cs... > internal_index_columns_t
Definition ASoA.h:218
framework::selected_pack< soa::is_persistent_column_t, Cs... > persistent_columns_t
Definition ASoA.h:216
framework::selected_pack< soa::is_external_index_t, Cs... > external_index_columns_t
Definition ASoA.h:217
static consteval std::array< bool, sizeof...(PCs)> getMap(framework::pack< PCs... >)
Definition ASoA.h:221
SliceInfoUnsortedPtr getCacheUnsortedFor(Entry const &bindingKey) const
SliceInfoPtr getCacheFor(Entry const &bindingKey) const
std::shared_ptr< arrow::Table > getSliceFor(int value, std::shared_ptr< arrow::Table > const &input, uint64_t &offset) const
Definition ASoA.h:1446
static constexpr bool optional
Definition ASoA.h:1436
PresliceBase(expressions::BindingNode index_)
Definition ASoA.h:1441
gsl::span< const int64_t > getSliceFor(int value) const
Definition ASoA.h:1456
const std::string binding
Definition ASoA.h:1439
const std::string binding
Definition ASoA.h:1413
Entry const & getBindingKey() const
Definition ASoA.cxx:197
SliceInfoUnsortedPtr sliceInfo
Definition ASoA.h:1430
gsl::span< const int64_t > getSliceFor(int value) const
Definition ASoA.cxx:220
void updateSliceInfo(SliceInfoUnsortedPtr &&si)
Definition ASoA.cxx:207
void updateSliceInfo(SliceInfoPtr &&si)
Definition ASoA.cxx:202
std::shared_ptr< arrow::Table > getSliceFor(int value, std::shared_ptr< arrow::Table > const &input, uint64_t &offset) const
Definition ASoA.cxx:212
ArrowTableSlicingCache * ptr
Definition SliceCache.h:22
std::pair< int64_t, int64_t > getSliceFor(int value) const
An expression tree node corresponding to a column binding.
A struct, containing the root of the expression tree.
From https://en.cppreference.com/w/cpp/utility/variant/visit.
static std::shared_ptr< arrow::Table > joinTables(std::vector< std::shared_ptr< arrow::Table > > &&tables, std::span< const char *const > labels)
Definition ASoA.cxx:67
static std::shared_ptr< arrow::Table > concatTables(std::vector< std::shared_ptr< arrow::Table > > &&tables)
Definition ASoA.cxx:97
Type-checking index column binding.
Definition ASoA.h:383
std::span< TableRef const > refs
Definition ASoA.h:386
size_t hash
Definition ASoA.h:385
void const * ptr
Definition ASoA.h:384
void bind(T const *table)
Definition ASoA.h:389
T const * get() const
Definition ASoA.h:397
static constexpr bool chunked
Definition ASoA.h:455
arrow::ChunkedArray * second
Definition ASoA.h:1042
Column(ColumnIterator< T > const &it)
Definition ASoA.h:665
Column()=default
static constexpr const char *const & columnLabel()
Definition ASoA.h:678
ColumnIterator< T > const & getIterator() const
Definition ASoA.h:679
Column & operator=(Column const &)=default
INHERIT inherited_t
Definition ASoA.h:664
Column(Column &&)=default
static auto asArrowField()
Definition ASoA.h:684
Column & operator=(Column &&)=default
Column(Column const &)=default
ColumnIterator< T > mColumnIterator
Definition ASoA.h:691
table_t::template iterator_template< DefaultIndexPolicy, self_t, Ts... > iterator
Definition ASoA.h:3329
Concat(Ts const &... t, uint64_t offset=0)
Definition ASoA.h:3314
typename table_t::persistent_columns_t persistent_columns_t
Definition ASoA.h:3327
typename table_t::columns_t columns_t
Definition ASoA.h:3326
iterator const_iterator
Definition ASoA.h:3330
const_iterator unfiltered_const_iterator
Definition ASoA.h:3332
iterator unfiltered_iterator
Definition ASoA.h:3331
table_t::template iterator_template< FilteredIndexPolicy, self_t, Ts... > filtered_iterator
Definition ASoA.h:3333
Concat(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
Definition ASoA.h:3309
filtered_iterator filtered_const_iterator
Definition ASoA.h:3334
DefaultIndexPolicy(int64_t nRows, uint64_t offset)
Definition ASoA.h:964
friend bool operator==(DefaultIndexPolicy const &lh, DefaultIndexPolicy const &rh)
Definition ASoA.h:1010
bool operator==(RowViewSentinel const &sentinel) const
Definition ASoA.h:1015
DefaultIndexPolicy(FilteredIndexPolicy const &other)
Definition ASoA.h:970
std::tuple< uint64_t const * > getOffsets() const
Definition ASoA.h:991
DefaultIndexPolicy & operator=(DefaultIndexPolicy &&)=default
void setCursor(int64_t i)
Definition ASoA.h:996
void limitRange(int64_t start, int64_t end)
Definition ASoA.h:976
DefaultIndexPolicy(DefaultIndexPolicy &&)=default
DefaultIndexPolicy(DefaultIndexPolicy const &)=default
DefaultIndexPolicy & operator=(DefaultIndexPolicy const &)=default
std::tuple< int64_t const *, int64_t const * > getIndices() const
Definition ASoA.h:985
DefaultIndexPolicy()=default
Needed to be able to copy the policy.
void moveByIndex(int64_t i)
Definition ASoA.h:1000
static constexpr const char *const & columnLabel()
Definition ASoA.h:700
INHERIT inherited_t
Definition ASoA.h:698
void resetSelection(gsl::span< int64_t const > selection)
Definition ASoA.h:863
FilteredIndexPolicy & operator=(FilteredIndexPolicy &&)=default
std::tuple< int64_t const *, int64_t const * > getIndices() const
Definition ASoA.h:877
FilteredIndexPolicy & operator=(FilteredIndexPolicy const &)=default
auto getSelectionRow() const
Definition ASoA.h:927
friend bool operator==(FilteredIndexPolicy const &lh, FilteredIndexPolicy const &rh)
Definition ASoA.h:908
void setCursor(int64_t i)
Definition ASoA.h:896
FilteredIndexPolicy(FilteredIndexPolicy const &)=default
auto raw_size() const
Definition ASoA.h:937
bool operator==(RowViewSentinel const &sentinel) const
Definition ASoA.h:913
std::tuple< uint64_t const * > getOffsets() const
Definition ASoA.h:883
void limitRange(int64_t start, int64_t end)
Definition ASoA.h:888
FilteredIndexPolicy(gsl::span< int64_t const > selection, int64_t rows, uint64_t offset=0)
Definition ASoA.h:854
FilteredIndexPolicy(FilteredIndexPolicy &&)=default
void moveByIndex(int64_t i)
Definition ASoA.h:902
static constexpr bool chunked
Definition ASoA.h:461
static constexpr const char *const & columnLabel()
Definition ASoA.h:708
INHERIT inherited_t
Definition ASoA.h:705
static constexpr const uint32_t hash
Definition ASoA.h:706
uint64_t mOffset
Offset within a larger table.
Definition ASoA.h:841
int64_t mRowIndex
Position inside the current table.
Definition ASoA.h:839
IndexTable(std::vector< std::shared_ptr< arrow::Table > > tables, uint64_t offset=0)
Definition ASoA.h:3965
IndexTable(std::shared_ptr< arrow::Table > table, uint64_t offset=0)
Definition ASoA.h:3960
typename base_t::template iterator_template_o< DefaultIndexPolicy, self_t > iterator
Definition ASoA.h:3975
filtered_iterator const_filtered_iterator
Definition ASoA.h:3978
IndexTable(IndexTable &&)=default
IndexTable & operator=(IndexTable const &)=default
iterator const_iterator
Definition ASoA.h:3976
IndexTable & operator=(IndexTable &&)=default
typename H::binding_t first_t
Definition ASoA.h:3957
typename base_t::template iterator_template_o< FilteredIndexPolicy, self_t > filtered_iterator
Definition ASoA.h:3977
IndexTable(IndexTable const &)=default
int64_t type
Definition ASoA.h:806
Index(Index const &)=default
void setIndices(std::tuple< int64_t const *, int64_t const * > indices)
Definition ASoA.h:795
Index & operator=(Index &&)=default
int64_t index() const
Definition ASoA.h:768
Index()=default
Index(arrow::ChunkedArray const *)
Definition ASoA.h:754
int64_t filteredIndex() const
Definition ASoA.h:773
constexpr int64_t rangeEnd()
Definition ASoA.h:763
constexpr int64_t rangeStart()
Definition ASoA.h:758
Index(Index &&)=default
Index & operator=(Index const &)=default
int64_t index() const
Definition ASoA.h:784
int64_t globalIndex() const
Definition ASoA.h:778
std::tuple< int64_t const *, int64_t const * > rowIndices
Definition ASoA.h:808
int64_t offsets() const
Definition ASoA.h:790
void setOffsets(std::tuple< uint64_t const * > offsets)
Definition ASoA.h:800
static constexpr const char * mLabel
Definition ASoA.h:805
std::tuple< uint64_t const * > rowOffsets
Definition ASoA.h:811
iterator begin()
Definition ASoA.h:3235
iterator unfiltered_iterator
Definition ASoA.h:3230
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
Definition ASoA.h:3256
auto rawSlice(uint64_t start, uint64_t end) const
Definition ASoA.h:3273
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3250
JoinFull(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
Definition ASoA.h:3214
static constexpr const auto originalLabels
Definition ASoA.h:3225
const_iterator unfiltered_const_iterator
Definition ASoA.h:3231
filtered_iterator filtered_const_iterator
Definition ASoA.h:3233
static consteval bool contains()
Definition ASoA.h:3284
iterator iteratorAt(uint64_t i) const
Definition ASoA.h:3268
typename table_t::columns_t columns_t
Definition ASoA.h:3226
table_t::template iterator_template< DefaultIndexPolicy, self_t, Ts... > iterator
Definition ASoA.h:3228
table_t::template iterator_template< FilteredIndexPolicy, self_t, Ts... > filtered_iterator
Definition ASoA.h:3232
static constexpr const auto originals
Definition ASoA.h:3224
JoinFull< D, Ts... > self_t
Definition ASoA.h:3222
const_iterator begin() const
Definition ASoA.h:3240
typename table_t::persistent_columns_t persistent_columns_t
Definition ASoA.h:3227
iterator const_iterator
Definition ASoA.h:3229
iterator rawIteratorAt(uint64_t i) const
Definition ASoA.h:3261
Table< o2::aod::Hash<"JOIN"_h >, D, o2::aod::Hash<"JOIN"_h >, Ts... > base
Definition ASoA.h:3207
JoinFull(std::shared_ptr< arrow::Table > &&table, uint64_t offset=0)
Definition ASoA.h:3209
auto emptySlice() const
Definition ASoA.h:3278
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Definition ASoA.h:3245
static constexpr const uint32_t hash
Definition ASoA.h:714
static constexpr const char *const & columnLabel()
Definition ASoA.h:716
INHERIT inherited_t
Definition ASoA.h:713
constexpr auto mark()
Definition ASoA.h:733
Marker & operator=(Marker const &)=default
size_t type
Definition ASoA.h:721
static constexpr auto value
Definition ASoA.h:723
static constexpr const char * mLabel
Definition ASoA.h:738
Marker(arrow::ChunkedArray const *)
Definition ASoA.h:732
Marker()=default
Marker(Marker const &)=default
Marker & operator=(Marker &&)=default
Marker(Marker &&)=default
int64_t const index
Definition ASoA.h:845
SmallGroupsBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, SelectionVector &&selection, uint64_t offset=0)
Definition ASoA.h:3987
SmallGroupsBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
Definition ASoA.h:3990
SmallGroupsBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
Definition ASoA.h:3984
framework::selected_pack< soa::is_persistent_column_t, C... > persistent_columns_t
Definition ASoA.h:1059
void doSetCurrentIndexRaw(framework::pack< Cs... > p, std::vector< o2::soa::Binding > &&ptrs)
Definition ASoA.h:1182
void bindInternalIndices(I const *table)
Definition ASoA.h:1201
TableIterator(TableIterator< D, O, FilteredIndexPolicy, C... > const &other)
Definition ASoA.h:1100
TableIterator(self_t const &other)
Definition ASoA.h:1085
TableIterator operator-(int64_t dec) const
Definition ASoA.h:1142
TableIterator(arrow::ChunkedArray *columnData[sizeof...(C)], IP &&policy)
Definition ASoA.h:1071
TableIterator & operator=(TableIterator other)
Definition ASoA.h:1092
TableIterator & operator++()
Definition ASoA.h:1108
void doSetCurrentInternal(framework::pack< Cs... >, I const *ptr)
Definition ASoA.h:1188
auto getIndexBindingsImpl(framework::pack< Cs... >) const
Definition ASoA.h:1165
TableIterator operator--(int)
Definition ASoA.h:1127
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
Definition ASoA.h:1195
TableIterator(arrow::ChunkedArray *columnData[sizeof...(C)], IP &&policy)
Definition ASoA.h:1064
decltype([]< typename... Cs >(framework::pack< Cs... >) -> framework::pack< typename Cs::binding_t... > {}(external_index_columns_t{})) bindings_pack_t
Definition ASoA.h:1062
void bindExternalIndices(TA *... current)
Definition ASoA.h:1176
auto getCurrent() const
Definition ASoA.h:1159
TableIterator & operator--()
Definition ASoA.h:1121
framework::selected_pack< soa::is_external_index_t, C... > external_index_columns_t
Definition ASoA.h:1060
TableIterator const & operator*() const
Definition ASoA.h:1147
TableIterator operator++(int)
Definition ASoA.h:1114
framework::selected_pack< soa::is_self_index_t, C... > internal_index_columns_t
Definition ASoA.h:1061
auto getIndexBindings() const
Definition ASoA.h:1170
void doSetCurrentIndex(framework::pack< CL... >, TA *current)
Definition ASoA.h:1153
TableIterator operator+(int64_t inc) const
Allow incrementing by more than one the iterator.
Definition ASoA.h:1135
Generic identifier for a table type.
Definition ASoA.h:58
constexpr TableRef & operator=(TableRef const &)=default
consteval TableRef()
Definition ASoA.h:59
uint32_t label_hash
Definition ASoA.h:73
constexpr bool descriptionCompatible(uint32_t _desc_hash) const noexcept
Definition ASoA.h:91
constexpr bool operator==(TableRef const &other) const noexcept
Definition ASoA.h:78
constexpr TableRef(TableRef &&)=default
uint32_t version
Definition ASoA.h:76
constexpr TableRef(TableRef const &)=default
consteval TableRef(uint32_t _label, uint32_t _desc, uint32_t _origin, uint32_t _version)
Definition ASoA.h:66
constexpr bool descriptionCompatible(TableRef const &other) const noexcept
Definition ASoA.h:86
uint32_t desc_hash
Definition ASoA.h:74
uint32_t origin_hash
Definition ASoA.h:75
constexpr TableRef & operator=(TableRef &&)=default
TableIteratorBase const & operator*() const
Definition ASoA.h:1904
TableIteratorBase(TableIteratorBase< IP, P, T... > const &other)
Definition ASoA.h:1812
typename Parent::columns_t columns_t
Definition ASoA.h:1759
TableIteratorBase(TableIteratorBase< IP, P, O1, Os... > const &other)
Definition ASoA.h:1798
typename Parent::external_index_columns_t external_index_columns_t
Definition ASoA.h:1760
TableIteratorBase operator-(int64_t dec) const
Definition ASoA.h:1899
void matchTo(TableIteratorBase< IP, P, T... > const &other)
Definition ASoA.h:1836
void matchTo(TableIteratorBase< IP, P, Os... > const &other)
Definition ASoA.h:1842
TableIteratorBase(TableIteratorBase< FilteredIndexPolicy, P, T... > other)
Definition ASoA.h:1824
std::array< B, sizeof...(CCs)> getValues() const
Definition ASoA.h:1881
static constexpr auto originals
Definition ASoA.h:1763
TableIteratorBase(TableIteratorBase< IP, P, T... > &&other) noexcept
Definition ASoA.h:1818
decltype([]< typename... C >(framework::pack< C... >) -> framework::pack< typename C::binding_t... > {}(external_index_columns_t{})) bindings_pack_t
Definition ASoA.h:1761
TableIteratorBase & operator=(TableIteratorBase< IP, P, Os... > other)
Definition ASoA.h:1775
TableIteratorBase(TableIteratorBase< IP, P, O1, Os... > &&other) noexcept
Definition ASoA.h:1805
TableIteratorBase & operator=(RowViewSentinel const &other)
Definition ASoA.h:1830
TableIteratorBase(arrow::ChunkedArray *columnData[framework::pack_size(columns_t{})], IP &&policy)
Definition ASoA.h:1769
TableIteratorBase & operator=(TableIteratorBase< IP, P, T... > other)
Definition ASoA.h:1783
TableIteratorBase operator+(int64_t inc) const
Allow incrementing by more than one the iterator.
Definition ASoA.h:1892
TableIteratorBase & operator=(TableIteratorBase< FilteredIndexPolicy, P, T... > other)
Definition ASoA.h:1790
unwrapper
Definition ASoA.h:466
VectorOfTObjectPtrs other
std::vector< ReadoutWindowData > rows
const std::string str