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