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