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