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