12#ifndef O2_FRAMEWORK_ASOA_H_
13#define O2_FRAMEWORK_ASOA_H_
26#include <arrow/table.h>
27#include <arrow/array.h>
28#include <arrow/util/config.h>
29#include <gandiva/selection_vector.h>
32#include <fmt/format.h>
40using ListVector = std::vector<std::vector<int64_t>>;
65 consteval TableRef(uint32_t _label, uint32_t _desc, uint32_t _origin, uint32_t _version)
79 return (this->label_hash ==
other.label_hash) &&
80 (this->desc_hash ==
other.desc_hash) &&
81 (this->origin_hash ==
other.origin_hash) &&
82 (this->version ==
other.version);
87 return this->desc_hash ==
other.desc_hash;
92 return this->desc_hash == _desc_hash;
102template <
size_t N1,
size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2>
105 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](
TableRef const&
a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
106 std::array<TableRef, N1 + N2 - duplicates> out;
108 auto pos = std::copy(ar1.begin(), ar1.end(), out.begin());
109 std::copy_if(ar2.begin(), ar2.end(),
pos, [&](TableRef
const&
a) { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
113template <
size_t N1,
size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2,
typename L>
116 constexpr const int to_remove = std::ranges::count_if(ar1.begin(), ar1.end(), [&](
TableRef const&
a) { return !l(a); });
117 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](
TableRef const&
a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) || !l(
a); });
118 std::array<TableRef, N1 + N2 - duplicates - to_remove> out;
120 auto pos = std::copy_if(ar1.begin(), ar1.end(), out.begin(), [&](TableRef
const&
a) { return l(a); });
121 std::copy_if(ar2.begin(), ar2.end(),
pos, [&](TableRef
const&
a) { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) && l(
a); });
125template <
size_t N, std::array<TableRef, N> ar,
typename L>
128 constexpr const int to_remove = std::ranges::count_if(ar.begin(), ar.end(), [&l](
TableRef const& e) { return l(e); });
129 std::array<
TableRef, N - to_remove> out;
130 std::copy_if(ar.begin(), ar.end(), out.begin(), [&l](
TableRef const& e) { return !l(e); });
134template <
size_t N1,
size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2>
135consteval auto intersect()
137 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](
TableRef const&
a) { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
138 std::array<TableRef, duplicates> out;
139 std::copy_if(ar1.begin(), ar1.end(), out.begin(), [](TableRef
const&
a) { return std::find(ar2.begin(), ar2.end(), a) != ar2.end(); });
143template <
typename T,
typename... Ts>
145 requires(
sizeof...(Ts) == 1)
148 return merge<T::originals.size(), T1::originals.size(), T::originals, T1::originals>();
151template <
typename T,
typename...
Ts>
153 requires(
sizeof...(Ts) > 1)
156 return merge<T::originals.size(), tail.size(), T::originals, tail>();
159template <
typename T,
typename...
Ts>
160 requires(
sizeof...(Ts) == 1)
161consteval auto intersectOriginals()
164 return intersect<T::originals.size(), T1::originals.size(), T::originals, T1::originals>();
167template <
typename T,
typename...
Ts>
168 requires(
sizeof...(Ts) > 1)
169consteval auto intersectOriginals()
172 return intersect<T::originals.size(), tail.size(), T::originals, tail>();
181concept not_void =
requires { !std::same_as<T, void>; };
198 {
c.setCurrentRaw(
b) } -> std::same_as<bool>;
203using is_external_index_t =
typename std::conditional_t<is_index_column<C>, std::true_type, std::false_type>;
206using is_self_index_t =
typename std::conditional_t<is_self_index_column<C>, std::true_type, std::false_type>;
212template <
typename D,
typename... Cs>
219 template <
typename Key,
typename... PCs>
222 return std::array<bool,
sizeof...(PCs)>{[]() {
223 if constexpr (
requires { PCs::index_targets.size(); }) {
224 return Key::template isIndexTargetOf<PCs::index_targets.size(), PCs::index_targets>();
231 template <
typename Key>
237 template <
typename Key,
size_t N, std::array<
bool, N> map>
240 constexpr const auto pos = std::find(map.begin(), map.end(),
true);
241 if constexpr (
pos != map.end()) {
242 return std::distance(map.begin(),
pos);
258 static constexpr uint32_t
hash = H;
259 static constexpr char const*
const str{
""};
263template <
size_t N, std::array<soa::TableRef, N> ar,
typename Key>
266 constexpr std::array<bool, N>
test = []<
size_t... Is>(std::index_sequence<Is...>) {
267 return std::array<bool, N>{(Key::template hasOriginal<ar[Is]>() || (
o2::aod::MetadataTrait<
o2::aod::Hash<ar[Is].desc_hash>>::metadata::template getIndexPosToKey<Key>() >= 0))...};
268 }(std::make_index_sequence<N>());
269 constexpr int correct = std::ranges::count(
test.begin(),
test.end(),
true);
270 std::array<soa::TableRef, correct> out;
271 std::ranges::copy_if(ar.begin(), ar.end(), out.begin(), [&
test](
soa::TableRef const&
r) { return test[std::distance(ar.begin(), std::find(ar.begin(), ar.end(), r))]; });
276#define O2HASH(_Str_) \
278 struct Hash<_Str_ ""_h> { \
279 static constexpr uint32_t hash = _Str_ ""_h; \
280 static constexpr char const* const str{_Str_}; \
284#define O2ORIGIN(_Str_) \
286 struct Hash<_Str_ ""_h> { \
287 static constexpr header::DataOrigin origin{_Str_}; \
288 static constexpr uint32_t hash = _Str_ ""_h; \
289 static constexpr char const* const str{_Str_}; \
293static inline constexpr uint32_t
version(
const char*
const str)
295 if (
str[0] ==
'\0') {
303 if (
str[
len - 1] ==
'\0') {
306 for (
auto i =
len + 1;
str[
i] !=
'\0'; ++
i) {
313static inline constexpr std::string_view description_str(
const char*
const str)
319 return std::string_view{
str,
len};
329 for (
auto i = 0;
i < 16; ++
i) {
332 std::memcpy(out,
str,
len);
337template <soa::TableRef R>
343template <soa::TableRef R>
349template <soa::TableRef R>
355template <soa::TableRef R>
369template <soa::TableRef R>
370static constexpr auto sourceSpec()
372 return fmt::format(
"{}/{}/{}/{}",
label<R>(), origin_str<R>(), description_str(signature<R>()),
R.version);
378template <aod::is_aod_hash L, aod::is_aod_hash D, aod::is_origin_hash O,
typename... Ts>
383 void const*
ptr =
nullptr;
385 std::span<TableRef const>
refs;
387 template <
typename T>
391 hash = o2::framework::TypeIdHelpers::uniqueId<T>();
392 refs = std::span{T::originals};
395 template <
typename T>
398 if (
hash == o2::framework::TypeIdHelpers::uniqueId<T>()) {
399 return static_cast<T const*
>(
ptr);
405template <
typename... C>
408 return std::vector<std::shared_ptr<arrow::Field>>{C::asArrowField()...};
434template <
typename B,
typename E>
436 constexpr static bool value =
false;
439template <aod::is_aod_hash A, aod::is_aod_hash B>
441 constexpr static bool value =
false;
444template <
typename B,
typename E>
447template <aod::is_aod_hash A, aod::is_aod_hash B>
486template <
typename T,
typename ChunkingPolicy = Chunked>
489 static constexpr char SCALE_FACTOR = std::same_as<std::decay_t<T>,
bool> ? 3 : 0;
505 auto array = getCurrentArray();
520 auto previousArray = getCurrentArray();
524 auto array = getCurrentArray();
531 auto previousArray = getCurrentArray();
535 auto array = getCurrentArray();
557 auto array = getCurrentArray();
563 decltype(
auto)
operator*()
const
564 requires std::same_as<bool, std::decay_t<T>>
570 decltype(
auto)
operator*()
const
571 requires((!std::same_as<bool, std::decay_t<T>>) && std::same_as<
arrow_array_for_t<T>, arrow::ListArray>)
580 decltype(
auto)
operator*()
const
581 requires((!std::same_as<bool, std::decay_t<T>>) && !std::same_as<
arrow_array_for_t<T>, arrow::ListArray>)
603 void checkSkipChunk() const
612 void checkSkipChunk() const
620 void checkSkipChunk() const
621 requires(ChunkingPolicy::
chunked == false)
625 auto getCurrentArray() const
629 mOffset = chunkToUse->offset();
630 chunkToUse = std::dynamic_pointer_cast<arrow::FixedSizeListArray>(chunkToUse)->values();
631 return std::static_pointer_cast<arrow_array_for_t<value_for_t<T>>>(chunkToUse);
634 auto getCurrentArray() const
638 mOffset = chunkToUse->offset();
639 chunkToUse = std::dynamic_pointer_cast<arrow::ListArray>(chunkToUse)->values();
640 mOffset = chunkToUse->offset();
641 return std::static_pointer_cast<arrow_array_for_t<value_for_t<T>>>(chunkToUse);
644 auto getCurrentArray() const
648 mOffset = chunkToUse->offset();
649 return std::static_pointer_cast<arrow_array_for_t<T>>(chunkToUse);
653template <
typename T,
typename INHERIT>
669 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
687template <
typename F,
typename INHERIT>
691 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
694template <
typename INHERIT>
698 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
701template <
typename INHERIT>
705 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
708template <
size_t M = 0>
712 constexpr inline static auto value = M;
727 static constexpr const char*
mLabel =
"Marker";
730template <int64_t START = 0, int64_t
END = -1>
733 constexpr inline static int64_t
start = START;
734 constexpr inline static int64_t
end =
END;
794 static constexpr const char*
mLabel =
"Index";
818using is_dynamic_t = std::conditional_t<is_dynamic_column<T>, std::true_type, std::false_type>;
824using is_indexing_t = std::conditional_t<is_indexing_column<T>, std::true_type, std::false_type>;
845 mSelectedRows(selection),
846 mMaxSelection(selection.
size()),
854 mSelectedRows = selection;
855 mMaxSelection = selection.size();
865 [[nodiscard]] std::tuple<int64_t const*, int64_t const*>
868 return std::make_tuple(&
mRowIndex, &mSelectionRow);
871 [[nodiscard]] std::tuple<uint64_t const*>
874 return std::make_tuple(&
mOffset);
881 mMaxSelection = std::min(
end, mMaxSelection);
899 return lh.mSelectionRow == rh.mSelectionRow;
912 this->mSelectionRow = this->mMaxSelection;
918 return mSelectionRow;
921 [[nodiscard]]
auto size()
const
923 return mMaxSelection;
932 inline void updateRow()
936 gsl::span<int64_t const> mSelectedRows;
937 int64_t mSelectionRow = 0;
938 int64_t mMaxSelection = 0;
973 [[nodiscard]] std::tuple<int64_t const*, int64_t const*>
979 [[nodiscard]] std::tuple<uint64_t const*>
982 return std::make_tuple(&
mOffset);
1023template <
typename T>
1028template <
typename C>
1034template <
typename T,
typename B>
1036 { t.B::mColumnIterator };
1039template <
typename...
C>
1042template <
typename D,
typename O,
typename IP,
typename... C>
1070 this->limitRange(this->rangeStart(), this->rangeEnd());
1076 C(static_cast<
C const&>(
other))...
1083 IP::operator=(
static_cast<IP const&
>(
other));
1084 (
void(
static_cast<C&
>(*
this) =
static_cast<C>(
other)), ...);
1090 requires std::same_as<IP, DefaultIndexPolicy>
1092 C(
static_cast<C const&
>(
other))...
1099 this->moveByIndex(1);
1112 this->moveByIndex(-1);
1127 copy.moveByIndex(inc);
1141 template <
typename... CL,
typename TA>
1144 (CL::setCurrent(current), ...);
1147 template <
typename CL>
1150 return CL::getCurrentRaw();
1153 template <
typename... Cs>
1156 return std::vector<o2::soa::Binding>{
static_cast<Cs const&
>(*this).getCurrentRaw()...};
1164 template <
typename... TA>
1170 template <
typename... Cs>
1173 (Cs::setCurrentRaw(ptrs[framework::has_type_at_v<Cs>(p)]), ...);
1176 template <
typename... Cs,
typename I>
1181 (Cs::setCurrentRaw(
b), ...);
1189 template <
typename I>
1197 template <
typename... PC>
1200 (PC::mColumnIterator.moveToEnd(), ...);
1210 [
this]<soa::is_dynamic_column T>(T*) ->
void { bindDynamicColumn<T>(
typename T::bindings_t{}); },
1211 [
this]<
typename T>(
T*) ->
void {},
1213 (
f(
static_cast<C*
>(
nullptr)), ...);
1214 if constexpr (has_index<
C...>) {
1215 this->setIndices(this->getIndices());
1216 this->setOffsets(this->getOffsets());
1220 template <
typename DC,
typename...
B>
1223 DC::boundIterators = std::make_tuple(getDynamicBinding<B>()...);
1231 template <
typename B>
1232 requires(can_bind<self_t, B>)
1233 decltype(
auto) getDynamicBinding()
1235 static_assert(std::same_as<decltype(&(static_cast<B*>(
this)->mColumnIterator)), std::decay_t<
decltype(B::mColumnIterator)>*>,
"foo");
1236 return &(
static_cast<B*
>(
this)->mColumnIterator);
1240 template <
typename B>
1241 decltype(
auto) getDynamicBinding()
1243 return static_cast<std::decay_t<decltype(B::mColumnIterator)
>*>(
nullptr);
1248 static std::shared_ptr<arrow::Table>
joinTables(std::vector<std::shared_ptr<arrow::Table>>&& tables, std::span<const char* const> labels);
1249 static std::shared_ptr<arrow::Table>
concatTables(std::vector<std::shared_ptr<arrow::Table>>&& tables);
1253template <
typename T>
1256template <
typename T>
1258 T::originals.size();
1261template <
typename T>
1266template <
typename T>
1269template <
size_t N1, std::array<TableRef, N1> os1,
size_t N2, std::array<TableRef, N2> os2>
1272 return []<
size_t... Is>(std::index_sequence<Is...>) {
1273 return ([]<
size_t... Ks>(std::index_sequence<Ks...>) {
1274 constexpr auto h = os1[Is].desc_hash;
1277 }(std::make_index_sequence<N2>()) ||
1279 }(std::make_index_sequence<N1>());
1282template <with_originals T, with_originals B>
1285 return is_compatible<T::originals.size(), T::originals, B::originals.size(), B::originals>();
1288template <
typename T,
typename B>
1289using is_binding_compatible = std::conditional_t<is_binding_compatible_v<T, typename B::binding_t>(), std::true_type, std::false_type>;
1291template <
typename L,
typename D,
typename O,
typename Key,
typename H,
typename...
Ts>
1294template <
typename T>
1297template <soa::is_table T>
1298static constexpr std::string getLabelForTable()
1300 return std::string{aod::label<std::decay_t<T>::originals[0]>()};
1303template <soa::is_table T>
1305static constexpr std::string getLabelFromType()
1307 return getLabelForTable<T>();
1310template <soa::is_iterator T>
1311static constexpr std::string getLabelFromType()
1313 return getLabelForTable<typename std::decay_t<T>::parent_t>();
1316template <soa::is_index_table T>
1317static constexpr std::string getLabelFromType()
1319 return getLabelForTable<typename std::decay_t<T>::first_t>();
1321template <soa::with_base_table T>
1322static constexpr std::string getLabelFromType()
1327template <
typename...
C>
1330 return ((C::inherited_t::mLabel ==
key) || ...);
1333template <TableRef ref>
1334static constexpr std::pair<bool, std::string> hasKey(std::string
const&
key)
1339template <
typename...
C>
1342 return std::vector{hasKey<C>(
key)...};
1348template <with_originals T,
bool OPT = false>
1349static constexpr std::string getLabelFromTypeForKey(std::string
const&
key)
1351 if constexpr (T::originals.size() == 1) {
1352 auto locate = hasKey<T::originals[0]>(
key);
1354 return locate.second;
1357 auto locate = [&]<
size_t... Is>(std::index_sequence<Is...>) {
1358 return std::vector{hasKey<T::originals[Is]>(
key)...};
1359 }(std::make_index_sequence<T::originals.size()>{});
1360 auto it = std::find_if(locate.begin(), locate.end(), [](
auto const&
x) { return x.first; });
1361 if (it != locate.end()) {
1365 if constexpr (!OPT) {
1373template <
typename B,
typename...
C>
1376 return (o2::soa::is_binding_compatible_v<B, typename C::binding_t>() || ...);
1379template <
typename B,
typename...
C>
1382 return ((C::sorted && o2::soa::is_binding_compatible_v<B, typename C::binding_t>()) || ...);
1385template <
typename B,
typename Z>
1386consteval static bool relatedByIndex()
1388 return hasIndexTo<B>(
typename Z::table_t::external_index_columns_t{});
1391template <
typename B,
typename Z>
1392consteval static bool relatedBySortedIndex()
1394 return hasSortedIndexTo<B>(
typename Z::table_t::external_index_columns_t{});
1413 std::shared_ptr<arrow::Table>
getSliceFor(
int value, std::shared_ptr<arrow::Table>
const& input, uint64_t&
offset)
const;
1423template <
typename T,
typename Policy,
bool OPT = false>
1431 : Policy{
PreslicePolicyBase{{o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.
name})},
Entry(o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name}), std::string{index_.name})}, {}}
1437 if constexpr (OPT) {
1438 if (Policy::isMissing()) {
1447 if constexpr (OPT) {
1448 if (Policy::isMissing()) {
1452 return Policy::getSliceFor(
value);
1456template <
typename T>
1458template <
typename T>
1460template <
typename T>
1462template <
typename T>
1465template <
typename T>
1472template <soa::is_table T>
1474template <
typename T>
1477template <
typename T>
1480template <
typename T>
1483template <
typename T>
1487template <
typename T>
1490template <
typename T>
1493template <
typename T>
1497template <
typename... Is>
1505template <
typename T,
typename C,
typename Policy,
bool OPT>
1506 requires std::same_as<Policy, framework::PreslicePolicySorted> && (o2::soa::is_binding_compatible_v<C, T>())
1509 if constexpr (OPT) {
1510 if (container.isMissing()) {
1516 auto t =
typename T::self_t({out},
offset);
1517 table->copyIndexBindings(t);
1518 t.bindInternalIndicesTo(table);
1522template <soa::is_filtered_table T>
1527 t.bindInternalIndicesTo(table);
1528 t.intersectWithSelection(table->getSelectedRows());
1532template <soa::is_table T>
1538 t.bindInternalIndicesTo(table);
1542template <
typename T,
typename C,
typename Policy,
bool OPT>
1543 requires std::same_as<Policy, framework::PreslicePolicyGeneral> && (o2::soa::is_binding_compatible_v<C, T>())
1546 if constexpr (OPT) {
1547 if (container.isMissing()) {
1557template <soa::is_filtered_table T>
1560 if (
offset >=
static_cast<uint64_t
>(table->tableSize())) {
1571template <soa::is_filtered_table T,
typename C,
bool OPT>
1572 requires(o2::soa::is_binding_compatible_v<C, T>())
1575 if constexpr (OPT) {
1576 if (container.isMissing()) {
1585template <
typename T>
1590 auto t =
typename T::self_t({table->asArrowTable()->Slice(
static_cast<uint64_t
>(
offset),
count)},
static_cast<uint64_t
>(
offset));
1591 table->copyIndexBindings(t);
1595template <
typename T>
1600 auto slice = table->asArrowTable()->Slice(
static_cast<uint64_t
>(
offset),
count);
1604template <
typename T>
1609 auto t =
typename T::self_t({table->asArrowTable()}, localCache.getSliceFor(
value));
1610 t.intersectWithSelection(table->getSelectedRows());
1611 table->copyIndexBindings(t);
1614 auto t =
Filtered<T>({table->asArrowTable()}, localCache.getSliceFor(
value));
1615 table->copyIndexBindings(t);
1620template <with_originals T>
1628template <
typename D,
typename O,
typename IP,
typename...
C>
1665 return std::array<TableRef, 1>{
ref};
1681 static constexpr const auto ref =
TableRef{L::hash, D::hash, O::hash, o2::aod::version(D::str)};
1686 static constexpr const auto originalLabels = []<
size_t N, std::array<TableRef, N> refs,
size_t... Is>(std::index_sequence<Is...>) {
return std::array<const char*, N>{o2::aod::label<refs[Is]>()...}; }.template operator()<
originals.size(),
originals>(std::make_index_sequence<
originals.size()>());
1688 template <
size_t N, std::array<TableRef, N> bindings>
1689 requires(
ref.origin_hash ==
"CONC"_h)
1695 template <
size_t N, std::array<TableRef, N> bindings>
1696 requires(
ref.origin_hash ==
"JOIN"_h)
1701 return std::find(bindings.begin(), bindings.end(),
r) != bindings.end();
1705 template <
size_t N, std::array<TableRef, N> bindings>
1706 requires(!(
ref.origin_hash ==
"CONC"_h ||
ref.origin_hash ==
"JOIN"_h))
1709 return std::find(bindings.begin(), bindings.end(),
self_t::ref) != bindings.end();
1712 template <TableRef r>
1725 template <
typename IP>
1728 template <
typename IP,
typename Parent,
typename... T>
1745 template <
typename P,
typename... Os>
1747 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1753 template <
typename P>
1760 template <
typename P>
1762 requires std::same_as<IP, DefaultIndexPolicy>
1768 template <
typename P,
typename O1,
typename... Os>
1770 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1775 template <
typename P,
typename O1,
typename... Os>
1777 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1782 template <
typename P>
1788 template <
typename P>
1794 template <
typename P>
1796 requires std::same_as<IP, DefaultIndexPolicy>
1803 this->mRowIndex =
other.index;
1806 template <
typename P>
1809 this->mRowIndex =
other.mRowIndex;
1812 template <
typename P,
typename... Os>
1814 requires std::same_as<typename P::table_t, typename Parent::table_t>
1816 this->mRowIndex =
other.mRowIndex;
1819 template <
typename TI>
1822 using decayed = std::decay_t<TI>;
1824 constexpr auto idx = framework::has_type_at_v<decayed>(
bindings_pack_t{});
1826 }
else if constexpr (std::same_as<decayed, Parent>) {
1827 return this->globalIndex();
1829 return this->globalIndex();
1831 return static_cast<int32_t
>(-1);
1835 template <
typename CD,
typename... CDArgs>
1838 using decayed = std::decay_t<CD>;
1840 return static_cast<decayed
>(*this).template getDynamicValue<CDArgs...>();
1843 template <
typename B,
typename CC>
1846 using COL = std::decay_t<CC>;
1848 return static_cast<B>(
static_cast<COL
>(*this).get());
1851 template <
typename B,
typename... CCs>
1854 static_assert(std::same_as<B, float> || std::same_as<B, double>,
"The common return type should be float or double");
1855 return {getValue<B, CCs>()...};
1866 copy.moveByIndex(inc);
1881 template <
typename IP,
typename Parent,
typename... T>
1884 template <
typename IP,
typename Parent>
1887 if constexpr (
sizeof...(Ts) == 0) {
1898 template <
typename IP,
typename Parent>
1910 return []<
typename...
C>(
framework::pack<
C...>) {
return std::set{{o2::framework::TypeIdHelpers::uniqueId<C>()...}}; }(
columns_t{});
1915 mEnd{table->num_rows()},
1918 if (mTable->num_rows() == 0) {
1920 mColumnChunks[ci] =
nullptr;
1926 mColumnChunks[ci] = lookups[ci];
1929 mBegin.bindInternalIndices(
this);
1933 Table(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t
offset = 0)
1934 requires(
ref.origin_hash !=
"CONC"_h)
1939 Table(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t
offset = 0)
1940 requires(
ref.origin_hash ==
"CONC"_h)
1945 template <
typename Key>
1949 return std::array<bool,
sizeof...(Cs)>{[]() {
1950 if constexpr (
requires { Cs::index_targets.size(); }) {
1951 return Key::template
isIndexTargetOf<Cs::index_targets.size(), Cs::index_targets>();
1957 constexpr auto pos = std::find(map.begin(), map.end(),
true);
1958 if constexpr (
pos != map.end()) {
1959 return mColumnChunks[std::distance(map.begin(),
pos)];
1961 static_assert(framework::always_static_assert_v<Key>,
"This table does not have an index to given Key");
1991 return filtered_iterator(mColumnChunks, {selection, mTable->num_rows(), mOffset});
2029 return mTable->num_rows();
2039 template <
typename... TA>
2042 mBegin.bindExternalIndices(current...);
2045 template <
typename I>
2048 mBegin.bindInternalIndices(
ptr);
2056 template <
typename... Cs>
2059 (
static_cast<Cs
>(mBegin).setCurrentRaw(binding), ...);
2064 mBegin.bindExternalIndicesRaw(std::forward<std::vector<o2::soa::Binding>>(ptrs));
2067 template <
typename T,
typename... Cs>
2070 dest.bindExternalIndicesRaw(mBegin.getIndexBindings());
2073 template <
typename T>
2096 template <
typename T1,
typename Policy,
bool OPT>
2109 return self_t{mTable->Slice(0, 0), 0};
2113 template <
typename T>
2114 arrow::ChunkedArray* lookupColumn()
2117 auto label = T::columnLabel();
2123 std::shared_ptr<arrow::Table> mTable =
nullptr;
2124 uint64_t mOffset = 0;
2131template <uint32_t
D, soa::is_column...
C>
2137namespace row_helpers
2148 return std::array<std::shared_ptr<arrow::Array>,
sizeof...(Cs)>{
o2::soa::getIndexFromLabel(table, Cs::columnLabel())->chunk(ci)...};
2151template <
typename T, soa::is_persistent_column C>
2152typename C::type
getSingleRowData(arrow::Table* table, T& rowIterator, uint64_t ci = std::numeric_limits<uint64_t>::max(), uint64_t ai = std::numeric_limits<uint64_t>::max(), uint64_t globalIndex = std::numeric_limits<uint64_t>::max())
2154 if (ci == std::numeric_limits<uint64_t>::max() || ai == std::numeric_limits<uint64_t>::max()) {
2155 auto colIterator =
static_cast<C>(rowIterator).getIterator();
2156 ci = colIterator.mCurrentChunk;
2157 ai = *(colIterator.mCurrentPos) - colIterator.mFirstIndex;
2159 return std::static_pointer_cast<o2::soa::arrow_array_for_t<typename C::type>>(
o2::soa::getIndexFromLabel(table, C::columnLabel())->chunk(ci))->raw_values()[ai];
2162template <
typename T, soa::is_dynamic_column C>
2163typename C::type
getSingleRowData(arrow::Table*, T& rowIterator, uint64_t ci = std::numeric_limits<uint64_t>::max(), uint64_t ai = std::numeric_limits<uint64_t>::max(), uint64_t globalIndex = std::numeric_limits<uint64_t>::max())
2165 if (globalIndex != std::numeric_limits<uint64_t>::max() && globalIndex != *std::get<0>(rowIterator.getIndices())) {
2166 rowIterator.setCursor(globalIndex);
2168 return rowIterator.template getDynamicColumn<C>();
2171template <
typename T, soa::is_index_column C>
2172typename C::type
getSingleRowData(arrow::Table*, T& rowIterator, uint64_t ci = std::numeric_limits<uint64_t>::max(), uint64_t ai = std::numeric_limits<uint64_t>::max(), uint64_t globalIndex = std::numeric_limits<uint64_t>::max())
2174 if (globalIndex != std::numeric_limits<uint64_t>::max() && globalIndex != *std::get<0>(rowIterator.getIndices())) {
2175 rowIterator.setCursor(globalIndex);
2177 return rowIterator.template getId<C>();
2180template <
typename T,
typename... Cs>
2181std::tuple<
typename Cs::type...>
getRowData(arrow::Table* table, T rowIterator, uint64_t ci = std::numeric_limits<uint64_t>::max(), uint64_t ai = std::numeric_limits<uint64_t>::max(), uint64_t globalIndex = std::numeric_limits<uint64_t>::max())
2183 return std::make_tuple(getSingleRowData<T, Cs>(table, rowIterator, ci, ai, globalIndex)...);
2188template <
typename R,
typename T,
typename C>
2189R getColumnValue(
const T& rowIterator)
2191 return static_cast<R>(
static_cast<C>(rowIterator).get());
2194template <
typename R,
typename T>
2195using ColumnGetterFunction =
R (*)(
const T&);
2197template <
typename T,
typename R>
2202 { t.get() } -> std::convertible_to<R>;
2205template <
typename T,
typename R>
2207 { t.get() } -> std::convertible_to<R>;
2210template <
typename R,
typename T, persistent_with_common_getter<R> C>
2211ColumnGetterFunction<R, T> createGetterPtr(
const std::string_view& targetColumnLabel)
2213 return targetColumnLabel == C::columnLabel() ? &getColumnValue<R, T, C> :
nullptr;
2216template <
typename R,
typename T, dynamic_with_common_getter<R> C>
2217ColumnGetterFunction<R, T> createGetterPtr(
const std::string_view& targetColumnLabel)
2219 std::string_view columnLabel(C::columnLabel());
2223 if (targetColumnLabel.starts_with(
"f") && targetColumnLabel.substr(1) == columnLabel) {
2224 return &getColumnValue<R, T, C>;
2228 if (targetColumnLabel == columnLabel) {
2229 return &getColumnValue<R, T, C>;
2235template <
typename R,
typename T,
typename... Cs>
2238 ColumnGetterFunction<R, T>
func;
2240 (
void)((
func = createGetterPtr<R, T, Cs>(targetColumnLabel),
func) || ...);
2249template <
typename T,
typename R>
2250using with_common_getter_t =
typename std::conditional<persistent_with_common_getter<T, R> || dynamic_with_common_getter<T, R>, std::true_type, std::false_type>
::type;
2253template <
typename R,
typename T>
2258 if (targetColumnLabel.size() == 0) {
2262 return getColumnGetterByLabel<R, typename T::iterator>(TypesWithCommonGetter{}, targetColumnLabel);
2282#define DECLARE_EQUIVALENT_FOR_INDEX(_Base_, _Equiv_) \
2284 struct EquivalentIndexNG<o2::aod::Hash<_Base_::ref.desc_hash>, o2::aod::Hash<_Equiv_::ref.desc_hash>> { \
2285 constexpr static bool value = true; \
2288#define DECLARE_EQUIVALENT_FOR_INDEX_NG(_Base_, _Equiv_) \
2290 struct EquivalentIndexNG<o2::aod::Hash<_Base_ ""_h>, o2::aod::Hash<_Equiv_ ""_h>> { \
2291 constexpr static bool value = true; \
2294#define DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) \
2295 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2296 static constexpr const char* mLabel = _Label_; \
2297 static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \
2298 using base = o2::soa::Column<_Type_, _Name_>; \
2299 using type = _Type_; \
2300 using column_t = _Name_; \
2301 _Name_(arrow::ChunkedArray const* column) \
2302 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2306 _Name_() = default; \
2307 _Name_(_Name_ const& other) = default; \
2308 _Name_& operator=(_Name_ const& other) = default; \
2310 decltype(auto) _Getter_() const \
2312 return *mColumnIterator; \
2315 decltype(auto) get() const \
2317 return _Getter_(); \
2320 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_>(), \
2321 o2::framework::expressions::selectArrowType<_Type_>() }
2323#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_) \
2324 DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, "f" #_Name_)
2328#define MAKEINT(_Size_) uint##_Size_##_t
2330#define DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, _Label_) \
2331 struct _Name_ : o2::soa::Column<MAKEINT(_Size_), _Name_> { \
2332 static constexpr const char* mLabel = _Label_; \
2333 static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \
2334 using base = o2::soa::Column<MAKEINT(_Size_), _Name_>; \
2335 using type = MAKEINT(_Size_); \
2336 _Name_(arrow::ChunkedArray const* column) \
2337 : o2::soa::Column<type, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2341 _Name_() = default; \
2342 _Name_(_Name_ const& other) = default; \
2343 _Name_& operator=(_Name_ const& other) = default; \
2345 decltype(auto) _Getter_##_raw() const \
2347 return *mColumnIterator; \
2350 bool _Getter_##_bit(int bit) const \
2352 return (*mColumnIterator & (static_cast<type>(1) << bit)) >> bit; \
2355 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_>(), \
2356 o2::framework::expressions::selectArrowType<MAKEINT(_Size_)>() }
2358#define DECLARE_SOA_BITMAP_COLUMN(_Name_, _Getter_, _Size_) \
2359 DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, "f" #_Name_)
2363#define DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_, _Expression_) \
2364 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2365 static constexpr const char* mLabel = _Label_; \
2366 using base = o2::soa::Column<_Type_, _Name_>; \
2367 using type = _Type_; \
2368 using column_t = _Name_; \
2369 using spawnable_t = std::true_type; \
2370 _Name_(arrow::ChunkedArray const* column) \
2371 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2375 _Name_() = default; \
2376 _Name_(_Name_ const& other) = default; \
2377 _Name_& operator=(_Name_ const& other) = default; \
2379 decltype(auto) _Getter_() const \
2381 return *mColumnIterator; \
2384 decltype(auto) get() const \
2386 return _Getter_(); \
2389 static o2::framework::expressions::Projector Projector() \
2391 return _Expression_; \
2394 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_>(), \
2395 o2::framework::expressions::selectArrowType<_Type_>() }
2397#define DECLARE_SOA_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Expression_) \
2398 DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, "f" #_Name_, _Expression_);
2402#define DECLARE_SOA_CONFIGURABLE_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Label_) \
2403 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2404 static constexpr const char* mLabel = _Label_; \
2405 static constexpr const int32_t mHash = _Label_ ""_h; \
2406 using base = o2::soa::Column<_Type_, _Name_>; \
2407 using type = _Type_; \
2408 using column_t = _Name_; \
2409 using spawnable_t = std::true_type; \
2410 _Name_(arrow::ChunkedArray const* column) \
2411 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2415 _Name_() = default; \
2416 _Name_(_Name_ const& other) = default; \
2417 _Name_& operator=(_Name_ const& other) = default; \
2419 decltype(auto) _Getter_() const \
2421 return *mColumnIterator; \
2424 decltype(auto) get() const \
2426 return _Getter_(); \
2429 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_>(), \
2430 o2::framework::expressions::selectArrowType<_Type_>() }
2453template <o2::soa::is_table T>
2456 return T::originals;
2459#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2460 struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \
2461 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2462 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2463 static constexpr const char* mLabel = "fIndexSlice" _Label_ _Suffix_; \
2464 using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \
2465 using type = _Type_[2]; \
2466 using column_t = _Name_##IdSlice; \
2467 using binding_t = _Table_; \
2468 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2469 _Name_##IdSlice(arrow::ChunkedArray const* column) \
2470 : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator<type>(column)) \
2474 _Name_##IdSlice() = default; \
2475 _Name_##IdSlice(_Name_##IdSlice const& other) = default; \
2476 _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \
2477 std::array<_Type_, 2> inline getIds() const \
2479 return _Getter_##Ids(); \
2482 bool has_##_Getter_() const \
2484 auto a = *mColumnIterator; \
2485 return a[0] >= 0 && a[1] >= 0; \
2488 std::array<_Type_, 2> _Getter_##Ids() const \
2490 auto a = *mColumnIterator; \
2491 return std::array{a[0], a[1]}; \
2494 template <typename T> \
2495 auto _Getter_##_as() const \
2497 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2498 o2::soa::notBoundTable(#_Table_); \
2500 auto t = mBinding.get<T>(); \
2501 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2502 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2504 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2505 return t->emptySlice(); \
2507 auto a = *mColumnIterator; \
2508 auto r = t->rawSlice(a[0], a[1]); \
2509 t->copyIndexBindings(r); \
2510 r.bindInternalIndicesTo(t); \
2514 auto _Getter_() const \
2516 return _Getter_##_as<binding_t>(); \
2519 template <typename T> \
2520 bool setCurrent(T const* current) \
2522 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2523 assert(current != nullptr); \
2524 this->mBinding.bind(current); \
2530 bool setCurrentRaw(o2::soa::Binding current) \
2532 this->mBinding = current; \
2535 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2536 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2537 o2::soa::Binding mBinding; \
2540#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2541#define DECLARE_SOA_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2542#define DECLARE_SOA_SLICE_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2545#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2546 struct _Name_##Ids : o2::soa::Column<std::vector<_Type_>, _Name_##Ids> { \
2547 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2548 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2549 static constexpr const char* mLabel = "fIndexArray" _Label_ _Suffix_; \
2550 using base = o2::soa::Column<std::vector<_Type_>, _Name_##Ids>; \
2551 using type = std::vector<_Type_>; \
2552 using column_t = _Name_##Ids; \
2553 using binding_t = _Table_; \
2554 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2555 _Name_##Ids(arrow::ChunkedArray const* column) \
2556 : o2::soa::Column<std::vector<_Type_>, _Name_##Ids>(o2::soa::ColumnIterator<type>(column)) \
2560 _Name_##Ids() = default; \
2561 _Name_##Ids(_Name_##Ids const& other) = default; \
2562 _Name_##Ids& operator=(_Name_##Ids const& other) = default; \
2564 gsl::span<const _Type_> inline getIds() const \
2566 return _Getter_##Ids(); \
2569 gsl::span<const _Type_> _Getter_##Ids() const \
2571 return *mColumnIterator; \
2574 bool has_##_Getter_() const \
2576 return !(*mColumnIterator).empty(); \
2579 template <typename T> \
2580 auto _Getter_##_as() const \
2582 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2583 o2::soa::notBoundTable(#_Table_); \
2585 auto t = mBinding.get<T>(); \
2586 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2587 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2589 return getIterators<T>(); \
2592 template <typename T> \
2593 auto filtered_##_Getter_##_as() const \
2595 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2596 o2::soa::notBoundTable(#_Table_); \
2598 auto t = mBinding.get<T>(); \
2599 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2600 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2602 return getFilteredIterators<T>(); \
2605 template <typename T> \
2606 auto getIterators() const \
2608 auto result = std::vector<typename T::unfiltered_iterator>(); \
2609 for (auto& i : *mColumnIterator) { \
2610 result.push_back(mBinding.get<T>()->rawIteratorAt(i)); \
2615 template <typename T> \
2616 std::vector<typename T::iterator> getFilteredIterators() const \
2618 if constexpr (o2::soa::is_filtered_table<T>) { \
2619 auto result = std::vector<typename T::iterator>(); \
2620 for (auto const& i : *mColumnIterator) { \
2621 auto pos = mBinding.get<T>()->isInSelectedRows(i); \
2623 result.emplace_back(mBinding.get<T>()->iteratorAt(pos)); \
2628 static_assert(o2::framework::always_static_assert_v<T>, "T is not a Filtered type"); \
2633 auto _Getter_() const \
2635 return _Getter_##_as<binding_t>(); \
2638 template <typename T> \
2639 auto _Getter_##_first_as() const \
2641 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2642 o2::soa::notBoundTable(#_Table_); \
2644 auto t = mBinding.get<T>(); \
2645 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2646 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2648 return t->rawIteratorAt((*mColumnIterator)[0]); \
2651 template <typename T> \
2652 auto _Getter_##_last_as() const \
2654 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2655 o2::soa::notBoundTable(#_Table_); \
2657 auto t = mBinding.get<T>(); \
2658 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2659 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2661 return t->rawIteratorAt((*mColumnIterator).back()); \
2664 auto _Getter_first() const \
2666 return _Getter_##_first_as<binding_t>(); \
2669 auto _Getter_last() const \
2671 return _Getter_##_last_as<binding_t>(); \
2674 template <typename T> \
2675 bool setCurrent(T const* current) \
2677 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2678 assert(current != nullptr); \
2679 this->mBinding.bind(current); \
2685 bool setCurrentRaw(o2::soa::Binding current) \
2687 this->mBinding = current; \
2690 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2691 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2692 o2::soa::Binding mBinding; \
2695#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2696#define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2697#define DECLARE_SOA_ARRAY_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2700#define DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2701 struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \
2702 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2703 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2704 static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \
2705 using base = o2::soa::Column<_Type_, _Name_##Id>; \
2706 using type = _Type_; \
2707 using column_t = _Name_##Id; \
2708 using binding_t = _Table_; \
2709 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2710 _Name_##Id(arrow::ChunkedArray const* column) \
2711 : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator<type>(column)) \
2715 _Name_##Id() = default; \
2716 _Name_##Id(_Name_##Id const& other) = default; \
2717 _Name_##Id& operator=(_Name_##Id const& other) = default; \
2718 type inline getId() const \
2720 return _Getter_##Id(); \
2723 type _Getter_##Id() const \
2725 return *mColumnIterator; \
2728 bool has_##_Getter_() const \
2730 return *mColumnIterator >= 0; \
2733 template <typename T> \
2734 auto _Getter_##_as() const \
2736 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2737 o2::soa::notBoundTable(#_Table_); \
2739 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2740 o2::soa::accessingInvalidIndexFor(#_Getter_); \
2742 auto t = mBinding.get<T>(); \
2743 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2744 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2746 return t->rawIteratorAt(*mColumnIterator); \
2749 auto _Getter_() const \
2751 return _Getter_##_as<binding_t>(); \
2754 template <typename T> \
2755 bool setCurrent(T* current) \
2757 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2758 assert(current != nullptr); \
2759 this->mBinding.bind(current); \
2765 bool setCurrentRaw(o2::soa::Binding current) \
2767 this->mBinding = current; \
2770 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2771 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2772 o2::soa::Binding mBinding; \
2774 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" #_Table_ _Suffix_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \
2775 o2::framework::expressions::selectArrowType<_Type_>() }
2777#define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2778#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2779#define DECLARE_SOA_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2782#define DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2783 struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \
2784 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2785 static constexpr const char* mLabel = "fIndex" _Label_; \
2786 using base = o2::soa::Column<_Type_, _Name_##Id>; \
2787 using type = _Type_; \
2788 using column_t = _Name_##Id; \
2789 using self_index_t = std::true_type; \
2790 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2791 _Name_##Id(arrow::ChunkedArray const* column) \
2792 : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator<type>(column)) \
2796 _Name_##Id() = default; \
2797 _Name_##Id(_Name_##Id const& other) = default; \
2798 _Name_##Id& operator=(_Name_##Id const& other) = default; \
2799 type inline getId() const \
2801 return _Getter_##Id(); \
2804 type _Getter_##Id() const \
2806 return *mColumnIterator; \
2809 bool has_##_Getter_() const \
2811 return *mColumnIterator >= 0; \
2814 template <typename T> \
2815 auto _Getter_##_as() const \
2817 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2818 o2::soa::accessingInvalidIndexFor(#_Getter_); \
2820 auto t = mBinding.get<T>(); \
2821 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2822 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2824 return t->rawIteratorAt(*mColumnIterator); \
2827 bool setCurrentRaw(o2::soa::Binding current) \
2829 this->mBinding = current; \
2832 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2833 o2::soa::Binding mBinding; \
2835 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" _Label_, o2::framework::TypeIdHelpers::uniqueId<_Name_##Id>(), \
2836 o2::framework::expressions::selectArrowType<_Type_>() }
2838#define DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2839#define DECLARE_SOA_SELF_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, #_Name_)
2841#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2842 struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \
2843 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2844 static constexpr const char* mLabel = "fIndexSlice" _Label_; \
2845 using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \
2846 using type = _Type_[2]; \
2847 using column_t = _Name_##IdSlice; \
2848 using self_index_t = std::true_type; \
2849 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2850 _Name_##IdSlice(arrow::ChunkedArray const* column) \
2851 : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator<type>(column)) \
2855 _Name_##IdSlice() = default; \
2856 _Name_##IdSlice(_Name_##IdSlice const& other) = default; \
2857 _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \
2858 std::array<_Type_, 2> inline getIds() const \
2860 return _Getter_##Ids(); \
2863 bool has_##_Getter_() const \
2865 auto a = *mColumnIterator; \
2866 return a[0] >= 0 && a[1] >= 0; \
2869 std::array<_Type_, 2> _Getter_##Ids() const \
2871 auto a = *mColumnIterator; \
2872 return std::array{a[0], a[1]}; \
2875 template <typename T> \
2876 auto _Getter_##_as() const \
2878 auto t = mBinding.get<T>(); \
2879 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2880 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2882 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2883 return t->emptySlice(); \
2885 auto a = *mColumnIterator; \
2886 auto r = t->rawSlice(a[0], a[1]); \
2887 t->copyIndexBindings(r); \
2888 r.bindInternalIndicesTo(t); \
2892 bool setCurrentRaw(o2::soa::Binding current) \
2894 this->mBinding = current; \
2897 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2898 o2::soa::Binding mBinding; \
2901#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2902#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_)
2904#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2905 struct _Name_##Ids : o2::soa::Column<std::vector<_Type_>, _Name_##Ids> { \
2906 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2907 static constexpr const char* mLabel = "fIndexArray" _Label_; \
2908 using base = o2::soa::Column<std::vector<_Type_>, _Name_##Ids>; \
2909 using type = std::vector<_Type_>; \
2910 using column_t = _Name_##Ids; \
2911 using self_index_t = std::true_type; \
2912 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2913 _Name_##Ids(arrow::ChunkedArray const* column) \
2914 : o2::soa::Column<std::vector<_Type_>, _Name_##Ids>(o2::soa::ColumnIterator<type>(column)) \
2918 _Name_##Ids() = default; \
2919 _Name_##Ids(_Name_##Ids const& other) = default; \
2920 _Name_##Ids& operator=(_Name_##Ids const& other) = default; \
2921 gsl::span<const _Type_> inline getIds() const \
2923 return _Getter_##Ids(); \
2926 gsl::span<const _Type_> _Getter_##Ids() const \
2928 return *mColumnIterator; \
2931 bool has_##_Getter_() const \
2933 return !(*mColumnIterator).empty(); \
2936 template <typename T> \
2937 auto _Getter_##_as() const \
2939 auto t = mBinding.get<T>(); \
2940 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2941 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2943 return getIterators<T>(); \
2946 template <typename T> \
2947 auto getIterators() const \
2949 auto result = std::vector<typename T::unfiltered_iterator>(); \
2950 for (auto& i : *mColumnIterator) { \
2951 result.push_back(mBinding.get<T>()->rawIteratorAt(i)); \
2956 template <typename T> \
2957 auto _Getter_##_first_as() const \
2959 return mBinding.get<T>()->rawIteratorAt((*mColumnIterator)[0]); \
2962 template <typename T> \
2963 auto _Getter_##_last_as() const \
2965 return mBinding.get<T>()->rawIteratorAt((*mColumnIterator).back()); \
2968 bool setCurrentRaw(o2::soa::Binding current) \
2970 this->mBinding = current; \
2973 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2974 o2::soa::Binding mBinding; \
2977#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2978#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_)
3008#define DECLARE_SOA_DYNAMIC_COLUMN(_Name_, _Getter_, ...) \
3009 struct _Name_##Callback { \
3010 static inline constexpr auto getLambda() { return __VA_ARGS__; } \
3013 struct _Name_##Helper { \
3014 using callable_t = decltype(o2::framework::FunctionMetadata(std::declval<decltype(_Name_##Callback::getLambda())>())); \
3015 using return_type = typename callable_t::return_type; \
3017 template <typename... Bindings> \
3018 struct _Name_ : o2::soa::DynamicColumn<typename _Name_##Helper::callable_t::type, _Name_<Bindings...>> { \
3019 using base = o2::soa::DynamicColumn<typename _Name_##Helper::callable_t::type, _Name_<Bindings...>>; \
3020 using helper = _Name_##Helper; \
3021 using callback_holder_t = _Name_##Callback; \
3022 using callable_t = helper::callable_t; \
3023 using callback_t = callable_t::type; \
3025 _Name_(arrow::ChunkedArray const*) \
3028 _Name_() = default; \
3029 _Name_(_Name_ const& other) = default; \
3030 _Name_& operator=(_Name_ const& other) = default; \
3031 static constexpr const char* mLabel = #_Name_; \
3032 using type = typename callable_t::return_type; \
3034 template <typename... FreeArgs> \
3035 type _Getter_(FreeArgs... freeArgs) const \
3037 return boundGetter(std::make_index_sequence<std::tuple_size_v<decltype(boundIterators)>>{}, freeArgs...); \
3039 template <typename... FreeArgs> \
3040 type getDynamicValue(FreeArgs... freeArgs) const \
3042 return boundGetter(std::make_index_sequence<std::tuple_size_v<decltype(boundIterators)>>{}, freeArgs...); \
3047 return _Getter_(); \
3050 template <size_t... Is, typename... FreeArgs> \
3051 type boundGetter(std::integer_sequence<size_t, Is...>&&, FreeArgs... freeArgs) const \
3053 return __VA_ARGS__((**std::get<Is>(boundIterators))..., freeArgs...); \
3056 using bindings_t = typename o2::framework::pack<Bindings...>; \
3057 std::tuple<o2::soa::ColumnIterator<typename Bindings::type> const*...> boundIterators; \
3060#define DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, ...) \
3061 using _Name_##Metadata = TableMetadata<Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__>;
3063#define DECLARE_SOA_TABLE_METADATA_TRAIT(_Name_, _Desc_, _Version_) \
3065 struct MetadataTrait<Hash<_Desc_ "/" #_Version_ ""_h>> { \
3066 using metadata = _Name_##Metadata; \
3069#define DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, _Version_) \
3070 O2HASH(_Desc_ "/" #_Version_); \
3071 template <typename O> \
3072 using _Name_##From = o2::soa::Table<Hash<_Label_ ""_h>, Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3073 using _Name_ = _Name_##From<Hash<_Origin_ ""_h>>; \
3075 struct MetadataTrait<Hash<_Desc_ "/" #_Version_ ""_h>> { \
3076 using metadata = _Name_##Metadata; \
3079#define DECLARE_SOA_STAGE(_Name_, _Origin_, _Desc_, _Version_) \
3080 template <typename O> \
3081 using _Name_##From = o2::soa::Table<Hash<#_Name_ ""_h>, Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3082 using _Name_ = _Name_##From<Hash<_Origin_ ""_h>>;
3084#define DECLARE_SOA_TABLE_FULL_VERSIONED(_Name_, _Label_, _Origin_, _Desc_, _Version_, ...) \
3085 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, __VA_ARGS__); \
3086 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, _Version_);
3088#define DECLARE_SOA_TABLE_FULL(_Name_, _Label_, _Origin_, _Desc_, ...) \
3090 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, 0, __VA_ARGS__); \
3091 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, 0)
3093#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_, ...) \
3094 DECLARE_SOA_TABLE_FULL(_Name_, #_Name_, _Origin_, _Desc_, __VA_ARGS__)
3096#define DECLARE_SOA_TABLE_VERSIONED(_Name_, _Origin_, _Desc_, _Version_, ...) \
3098 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, __VA_ARGS__); \
3099 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, #_Name_, _Origin_, _Desc_, _Version_)
3101#define DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Desc_, _Version_, ...) \
3102 O2HASH(_Desc_ "/" #_Version_); \
3103 O2HASH(#_BaseName_); \
3104 O2HASH("Stored" #_BaseName_); \
3105 DECLARE_SOA_TABLE_METADATA(_BaseName_, _Desc_, _Version_, __VA_ARGS__); \
3106 using Stored##_BaseName_##Metadata = _BaseName_##Metadata; \
3107 DECLARE_SOA_TABLE_METADATA_TRAIT(_BaseName_, _Desc_, _Version_); \
3108 DECLARE_SOA_STAGE(_BaseName_, "AOD", _Desc_, _Version_); \
3109 DECLARE_SOA_STAGE(Stored##_BaseName_, "AOD1", _Desc_, _Version_);
3111#define DECLARE_SOA_TABLE_STAGED(_BaseName_, _Desc_, ...) \
3112 DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Desc_, 0, __VA_ARGS__);
3114#define DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, _Label_, _OriginalTable_, _Origin_, _Desc_, _Version_, ...) \
3115 O2HASH(_Desc_ "/" #_Version_); \
3116 template <typename O> \
3117 using _Name_##ExtensionFrom = soa::Table<o2::aod::Hash<_Label_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3118 using _Name_##Extension = _Name_##ExtensionFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3119 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3120 struct _Name_##ExtensionMetadataFrom : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3121 using base_table_t = _OriginalTable_; \
3122 using extension_table_t = _Name_##ExtensionFrom<O>; \
3123 using expression_pack_t = framework::pack<__VA_ARGS__>; \
3124 static constexpr auto sources = _OriginalTable_::originals; \
3126 using _Name_##ExtensionMetadata = _Name_##ExtensionMetadataFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3128 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3129 using metadata = _Name_##ExtensionMetadata; \
3131 template <typename O> \
3132 using _Name_##From = o2::soa::JoinFull<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, _OriginalTable_, _Name_##ExtensionFrom<O>>; \
3133 using _Name_ = _Name_##From<o2::aod::Hash<_Origin_ ""_h>>;
3135#define DECLARE_SOA_EXTENDED_TABLE(_Name_, _Table_, _Description_, _Version_, ...) \
3136 O2HASH(#_Name_ "Extension"); \
3137 DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, #_Name_ "Extension", _Table_, "DYN", _Description_, _Version_, __VA_ARGS__)
3139#define DECLARE_SOA_EXTENDED_TABLE_USER(_Name_, _Table_, _Description_, ...) \
3140 O2HASH(#_Name_ "Extension"); \
3141 DECLARE_SOA_EXTENDED_TABLE_FULL(_Name_, #_Name_ "Extension", _Table_, "AOD", "EX" _Description_, 0, __VA_ARGS__)
3143#define DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE_FULL(_Name_, _Label_, _OriginalTable_, _Origin_, _Desc_, _Version_, ...) \
3144 O2HASH(_Desc_ "/" #_Version_); \
3145 template <typename O> \
3146 using _Name_##CfgExtensionFrom = soa::Table<o2::aod::Hash<_Label_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3147 using _Name_##CfgExtension = _Name_##CfgExtensionFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3148 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3149 struct _Name_##CfgExtensionMetadataFrom : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3150 using base_table_t = _OriginalTable_; \
3151 using extension_table_t = _Name_##CfgExtensionFrom<O>; \
3152 using placeholders_pack_t = framework::pack<__VA_ARGS__>; \
3153 using configurable_t = std::true_type; \
3154 static constexpr auto sources = _OriginalTable_::originals; \
3156 using _Name_##CfgExtensionMetadata = _Name_##CfgExtensionMetadataFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3158 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3159 using metadata = _Name_##CfgExtensionMetadata; \
3161 template <typename O> \
3162 using _Name_##From = o2::soa::JoinFull<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, _OriginalTable_, _Name_##CfgExtensionFrom<O>>; \
3163 using _Name_ = _Name_##From<o2::aod::Hash<_Origin_ ""_h>>;
3165#define DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE(_Name_, _Table_, _Description_, ...) \
3166 O2HASH(#_Name_ "CfgExtension"); \
3167 DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE_FULL(_Name_, #_Name_ "CfgExtension", _Table_, "AOD", "EX" _Description_, 0, __VA_ARGS__)
3169#define DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, _Origin_, _Version_, _Desc_, _Exclusive_, ...) \
3171 O2HASH(_Desc_ "/" #_Version_); \
3172 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3173 struct _Name_##MetadataFrom : o2::aod::TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, soa::Index<>, __VA_ARGS__> { \
3174 static constexpr bool exclusive = _Exclusive_; \
3175 using Key = _Key_; \
3176 using index_pack_t = framework::pack<__VA_ARGS__>; \
3177 static constexpr const auto sources = []<typename... Cs>(framework::pack<Cs...>) { \
3178 constexpr auto a = o2::soa::mergeOriginals<typename Cs::binding_t...>(); \
3179 return o2::aod::filterForKey<a.size(), a, Key>(); \
3180 }(framework::pack<__VA_ARGS__>{}); \
3182 using _Name_##Metadata = _Name_##MetadataFrom<o2::aod::Hash<_Origin_ ""_h>>; \
3184 template <typename O = o2::aod::Hash<_Origin_ ""_h>> \
3185 using _Name_##From = o2::soa::IndexTable<o2::aod::Hash<#_Name_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O, _Key_, __VA_ARGS__>; \
3186 using _Name_ = _Name_##From<o2::aod::Hash<_Origin_ ""_h>>; \
3189 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3190 using metadata = _Name_##Metadata; \
3193#define DECLARE_SOA_INDEX_TABLE(_Name_, _Key_, _Description_, ...) \
3194 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "IDX", 0, _Description_, false, __VA_ARGS__)
3196#define DECLARE_SOA_INDEX_TABLE_EXCLUSIVE(_Name_, _Key_, _Description_, ...) \
3197 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "IDX", 0, _Description_, true, __VA_ARGS__)
3199#define DECLARE_SOA_INDEX_TABLE_USER(_Name_, _Key_, _Description_, ...) \
3200 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "AOD", 0, _Description_, false, __VA_ARGS__)
3202#define DECLARE_SOA_INDEX_TABLE_EXCLUSIVE_USER(_Name_, _Key_, _Description_, ...) \
3203 DECLARE_SOA_INDEX_TABLE_FULL(_Name_, _Key_, "AOD", 0, _Description_, true, __VA_ARGS__)
3207template <
typename D,
typename...
Ts>
3208struct JoinFull :
Table<o2::aod::Hash<"JOIN"_h>, D, o2::aod::Hash<"JOIN"_h>, Ts...> {
3257 template <
typename T1,
typename Policy,
bool OPT>
3285 template <
typename T>
3292template <
typename...
Ts>
3295template <
typename...
Ts>
3301template <
typename T>
3304template <
typename T>
3307template <
typename...
Ts>
3308struct Concat :
Table<o2::aod::Hash<"CONC"_h>, o2::aod::Hash<"CONC/0"_h>, o2::aod::Hash<"CONC"_h>, Ts...> {
3311 Concat(std::vector<std::shared_ptr<arrow::Table>>&& tables, uint64_t
offset = 0)
3319 bindInternalIndicesTo(
this);
3322 using base::originals;
3324 using base::bindExternalIndices;
3325 using base::bindInternalIndicesTo;
3339template <
typename...
Ts>
3345template <soa::is_table T>
3356 using iterator = T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3362 mSelectedRows{getSpan(selection)}
3364 if (this->tableSize() != 0) {
3365 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3368 mFilteredBegin.bindInternalIndices(
this);
3373 mSelectedRowsCache{
std::move(selection)},
3376 mSelectedRows = gsl::span{mSelectedRowsCache};
3377 if (this->tableSize() != 0) {
3378 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3381 mFilteredBegin.bindInternalIndices(
this);
3384 FilteredBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, gsl::span<int64_t const>
const& selection, uint64_t
offset = 0)
3386 mSelectedRows{selection}
3388 if (this->tableSize() != 0) {
3389 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3392 mFilteredBegin.bindInternalIndices(
this);
3419 return mFilteredBegin;
3424 return mFilteredBegin;
3429 return mFilteredBegin +
i;
3434 return mSelectedRows.size();
3439 return table_t::asArrowTable()->num_rows();
3444 return mSelectedRows;
3450 newSelection.resize(
static_cast<int64_t
>(
end -
start + 1));
3451 std::iota(newSelection.begin(), newSelection.end(),
start);
3452 return self_t{{this->asArrowTable()}, std::move(newSelection), 0};
3462 if (sel ==
nullptr) {
3463 return gsl::span<int64_t const>{};
3465 auto array = std::static_pointer_cast<arrow::Int64Array>(sel->ToArray());
3468 return gsl::span{
start, stop};
3473 template <
typename... TA>
3476 table_t::bindExternalIndices(current...);
3477 mFilteredBegin.bindExternalIndices(current...);
3482 mFilteredBegin.bindExternalIndicesRaw(std::forward<std::vector<o2::soa::Binding>>(ptrs));
3485 template <
typename I>
3488 mFilteredBegin.bindInternalIndices(
ptr);
3491 template <
typename T1,
typename... Cs>
3494 dest.bindExternalIndicesRaw(mFilteredBegin.getIndexBindings());
3497 template <
typename T1>
3503 template <
typename T1>
3519 template <
typename T1,
bool OPT>
3525 template <
typename T1,
bool OPT>
3534 copyIndexBindings(t);
3540 auto locate = std::find(mSelectedRows.begin(), mSelectedRows.end(),
i);
3541 if (locate == mSelectedRows.end()) {
3544 return static_cast<int>(std::distance(mSelectedRows.begin(), locate));
3551 std::set_union(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(rowsUnion));
3552 mSelectedRowsCache.clear();
3553 mSelectedRowsCache = rowsUnion;
3561 std::set_intersection(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(intersection));
3562 mSelectedRowsCache.clear();
3563 mSelectedRowsCache = intersection;
3571 std::set_union(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(rowsUnion));
3572 mSelectedRowsCache.clear();
3573 mSelectedRowsCache = rowsUnion;
3581 std::set_intersection(mSelectedRows.begin(), mSelectedRows.end(), selection.begin(), selection.end(), std::back_inserter(intersection));
3582 mSelectedRowsCache.clear();
3583 mSelectedRowsCache = intersection;
3596 mSelectedRows = gsl::span{mSelectedRowsCache};
3598 mFilteredEnd.reset(
new RowViewSentinel{
static_cast<int64_t
>(mSelectedRows.size())});
3599 if (tableSize() == 0) {
3600 mFilteredBegin = *mFilteredEnd;
3602 mFilteredBegin.resetSelection(mSelectedRows);
3606 gsl::span<int64_t const> mSelectedRows;
3608 bool mCached =
false;
3609 iterator mFilteredBegin;
3610 std::shared_ptr<RowViewSentinel> mFilteredEnd;
3613template <
typename T>
3622 using iterator = T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3628 return iterator(this->cached_begin());
3642 Filtered(std::vector<std::shared_ptr<arrow::Table>>&& tables, gsl::span<int64_t const>
const& selection, uint64_t
offset = 0)
3666 this->sumWithSelection(selection);
3672 this->sumWithSelection(selection);
3678 return operator+=(
other.getSelectedRows());
3697 return operator*(
other.getSelectedRows());
3702 this->intersectWithSelection(selection);
3708 this->intersectWithSelection(selection);
3714 return operator*=(
other.getSelectedRows());
3729 newSelection.resize(
static_cast<int64_t
>(
end -
start + 1));
3730 std::iota(newSelection.begin(), newSelection.end(),
start);
3731 return self_t{{this->asArrowTable()}, std::move(newSelection), 0};
3739 template <
typename T1>
3755 template <
typename T1,
bool OPT>
3761 template <
typename T1,
bool OPT>
3770 copyIndexBindings(t);
3775template <
typename T>
3784 using iterator =
typename T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3790 return iterator(this->cached_begin());
3801 for (
auto& table : tables) {
3809 for (
auto& table : tables) {
3817 for (
auto& table : tables) {
3843 this->sumWithSelection(selection);
3849 this->sumWithSelection(selection);
3855 return operator+=(
other.getSelectedRows());
3861 copy.intersectionWithSelection(selection);
3868 copy.intersectionWithSelection(selection);
3874 return operator*(
other.getSelectedRows());
3879 this->intersectWithSelection(selection);
3885 this->intersectWithSelection(selection);
3891 return operator*=(
other.getSelectedRows());
3904 newSelection.resize(
static_cast<int64_t
>(
end -
start + 1));
3905 std::iota(newSelection.begin(), newSelection.end(),
start);
3906 return self_t{{this->asArrowTable()}, std::move(newSelection), 0};
3924 template <
typename T1,
bool OPT>
3930 template <
typename T1,
bool OPT>
3937 std::vector<std::shared_ptr<arrow::Table>> extractTablesFromFiltered(std::vector<
Filtered<T>>& tables)
3939 std::vector<std::shared_ptr<arrow::Table>> outTables;
3940 for (
auto& table : tables) {
3941 outTables.push_back(table.asArrowTable());
3952template <
typename L,
typename D,
typename O,
typename Key,
typename H,
typename...
Ts>
3983template <
typename T,
bool APPLY>
3985 static constexpr bool applyFilters = APPLY;
3992 SmallGroupsBase(std::vector<std::shared_ptr<arrow::Table>>&& tables, gsl::span<int64_t const>
const& selection, uint64_t
offset = 0)
3996template <
typename T>
3999template <
typename T>
4002template <
typename T>
#define O2HASH(_Str_)
Pre-declare Hash specialization for a generic string.
#define O2ORIGIN(_Str_)
Pre-declare Hash specialization for an origin string.
consteval auto getIndexTargets()
SLICE.
o2::monitoring::tags::Key Key
#define O2_BUILTIN_UNREACHABLE
#define O2_BUILTIN_LIKELY(x)
#define O2_BUILTIN_UNLIKELY(x)
Class for time synchronization of RawReader instances.
int64_t const * mCurrentPos
ColumnIterator(arrow::ChunkedArray const *column)
ColumnIterator(ColumnIterator< T, ChunkingPolicy > const &)=default
void moveToEnd()
Move the iterator to the end of the column.
ColumnIterator< T > & moveToPos()
ColumnIterator< T, ChunkingPolicy > & operator=(ColumnIterator< T, ChunkingPolicy > const &)=default
unwrap_t< T > const * mCurrent
unwrap_t< T > const * mLast
ColumnIterator(ColumnIterator< T, ChunkingPolicy > &&)=default
arrow::ChunkedArray const * mColumn
ColumnIterator< T, ChunkingPolicy > & operator=(ColumnIterator< T, ChunkingPolicy > &&)=default
void moveToChunk(int chunk)
void nextChunk() const
Move the iterator to the next chunk.
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
FilteredBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
int64_t tableSize() const
FilteredBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
typename T::external_index_columns_t external_index_columns_t
auto select(framework::expressions::Filter const &f) const
static auto getSpan(gandiva::Selection const &sel)
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
auto rawSliceBy(o2::framework::Preslice< T1 > const &container, int value) const
T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
void copyIndexBindings(T1 &dest) const
auto const & getSelectedRows() const
typename T::columns_t columns_t
void bindExternalIndices(TA *... current)
void sumWithSelection(SelectionVector const &selection)
void bindInternalIndicesTo(I const *ptr)
void intersectWithSelection(SelectionVector const &selection)
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
auto rawSlice(uint64_t start, uint64_t end) const
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
iterator iteratorAt(uint64_t i) const
typename T::table_t table_t
typename T::persistent_columns_t persistent_columns_t
RowViewSentinel end() const
void intersectWithSelection(gsl::span< int64_t const > const &selection)
FilteredBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, SelectionVector &&selection, uint64_t offset=0)
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
const_iterator begin() const
unfiltered_iterator rawIteratorAt(uint64_t i) const
int isInSelectedRows(int i) const
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
void doCopyIndexBindings(framework::pack< Cs... >, T1 &dest) const
void sumWithSelection(gsl::span< int64_t const > const &selection)
auto const & cached_begin() const
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
typename FilteredBase< typename T::table_t >::table_t table_t
Filtered< Filtered< T > > operator+=(gsl::span< int64_t const > const &selection)
typename T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
Filtered< Filtered< T > > operator+(SelectionVector const &selection)
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
Filtered< Filtered< T > > operator*(gsl::span< int64_t const > const &selection)
typename T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
typename T::columns_t columns_t
const_iterator begin() const
Filtered(std::vector< Filtered< T > > &&tables, SelectionVector &&selection, uint64_t offset=0)
unfiltered_iterator rawIteratorAt(uint64_t i) const
Filtered< Filtered< T > > operator+=(Filtered< T > const &other)
Filtered< Filtered< T > > operator+=(SelectionVector const &selection)
Filtered< Filtered< T > > operator*=(SelectionVector const &selection)
auto rawSlice(uint64_t start, uint64_t end) const
Filtered< Filtered< T > > operator+(Filtered< T > const &other)
Filtered(std::vector< Filtered< T > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
Filtered< Filtered< T > > operator*=(Filtered< T > const &other)
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Filtered< Filtered< T > > operator*=(gsl::span< int64_t const > const &selection)
Filtered< Filtered< T > > operator*(Filtered< T > const &other)
Filtered< Filtered< T > > operator+(gsl::span< int64_t const > const &selection)
Filtered< Filtered< T > > operator*(SelectionVector const &selection)
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Filtered(std::vector< Filtered< T > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
Filtered< T > operator+=(Filtered< T > const &other)
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
Filtered(std::vector< std::shared_ptr< arrow::Table > > &&tables, SelectionVector &&selection, uint64_t offset=0)
Filtered(std::vector< std::shared_ptr< arrow::Table > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Filtered< T > operator+(Filtered< T > const &other)
Filtered< T > operator*=(SelectionVector const &selection)
const_iterator begin() const
T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
auto select(framework::expressions::Filter const &f) const
Filtered< T > operator+(SelectionVector const &selection)
Filtered< T > operator*(gsl::span< int64_t const > const &selection)
T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
unfiltered_iterator rawIteratorAt(uint64_t i) const
Filtered< T > operator*(SelectionVector const &selection)
Filtered< T > operator*=(Filtered< T > const &other)
Filtered< T > operator*(Filtered< T > const &other)
auto rawSliceBy(o2::framework::Preslice< T1 > const &container, int value) const
Filtered< T > operator+=(SelectionVector const &selection)
Filtered< T > operator*=(gsl::span< int64_t const > const &selection)
Filtered< T > operator+(gsl::span< int64_t const > const &selection)
Filtered< T > operator+=(gsl::span< int64_t const > const &selection)
auto rawSlice(uint64_t start, uint64_t end) const
Filtered(std::vector< std::shared_ptr< arrow::Table > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
typename T::table_t table_t
typename T::columns_t columns_t
decltype([]< typename... C >(framework::pack< C... > &&) -> framework::selected_pack< soa::is_self_index_t, C... > {}(columns_t{})) internal_index_columns_t
void bindInternalIndicesExplicit(o2::soa::Binding binding)
iterator iteratorAt(uint64_t i) const
decltype([]< typename... C >(framework::pack< C... > &&) -> framework::selected_pack< soa::is_persistent_column_t, C... > {}(columns_t{})) persistent_columns_t
static constexpr const auto ref
auto offset() const
Return offset.
static consteval bool hasOriginal()
unfiltered_iterator begin()
int64_t tableSize() const
auto rawSlice(uint64_t start, uint64_t end) const
void bindExternalIndices(TA *... current)
auto select(framework::expressions::Filter const &f) const
unfiltered_iterator unfiltered_const_iterator
static consteval auto full_iter()
auto const & cached_begin() const
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
TableIteratorBase< IP, Parent, T... > iterator_template
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
static constexpr auto hashes()
iterator unfiltered_iterator
std::shared_ptr< arrow::Table > asArrowTable() const
Return a type erased arrow table backing store for / the type safe table.
void doCopyIndexBindings(framework::pack< Cs... >, T &dest) const
int64_t size() const
Size of the table, in rows.
Table(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
decltype(getColumns< ref, Ts... >()) columns_t
arrow::ChunkedArray * getIndexToKey()
decltype([]< typename... C >(framework::pack< C... >) -> framework::pack< typename C::type... > {}(persistent_columns_t{})) column_types
static consteval auto isIndexTargetOf()
iterator_template_o< FilteredIndexPolicy, table_t > filtered_iterator
unfiltered_const_iterator begin() const
void copyIndexBindings(T &dest) const
static constexpr const auto originalLabels
Table(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
Table< L, D, O, Ts... > self_t
static consteval auto isIndexTargetOf()
decltype(full_iter< IP, Parent >()) iterator_template_o
void doBindInternalIndicesExplicit(framework::pack< Cs... >, o2::soa::Binding binding)
static constexpr const auto originals
decltype([]< typename... C >(framework::pack< C... > &&) -> framework::selected_pack< soa::is_external_index_t, C... > {}(columns_t{})) external_index_columns_t
Table(std::shared_ptr< arrow::Table > table, uint64_t offset=0)
RowViewSentinel end() const
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
void bindInternalIndicesTo(I const *ptr)
unfiltered_iterator rawIteratorAt(uint64_t i) const
filtered_iterator filtered_begin(gsl::span< int64_t const > selection)
iterator_template_o< DefaultIndexPolicy, table_t > iterator
hash identification concepts
Helper to check if a type T is an iterator.
column identification concepts
GLuint GLsizei const GLuint const GLintptr * offsets
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLuint GLsizei GLsizei * length
GLuint GLsizei const GLchar * label
GLsizei GLenum const void * indices
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLenum GLenum GLsizei len
GLboolean GLboolean GLboolean GLboolean a
std::shared_ptr< gandiva::SelectionVector > Selection
consteval const char * origin_str()
consteval const char * signature()
consteval auto filterForKey()
Filter TableRef array for compatibility with Key table.
consteval const char * label()
consteval header::DataOrigin origin()
std::shared_ptr< arrow::DataType > concreteArrowType(atype::type type)
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
Defining PrimaryVertex explicitly as messageable.
std::decay_t< decltype(select_pack< Condition >(pack<>{}, Pack{}, CondPack{}))> selected_pack_multicondition
std::decay_t< decltype(prune_voids_pack(pack<>{}, with_condition_pack< Condition, Types... >{}))> selected_pack
decltype(intersected_pack(Ps{}...)) full_intersected_pack_t
typename pack_element< I, T >::type pack_element_t
consteval size_t has_type_at_v(pack< Ts... >)
constexpr std::size_t pack_size(pack< Ts... > const &)
template function to determine number of types in a pack
decltype(concatenate_pack_unique(Ps{}...)) concatenated_pack_unique_t
std::string strToUpper(std::string &&str)
typename pack_element< 0, T >::type pack_head_t
std::string cutString(std::string &&str)
std::vector< std::vector< int64_t > > ListVector
std::array< std::shared_ptr< arrow::Array >, sizeof...(Cs)> getChunks(arrow::Table *table, framework::pack< Cs... >, uint64_t ci)
ColumnGetterFunction< R, typename T::iterator > getColumnGetterByLabel(const std::string_view &targetColumnLabel)
std::array< arrow::ChunkedArray *, sizeof...(Cs)> getArrowColumns(arrow::Table *table, framework::pack< Cs... >)
std::tuple< typename Cs::type... > getRowData(arrow::Table *table, T rowIterator, uint64_t ci=std::numeric_limits< uint64_t >::max(), uint64_t ai=std::numeric_limits< uint64_t >::max(), uint64_t globalIndex=std::numeric_limits< uint64_t >::max())
C::type getSingleRowData(arrow::Table *table, T &rowIterator, uint64_t ci=std::numeric_limits< uint64_t >::max(), uint64_t ai=std::numeric_limits< uint64_t >::max(), uint64_t globalIndex=std::numeric_limits< uint64_t >::max())
consteval auto computeOriginals()
auto createFieldsFromColumns(framework::pack< C... >)
SelectionVector selectionToVector(gandiva::Selection const &sel)
constexpr bool is_persistent_v
constexpr bool is_ng_index_equivalent_v
consteval auto remove_if(L l)
constexpr auto join(Ts const &... t)
auto doSliceBy(T const *table, o2::framework::PresliceBase< C, Policy, OPT > const &container, int value)
SelectionVector sliceSelection(gsl::span< int64_t const > const &mSelectedRows, int64_t nrows, uint64_t offset)
void notBoundTable(const char *tableName)
auto doFilteredSliceBy(T const *table, o2::framework::PresliceBase< C, framework::PreslicePolicySorted, OPT > const &container, int value)
constexpr auto concat(Ts const &... t)
consteval auto intersectOriginals()
consteval auto getColumns()
std::vector< int64_t > SelectionVector
std::conditional_t< is_binding_compatible_v< T, typename B::binding_t >(), std::true_type, std::false_type > is_binding_compatible
consteval auto mergeOriginals()
constexpr bool is_soa_filtered_v
typename std::conditional_t< is_index_column< C >, std::true_type, std::false_type > is_external_index_t
void missingFilterDeclaration(int hash, int ai)
auto doSliceByCachedUnsorted(T const *table, framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache)
auto doSliceByCached(T const *table, framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache)
void accessingInvalidIndexFor(const char *getter)
auto select(T const &t, framework::expressions::Filter const &f)
consteval auto base_iter(framework::pack< C... > &&) -> TableIterator< D, O, IP, C... >
constexpr bool is_index_equivalent_v
constexpr bool is_soa_join_v
void dereferenceWithWrongType(const char *getter, const char *target)
std::conditional_t< is_indexing_column< T >, std::true_type, std::false_type > is_indexing_t
auto doSliceByHelper(T const *table, gsl::span< const int64_t > const &selection)
consteval bool is_binding_compatible_v()
auto prepareFilteredSlice(T const *table, std::shared_ptr< arrow::Table > slice, uint64_t offset)
typename unwrap< T >::type unwrap_t
void getterNotFound(const char *targetColumnLabel)
auto doFilteredSliceByCached(T const *table, framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache)
void missingOptionalPreslice(const char *label, const char *key)
consteval bool is_compatible()
arrow::ChunkedArray * getIndexFromLabel(arrow::Table *table, std::string_view label)
consteval auto merge()
Helpers to manipulate TableRef arrays.
consteval auto merge_if(L l)
std::conditional_t< is_persistent_column< C >, std::true_type, std::false_type > is_persistent_column_t
typename arrow_array_for< T >::type arrow_array_for_t
void notFoundColumn(const char *label, const char *key)
std::conditional_t< is_dynamic_column< T >, std::true_type, std::false_type > is_dynamic_t
typename std::conditional_t< is_self_index_column< C >, std::true_type, std::false_type > is_self_index_t
Defining DataPointCompositeObject explicitly as copiable.
FIXME: do not use data model tables.
static constexpr uint32_t hash
static constexpr char const *const str
SliceInfoUnsortedPtr getCacheUnsortedFor(Entry const &bindingKey) const
SliceInfoPtr getCacheFor(Entry const &bindingKey) const
std::shared_ptr< arrow::Table > getSliceFor(int value, std::shared_ptr< arrow::Table > const &input, uint64_t &offset) const
static constexpr bool optional
PresliceBase(expressions::BindingNode index_)
gsl::span< const int64_t > getSliceFor(int value) const
const std::string binding
const std::string binding
Entry const & getBindingKey() const
SliceInfoUnsortedPtr sliceInfo
gsl::span< const int64_t > getSliceFor(int value) const
void updateSliceInfo(SliceInfoUnsortedPtr &&si)
void updateSliceInfo(SliceInfoPtr &&si)
std::shared_ptr< arrow::Table > getSliceFor(int value, std::shared_ptr< arrow::Table > const &input, uint64_t &offset) const
ArrowTableSlicingCache * ptr
std::pair< int64_t, int64_t > getSliceFor(int value) const
An expression tree node corresponding to a column binding.
A struct, containing the root of the expression tree.
From https://en.cppreference.com/w/cpp/utility/variant/visit.
static std::shared_ptr< arrow::Table > joinTables(std::vector< std::shared_ptr< arrow::Table > > &&tables, std::span< const char *const > labels)
static std::shared_ptr< arrow::Table > concatTables(std::vector< std::shared_ptr< arrow::Table > > &&tables)
Type-checking index column binding.
std::span< TableRef const > refs
void bind(T const *table)
static constexpr bool chunked
arrow::ChunkedArray * second
Column(ColumnIterator< T > const &it)
static constexpr const char *const & columnLabel()
ColumnIterator< T > const & getIterator() const
Column & operator=(Column const &)=default
Column(Column &&)=default
static auto asArrowField()
Column & operator=(Column &&)=default
Column(Column const &)=default
ColumnIterator< T > mColumnIterator
table_t::template iterator_template< DefaultIndexPolicy, self_t, Ts... > iterator
Concat(Ts const &... t, uint64_t offset=0)
typename table_t::persistent_columns_t persistent_columns_t
typename table_t::columns_t columns_t
const_iterator unfiltered_const_iterator
iterator unfiltered_iterator
table_t::template iterator_template< FilteredIndexPolicy, self_t, Ts... > filtered_iterator
Concat(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
filtered_iterator filtered_const_iterator
DefaultIndexPolicy(int64_t nRows, uint64_t offset)
friend bool operator==(DefaultIndexPolicy const &lh, DefaultIndexPolicy const &rh)
bool operator==(RowViewSentinel const &sentinel) const
DefaultIndexPolicy(FilteredIndexPolicy const &other)
std::tuple< uint64_t const * > getOffsets() const
DefaultIndexPolicy & operator=(DefaultIndexPolicy &&)=default
void setCursor(int64_t i)
void limitRange(int64_t start, int64_t end)
DefaultIndexPolicy(DefaultIndexPolicy &&)=default
DefaultIndexPolicy(DefaultIndexPolicy const &)=default
DefaultIndexPolicy & operator=(DefaultIndexPolicy const &)=default
std::tuple< int64_t const *, int64_t const * > getIndices() const
DefaultIndexPolicy()=default
Needed to be able to copy the policy.
void moveByIndex(int64_t i)
static constexpr const char *const & columnLabel()
void resetSelection(gsl::span< int64_t const > selection)
FilteredIndexPolicy & operator=(FilteredIndexPolicy &&)=default
std::tuple< int64_t const *, int64_t const * > getIndices() const
FilteredIndexPolicy & operator=(FilteredIndexPolicy const &)=default
auto getSelectionRow() const
FilteredIndexPolicy()=default
friend bool operator==(FilteredIndexPolicy const &lh, FilteredIndexPolicy const &rh)
void setCursor(int64_t i)
FilteredIndexPolicy(FilteredIndexPolicy const &)=default
bool operator==(RowViewSentinel const &sentinel) const
std::tuple< uint64_t const * > getOffsets() const
void limitRange(int64_t start, int64_t end)
FilteredIndexPolicy(gsl::span< int64_t const > selection, int64_t rows, uint64_t offset=0)
FilteredIndexPolicy(FilteredIndexPolicy &&)=default
void moveByIndex(int64_t i)
static constexpr bool chunked
static constexpr const char *const & columnLabel()
uint64_t mOffset
Offset within a larger table.
int64_t mRowIndex
Position inside the current table.
IndexTable(std::vector< std::shared_ptr< arrow::Table > > tables, uint64_t offset=0)
IndexTable(std::shared_ptr< arrow::Table > table, uint64_t offset=0)
typename base_t::template iterator_template_o< DefaultIndexPolicy, self_t > iterator
filtered_iterator const_filtered_iterator
IndexTable(IndexTable &&)=default
IndexTable & operator=(IndexTable const &)=default
IndexTable & operator=(IndexTable &&)=default
typename H::binding_t first_t
typename base_t::template iterator_template_o< FilteredIndexPolicy, self_t > filtered_iterator
IndexTable(IndexTable const &)=default
Index(Index const &)=default
void setIndices(std::tuple< int64_t const *, int64_t const * > indices)
Index & operator=(Index &&)=default
Index(arrow::ChunkedArray const *)
int64_t filteredIndex() const
constexpr int64_t rangeEnd()
constexpr int64_t rangeStart()
Index & operator=(Index const &)=default
int64_t globalIndex() const
std::tuple< int64_t const *, int64_t const * > rowIndices
void setOffsets(std::tuple< uint64_t const * > offsets)
static constexpr const char * mLabel
std::tuple< uint64_t const * > rowOffsets
iterator unfiltered_iterator
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
auto rawSlice(uint64_t start, uint64_t end) const
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
JoinFull(std::vector< std::shared_ptr< arrow::Table > > &&tables, uint64_t offset=0)
static constexpr const auto originalLabels
const_iterator unfiltered_const_iterator
filtered_iterator filtered_const_iterator
static consteval bool contains()
iterator iteratorAt(uint64_t i) const
typename table_t::columns_t columns_t
table_t::template iterator_template< DefaultIndexPolicy, self_t, Ts... > iterator
table_t::template iterator_template< FilteredIndexPolicy, self_t, Ts... > filtered_iterator
static constexpr const auto originals
JoinFull< D, Ts... > self_t
const_iterator begin() const
typename table_t::persistent_columns_t persistent_columns_t
iterator rawIteratorAt(uint64_t i) const
Table< o2::aod::Hash<"JOIN"_h >, D, o2::aod::Hash<"JOIN"_h >, Ts... > base
JoinFull(std::shared_ptr< arrow::Table > &&table, uint64_t offset=0)
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
static constexpr const char *const & columnLabel()
Marker & operator=(Marker const &)=default
static constexpr auto value
static constexpr const char * mLabel
Marker(arrow::ChunkedArray const *)
Marker(Marker const &)=default
Marker & operator=(Marker &&)=default
Marker(Marker &&)=default
SmallGroupsBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, SelectionVector &&selection, uint64_t offset=0)
SmallGroupsBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gsl::span< int64_t const > const &selection, uint64_t offset=0)
SmallGroupsBase(std::vector< std::shared_ptr< arrow::Table > > &&tables, gandiva::Selection const &selection, uint64_t offset=0)
framework::selected_pack< soa::is_persistent_column_t, C... > persistent_columns_t
void doSetCurrentIndexRaw(framework::pack< Cs... > p, std::vector< o2::soa::Binding > &&ptrs)
void bindInternalIndices(I const *table)
TableIterator(TableIterator< D, O, FilteredIndexPolicy, C... > const &other)
TableIterator(self_t const &other)
TableIterator operator-(int64_t dec) const
TableIterator(arrow::ChunkedArray *columnData[sizeof...(C)], IP &&policy)
TableIterator & operator=(TableIterator other)
TableIterator & operator++()
void doSetCurrentInternal(framework::pack< Cs... >, I const *ptr)
auto getIndexBindingsImpl(framework::pack< Cs... >) const
TableIterator operator--(int)
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
TableIterator(arrow::ChunkedArray *columnData[sizeof...(C)], IP &&policy)
decltype([]< typename... Cs >(framework::pack< Cs... >) -> framework::pack< typename Cs::binding_t... > {}(external_index_columns_t{})) bindings_pack_t
void bindExternalIndices(TA *... current)
TableIterator & operator--()
framework::selected_pack< soa::is_external_index_t, C... > external_index_columns_t
TableIterator const & operator*() const
TableIterator operator++(int)
framework::selected_pack< soa::is_self_index_t, C... > internal_index_columns_t
auto getIndexBindings() const
void doSetCurrentIndex(framework::pack< CL... >, TA *current)
TableIterator operator+(int64_t inc) const
Allow incrementing by more than one the iterator.
Generic identifier for a table type.
constexpr TableRef & operator=(TableRef const &)=default
constexpr bool descriptionCompatible(uint32_t _desc_hash) const noexcept
constexpr bool operator==(TableRef const &other) const noexcept
constexpr TableRef(TableRef &&)=default
constexpr TableRef(TableRef const &)=default
consteval TableRef(uint32_t _label, uint32_t _desc, uint32_t _origin, uint32_t _version)
constexpr bool descriptionCompatible(TableRef const &other) const noexcept
constexpr TableRef & operator=(TableRef &&)=default
TableIteratorBase const & operator*() const
TableIteratorBase(TableIteratorBase< IP, P, T... > const &other)
typename Parent::columns_t columns_t
TableIteratorBase(TableIteratorBase< IP, P, O1, Os... > const &other)
typename Parent::external_index_columns_t external_index_columns_t
TableIteratorBase operator-(int64_t dec) const
void matchTo(TableIteratorBase< IP, P, T... > const &other)
auto getDynamicColumn() const
TableIteratorBase()=default
void matchTo(TableIteratorBase< IP, P, Os... > const &other)
TableIteratorBase(TableIteratorBase< FilteredIndexPolicy, P, T... > other)
std::array< B, sizeof...(CCs)> getValues() const
static constexpr auto originals
TableIteratorBase(TableIteratorBase< IP, P, T... > &&other) noexcept
decltype([]< typename... C >(framework::pack< C... >) -> framework::pack< typename C::binding_t... > {}(external_index_columns_t{})) bindings_pack_t
TableIteratorBase & operator=(TableIteratorBase< IP, P, Os... > other)
TableIteratorBase(TableIteratorBase< IP, P, O1, Os... > &&other) noexcept
TableIteratorBase & operator=(RowViewSentinel const &other)
TableIteratorBase(arrow::ChunkedArray *columnData[framework::pack_size(columns_t{})], IP &&policy)
TableIteratorBase & operator=(TableIteratorBase< IP, P, T... > other)
TableIteratorBase operator+(int64_t inc) const
Allow incrementing by more than one the iterator.
TableIteratorBase & operator=(TableIteratorBase< FilteredIndexPolicy, P, T... > other)
VectorOfTObjectPtrs other
std::vector< ReadoutWindowData > rows