1212#ifndef O2_FRAMEWORK_ASOA_H_
1313#define O2_FRAMEWORK_ASOA_H_
1414
15+ #include " Framework/ConcreteDataMatcher.h"
1516#include " Framework/Pack.h" // IWYU pragma: export
1617#include " Framework/FunctionalHelpers.h" // IWYU pragma: export
1718#include " Headers/DataHeader.h" // IWYU pragma: export
@@ -375,6 +376,12 @@ consteval const char* signature()
375376 return o2::aod::Hash<R.desc_hash >::str;
376377}
377378
379+ template <soa::TableRef R>
380+ constexpr framework::ConcreteDataMatcher matcher ()
381+ {
382+ return {origin<R>(), description (signature<R>()), R.version };
383+ }
384+
378385// / hash identification concepts
379386template <typename T>
380387concept is_aod_hash = requires (T t) { t.hash ; t.str ; };
@@ -1393,6 +1400,12 @@ static constexpr std::pair<bool, std::string> hasKey(std::string const& key)
13931400 return {hasColumnForKey (typename aod::MetadataTrait<o2::aod::Hash<ref.desc_hash >>::metadata::columns{}, key), aod::label<ref>()};
13941401}
13951402
1403+ template <TableRef ref>
1404+ static constexpr std::pair<bool , framework::ConcreteDataMatcher> hasKeyM (std::string const & key)
1405+ {
1406+ return {hasColumnForKey (typename aod::MetadataTrait<o2::aod::Hash<ref.desc_hash >>::metadata::columns{}, key), aod::matcher<ref>()};
1407+ }
1408+
13961409template <typename ... C>
13971410static constexpr auto haveKey (framework::pack<C...>, std::string const & key)
13981411{
@@ -1427,6 +1440,31 @@ static constexpr std::string getLabelFromTypeForKey(std::string const& key)
14271440 O2_BUILTIN_UNREACHABLE ();
14281441}
14291442
1443+ template <with_originals T, bool OPT = false >
1444+ static constexpr framework::ConcreteDataMatcher getMatcherFromTypeForKey (std::string const & key)
1445+ {
1446+ if constexpr (T::originals.size () == 1 ) {
1447+ auto locate = hasKeyM<T::originals[0 ]>(key);
1448+ if (locate.first ) {
1449+ return locate.second ;
1450+ }
1451+ } else {
1452+ auto locate = [&]<size_t ... Is>(std::index_sequence<Is...>) {
1453+ return std::vector{hasKeyM<T::originals[Is]>(key)...};
1454+ }(std::make_index_sequence<T::originals.size ()>{});
1455+ auto it = std::find_if (locate.begin (), locate.end (), [](auto const & x) { return x.first ; });
1456+ if (it != locate.end ()) {
1457+ return it->second ;
1458+ }
1459+ }
1460+ if constexpr (!OPT) {
1461+ notFoundColumn (getLabelFromType<std::decay_t <T>>().data (), key.data ());
1462+ } else {
1463+ return framework::ConcreteDataMatcher{header::DataOrigin{" AOD" }, header::DataDescription{" [MISSING]" }, 0 };
1464+ }
1465+ O2_BUILTIN_UNREACHABLE ();
1466+ }
1467+
14301468template <typename B, typename ... C>
14311469consteval static bool hasIndexTo (framework::pack<C...>&&)
14321470{
@@ -1477,15 +1515,18 @@ struct PreslicePolicyGeneral : public PreslicePolicyBase {
14771515 std::span<const int64_t > getSliceFor (int value) const ;
14781516};
14791517
1480- template <typename T, typename Policy, bool OPT = false >
1518+ template <typename T>
1519+ concept is_preslice_policy = std::derived_from<T, PreslicePolicyBase>;
1520+
1521+ template <typename T, is_preslice_policy Policy, bool OPT = false >
14811522struct PresliceBase : public Policy {
14821523 constexpr static bool optional = OPT;
14831524 using target_t = T;
14841525 using policy_t = Policy;
14851526 const std::string binding;
14861527
14871528 PresliceBase (expressions::BindingNode index_)
1488- : Policy{PreslicePolicyBase{{o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name })}, Entry (o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name }), std::string{index_.name })}, {}}
1529+ : 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 })}, {}}
14891530 {
14901531 }
14911532
@@ -1520,7 +1561,11 @@ template <typename T>
15201561using PresliceOptional = PresliceBase<T, PreslicePolicySorted, true >;
15211562
15221563template <typename T>
1523- concept is_preslice = std::derived_from<T, PreslicePolicyBase>;
1564+ concept is_preslice = std::derived_from<T, PreslicePolicyBase>&&
1565+ requires (T)
1566+ {
1567+ T::optional;
1568+ };
15241569
15251570// / Can be user to group together a number of Preslice declaration
15261571// / to avoid the limit of 100 data members per task
@@ -1667,10 +1712,10 @@ auto doFilteredSliceBy(T const* table, o2::framework::PresliceBase<C, framework:
16671712 return prepareFilteredSlice (table, slice, offset);
16681713}
16691714
1670- template <typename T>
1715+ template <soa::is_table T>
16711716auto doSliceByCached (T const * table, framework::expressions::BindingNode const & node, int value, o2::framework::SliceCache& cache)
16721717{
1673- auto localCache = cache.ptr ->getCacheFor ({o2::soa::getLabelFromTypeForKey <T>(node.name ), node.name });
1718+ auto localCache = cache.ptr ->getCacheFor ({" " , o2::soa::getMatcherFromTypeForKey <T>(node.name ), node.name });
16741719 auto [offset, count] = localCache.getSliceFor (value);
16751720 auto t = typename T::self_t ({table->asArrowTable ()->Slice (static_cast <uint64_t >(offset), count)}, static_cast <uint64_t >(offset));
16761721 if (t.tableSize () != 0 ) {
@@ -1679,19 +1724,19 @@ auto doSliceByCached(T const* table, framework::expressions::BindingNode const&
16791724 return t;
16801725}
16811726
1682- template <typename T>
1727+ template <soa::is_filtered_table T>
16831728auto doFilteredSliceByCached (T const * table, framework::expressions::BindingNode const & node, int value, o2::framework::SliceCache& cache)
16841729{
1685- auto localCache = cache.ptr ->getCacheFor ({o2::soa::getLabelFromTypeForKey <T>(node.name ), node.name });
1730+ auto localCache = cache.ptr ->getCacheFor ({" " , o2::soa::getMatcherFromTypeForKey <T>(node.name ), node.name });
16861731 auto [offset, count] = localCache.getSliceFor (value);
16871732 auto slice = table->asArrowTable ()->Slice (static_cast <uint64_t >(offset), count);
16881733 return prepareFilteredSlice (table, slice, offset);
16891734}
16901735
1691- template <typename T>
1736+ template <soa::is_table T>
16921737auto doSliceByCachedUnsorted (T const * table, framework::expressions::BindingNode const & node, int value, o2::framework::SliceCache& cache)
16931738{
1694- auto localCache = cache.ptr ->getCacheUnsortedFor ({o2::soa::getLabelFromTypeForKey <T>(node.name ), node.name });
1739+ auto localCache = cache.ptr ->getCacheUnsortedFor ({" " , o2::soa::getMatcherFromTypeForKey <T>(node.name ), node.name });
16951740 if constexpr (soa::is_filtered_table<T>) {
16961741 auto t = typename T::self_t ({table->asArrowTable ()}, localCache.getSliceFor (value));
16971742 if (t.tableSize () != 0 ) {
0 commit comments