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