12#ifndef O2_FRAMEWORK_ASOA_H_
13#define O2_FRAMEWORK_ASOA_H_
16#error "Please do not include this file in ROOT dictionary generation"
31#include <fairmq/Version.h>
32#include <arrow/array/array_binary.h>
33#include <arrow/table.h>
34#include <arrow/array.h>
35#include <arrow/util/config.h>
36#include <gandiva/selection_vector.h>
39#include <fmt/format.h>
51using ListVector = std::vector<std::vector<int64_t>>;
73 return (
c >=
'A' &&
c <=
'Z') ?
static_cast<char>(
c + 32) :
c;
76template <
typename... C>
79 return std::vector<std::shared_ptr<arrow::Field>>{C::asArrowField()...};
94 consteval TableRef(uint32_t _label, uint32_t _desc, uint32_t _origin, uint32_t _version)
108 return (this->label_hash ==
other.label_hash) &&
109 (this->desc_hash ==
other.desc_hash) &&
110 (this->origin_hash ==
other.origin_hash) &&
111 (this->version ==
other.version);
116 return this->desc_hash ==
other.desc_hash;
121 return this->desc_hash == _desc_hash;
131template <
size_t N1,
size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2>
134 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](
TableRef const&
a)
consteval { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
135 std::array<TableRef, N1 + N2 - duplicates> out;
137 auto pos = std::copy(ar1.begin(), ar1.end(), out.begin());
138 std::copy_if(ar2.begin(), ar2.end(),
pos, [&](TableRef
const&
a)
consteval { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
142template <
size_t N1,
size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2,
typename L>
145 constexpr const int to_remove = std::ranges::count_if(ar1.begin(), ar1.end(), [&](
TableRef const&
a)
consteval { return !l(a); });
146 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](
TableRef const&
a)
consteval { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) || !l(
a); });
147 std::array<TableRef, N1 + N2 - duplicates - to_remove> out;
149 auto pos = std::copy_if(ar1.begin(), ar1.end(), out.begin(), [&](TableRef
const&
a)
consteval { return l(a); });
150 std::copy_if(ar2.begin(), ar2.end(),
pos, [&](TableRef
const&
a)
consteval { return std::none_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }) && l(
a); });
154template <
size_t N, std::array<TableRef, N> ar,
typename L>
157 constexpr const int to_remove = std::ranges::count_if(ar.begin(), ar.end(), [&l](
TableRef const& e)
consteval { return l(e); });
158 std::array<
TableRef, N - to_remove> out;
159 std::copy_if(ar.begin(), ar.end(), out.begin(), [&l](
TableRef const& e)
consteval { return !l(e); });
163template <
size_t N1,
size_t N2, std::array<TableRef, N1> ar1, std::array<TableRef, N2> ar2>
164consteval auto intersect()
166 constexpr const int duplicates = std::ranges::count_if(ar2.begin(), ar2.end(), [&](
TableRef const&
a)
consteval { return std::any_of(ar1.begin(), ar1.end(), [&](TableRef const& e) { return e == a; }); });
167 std::array<TableRef, duplicates> out;
168 std::copy_if(ar1.begin(), ar1.end(), out.begin(), [](TableRef
const&
a)
consteval { return std::find(ar2.begin(), ar2.end(), a) != ar2.end(); });
172template <
typename T,
typename... Ts>
174 requires(
sizeof...(Ts) == 1)
177 return merge<T::originals.size(), T1::originals.size(), T::originals, T1::originals>();
180template <
typename T,
typename...
Ts>
182 requires(
sizeof...(Ts) > 1)
185 return merge<T::originals.size(), tail.size(), T::originals, tail>();
188template <
typename T,
typename...
Ts>
189 requires(
sizeof...(Ts) == 1)
190consteval auto intersectOriginals()
193 return intersect<T::originals.size(), T1::originals.size(), T::originals, T1::originals>();
196template <
typename T,
typename...
Ts>
197 requires(
sizeof...(Ts) > 1)
198consteval auto intersectOriginals()
201 return intersect<T::originals.size(), tail.size(), T::originals, tail>();
215using is_external_index_t =
typename std::conditional_t<is_index_column<C>, std::true_type, std::false_type>;
218using is_self_index_t =
typename std::conditional_t<is_self_index_column<C>, std::true_type, std::false_type>;
225template <
typename Key,
size_t N, std::array<
bool, N> map>
226static consteval int getIndexPosToKey_impl()
228 constexpr const auto pos = std::find(map.begin(), map.end(),
true);
229 if constexpr (
pos != map.end()) {
230 return std::distance(map.begin(),
pos);
238template <
typename D,
typename... Cs>
246 template <
typename Key,
typename... PCs>
249 return std::array<bool,
sizeof...(PCs)>{[]()
consteval {
250 if constexpr (
requires { PCs::index_targets.size(); }) {
251 return Key::template isIndexTargetOf<PCs::index_targets.size(), PCs::index_targets>();
258 template <
typename Key>
281 static constexpr uint32_t
hash = H;
282 static constexpr char const*
const str{
""};
286template <
size_t N, std::array<soa::TableRef, N> ar,
typename Key>
289 constexpr std::array<bool, N>
test = []<
size_t... Is>(std::index_sequence<Is...>)
consteval {
290 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))...};
291 }(std::make_index_sequence<N>());
292 constexpr int correct = std::ranges::count(
test.begin(),
test.end(),
true);
293 std::array<soa::TableRef, correct> out;
294 std::ranges::copy_if(ar.begin(), ar.end(), out.begin(), [&
test](
soa::TableRef const&
r)
consteval { return test[std::distance(ar.begin(), std::find(ar.begin(), ar.end(), r))]; });
299#define O2HASH(_Str_) \
301 struct Hash<_Str_ ""_h> { \
302 static constexpr void isHash() {}; \
303 static constexpr uint32_t hash = _Str_ ""_h; \
304 static constexpr char const* const str{_Str_}; \
308#define O2ORIGIN(_Str_) \
310 struct Hash<_Str_ ""_h> { \
311 static constexpr void isHash() {}; \
312 static constexpr void isOriginHash() {}; \
313 static constexpr header::DataOrigin origin{_Str_}; \
314 static constexpr uint32_t hash = _Str_ ""_h; \
315 static constexpr char const* const str{_Str_}; \
319static inline constexpr uint32_t
version(
const char*
const str)
321 if (
str[0] ==
'\0') {
329 if (
str[
len - 1] ==
'\0') {
332 for (
auto i =
len + 1;
str[
i] !=
'\0'; ++
i) {
339static inline constexpr std::string_view description_str(
const char*
const str)
345 return std::string_view{
str,
len};
355 for (
auto i = 0;
i < 16; ++
i) {
358 std::memcpy(out,
str,
len);
363template <soa::TableRef R>
369template <soa::TableRef R>
375template <soa::TableRef R>
381template <soa::TableRef R>
387template <soa::TableRef R>
390 return {origin<R>(),
description(signature<R>()),
R.version};
394template <soa::TableRef R>
395static constexpr auto sourceSpec()
397 return fmt::format(
"{}/{}/{}/{}",
label<R>(), origin_str<R>(), description_str(signature<R>()),
R.version);
401template <
size_t N, std::array<soa::TableRef, N> ar, o2::aod::is_origin_hash O>
404 std::array<soa::TableRef, N>
res;
405 for (
auto i = 0U;
i < N; ++
i) {
406 res[
i].label_hash = ar[
i].label_hash;
407 res[
i].desc_hash = ar[
i].desc_hash;
408 res[
i].origin_hash = O::hash;
409 res[
i].version = ar[
i].version;
417template <aod::is_aod_hash L, aod::is_aod_hash D, aod::is_origin_hash O,
typename... Ts>
422 void const*
ptr =
nullptr;
426 template <
typename T>
430 hash = o2::framework::TypeIdHelpers::uniqueId<T>();
434 template <
typename T>
437 if (
hash == o2::framework::TypeIdHelpers::uniqueId<T>()) {
438 return static_cast<T const*
>(
ptr);
446template <
typename B,
typename E>
448 constexpr static bool value =
false;
451template <aod::is_aod_hash A, aod::is_aod_hash B>
453 constexpr static bool value =
false;
456template <
typename B,
typename E>
459template <aod::is_aod_hash A, aod::is_aod_hash B>
498template <
typename T,
typename ChunkingPolicy = Chunked>
501 static constexpr char SCALE_FACTOR = std::same_as<std::decay_t<T>,
bool> ? 3 : 0;
517 auto array = getCurrentArray();
532 auto previousArray = getCurrentArray();
535 auto array = getCurrentArray();
542 auto previousArray = getCurrentArray();
545 auto array = getCurrentArray();
567 auto array = getCurrentArray();
574 requires
std::same_as<
bool,
std::decay_t<T>>
590 decltype(
auto)
operator*()
const
591 requires((!std::same_as<bool, std::decay_t<T>>) && std::same_as<
arrow_array_for_t<T>, arrow::BinaryViewArray>)
598 decltype(
auto)
operator*()
const
621 void checkSkipChunk() const
630 void checkSkipChunk() const
638 void checkSkipChunk() const
639 requires(ChunkingPolicy::
chunked == false)
643 auto getCurrentArray() const
647 chunkToUse = std::dynamic_pointer_cast<arrow::FixedSizeListArray>(chunkToUse)->values();
648 return std::static_pointer_cast<arrow_array_for_t<value_for_t<T>>>(chunkToUse);
651 auto getCurrentArray() const
655 chunkToUse = std::dynamic_pointer_cast<arrow::ListArray>(chunkToUse)->values();
656 return std::static_pointer_cast<arrow_array_for_t<value_for_t<T>>>(chunkToUse);
659 auto getCurrentArray() const
663 return std::static_pointer_cast<arrow_array_for_t<T>>(chunkToUse);
667template <
typename T,
typename INHERIT>
685 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
693 return std::make_shared<arrow::Field>(inherited_t::mLabel, soa::asArrowDataType<type>());
703template <
typename F,
typename INHERIT>
708 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
711template <
typename INHERIT>
715 static constexpr const uint32_t
hash = 0;
717 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
720template <
typename INHERIT>
724 static constexpr const uint32_t
hash = 0;
726 static constexpr const char*
const&
columnLabel() {
return INHERIT::mLabel; }
729template <
size_t M = 0>
733 constexpr inline static auto value = M;
748 static constexpr const char*
mLabel =
"Marker";
815 static constexpr const char*
mLabel =
"Index";
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 std::span<int64_t const> mSelectedRows;
974 [[nodiscard]] std::tuple<int64_t const*, int64_t const*>
980 [[nodiscard]] std::tuple<uint64_t const*>
983 return std::make_tuple(&
mOffset);
1020template <
typename C>
1026template <
typename C>
1029template <
typename D,
typename O,
typename IP,
typename... C>
1045 if (this->
size() != 0) {
1055 if (this->
size() != 0) {
1062 this->limitRange(this->rangeStart(), this->rangeEnd());
1068 C(static_cast<
C const&>(
other))...
1070 if (this->
size() != 0) {
1077 IP::operator=(
static_cast<IP const&
>(
other));
1078 (
void(
static_cast<C&
>(*
this) =
static_cast<C>(
other)), ...);
1079 if (this->
size() != 0) {
1086 requires std::same_as<IP, DefaultIndexPolicy>
1088 C(
static_cast<C const&
>(
other))...
1090 if (this->
size() != 0) {
1097 this->moveByIndex(1);
1110 this->moveByIndex(-1);
1125 copy.moveByIndex(inc);
1139 template <
typename CL>
1142 return CL::getCurrentRaw();
1145 template <
typename... Cs>
1148 return std::vector<o2::soa::Binding>{
static_cast<Cs const&
>(*this).getCurrentRaw()...};
1156 template <
typename... TA>
1160 (CCs::setCurrent(cur), ...);
1165 template <
typename TA>
1169 (CCs::setCurrent(cur), ...);
1173 template <
typename... Cs>
1176 (Cs::setCurrentRaw(ptrs[framework::has_type_at_v<Cs>(p)]), ...);
1179 template <
typename... Cs,
typename I>
1184 (Cs::setCurrentRaw(
b), ...);
1192 template <
typename I>
1200 [&pointerReconstructor,
this]<
typename... Cs>(
framework::pack<Cs...>) {
1201 ([&pointerReconstructor,
this]<
typename CC>() {
1203 if (pointerReconstructor) {
1204 CC::ptrRec = &pointerReconstructor;
1207 }.template operator()<Cs>(),
1214 template <
typename... PC>
1217 (PC::mColumnIterator.moveToEnd(), ...);
1226 [
this]<
soa::is_persistent_column T>(T*) ->
void { T::mColumnIterator.mCurrentPos = &this->mRowIndex; T::mColumnIterator.mGlobalOffset = &this->mOffset; },
1227 [
this]<soa::is_dynamic_column T>(T*) ->
void { bindDynamicColumn<T>(
typename T::bindings_t{}); },
1228 [
this]<
typename T>(
T*) ->
void {},
1230 (
f(
static_cast<C*
>(
nullptr)), ...);
1231 if constexpr (has_index<
C...>) {
1232 this->setIndices(this->getIndices());
1233 this->setOffsets(this->getOffsets());
1237 template <
typename DC,
typename...
B>
1240 DC::boundIterators = std::make_tuple(getDynamicBinding<B>()...);
1248 template <
typename B>
1249 requires(can_bind<self_t, B>)
1250 decltype(
auto) getDynamicBinding()
1252 static_assert(std::same_as<decltype(&(static_cast<B*>(
this)->mColumnIterator)), std::decay_t<
decltype(B::mColumnIterator)>*>,
"foo");
1253 return &(
static_cast<B*
>(
this)->mColumnIterator);
1256 template <
typename B>
1257 decltype(
auto) getDynamicBinding()
1259 return static_cast<std::decay_t<decltype(B::mColumnIterator)
>*>(
nullptr);
1274template <
size_t N1, std::array<TableRef, N1> os1,
size_t N2, std::array<TableRef, N2> os2>
1277 return []<
size_t NN2,
size_t... Is>(std::index_sequence<Is...>)
consteval {
1278 return ([]<
size_t... Ks>(std::index_sequence<Ks...>)
consteval {
1279 constexpr auto h = os1[Is].desc_hash;
1282 }(std::make_index_sequence<NN2>()) ||
1284 }.template operator()<N2>(std::make_index_sequence<N1>());
1287template <with_originals T, with_originals B>
1290 return is_compatible<T::originals.size(), T::originals, B::originals.size(), B::originals>();
1293template <
typename T,
typename B>
1294using is_binding_compatible = std::conditional_t<is_binding_compatible_v<T, typename B::binding_t>(), std::true_type, std::false_type>;
1296template <soa::is_table T>
1297static constexpr std::string getLabelForTable()
1299 return std::string{aod::label<std::decay_t<T>::originals[0]>()};
1302template <soa::is_table T>
1304static constexpr std::string getLabelFromType()
1306 return getLabelForTable<T>();
1309template <soa::is_iterator T>
1310static constexpr std::string getLabelFromType()
1312 return getLabelForTable<typename std::decay_t<T>::parent_t>();
1315template <soa::is_index_table T>
1316static constexpr std::string getLabelFromType()
1318 return getLabelForTable<typename std::decay_t<T>::first_t>();
1320template <soa::with_base_table T>
1321 requires(!soa::is_iterator<T>)
1322static constexpr std::string getLabelFromType()
1327template <
typename...
C>
1330 auto caseInsensitiveCompare = [](
const std::string_view& str1,
const std::string_view& str2) {
1331 return std::ranges::equal(
1333 [](
char c1,
char c2) {
1338 return (caseInsensitiveCompare(C::inherited_t::mLabel,
key) || ...);
1341template <TableRef ref>
1342static constexpr std::pair<bool, std::string> hasKey(std::string_view
key)
1347template <TableRef ref>
1348static constexpr std::pair<bool, framework::ConcreteDataMatcher> hasKeyM(std::string_view
key)
1356template <with_originals T,
bool OPT = false>
1357static constexpr std::string getLabelFromTypeForKey(std::string_view
key)
1359 auto locate = []<
size_t... Is>(std::index_sequence<Is...>, std::string_view
key) {
1360 return std::array{hasKey<T::originals[Is]>(
key)...} |
1361 std::views::filter([](
auto const&
x) {
return x.first; });
1362 }(std::make_index_sequence<T::originals.size()>{},
key);
1363 if (!locate.empty()) {
1364 return locate.front().second;
1367 if constexpr (!OPT) {
1375template <with_originals T,
bool OPT = false>
1378 auto locate = []<
size_t... Is>(std::index_sequence<Is...>, std::string_view
key) {
1379 return std::array{hasKeyM<T::originals[Is]>(
key)...} |
1380 std::views::filter([](
auto const&
x) {
return x.first; });
1381 }(std::make_index_sequence<T::originals.size()>{},
key);
1382 if (!locate.empty()) {
1383 return locate.front().second;
1386 if constexpr (!OPT) {
1394template <
typename B,
typename...
C>
1397 return (o2::soa::is_binding_compatible_v<B, typename C::binding_t>() || ...);
1400template <
typename B,
typename...
C>
1403 return ((C::sorted && o2::soa::is_binding_compatible_v<B, typename C::binding_t>()) || ...);
1406template <
typename B,
typename Z>
1407consteval static bool relatedByIndex()
1409 return hasIndexTo<B>(
typename Z::table_t::external_index_columns_t{});
1412template <
typename B,
typename Z>
1413consteval static bool relatedBySortedIndex()
1415 return hasSortedIndexTo<B>(
typename Z::table_t::external_index_columns_t{});
1445template <soa::is_table T, is_preslice_policy Policy,
bool OPT = false>
1454 : Policy{
PreslicePolicyBase{{o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.
name})},
Entry(o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name}), o2::soa::getMatcherFromTypeForKey<T, OPT>(std::string{index_.name}), std::string{index_.name})}, {}}
1460 if constexpr (OPT) {
1461 if (Policy::isMissing()) {
1462 return {
nullptr, {0, 0}};
1465 return Policy::getSliceFor(
value, input);
1470 if constexpr (OPT) {
1471 if (Policy::isMissing()) {
1475 return Policy::getSliceFor(
value);
1479template <soa::is_table T>
1481template <soa::is_table T>
1483template <soa::is_table T>
1485template <soa::is_table T>
1507template <soa::is_table T>
1509template <
typename T>
1513template <
typename T>
1517template <
typename... Is>
1525template <
typename T,
typename C,
typename Policy,
bool OPT>
1526 requires std::same_as<Policy, framework::PreslicePolicySorted> && (o2::soa::is_binding_compatible_v<C, T>())
1529 if constexpr (OPT) {
1530 if (container.isMissing()) {
1535 auto t =
typename T::self_t({out});
1536 if (t.tableSize() != 0) {
1537 table->copyIndexBindings(t);
1538 t.bindInternalIndicesTo(table);
1543template <soa::is_filtered_table T>
1547 if (t.tableSize() != 0) {
1549 t.bindInternalIndicesTo(table);
1550 t.intersectWithSelection(table->getSelectedRows());
1555template <soa::is_table T>
1560 if (t.tableSize() != 0) {
1562 t.bindInternalIndicesTo(table);
1567template <
typename T,
typename C,
typename Policy,
bool OPT>
1568 requires std::same_as<Policy, framework::PreslicePolicyGeneral> && (o2::soa::is_binding_compatible_v<C, T>())
1571 if constexpr (OPT) {
1572 if (container.isMissing()) {
1582template <soa::is_filtered_table T>
1585 if (slice.
range.
offset >=
static_cast<uint64_t
>(table->tableSize())) {
1587 if (fresult.tableSize() != 0) {
1588 table->copyIndexBindings(fresult);
1594 if (fresult.tableSize() != 0) {
1595 table->copyIndexBindings(fresult);
1600template <soa::is_filtered_table T,
typename C,
bool OPT>
1601 requires(o2::soa::is_binding_compatible_v<C, T>())
1604 if constexpr (OPT) {
1605 if (container.isMissing()) {
1615template <soa::is_table T>
1621 auto t =
typename T::self_t({table->asArrowTableRef().slice({
static_cast<uint64_t
>(
offset),
count})});
1622 if (t.tableSize() != 0) {
1623 table->copyIndexBindings(t);
1628template <soa::is_filtered_table T>
1634 return prepareFilteredSlice(table, table->asArrowTableRef().slice({static_cast<uint64_t>(offset), count}));
1637template <soa::is_table T>
1643 auto t =
typename T::self_t({table->asArrowTableRef()}, localCache.getSliceFor(
value));
1644 if (t.tableSize() != 0) {
1645 t.intersectWithSelection(table->getSelectedRows());
1646 table->copyIndexBindings(t);
1650 auto t =
Filtered<T>({table->asArrowTableRef()}, localCache.getSliceFor(
value));
1651 if (t.tableSize() != 0) {
1652 table->copyIndexBindings(t);
1658template <with_originals T>
1666template <
typename D,
typename O,
typename IP,
typename...
C>
1702 return std::array<TableRef, 1>{
ref};
1719 static constexpr const auto ref =
TableRef{L::hash, D::hash, O::hash, o2::aod::version(D::str)};
1724 static constexpr const auto originalLabels = []<
size_t N, std::array<TableRef, N> refs,
size_t... Is>(std::index_sequence<Is...>)
consteval {
1725 return std::array<const char*, N>{o2::aod::label<refs[Is]>()...};
1730 template <
size_t N, std::array<TableRef, N> bindings>
1731 requires(
ref.origin_hash ==
"CONC"_h)
1737 template <
size_t N, std::array<TableRef, N> bindings>
1738 requires(
ref.origin_hash ==
"JOIN"_h)
1743 return std::ranges::any_of(bindings, [&
r](
TableRef const&
b) {
return b ==
r; });
1747 template <
size_t N, std::array<TableRef, N> bindings>
1748 requires(!(
ref.origin_hash ==
"CONC"_h ||
ref.origin_hash ==
"JOIN"_h))
1751 return std::find(bindings.begin(), bindings.end(),
self_t::ref) != bindings.end();
1754 template <TableRef r>
1763 auto hashes = std::array{C::hash...};
1764 std::ranges::sort(hashes);
1773 template <
typename IP>
1776 template <
typename IP,
typename Parent,
typename... T>
1792 template <
typename P,
typename... Os>
1794 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1800 template <
typename P>
1807 template <
typename P>
1809 requires std::same_as<IP, DefaultIndexPolicy>
1815 template <
typename P,
typename O1,
typename... Os>
1817 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1822 template <
typename P,
typename O1,
typename... Os>
1824 requires(P::ref.desc_hash == Parent::ref.desc_hash)
1829 template <
typename P>
1835 template <
typename P>
1841 template <
typename P>
1843 requires std::same_as<IP, DefaultIndexPolicy>
1850 this->mRowIndex =
other.index;
1853 template <
typename P>
1856 this->mRowIndex =
other.mRowIndex;
1859 template <
typename P,
typename... Os>
1861 requires std::same_as<typename P::table_t, typename Parent::table_t>
1863 this->mRowIndex =
other.mRowIndex;
1866 template <
typename TI>
1869 using decayed = std::decay_t<TI>;
1871 constexpr auto idx = framework::has_type_at_v<decayed>(
bindings_pack_t{});
1873 }
else if constexpr (std::same_as<decayed, Parent>) {
1874 return this->globalIndex();
1876 return this->globalIndex();
1878 return static_cast<int32_t
>(-1);
1882 template <
typename CD,
typename... CDArgs>
1885 using decayed = std::decay_t<CD>;
1887 return static_cast<decayed
>(*this).template getDynamicValue<CDArgs...>();
1890 template <
typename B,
typename CC>
1893 using COL = std::decay_t<CC>;
1895 return static_cast<B>(
static_cast<COL
>(*this).get());
1898 template <
typename B,
typename... CCs>
1901 static_assert(std::same_as<B, float> || std::same_as<B, double>,
"The common return type should be float or double");
1902 return {getValue<B, CCs>()...};
1913 copy.moveByIndex(inc);
1928 template <
typename IP,
typename Parent,
typename... T>
1931 template <
typename IP,
typename Parent>
1933 if constexpr (
sizeof...(Ts) == 0) {
1937 return iterator_template<IP, Parent>{};
1952 : mArrowTableRef(tableRef),
1955 if (mArrowTableRef.
tablePtr->num_rows() == 0) {
1957 mColumnChunks[ci] =
nullptr;
1963 mColumnChunks[ci] = lookups[ci];
1966 mBegin.bindInternalIndices(
this);
1970 Table(std::shared_ptr<arrow::Table> table)
1975 Table(std::vector<o2::soa::ArrowTableRef>&& tables)
1976 requires(
ref.origin_hash !=
"CONC"_h)
1981 Table(std::vector<o2::soa::ArrowTableRef>&& tables)
1982 requires(
ref.origin_hash ==
"CONC"_h)
1987 Table(std::vector<std::shared_ptr<arrow::Table>>&& tables)
1988 requires(
ref.origin_hash !=
"CONC"_h)
1993 Table(std::vector<std::shared_ptr<arrow::Table>>&& tables)
1994 requires(
ref.origin_hash ==
"CONC"_h)
1999 template <
typename Key>
2002 constexpr auto map = []<
typename... Cs>(
framework::pack<Cs...>)
consteval {
2003 return std::array<bool,
sizeof...(Cs)>{[]() {
2004 if constexpr (
requires { Cs::index_targets.size(); }) {
2005 return Key::template
isIndexTargetOf<Cs::index_targets.size(), Cs::index_targets>();
2011 constexpr auto pos = std::find(map.begin(), map.end(),
true);
2012 if constexpr (
pos != map.end()) {
2013 return mColumnChunks[std::distance(map.begin(),
pos)];
2015 static_assert(framework::always_static_assert_v<Key>,
"This table does not have an index to given Key");
2083 return mArrowTableRef;
2103 template <
typename... TA>
2108 mBegin.bindExternalIndex(cur);
2114 template <
typename TA>
2117 mBegin.bindExternalIndex(current);
2120 template <
typename I>
2123 mBegin.bindInternalIndices(
ptr);
2131 template <
typename... Cs>
2134 (
static_cast<Cs
>(mBegin).setCurrentRaw(
binding), ...);
2139 mBegin.bindExternalIndicesRaw(std::forward<std::vector<o2::soa::Binding>>(ptrs));
2142 template <
typename T,
typename... Cs>
2145 dest.bindExternalIndicesRaw(mBegin.getIndexBindings());
2148 template <
typename T>
2171 template <
typename T1,
typename Policy,
bool OPT>
2189 mBegin.setPointerReconstructor(pointerReconstructor);
2193 template <
typename T>
2194 arrow::ChunkedArray* lookupColumn()
2199 template <soa::is_persistent_column T>
2200 arrow::ChunkedArray* lookupColumn()
2214template <uint32_t
D, soa::is_column...
C>
2220namespace row_helpers
2222template <
typename R,
typename T,
typename C>
2225 return static_cast<R>(
static_cast<C>(rowIterator).get());
2230template <
typename R,
typename T>
2231using ColumnGetterFunction =
R (*)(
const T&);
2233template <
typename T,
typename R>
2238 { t.get() } -> std::convertible_to<R>;
2241template <
typename T,
typename R>
2243 { t.get() } -> std::convertible_to<R>;
2246template <
typename R,
typename T, persistent_with_common_getter<R> C>
2247ColumnGetterFunction<R, T> createGetterPtr(
const std::string_view& targetColumnLabel)
2249 return targetColumnLabel == C::columnLabel() ? &getColumnValue<R, T, C> :
nullptr;
2252template <
typename R,
typename T, dynamic_with_common_getter<R> C>
2253ColumnGetterFunction<R, T> createGetterPtr(
const std::string_view& targetColumnLabel)
2259 if (targetColumnLabel.starts_with(
"f") && targetColumnLabel.substr(1) ==
columnLabel) {
2260 return &getColumnValue<R, T, C>;
2265 return &getColumnValue<R, T, C>;
2271template <
typename R,
typename T,
typename... Cs>
2274 ColumnGetterFunction<R, T>
func;
2276 (
void)((
func = createGetterPtr<R, T, Cs>(targetColumnLabel),
func) || ...);
2285template <
typename T,
typename R>
2286using 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;
2289template <
typename R,
typename T>
2294 if (targetColumnLabel.size() == 0) {
2298 return getColumnGetterByLabel<R, typename T::iterator>(TypesWithCommonGetter{}, targetColumnLabel);
2324template <
typename T>
2325consteval static std::string_view namespace_prefix()
2327 constexpr auto name = o2::framework::type_name<T>();
2328 const auto pos =
name.rfind(std::string_view{
":"});
2329 return name.substr(0,
pos + 1);
2333#define DECLARE_EQUIVALENT_FOR_INDEX(_Base_, _Equiv_) \
2335 struct EquivalentIndexNG<o2::aod::Hash<_Base_::ref.desc_hash>, o2::aod::Hash<_Equiv_::ref.desc_hash>> { \
2336 constexpr static bool value = true; \
2339#define DECLARE_EQUIVALENT_FOR_INDEX_NG(_Base_, _Equiv_) \
2341 struct EquivalentIndexNG<o2::aod::Hash<_Base_ ""_h>, o2::aod::Hash<_Equiv_ ""_h>> { \
2342 constexpr static bool value = true; \
2345#define DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) \
2346 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2347 static constexpr const char* mLabel = _Label_; \
2348 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2349 static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \
2350 using base = o2::soa::Column<_Type_, _Name_>; \
2351 using type = _Type_; \
2352 using column_t = _Name_; \
2353 _Name_(arrow::ChunkedArray const* column) \
2354 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2358 _Name_() = default; \
2359 _Name_(_Name_ const& other) = default; \
2360 _Name_& operator=(_Name_ const& other) = default; \
2362 decltype(auto) _Getter_() const \
2364 return *mColumnIterator; \
2367 decltype(auto) get() const \
2369 return _Getter_(); \
2372 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2374#define DECLARE_SOA_CCDB_COLUMN_FULL(_Name_, _Label_, _Getter_, _ConcreteType_, _CCDBQuery_, _RunDependent_, ...) \
2375 struct _Name_ : o2::soa::Column<int64_t[3], _Name_> { \
2376 static constexpr const char* mLabel = _Label_; \
2377 static constexpr const char* query = _CCDBQuery_; \
2382 static constexpr int run_dependent = _RunDependent_; \
2383 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2384 static constexpr bool needs_ptr_rec = true; \
2390 using finaliser_t = _ConcreteType_* (*)(_ConcreteType_*); \
2391 static constexpr finaliser_t finalise = __VA_ARGS__; \
2392 std::function<std::byte*(fair::mq::shmem::MetaHeader&&)> const* ptrRec = nullptr; \
2393 using base = o2::soa::Column<int64_t[3], _Name_>; \
2394 using type = int64_t[3]; \
2395 using column_t = _Name_; \
2396 _Name_(arrow::ChunkedArray const* column) \
2397 : o2::soa::Column<int64_t[3], _Name_>(o2::soa::ColumnIterator<int64_t[3]>(column)) \
2401 _Name_() = default; \
2402 _Name_(_Name_ const& other) = default; \
2403 _Name_& operator=(_Name_ const& other) = default; \
2405 decltype(auto) _Getter_() const \
2407 auto& [handle, segment, size] = *mColumnIterator; \
2408 auto span = std::span<std::byte>{(*ptrRec)(fair::mq::shmem::MetaHeader{ \
2409 static_cast<size_t>(size), \
2411 static_cast<uint16_t>(segment), true}), \
2412 static_cast<size_t>(size)}; \
2413 if constexpr (std::same_as<_ConcreteType_, std::span<std::byte>>) { \
2416 static std::byte* payload = nullptr; \
2417 static _ConcreteType_* deserialised = nullptr; \
2418 static TClass* c = TClass::GetClass(#_ConcreteType_); \
2419 if (payload != (std::byte*)span.data()) { \
2420 payload = (std::byte*)span.data(); \
2421 delete deserialised; \
2422 TBufferFile f(TBufferFile::EMode::kRead, span.size(), (char*)span.data(), kFALSE); \
2423 auto* streamed = (_ConcreteType_*)soa::extractCCDBPayload((char*)payload, span.size(), c, "ccdb_object"); \
2426 "Could not deserialise a {} from the CCDB payload for {} ({} bytes). Check the configured " \
2427 "path (option \"ccdb:{}\") and that the object exists for this timestamp.", \
2428 #_ConcreteType_, _CCDBQuery_, span.size(), _Label_); \
2430 deserialised = finalise(streamed); \
2432 return *deserialised; \
2439 return _Getter_(); \
2447#define DECLARE_SOA_CCDB_COLUMN(_Name_, _Getter_, _ConcreteType_, _CCDBQuery_) \
2448 DECLARE_SOA_CCDB_COLUMN_FULL(_Name_, "f" #_Name_, _Getter_, _ConcreteType_, _CCDBQuery_, 0, \
2449 [](_ConcreteType_* ccdbObject) { return ccdbObject; })
2451#define DECLARE_SOA_COLUMN(_Name_, _Getter_, _Type_) \
2452 DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, "f" #_Name_)
2456#define MAKEINT(_Size_) uint##_Size_##_t
2458#define DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, _Label_) \
2459 struct _Name_ : o2::soa::Column<MAKEINT(_Size_), _Name_> { \
2460 static constexpr const char* mLabel = _Label_; \
2461 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2462 static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \
2463 using base = o2::soa::Column<MAKEINT(_Size_), _Name_>; \
2464 using type = MAKEINT(_Size_); \
2465 _Name_(arrow::ChunkedArray const* column) \
2466 : o2::soa::Column<type, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2470 _Name_() = default; \
2471 _Name_(_Name_ const& other) = default; \
2472 _Name_& operator=(_Name_ const& other) = default; \
2474 decltype(auto) _Getter_##_raw() const \
2476 return *mColumnIterator; \
2479 bool _Getter_##_bit(int bit) const \
2481 return (*mColumnIterator & (static_cast<type>(1) << bit)) >> bit; \
2484 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<MAKEINT(_Size_)>() }
2486#define DECLARE_SOA_BITMAP_COLUMN(_Name_, _Getter_, _Size_) \
2487 DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, "f" #_Name_)
2491#define DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_, _Expression_) \
2492 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2493 static constexpr const char* mLabel = _Label_; \
2494 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2495 using base = o2::soa::Column<_Type_, _Name_>; \
2496 using type = _Type_; \
2497 using column_t = _Name_; \
2498 using spawnable_t = std::true_type; \
2499 _Name_(arrow::ChunkedArray const* column) \
2500 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2504 _Name_() = default; \
2505 _Name_(_Name_ const& other) = default; \
2506 _Name_& operator=(_Name_ const& other) = default; \
2508 decltype(auto) _Getter_() const \
2510 return *mColumnIterator; \
2513 decltype(auto) get() const \
2515 return _Getter_(); \
2518 static o2::framework::expressions::Projector Projector() \
2520 return _Expression_; \
2523 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2525#define DECLARE_SOA_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Expression_) \
2526 DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, "f" #_Name_, _Expression_)
2530#define DECLARE_SOA_CONFIGURABLE_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Label_) \
2531 struct _Name_ : o2::soa::Column<_Type_, _Name_> { \
2532 static constexpr const char* mLabel = _Label_; \
2533 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_>(), std::string_view{#_Getter_}); \
2534 static constexpr const int32_t mHash = _Label_ ""_h; \
2535 using base = o2::soa::Column<_Type_, _Name_>; \
2536 using type = _Type_; \
2537 using column_t = _Name_; \
2538 using spawnable_t = std::true_type; \
2539 _Name_(arrow::ChunkedArray const* column) \
2540 : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator<type>(column)) \
2544 _Name_() = default; \
2545 _Name_(_Name_ const& other) = default; \
2546 _Name_& operator=(_Name_ const& other) = default; \
2548 decltype(auto) _Getter_() const \
2550 return *mColumnIterator; \
2553 decltype(auto) get() const \
2555 return _Getter_(); \
2558 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_ { _Label_, _Name_::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2581template <o2::soa::is_table T>
2584 return T::originals;
2587#define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2588 struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \
2589 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2590 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2591 static constexpr const char* mLabel = "fIndexSlice" _Label_ _Suffix_; \
2592 static constexpr const uint32_t hash = 0; \
2593 using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \
2594 using type = _Type_[2]; \
2595 using column_t = _Name_##IdSlice; \
2596 using binding_t = _Table_; \
2597 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2598 _Name_##IdSlice(arrow::ChunkedArray const* column) \
2599 : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator<type>(column)) \
2603 _Name_##IdSlice() = default; \
2604 _Name_##IdSlice(_Name_##IdSlice const& other) = default; \
2605 _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \
2606 std::array<_Type_, 2> inline getIds() const \
2608 return _Getter_##Ids(); \
2611 bool has_##_Getter_() const \
2613 auto a = *mColumnIterator; \
2614 return a[0] >= 0 && a[1] >= 0; \
2617 std::array<_Type_, 2> _Getter_##Ids() const \
2619 auto a = *mColumnIterator; \
2620 return std::array{a[0], a[1]}; \
2623 template <typename T> \
2624 auto _Getter_##_as() const \
2626 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2627 o2::soa::notBoundTable(#_Table_); \
2629 auto t = mBinding.get<T>(); \
2630 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2631 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2633 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2634 return t->emptySlice(); \
2636 auto a = *mColumnIterator; \
2637 auto r = t->rawSlice(a[0], a[1]); \
2638 t->copyIndexBindings(r); \
2639 r.bindInternalIndicesTo(t); \
2643 auto _Getter_() const \
2645 return _Getter_##_as<binding_t>(); \
2648 template <typename T> \
2649 bool setCurrent(T const* current) \
2651 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2652 assert(current != nullptr); \
2653 this->mBinding.bind(current); \
2659 bool setCurrentRaw(o2::soa::Binding current) \
2661 this->mBinding = current; \
2664 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2665 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2666 o2::soa::Binding mBinding; \
2669#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_)
2670#define DECLARE_SOA_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2671#define DECLARE_SOA_SLICE_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2674#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2675 struct _Name_##Ids : o2::soa::Column<std::vector<_Type_>, _Name_##Ids> { \
2676 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2677 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2678 static constexpr const char* mLabel = "fIndexArray" _Label_ _Suffix_; \
2679 static constexpr const uint32_t hash = 0; \
2680 using base = o2::soa::Column<std::vector<_Type_>, _Name_##Ids>; \
2681 using type = std::vector<_Type_>; \
2682 using column_t = _Name_##Ids; \
2683 using binding_t = _Table_; \
2684 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2685 _Name_##Ids(arrow::ChunkedArray const* column) \
2686 : o2::soa::Column<std::vector<_Type_>, _Name_##Ids>(o2::soa::ColumnIterator<type>(column)) \
2690 _Name_##Ids() = default; \
2691 _Name_##Ids(_Name_##Ids const& other) = default; \
2692 _Name_##Ids& operator=(_Name_##Ids const& other) = default; \
2694 gsl::span<const _Type_> inline getIds() const \
2696 return _Getter_##Ids(); \
2699 gsl::span<const _Type_> _Getter_##Ids() const \
2701 return *mColumnIterator; \
2704 bool has_##_Getter_() const \
2706 return !(*mColumnIterator).empty(); \
2709 template <soa::is_table T> \
2710 auto _Getter_##_as() const \
2712 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2713 o2::soa::notBoundTable(#_Table_); \
2715 auto t = mBinding.get<T>(); \
2716 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2717 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2719 auto result = std::vector<typename T::unfiltered_iterator>(); \
2720 result.reserve((*mColumnIterator).size()); \
2721 for (auto& i : *mColumnIterator) { \
2722 result.emplace_back(t->rawIteratorAt(i)); \
2727 template <soa::is_filtered_table T> \
2728 auto filtered_##_Getter_##_as() const \
2730 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2731 o2::soa::notBoundTable(#_Table_); \
2733 auto t = mBinding.get<T>(); \
2734 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2735 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2737 auto result = std::vector<typename T::iterator>(); \
2738 result.reserve((*mColumnIterator).size()); \
2739 for (auto const& i : *mColumnIterator) { \
2740 auto pos = t->isInSelectedRows(i); \
2742 result.emplace_back(t->iteratorAt(pos)); \
2748 auto _Getter_() const \
2750 return _Getter_##_as<binding_t>(); \
2753 template <typename T> \
2754 auto _Getter_##_first_as() const \
2756 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2757 o2::soa::notBoundTable(#_Table_); \
2759 auto t = mBinding.get<T>(); \
2760 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2761 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2763 return t->rawIteratorAt((*mColumnIterator)[0]); \
2766 template <typename T> \
2767 auto _Getter_##_last_as() const \
2769 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2770 o2::soa::notBoundTable(#_Table_); \
2772 auto t = mBinding.get<T>(); \
2773 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2774 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2776 return t->rawIteratorAt((*mColumnIterator).back()); \
2779 auto _Getter_first() const \
2781 return _Getter_##_first_as<binding_t>(); \
2784 auto _Getter_last() const \
2786 return _Getter_##_last_as<binding_t>(); \
2789 template <typename T> \
2790 bool setCurrent(T const* current) \
2792 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2793 assert(current != nullptr); \
2794 this->mBinding.bind(current); \
2800 bool setCurrentRaw(o2::soa::Binding current) \
2802 this->mBinding = current; \
2805 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2806 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2807 o2::soa::Binding mBinding; \
2810#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_)
2811#define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2812#define DECLARE_SOA_ARRAY_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2815#define DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \
2816 struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \
2817 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2818 static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \
2819 static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \
2820 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_##Id>(), std::string_view{#_Getter_ "Id"}); \
2821 using base = o2::soa::Column<_Type_, _Name_##Id>; \
2822 using type = _Type_; \
2823 using column_t = _Name_##Id; \
2824 using binding_t = _Table_; \
2825 static constexpr auto index_targets = getIndexTargets<_Table_>(); \
2826 _Name_##Id(arrow::ChunkedArray const* column) \
2827 : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator<type>(column)) \
2831 _Name_##Id() = default; \
2832 _Name_##Id(_Name_##Id const& other) = default; \
2833 _Name_##Id& operator=(_Name_##Id const& other) = default; \
2834 type inline getId() const \
2836 return _Getter_##Id(); \
2839 type _Getter_##Id() const \
2841 return *mColumnIterator; \
2844 bool has_##_Getter_() const \
2846 return *mColumnIterator >= 0; \
2849 template <typename T> \
2850 auto _Getter_##_as() const \
2852 if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \
2853 o2::soa::notBoundTable(#_Table_); \
2855 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2856 o2::soa::accessingInvalidIndexFor(#_Getter_); \
2858 auto t = mBinding.get<T>(); \
2859 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2860 o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \
2862 return t->rawIteratorAt(*mColumnIterator); \
2865 auto _Getter_() const \
2867 return _Getter_##_as<binding_t>(); \
2870 template <typename T> \
2871 bool setCurrent(T* current) \
2873 if constexpr (o2::soa::is_binding_compatible_v<T, binding_t>()) { \
2874 assert(current != nullptr); \
2875 this->mBinding.bind(current); \
2881 bool setCurrentRaw(o2::soa::Binding current) \
2883 this->mBinding = current; \
2886 binding_t const* getCurrent() const { return mBinding.get<binding_t>(); } \
2887 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2888 o2::soa::Binding mBinding; \
2890 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" _Label_ _Suffix_, _Name_##Id::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2892#define DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_)
2893#define DECLARE_SOA_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "")
2894#define DECLARE_SOA_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "")
2897#define DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2898 struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \
2899 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2900 static constexpr const char* mLabel = "fIndex" _Label_; \
2901 static constexpr const uint32_t hash = compile_time_hash(namespace_prefix<_Name_##Id>(), std::string_view{#_Getter_ "Id"}); \
2902 using base = o2::soa::Column<_Type_, _Name_##Id>; \
2903 using type = _Type_; \
2904 using column_t = _Name_##Id; \
2905 using self_index_t = std::true_type; \
2906 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2907 _Name_##Id(arrow::ChunkedArray const* column) \
2908 : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator<type>(column)) \
2912 _Name_##Id() = default; \
2913 _Name_##Id(_Name_##Id const& other) = default; \
2914 _Name_##Id& operator=(_Name_##Id const& other) = default; \
2915 type inline getId() const \
2917 return _Getter_##Id(); \
2920 type _Getter_##Id() const \
2922 return *mColumnIterator; \
2925 bool has_##_Getter_() const \
2927 return *mColumnIterator >= 0; \
2930 template <typename T> \
2931 auto _Getter_##_as() const \
2933 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2934 o2::soa::accessingInvalidIndexFor(#_Getter_); \
2936 auto t = mBinding.get<T>(); \
2937 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2938 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2940 return t->rawIteratorAt(*mColumnIterator); \
2943 bool setCurrentRaw(o2::soa::Binding current) \
2945 this->mBinding = current; \
2948 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
2949 o2::soa::Binding mBinding; \
2951 [[maybe_unused]] static constexpr o2::framework::expressions::BindingNode _Getter_##Id { "fIndex" _Label_, _Name_##Id::hash, o2::framework::expressions::selectArrowType<_Type_>() }
2953#define DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
2954#define DECLARE_SOA_SELF_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, #_Name_)
2956#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
2957 struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \
2958 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
2959 static constexpr const char* mLabel = "fIndexSlice" _Label_; \
2960 static constexpr const uint32_t hash = 0; \
2961 using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \
2962 using type = _Type_[2]; \
2963 using column_t = _Name_##IdSlice; \
2964 using self_index_t = std::true_type; \
2965 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
2966 _Name_##IdSlice(arrow::ChunkedArray const* column) \
2967 : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator<type>(column)) \
2971 _Name_##IdSlice() = default; \
2972 _Name_##IdSlice(_Name_##IdSlice const& other) = default; \
2973 _Name_##IdSlice& operator=(_Name_##IdSlice const& other) = default; \
2974 std::array<_Type_, 2> inline getIds() const \
2976 return _Getter_##Ids(); \
2979 bool has_##_Getter_() const \
2981 auto a = *mColumnIterator; \
2982 return a[0] >= 0 && a[1] >= 0; \
2985 std::array<_Type_, 2> _Getter_##Ids() const \
2987 auto a = *mColumnIterator; \
2988 return std::array{a[0], a[1]}; \
2991 template <typename T> \
2992 auto _Getter_##_as() const \
2994 auto t = mBinding.get<T>(); \
2995 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
2996 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
2998 if (O2_BUILTIN_UNLIKELY(!has_##_Getter_())) { \
2999 return t->emptySlice(); \
3001 auto a = *mColumnIterator; \
3002 auto r = t->rawSlice(a[0], a[1]); \
3003 t->copyIndexBindings(r); \
3004 r.bindInternalIndicesTo(t); \
3008 bool setCurrentRaw(o2::soa::Binding current) \
3010 this->mBinding = current; \
3013 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
3014 o2::soa::Binding mBinding; \
3017#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
3018#define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_)
3020#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \
3021 struct _Name_##Ids : o2::soa::Column<std::vector<_Type_>, _Name_##Ids> { \
3022 static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \
3023 static constexpr const char* mLabel = "fIndexArray" _Label_; \
3024 static constexpr const uint32_t hash = 0; \
3025 using base = o2::soa::Column<std::vector<_Type_>, _Name_##Ids>; \
3026 using type = std::vector<_Type_>; \
3027 using column_t = _Name_##Ids; \
3028 using self_index_t = std::true_type; \
3029 using compatible_signature = std::conditional<aod::is_aod_hash<_IndexTarget_>, _IndexTarget_, void>; \
3030 _Name_##Ids(arrow::ChunkedArray const* column) \
3031 : o2::soa::Column<std::vector<_Type_>, _Name_##Ids>(o2::soa::ColumnIterator<type>(column)) \
3035 _Name_##Ids() = default; \
3036 _Name_##Ids(_Name_##Ids const& other) = default; \
3037 _Name_##Ids& operator=(_Name_##Ids const& other) = default; \
3038 gsl::span<const _Type_> inline getIds() const \
3040 return _Getter_##Ids(); \
3043 gsl::span<const _Type_> _Getter_##Ids() const \
3045 return *mColumnIterator; \
3048 bool has_##_Getter_() const \
3050 return !(*mColumnIterator).empty(); \
3053 template <typename T> \
3054 auto _Getter_##_as() const \
3056 auto t = mBinding.get<T>(); \
3057 if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \
3058 o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \
3060 auto result = std::vector<typename T::unfiltered_iterator>(); \
3061 for (auto& i : *mColumnIterator) { \
3062 result.push_back(t->rawIteratorAt(i)); \
3067 template <typename T> \
3068 auto _Getter_##_first_as() const \
3070 return mBinding.get<T>()->rawIteratorAt((*mColumnIterator)[0]); \
3073 template <typename T> \
3074 auto _Getter_##_last_as() const \
3076 return mBinding.get<T>()->rawIteratorAt((*mColumnIterator).back()); \
3079 bool setCurrentRaw(o2::soa::Binding current) \
3081 this->mBinding = current; \
3084 o2::soa::Binding getCurrentRaw() const { return mBinding; } \
3085 o2::soa::Binding mBinding; \
3088#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void)
3089#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_)
3119#define DECLARE_SOA_DYNAMIC_COLUMN(_Name_, _Getter_, ...) \
3120 struct _Name_##Callback { \
3121 static inline constexpr auto getLambda() { return __VA_ARGS__; } \
3124 struct _Name_##Helper { \
3125 using callable_t = decltype(o2::framework::FunctionMetadata(std::declval<decltype(_Name_##Callback::getLambda())>())); \
3126 using return_type = typename callable_t::return_type; \
3128 template <typename... Bindings> \
3129 struct _Name_ : o2::soa::DynamicColumn<typename _Name_##Helper::callable_t::type, _Name_<Bindings...>> { \
3130 using base = o2::soa::DynamicColumn<typename _Name_##Helper::callable_t::type, _Name_<Bindings...>>; \
3131 using helper = _Name_##Helper; \
3132 using callback_holder_t = _Name_##Callback; \
3133 using callable_t = helper::callable_t; \
3134 using callback_t = callable_t::type; \
3135 static constexpr const uint32_t hash = 0; \
3137 _Name_(arrow::ChunkedArray const*) \
3140 _Name_() = default; \
3141 _Name_(_Name_ const& other) = default; \
3142 _Name_& operator=(_Name_ const& other) = default; \
3143 static constexpr const char* mLabel = #_Name_; \
3144 using type = typename callable_t::return_type; \
3146 template <typename... FreeArgs> \
3147 type _Getter_(FreeArgs... freeArgs) const \
3149 return boundGetter(std::make_index_sequence<std::tuple_size_v<decltype(boundIterators)>>{}, freeArgs...); \
3151 template <typename... FreeArgs> \
3152 type getDynamicValue(FreeArgs... freeArgs) const \
3154 return boundGetter(std::make_index_sequence<std::tuple_size_v<decltype(boundIterators)>>{}, freeArgs...); \
3159 return _Getter_(); \
3162 template <size_t... Is, typename... FreeArgs> \
3163 type boundGetter(std::integer_sequence<size_t, Is...>&&, FreeArgs... freeArgs) const \
3165 return __VA_ARGS__((**std::get<Is>(boundIterators))..., freeArgs...); \
3168 using bindings_t = typename o2::framework::pack<Bindings...>; \
3169 std::tuple<o2::soa::ColumnIterator<typename Bindings::type> const*...> boundIterators; \
3172#define DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, ...) \
3173 using _Name_##Metadata = TableMetadata<Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__>;
3175#define DECLARE_SOA_TABLE_METADATA_TRAIT(_Name_, _Desc_, _Version_) \
3177 struct MetadataTrait<Hash<_Desc_ "/" #_Version_ ""_h>> { \
3178 static constexpr void isMetadataTrait() {}; \
3179 using metadata = _Name_##Metadata; \
3182#define DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, _Version_) \
3183 O2HASH(_Desc_ "/" #_Version_); \
3184 template <typename O> \
3185 using _Name_##From = o2::soa::Table<Hash<_Label_ ""_h>, Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3186 using _Name_ = _Name_##From<Hash<_Origin_ ""_h>>; \
3188 struct MetadataTrait<Hash<_Desc_ "/" #_Version_ ""_h>> { \
3189 static constexpr void isMetadataTrait() {}; \
3190 using metadata = _Name_##Metadata; \
3193#define DECLARE_SOA_STAGE(_Name_, _Origin_, _Desc_, _Version_) \
3194 template <typename O> \
3195 using _Name_##From = o2::soa::Table<Hash<#_Name_ ""_h>, Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3196 using _Name_ = _Name_##From<Hash<_Origin_ ""_h>>;
3198#define DECLARE_SOA_TABLE_FULL_VERSIONED(_Name_, _Label_, _Origin_, _Desc_, _Version_, ...) \
3199 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, __VA_ARGS__); \
3200 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, _Version_);
3202#define DECLARE_SOA_TABLE_FULL(_Name_, _Label_, _Origin_, _Desc_, ...) \
3204 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, 0, __VA_ARGS__); \
3205 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, _Label_, _Origin_, _Desc_, 0)
3207#define DECLARE_SOA_TABLE(_Name_, _Origin_, _Desc_, ...) \
3208 DECLARE_SOA_TABLE_FULL(_Name_, #_Name_, _Origin_, _Desc_, __VA_ARGS__)
3210#define DECLARE_SOA_TABLE_VERSIONED(_Name_, _Origin_, _Desc_, _Version_, ...) \
3212 DECLARE_SOA_TABLE_METADATA(_Name_, _Desc_, _Version_, __VA_ARGS__) \
3213 DECLARE_SOA_TABLE_FULL_VERSIONED_(_Name_, #_Name_, _Origin_, _Desc_, _Version_)
3215#define DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Desc_, _Version_, ...) \
3216 O2HASH(_Desc_ "/" #_Version_); \
3217 O2HASH(#_BaseName_); \
3218 O2HASH("Stored" #_BaseName_); \
3219 DECLARE_SOA_TABLE_METADATA(_BaseName_, _Desc_, _Version_, __VA_ARGS__); \
3220 using Stored##_BaseName_##Metadata = _BaseName_##Metadata; \
3221 DECLARE_SOA_TABLE_METADATA_TRAIT(_BaseName_, _Desc_, _Version_); \
3222 DECLARE_SOA_STAGE(_BaseName_, "AOD", _Desc_, _Version_); \
3223 DECLARE_SOA_STAGE(Stored##_BaseName_, "AOD1", _Desc_, _Version_); \
3224 using StoredEMB##_BaseName_ = Stored##_BaseName_##From<o2::aod::Hash<"EMB"_h>>;
3226#define DECLARE_SOA_TABLE_STAGED(_BaseName_, _Desc_, ...) \
3227 DECLARE_SOA_TABLE_STAGED_VERSIONED(_BaseName_, _Desc_, 0, __VA_ARGS__);
3229#define DECLARE_SOA_EXTENDED_TABLE_NG(_Name_, _OriginalTable_, _Desc_, _Version_, ...) \
3230 O2HASH(_Desc_ "/" #_Version_); \
3231 O2HASH(#_Name_ "Extension"); \
3232 template <typename O> \
3233 using _Name_##ExtensionFrom = soa::Table<o2::aod::Hash<#_Name_ "Extension"_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3234 using _Name_##Extension = _Name_##ExtensionFrom<o2::aod::Hash<"AOD"_h>>; \
3235 struct _Name_##ExtensionMetadata : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3236 using base_table_t = _OriginalTable_; \
3237 template <o2::aod::is_origin_hash O> \
3238 using extension_table_t_from = _Name_##ExtensionFrom<O>; \
3239 using extension_table_t = _Name_##Extension; \
3240 using expression_pack_t = framework::pack<__VA_ARGS__>; \
3241 static constexpr auto N = _OriginalTable_::originals.size(); \
3242 template <o2::aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>> \
3243 static consteval auto generateSources() \
3245 return _OriginalTable_##From<O>::originals; \
3249 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3250 static constexpr void isMetadataTrait() {}; \
3251 using metadata = _Name_##ExtensionMetadata; \
3253 template <typename O> \
3254 using _Name_##From = o2::soa::Join<_OriginalTable_##From<O>, _Name_##ExtensionFrom<O>>; \
3255 using _Name_ = _Name_##From<o2::aod::Hash<"AOD"_h>>;
3257#define DECLARE_SOA_EXTENDED_TABLE(_Name_, _Table_, _Description_, _Version_, ...) \
3258 DECLARE_SOA_EXTENDED_TABLE_NG(_Name_, _Table_, _Description_, _Version_, __VA_ARGS__)
3260#define DECLARE_SOA_EXTENDED_TABLE_USER(_Name_, _Table_, _Description_, ...) \
3261 DECLARE_SOA_EXTENDED_TABLE_NG(_Name_, _Table_, "EX" _Description_, 0, __VA_ARGS__)
3263#define DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE_NG(_Name_, _OriginalTable_, _Desc_, _Version_, ...) \
3264 O2HASH(_Desc_ "/" #_Version_); \
3265 O2HASH(#_Name_ "CfgExtension"); \
3266 template <typename O> \
3267 using _Name_##CfgExtensionFrom = soa::Table<o2::aod::Hash<#_Name_ "CfgExtension"_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3268 using _Name_##CfgExtension = _Name_##CfgExtensionFrom<o2::aod::Hash<"AOD"_h>>; \
3269 struct _Name_##CfgExtensionMetadata : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3270 using base_table_t = _OriginalTable_; \
3271 template <o2::aod::is_origin_hash O> \
3272 using extension_table_t_from = _Name_##CfgExtensionFrom<O>; \
3273 using extension_table_t = _Name_##CfgExtension; \
3274 using placeholders_pack_t = framework::pack<__VA_ARGS__>; \
3275 using configurable_t = std::true_type; \
3276 static constexpr auto N = _OriginalTable_::originals.size(); \
3277 template <o2::aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>> \
3278 static consteval auto generateSources() \
3280 return _OriginalTable_##From<O>::originals; \
3284 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3285 static constexpr void isMetadataTrait() {}; \
3286 using metadata = _Name_##CfgExtensionMetadata; \
3288 template <typename O> \
3289 using _Name_##From = o2::soa::Join<_OriginalTable_##From<O>, _Name_##CfgExtensionFrom<O>>; \
3290 using _Name_ = _Name_##From<o2::aod::Hash<"AOD"_h>>;
3292#define DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE(_Name_, _OriginalTable_, _Description_, ...) \
3293 DECLARE_SOA_CONFIGURABLE_EXTENDED_TABLE_NG(_Name_, _OriginalTable_, "EX" _Description_, 0, __VA_ARGS__)
3295#define DECLARE_SOA_INDEX_TABLE_NG(_Name_, _Key_, _Version_, _Desc_, _Exclusive_, ...) \
3297 O2HASH(_Desc_ "/" #_Version_); \
3298 struct _Name_##Metadata : o2::aod::TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, soa::Index<>, __VA_ARGS__> { \
3299 static constexpr bool exclusive = _Exclusive_; \
3300 template <o2::aod::is_origin_hash O> \
3301 using KeyFrom = _Key_##From<O>; \
3302 using Key = _Key_; \
3303 using index_pack_t = framework::pack<__VA_ARGS__>; \
3304 template <o2::aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>> \
3305 static consteval auto generateSources() \
3307 return []<soa::is_index_column... Cs>(framework::pack<Cs...>) consteval { \
3308 constexpr auto first = o2::soa::mergeOriginals<typename Cs::binding_t...>(); \
3309 constexpr auto second = o2::aod::filterForKey<first.size(), first, Key>(); \
3310 return o2::aod::replaceOrigin<second.size(), second, O>(); \
3311 }(framework::pack<__VA_ARGS__>{}); \
3313 static constexpr auto N = []<typename... Cs>(framework::pack<Cs...>) consteval { \
3314 constexpr auto a = o2::soa::mergeOriginals<typename Cs::binding_t...>(); \
3315 return o2::aod::filterForKey<a.size(), a, Key>(); \
3316 }(framework::pack<__VA_ARGS__>{}) \
3320 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3321 static constexpr void isMetadataTrait() {}; \
3322 using metadata = _Name_##Metadata; \
3324 template <o2::aod::is_origin_hash O> \
3325 using _Name_##From = o2::soa::IndexTable<o2::aod::Hash<#_Name_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O, _Key_##From<O>, __VA_ARGS__>; \
3326 using _Name_ = _Name_##From<o2::aod::Hash<"AOD"_h>>;
3328#define DECLARE_SOA_INDEX_TABLE(_Name_, _Key_, _Description_, ...) \
3329 DECLARE_SOA_INDEX_TABLE_NG(_Name_, _Key_, 0, _Description_, false, __VA_ARGS__)
3331#define DECLARE_SOA_INDEX_TABLE_EXCLUSIVE(_Name_, _Key_, _Description_, ...) \
3332 DECLARE_SOA_INDEX_TABLE_NG(_Name_, _Key_, 0, _Description_, true, __VA_ARGS__)
3334#define DECLARE_SOA_INDEX_TABLE_USER(_Name_, _Key_, _Description_, ...) \
3335 DECLARE_SOA_INDEX_TABLE_NG(_Name_, _Key_, 0, _Description_, false, __VA_ARGS__)
3337#define DECLARE_SOA_INDEX_TABLE_EXCLUSIVE_USER(_Name_, _Key_, _Description_, ...) \
3338 DECLARE_SOA_INDEX_TABLE_NG(_Name_, _Key_, 0, _Description_, true, __VA_ARGS__)
3345#define DECLARE_SOA_TIMESTAMPED_TABLE_FULL(_Name_, _Label_, _TimestampSource_, _TimestampColumn_, _UniformitySource_, _UniformityColumn_, _Version_, _Desc_, ...) \
3346 O2HASH(_Desc_ "/" #_Version_); \
3347 template <typename O> \
3348 using _Name_##TimestampFrom = soa::Table<o2::aod::Hash<_Label_ ""_h>, o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, O>; \
3349 using _Name_##Timestamp = _Name_##TimestampFrom<o2::aod::Hash< \
3352 struct _Name_##TimestampMetadata : TableMetadata<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>, __VA_ARGS__> { \
3353 template <typename O = o2::aod::Hash<"AOD" \
3355 using base_table_t = _TimestampSource_##From<O>; \
3356 template <typename O = o2::aod::Hash<"AOD" \
3358 using extension_table_t = _Name_##TimestampFrom<O>; \
3359 static constexpr const auto ccdb_urls = []<typename... Cs>(framework::pack<Cs...>) consteval { \
3360 return std::array<std::string_view, sizeof...(Cs)>{Cs::query...}; \
3361 }(framework::pack<__VA_ARGS__>{}); \
3362 static constexpr const auto ccdb_bindings = []<typename... Cs>(framework::pack<Cs...>) consteval { \
3363 return std::array<std::string_view, sizeof...(Cs)>{Cs::mLabel...}; \
3364 }(framework::pack<__VA_ARGS__>{}); \
3365 static constexpr const auto ccdb_run_dependent = []<typename... Cs>(framework::pack<Cs...>) consteval { \
3366 return std::array<int, sizeof...(Cs)>{Cs::run_dependent...}; \
3367 }(framework::pack<__VA_ARGS__>{}); \
3374 static constexpr auto N = o2::soa::mergeOriginals<_TimestampSource_, _UniformitySource_>().size(); \
3375 template <o2::aod::is_origin_hash O = o2::aod::Hash<"AOD"_h>> \
3376 static consteval auto generateSources() \
3378 return o2::soa::mergeOriginals<_TimestampSource_##From<O>, _UniformitySource_##From<O>>(); \
3380 static constexpr auto timestamp_column_label = _TimestampColumn_::mLabel; \
3384 static constexpr auto uniformity_column_label = _UniformityColumn_::mLabel; \
3388 struct MetadataTrait<o2::aod::Hash<_Desc_ "/" #_Version_ ""_h>> { \
3389 static constexpr void isMetadataTrait() {}; \
3390 using metadata = _Name_##TimestampMetadata; \
3392 template <typename O> \
3393 using _Name_##From = o2::soa::Join<_TimestampSource_, _Name_##TimestampFrom<O>>; \
3394 using _Name_ = _Name_##From<o2::aod::Hash< \
3404#define DECLARE_SOA_TIMESTAMPED_TABLE(_Name_, _TimestampSource_, _TimestampColumn_, _Version_, _Desc_, ...) \
3405 O2HASH(#_Name_ "Timestamped"); \
3406 DECLARE_SOA_TIMESTAMPED_TABLE_FULL(_Name_, #_Name_ "Timestamped", _TimestampSource_, _TimestampColumn_, _TimestampSource_, _TimestampColumn_, _Version_, _Desc_, __VA_ARGS__)
3411#define DECLARE_SOA_UNIFORM_TABLE(_Name_, _TimestampSource_, _TimestampColumn_, _UniformitySource_, _UniformityColumn_, _Version_, _Desc_, ...) \
3412 O2HASH(#_Name_ "Timestamped"); \
3413 DECLARE_SOA_TIMESTAMPED_TABLE_FULL(_Name_, #_Name_ "Timestamped", _TimestampSource_, _TimestampColumn_, _UniformitySource_, _UniformityColumn_, _Version_, _Desc_, __VA_ARGS__)
3417template <
typename...
Ts>
3418struct Join :
Table<o2::aod::Hash<"JOIN"_h>, o2::aod::Hash<"JOIN/0"_h>, o2::aod::Hash<"JOIN"_h>, Ts...> {
3422 Join(std::vector<ArrowTableRef>&& tables)
3435 template <
typename... TA>
3479 template <
typename T1,
typename Policy,
bool OPT>
3507 template <
typename T>
3510 return []<
size_t... Is>(std::index_sequence<Is...>)
constexpr {
3511 return (std::ranges::any_of(
originals, [](
TableRef const&
ref)
constexpr {
return ref.desc_hash == T::originals[Is].desc_hash; }) && ...);
3512 }(std::make_index_sequence<T::originals.size()>());
3516template <
typename...
Ts>
3522template <
typename T>
3525template <
typename...
Ts>
3526struct Concat :
Table<o2::aod::Hash<"CONC"_h>, o2::aod::Hash<"CONC/0"_h>, o2::aod::Hash<"CONC"_h>, Ts...> {
3551 using base::originals;
3553 using base::bindExternalIndices;
3554 using base::bindInternalIndicesTo;
3568template <
typename...
Ts>
3574template <
typename S>
3577template <soa::is_table T>
3585 static constexpr const uint32_t binding_origin = T::binding_origin;
3587 template <
typename... TA>
3591 if constexpr (binding_origin == TA::binding_origin) {
3592 this->bindExternalIndex(cur);
3593 mFilteredBegin.bindExternalIndex(cur);
3602 using iterator = T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3607 : T{
std::move(tables)}
3609 adoptSelection(selection);
3610 if (this->tableSize() != 0) {
3611 mFilteredBegin = table_t::filtered_begin(mSelectedRows);
3614 mFilteredBegin.bindInternalIndices(
this);
3641 return mFilteredBegin;
3646 return mFilteredBegin;
3651 return mFilteredBegin +
i;
3656 return mSelectedRows.size();
3661 return this->asArrowTableRef().range.size;
3666 return mSelectedRows;
3673 std::iota(newSelection.begin(), newSelection.end(),
start);
3674 return self_t{{this->asArrowTableRef()}, std::move(newSelection)};
3684 if (sel ==
nullptr) {
3685 return std::span<int64_t const>{};
3687 auto array = std::static_pointer_cast<arrow::Int64Array>(sel->ToArray());
3690 return std::span{
start, stop};
3697 mFilteredBegin.bindExternalIndicesRaw(std::forward<std::vector<o2::soa::Binding>>(ptrs));
3700 template <
typename I>
3703 mFilteredBegin.bindInternalIndices(
ptr);
3706 template <
typename T1,
typename... Cs>
3709 dest.bindExternalIndicesRaw(mFilteredBegin.getIndexBindings());
3712 template <
typename T1>
3718 template <
typename T1>
3734 template <
typename T1,
bool OPT>
3740 template <
typename T1,
bool OPT>
3749 copyIndexBindings(t);
3755 auto locate = std::find(mSelectedRows.begin(), mSelectedRows.end(),
i);
3756 if (locate == mSelectedRows.end()) {
3759 return static_cast<int>(std::distance(mSelectedRows.begin(), locate));
3766 std::ranges::set_union(mSelectedRows, selection, std::back_inserter(rowsUnion));
3767 mSelectedRowsCache.clear();
3768 mSelectedRowsCache = rowsUnion;
3776 std::ranges::set_intersection(mSelectedRows, selection, std::back_inserter(intersection));
3777 mSelectedRowsCache.clear();
3778 mSelectedRowsCache = intersection;
3789 mFilteredBegin.setPointerReconstructor(pointerReconstructor);
3796 mSelectedRows = std::span{mSelectedRowsCache};
3800 mFilteredBegin = *mFilteredEnd;
3802 mFilteredBegin.resetSelection(mSelectedRows);
3806 template <
typename S>
3807 inline void adoptSelection(
S)
3811 template <
typename S>
3813 inline void adoptSelection(
S selection)
3815 mSelectedRows = getSpan(selection);
3819 template <
typename S>
3821 inline void adoptSelection(
S selection)
3823 mSelectedRowsCache = std::move(selection);
3824 mSelectedRows = std::span{mSelectedRowsCache};
3828 template <
typename S>
3829 requires(std::same_as<std::decay_t<S>, std::span<int64_t const>>)
3830 inline void adoptSelection(
S selection)
3832 mSelectedRows = selection;
3836 std::span<int64_t const> mSelectedRows;
3838 bool mCached =
false;
3839 iterator mFilteredBegin;
3840 std::shared_ptr<RowViewSentinel> mFilteredEnd;
3843template <
typename T>
3852 using iterator = T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3858 return iterator(this->cached_begin());
3867 :
FilteredBase<T>{std::move(tables), std::forward<decltype(selection)>(selection)} {}
3883 this->sumWithSelection(selection);
3889 return operator+=(
other.getSelectedRows());
3901 return operator*(
other.getSelectedRows());
3906 this->intersectWithSelection(selection);
3912 return operator*=(
other.getSelectedRows());
3928 std::iota(newSelection.begin(), newSelection.end(),
start);
3929 return self_t{{this->asArrowTableRef()}, std::move(newSelection)};
3937 template <
typename T1>
3953 template <
typename T1,
bool OPT>
3959 template <
typename T1,
bool OPT>
3968 copyIndexBindings(t);
3973template <
typename T>
3982 using iterator =
typename T::template iterator_template_o<FilteredIndexPolicy, self_t>;
3988 return iterator(this->cached_begin());
3997 :
FilteredBase<typename T::
table_t>(
std::move(extractTablesFromFiltered(tables)),
std::forward<decltype(selection)>(selection))
3999 for (
auto& table : tables) {
4018 this->sumWithSelection(selection);
4024 return operator+=(
other.getSelectedRows());
4030 copy.intersectionWithSelection(selection);
4036 return operator*(
other.getSelectedRows());
4041 this->intersectWithSelection(selection);
4047 return operator*=(
other.getSelectedRows());
4061 std::iota(newSelection.begin(), newSelection.end(),
start);
4062 return self_t{{this->asArrowTableRef()}, std::move(newSelection)};
4080 template <
typename T1,
bool OPT>
4086 template <
typename T1,
bool OPT>
4093 std::vector<ArrowTableRef> extractTablesFromFiltered(std::vector<
Filtered<T>>& tables)
4095 std::vector<ArrowTableRef> outTables;
4096 for (
auto& table : tables) {
4097 outTables.push_back(table.asArrowTableRef());
4108template <
typename L,
typename D,
typename O,
typename Key,
typename H,
typename...
Ts>
4119 static constexpr const uint32_t binding_origin = Key::binding_origin;
4122 template <
typename... TA>
4126 if constexpr (binding_origin == TA::binding_origin) {
4127 this->bindExternalIndex(cur);
4152template <
typename T,
bool APPLY>
4155 static constexpr bool applyFilters = APPLY;
4161template <
typename T>
4164template <
typename T>
header::DataDescription description
#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)
std::unique_ptr< expressions::Node > node
std::vector< o2::MCCompLabel > labels
Class for time synchronization of RawReader instances.
int64_t const * mCurrentPos
ColumnIterator(arrow::ChunkedArray const *column)
ColumnIterator(ColumnIterator< T, ChunkingPolicy > const &)=default
uint64_t const * mGlobalOffset
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
int64_t tableSize() const
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
void setPointerReconstructor(framework::PointerReconstructor const &pointerReconstructor)
typename T::columns_t columns_t
void bindExternalIndices(TA *... current)
void sumWithSelection(is_a_selection auto selection)
void bindInternalIndicesTo(I const *ptr)
FilteredBase(std::vector< ArrowTableRef > &&tables, is_a_selection auto 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
static constexpr void isFilteredBase()
RowViewSentinel end() const
void intersectWithSelection(is_a_selection auto selection)
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
auto const & cached_begin() const
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicySorted, OPT > const &container, int value) const
Filtered(std::vector< Filtered< T > > &&tables, is_a_selection auto selection)
typename FilteredBase< typename T::table_t >::table_t table_t
typename T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
typename T::template iterator_template_o< FilteredIndexPolicy, self_t > iterator
typename T::columns_t columns_t
const_iterator begin() const
Filtered< Filtered< T > > operator+=(is_a_selection auto selection)
Filtered< Filtered< T > > operator*(is_a_selection auto selection)
Filtered< Filtered< T > > operator+(is_a_selection auto selection)
unfiltered_iterator rawIteratorAt(uint64_t i) const
Filtered< Filtered< T > > operator*=(is_a_selection auto selection)
Filtered< Filtered< T > > operator+=(Filtered< T > const &other)
auto rawSlice(uint64_t start, uint64_t end) const
Filtered< Filtered< T > > operator+(Filtered< T > const &other)
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*(Filtered< T > const &other)
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Filtered< T > operator+=(Filtered< T > const &other)
Filtered(std::vector< ArrowTableRef > &&tables, is_a_selection auto selection)
auto sliceBy(o2::framework::PresliceBase< T1, framework::PreslicePolicyGeneral, OPT > const &container, int value) const
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
Filtered< T > operator+(Filtered< T > const &other)
const_iterator begin() const
Filtered< T > operator+(is_a_selection auto selection)
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*(is_a_selection auto selection)
T::template iterator_template_o< DefaultIndexPolicy, self_t > unfiltered_iterator
unfiltered_iterator rawIteratorAt(uint64_t i) const
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
auto rawSlice(uint64_t start, uint64_t end) const
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
Filtered< T > operator+=(is_a_selection auto selection)
Filtered< T > operator*=(is_a_selection auto selection)
void bindInternalIndicesExplicit(o2::soa::Binding binding)
decltype([]< typename... C >(framework::pack< C... > &&) consteval -> framework::selected_pack< soa::is_persistent_column_t, C... > {}(columns_t{})) persistent_columns_t
void setPointerReconstructor(framework::PointerReconstructor const &pointerReconstructor)
iterator iteratorAt(uint64_t i) const
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
Table(std::vector< o2::soa::ArrowTableRef > &&tables)
void bindExternalIndices(TA *... current)
auto select(framework::expressions::Filter const &f) const
decltype([]< typename... C >(framework::pack< C... >) consteval -> framework::pack< typename C::type... > {}(persistent_columns_t{})) column_types
unfiltered_iterator unfiltered_const_iterator
decltype([]() { if constexpr(sizeof...(Ts)==0) { return iterator_template< IP, Parent >{} iterator_template_o
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
static constexpr header::DataOrigin binding_origin_
void bindExternalIndicesRaw(std::vector< o2::soa::Binding > &&ptrs)
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
iterator unfiltered_iterator
void bindExternalIndex(TA *current)
std::shared_ptr< arrow::Table > asArrowTable() const
Return a type erased arrow table backing store for / the type safe table.
filtered_iterator filtered_begin(std::span< int64_t const > selection)
void doCopyIndexBindings(framework::pack< Cs... >, T &dest) const
int64_t size() const
Size of the table, in rows.
static constexpr auto column_hashes
decltype(getColumns< ref, Ts... >()) columns_t
arrow::ChunkedArray * getIndexToKey()
decltype([]< typename... C >(framework::pack< C... > &&) consteval -> framework::selected_pack< soa::is_external_index_t, C... > {}(columns_t{})) external_index_columns_t
ArrowTableRef asArrowTableRef() const
static constexpr const uint32_t binding_origin
static consteval auto isIndexTargetOf()
std::shared_ptr< arrow::Table > asArrowTableConstrained() const
iterator_template_o< FilteredIndexPolicy, table_t > filtered_iterator
unfiltered_const_iterator begin() const
void copyIndexBindings(T &dest) const
static constexpr const auto originalLabels
Table< L, D, O, Ts... > self_t
static consteval auto isIndexTargetOf()
void doBindInternalIndicesExplicit(framework::pack< Cs... >, o2::soa::Binding binding)
static constexpr const auto originals
Table(std::vector< std::shared_ptr< arrow::Table > > &&tables)
decltype([]< typename... C >(framework::pack< C... > &&) consteval -> framework::selected_pack< soa::is_self_index_t, C... > {}(columns_t{})) internal_index_columns_t
Table(std::shared_ptr< arrow::Table > table)
Table(o2::soa::ArrowTableRef tableRef)
Table(std::vector< std::shared_ptr< arrow::Table > > &&tables)
RowViewSentinel end() const
static constexpr void isSOATable()
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
Table(std::vector< o2::soa::ArrowTableRef > &&tables)
iterator_template_o< DefaultIndexPolicy, table_t > iterator
GLuint GLsizei const GLuint const GLintptr * offsets
GLuint const GLchar * name
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 replaceOrigin()
Replace origins in the TableRef array.
constexpr framework::ConcreteDataMatcher matcher()
consteval auto filterForKey()
Filter TableRef array for compatibility with Key table.
consteval const char * label()
consteval header::DataOrigin origin()
gandiva::Selection createSelection(std::shared_ptr< arrow::Table > const &table, Filter const &expression)
Function for creating gandiva selection from our internal filter tree.
Defining ITS Vertex explicitly as messageable.
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
std::function< std::byte *(fair::mq::shmem::MetaHeader &&)> PointerReconstructor
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
R getColumnValue(const T &rowIterator)
ColumnGetterFunction< R, typename T::iterator > getColumnGetterByLabel(const std::string_view &targetColumnLabel)
void * extractCCDBPayload(char *payload, size_t size, TClass const *cl, const char *what)
consteval auto computeOriginals()
auto createFieldsFromColumns(framework::pack< C... >)
SelectionVector selectionToVector(gandiva::Selection const &sel)
constexpr bool is_persistent_v
column identification
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)
void notBoundTable(const char *tableName)
SelectionVector sliceSelection(std::span< int64_t const > const &mSelectedRows, int64_t nrows, uint64_t offset)
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)
consteval bool is_binding_compatible_v()
typename unwrap< T >::type unwrap_t
auto prepareFilteredSlice(T const *table, o2::soa::ArrowTableRef slice)
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)
constexpr char asciiToLower(char c)
auto doSliceByHelper(T const *table, std::span< const int64_t > const &selection)
std::function< framework::ConcreteDataMatcher(framework::ConcreteDataMatcher &&)> originReplacement(header::DataOrigin newOrigin)
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
pack filtering helpers
typename std::conditional_t< is_self_index_column< C >, std::true_type, std::false_type > is_self_index_t
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
FIXME: do not use data model tables.
static constexpr uint32_t hash
static constexpr char const *const str
static constexpr void isHash()
SliceInfoUnsortedPtr getCacheUnsortedFor(Entry const &bindingKey) const
header::DataOrigin newOrigin
SliceInfoPtr getCacheFor(Entry const &bindingKey) const
static constexpr bool optional
PresliceBase(expressions::BindingNode index_)
std::span< const int64_t > getSliceFor(int value) const
const std::string binding
o2::soa::ArrowTableRef getSliceFor(int value, o2::soa::ArrowTableRef const &input) const
static constexpr void isPresliceContainer()
static constexpr void isPresliceGroup()
tracks origin in bindingKey matcher to handle the correct arguments
const std::string binding
Entry const & getBindingKey() const
static constexpr void isPreslicePolicy()
SliceInfoUnsortedPtr sliceInfo
std::span< const int64_t > getSliceFor(int value) const
void updateSliceInfo(SliceInfoUnsortedPtr &&si)
o2::soa::ArrowTableRef getSliceFor(int value, o2::soa::ArrowTableRef const &input) const
void updateSliceInfo(SliceInfoPtr &&si)
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 o2::soa::ArrowTableRef concatTables(std::vector< std::shared_ptr< arrow::Table > > &&tables)
static o2::soa::ArrowTableRef joinTables(std::vector< std::shared_ptr< arrow::Table > > &&tables)
static o2::soa::ArrowTableRef concatTables(std::vector< o2::soa::ArrowTableRef > &&tables)
ArrowTableRef makeEmpty() const
std::shared_ptr< arrow::Table > tablePtr
ArrowTableRef slice(ArrowRange newRange) const
Type-checking index column binding.
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
static constexpr void isIteratableColumn()
ColumnIterator< T > mColumnIterator
Concat(std::shared_ptr< arrow::Table > table)
table_t::template iterator_template< DefaultIndexPolicy, self_t, Ts... > iterator
typename table_t::persistent_columns_t persistent_columns_t
typename table_t::columns_t columns_t
Concat(std::vector< ArrowTableRef > &&tables)
const_iterator unfiltered_const_iterator
iterator unfiltered_iterator
table_t::template iterator_template< FilteredIndexPolicy, self_t, Ts... > filtered_iterator
Concat(ArrowTableRef table)
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
static constexpr void isDefaultIndexPolicy()
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()
static constexpr void isDynamicColumn()
FilteredIndexPolicy & operator=(FilteredIndexPolicy &&)=default
std::tuple< int64_t const *, int64_t const * > getIndices() const
FilteredIndexPolicy & operator=(FilteredIndexPolicy const &)=default
auto getSelectionRow() const
FilteredIndexPolicy()=default
FilteredIndexPolicy(std::span< int64_t const > selection, int64_t rows, uint64_t offset=0)
friend bool operator==(FilteredIndexPolicy const &lh, FilteredIndexPolicy const &rh)
void resetSelection(std::span< int64_t const > selection)
void setCursor(int64_t i)
static constexpr void isFilteredIndexPolicy()
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(FilteredIndexPolicy &&)=default
void moveByIndex(int64_t i)
static constexpr bool chunked
static constexpr const char *const & columnLabel()
static constexpr void isEnumeratingColumn()
static constexpr const uint32_t hash
uint64_t mOffset
Offset within a larger table.
int64_t mRowIndex
Position inside the current table.
static constexpr void isIndexTable()
void bindExternalIndices(TA *... current)
IndexTable(ArrowTableRef table)
typename base_t::template iterator_template_o< DefaultIndexPolicy, self_t > iterator
filtered_iterator const_filtered_iterator
IndexTable(IndexTable &&)=default
IndexTable(std::vector< ArrowTableRef > &&tables)
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
auto sliceBy(o2::framework::PresliceBase< T1, Policy, OPT > const &container, int value) const
static constexpr const auto originalLabels
static constexpr const auto originals
iterator rawIteratorAt(uint64_t i) const
static constexpr const uint32_t binding_origin
auto sliceByCached(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
const_iterator unfiltered_const_iterator
typename table_t::columns_t columns_t
Table< o2::aod::Hash<"JOIN"_h >, o2::aod::Hash<"JOIN/0"_h >, o2::aod::Hash<"JOIN"_h >, Ts... > base
iterator iteratorAt(uint64_t i) const
typename table_t::persistent_columns_t persistent_columns_t
const_iterator begin() const
void bindExternalIndices(TA *... current)
table_t::template iterator_template< DefaultIndexPolicy, self_t, Ts... > iterator
static consteval bool contains()
static constexpr void isJoin()
Join(std::vector< ArrowTableRef > &&tables)
table_t::template iterator_template< FilteredIndexPolicy, self_t, Ts... > filtered_iterator
auto sliceByCachedUnsorted(framework::expressions::BindingNode const &node, int value, o2::framework::SliceCache &cache) const
auto rawSlice(uint64_t start, uint64_t end) const
static constexpr const header::DataOrigin binding_origin_
iterator unfiltered_iterator
filtered_iterator filtered_const_iterator
static constexpr const uint32_t hash
static constexpr const char *const & columnLabel()
static constexpr void isMarkingColumn()
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
static constexpr void isRowViewSentinel()
SmallGroupsBase(std::vector< ArrowTableRef > &&tables, is_a_selection auto selection)
static constexpr void isSmallGroups()
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 bindExternalIndex(TA *current)
void doSetCurrentInternal(framework::pack< Cs... >, I const *ptr)
decltype([]< typename... Cs >(framework::pack< Cs... >) consteval -> framework::pack< typename Cs::binding_t... > {}(external_index_columns_t{})) bindings_pack_t
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)
void bindExternalIndices(TA *... current)
TableIterator & operator--()
framework::selected_pack< soa::is_external_index_t, C... > external_index_columns_t
TableIterator const & operator*() const
static constexpr void isTableIterator()
TableIterator operator++(int)
framework::selected_pack< soa::is_self_index_t, C... > internal_index_columns_t
auto getIndexBindings() const
void setPointerReconstructor(framework::PointerReconstructor const &pointerReconstructor)
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
TableIteratorBase & operator=(TableIteratorBase< IP, P, Os... > other)
TableIteratorBase(TableIteratorBase< IP, P, O1, Os... > &&other) noexcept
TableIteratorBase & operator=(RowViewSentinel const &other)
decltype([]< typename... C >(framework::pack< C... >) consteval -> framework::pack< typename C::binding_t... > {}(external_index_columns_t{})) bindings_pack_t
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