Skip to content
Prev Previous commit
Next Next commit
Handle missing Preslice bindings uniformly
Drop the duplicated binding
check isMissing() on the binding key for all Preslice kinds
rename missingOptionalPreslice to missingPreslice
  • Loading branch information
aalkin committed Sep 29, 2026
commit 9db24cf2cc4eb9ff43226896e2233084eaf53771
40 changes: 16 additions & 24 deletions Framework/Core/include/Framework/ASoA.h
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ static constexpr std::pair<bool, framework::ConcreteDataMatcher> hasKeyM(std::st
}

void notFoundColumn(const char* label, const char* key);
void missingOptionalPreslice(const char* label, const char* key);
void missingPreslice(const char* label, const char* key);

template <with_originals T, bool OPT = false>
static constexpr std::string getLabelFromTypeForKey(std::string_view key)
Expand Down Expand Up @@ -1421,7 +1421,6 @@ namespace o2::framework
/// tracks origin in bindingKey matcher to handle the correct arguments
struct PreslicePolicyBase {
static constexpr void isPreslicePolicy() {};
const std::string binding;
Entry bindingKey;

bool isMissing() const;
Expand All @@ -1448,29 +1447,28 @@ struct PresliceBase : public Policy {
constexpr static bool optional = OPT;
using target_t = T;
using policy_t = Policy;
const std::string binding;

PresliceBase(expressions::BindingNode index_)
: 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})}, {}}
: Policy{Entry(
o2::soa::getLabelFromTypeForKey<T, OPT>(std::string{index_.name}),
o2::soa::getMatcherFromTypeForKey<T, OPT>(std::string{index_.name}),
std::string{index_.name}
)}
{
}

o2::soa::ArrowTableRef getSliceFor(int value, o2::soa::ArrowTableRef const& input) const
{
if constexpr (OPT) {
if (Policy::isMissing()) {
return {nullptr, {0, 0}};
}
if (Policy::isMissing()) {
return {nullptr, {0, 0}};
}
return Policy::getSliceFor(value, input);
}

std::span<const int64_t> getSliceFor(int value) const
{
if constexpr (OPT) {
if (Policy::isMissing()) {
return {};
}
if (Policy::isMissing()) {
return {};
}
return Policy::getSliceFor(value);
}
Expand Down Expand Up @@ -1526,10 +1524,8 @@ template <typename T, typename C, typename Policy, bool OPT>
requires std::same_as<Policy, framework::PreslicePolicySorted> && (o2::soa::is_binding_compatible_v<C, T>())
auto doSliceBy(T const* table, o2::framework::PresliceBase<C, Policy, OPT> const& container, int value)
{
if constexpr (OPT) {
if (container.isMissing()) {
missingOptionalPreslice(getLabelFromType<std::decay_t<T>>().data(), container.bindingKey.key.c_str());
}
if (container.isMissing()) {
missingPreslice(getLabelFromType<std::decay_t<T>>().data(), container.bindingKey.key.c_str());
}
auto out = container.getSliceFor(value, table->asArrowTableRef());
auto t = typename T::self_t({out});
Expand Down Expand Up @@ -1568,10 +1564,8 @@ template <typename T, typename C, typename Policy, bool OPT>
requires std::same_as<Policy, framework::PreslicePolicyGeneral> && (o2::soa::is_binding_compatible_v<C, T>())
auto doSliceBy(T const* table, o2::framework::PresliceBase<C, Policy, OPT> const& container, int value)
{
if constexpr (OPT) {
if (container.isMissing()) {
missingOptionalPreslice(getLabelFromType<std::decay_t<T>>().data(), container.bindingKey.key.c_str());
}
if (container.isMissing()) {
missingPreslice(getLabelFromType<std::decay_t<T>>().data(), container.bindingKey.key.c_str());
}
auto selection = container.getSliceFor(value);
return doSliceByHelper(table, selection);
Expand Down Expand Up @@ -1601,10 +1595,8 @@ template <soa::is_filtered_table T, typename C, bool OPT>
requires(o2::soa::is_binding_compatible_v<C, T>())
auto doFilteredSliceBy(T const* table, o2::framework::PresliceBase<C, framework::PreslicePolicySorted, OPT> const& container, int value)
{
if constexpr (OPT) {
if (container.isMissing()) {
missingOptionalPreslice(getLabelFromType<T>().data(), container.bindingKey.key.c_str());
}
if (container.isMissing()) {
missingPreslice(getLabelFromType<T>().data(), container.bindingKey.key.c_str());
}
auto slice = container.getSliceFor(value, table->asArrowTableRef());
return prepareFilteredSlice(table, slice);
Expand Down
24 changes: 8 additions & 16 deletions Framework/Core/include/Framework/AnalysisManagers.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,10 +638,8 @@ template <is_preslice T>
requires std::same_as<typename T::policy_t, framework::PreslicePolicySorted>
bool registerCache(T& preslice, Cache& bsks, Cache&)
{
if constexpr (T::optional) {
if (preslice.binding == "[MISSING]") {
return true;
}
if (preslice.isMissing()) {
return true;
}
auto locate = std::find(bsks.begin(), bsks.end(), preslice.getBindingKey());
if (locate == bsks.end()) {
Expand All @@ -656,10 +654,8 @@ template <is_preslice T>
requires std::same_as<typename T::policy_t, framework::PreslicePolicyGeneral>
bool registerCache(T& preslice, Cache&, Cache& bsksU)
{
if constexpr (T::optional) {
if (preslice.binding == "[MISSING]") {
return true;
}
if (preslice.isMissing()) {
return true;
}
auto locate = std::find(bsksU.begin(), bsksU.end(), preslice.getBindingKey());
if (locate == bsksU.end()) {
Expand Down Expand Up @@ -688,10 +684,8 @@ template <is_preslice T>
static bool updateSliceInfo(T& preslice, ArrowTableSlicingCache& cache)
requires std::same_as<typename T::policy_t, framework::PreslicePolicySorted>
{
if constexpr (T::optional) {
if (preslice.binding == "[MISSING]") {
return true;
}
if (preslice.isMissing()) {
return true;
}
preslice.updateSliceInfo(cache.getCacheFor(preslice.getBindingKey()));
return true;
Expand All @@ -701,10 +695,8 @@ template <is_preslice T>
static bool updateSliceInfo(T& preslice, ArrowTableSlicingCache& cache)
requires std::same_as<typename T::policy_t, framework::PreslicePolicyGeneral>
{
if constexpr (T::optional) {
if (preslice.binding == "[MISSING]") {
return true;
}
if (preslice.isMissing()) {
return true;
}
preslice.updateSliceInfo(cache.getCacheUnsortedFor(preslice.getBindingKey()));
return true;
Expand Down
6 changes: 3 additions & 3 deletions Framework/Core/src/ASoA.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,9 @@ void notFoundColumn(const char* label, const char* key)
throw o2::framework::runtime_error_f(R"(Preslice not valid: table "%s" (or join based on it) does not have column "%s")", label, key);
}

void missingOptionalPreslice(const char* label, const char* key)
void missingPreslice(const char* label, const char* key)
{
throw o2::framework::runtime_error_f(R"(Optional Preslice with missing binding used: table "%s" (or join based on it) does not have column "%s")", label, key);
throw o2::framework::runtime_error_f(R"(Preslice with missing binding used: table "%s" (or join based on it) does not have column "%s")", label, key);
}

void* extractCCDBPayload(char* payload, size_t size, TClass const* cl, const char* what)
Expand Down Expand Up @@ -327,7 +327,7 @@ std::string strToUpper(std::string&& str)

bool PreslicePolicyBase::isMissing() const
{
return binding == "[MISSING]";
return bindingKey.binding == "[MISSING]";
}

Entry const& PreslicePolicyBase::getBindingKey() const
Expand Down