Skip to main content

RowVisitor

Trait RowVisitor 

Source
pub trait RowVisitor<Options>: Sealed + Sized {
    type VisitResult;

    // Required methods
    fn visit_prepared<Args, Out, Prepared>(
        self,
        prepare: impl FnOnce(Args::ConstElems<'_>) -> Prepared,
        apply: impl Fn(&Prepared, Args::Elems<'_>) -> Out,
    ) -> VortexResult<Self::VisitResult>
       where Args: IndexedElementTuple,
             Out: OutputElement;
    fn visit_prepared_into<Args, Sink, Prepared, ApplyResult>(
        self,
        prepare: impl FnOnce(Args::ConstElems<'_>) -> Prepared,
        apply: impl Fn(&Prepared, Args::Elems<'_>, <Sink as OutputSink<Options>>::Row<'_>) -> ApplyResult,
    ) -> VortexResult<Self::VisitResult>
       where Args: ElementTuple,
             Sink: OutputSink<Options>,
             ApplyResult: SinkResult<WriteToken = <Sink as OutputSink<Options>>::WriteToken>;
    fn visit_prepared_deferred<Args, Out, Prepared, Fail>(
        self,
        prepare: impl FnOnce(Args::ConstElems<'_>) -> Prepared,
        apply: impl Fn(&Prepared, Args::Elems<'_>) -> (Out, Fail),
        finish_failure: impl FnOnce(Fail) -> VortexResult<()>,
    ) -> VortexResult<Self::VisitResult>
       where Args: IndexedElementTuple,
             Out: OutputElement,
             Fail: FailureEvidence;

    // Provided methods
    fn visit<Args, Out>(
        self,
        apply: impl Fn(Args::Elems<'_>) -> Out,
    ) -> VortexResult<Self::VisitResult>
       where Args: IndexedElementTuple,
             Out: OutputElement { ... }
    fn visit_into<Args, Sink, ApplyResult>(
        self,
        apply: impl Fn(Args::Elems<'_>, <Sink as OutputSink<Options>>::Row<'_>) -> ApplyResult,
    ) -> VortexResult<Self::VisitResult>
       where Args: ElementTuple,
             Sink: OutputSink<Options>,
             ApplyResult: SinkResult<WriteToken = <Sink as OutputSink<Options>>::WriteToken> { ... }
    fn visit_deferred<Args, Out, Fail>(
        self,
        apply: impl Fn(Args::Elems<'_>) -> (Out, Fail),
        finish_failure: impl FnOnce(Fail) -> VortexResult<()>,
    ) -> VortexResult<Self::VisitResult>
       where Args: IndexedElementTuple,
             Out: OutputElement,
             Fail: FailureEvidence { ... }
}
Expand description

A planning or execution visit at concrete input and output types.

Only the framework implements this trait. The visit_prepared* methods derive shared state from constant arguments before visiting any rows. Every visit verifies that the argument tuple matches RowFn::ARG_NAMES and that fallible decoding agrees with RowFn::INFALLIBLE.

Required Associated Types§

Source

type VisitResult

The framework result of visiting one concrete row signature.

This is a batch plan or execution result, not a per-row output.

Required Methods§

Source

fn visit_prepared<Args, Out, Prepared>( self, prepare: impl FnOnce(Args::ConstElems<'_>) -> Prepared, apply: impl Fn(&Prepared, Args::Elems<'_>) -> Out, ) -> VortexResult<Self::VisitResult>

The prepared form of visit, with the same prerequisites.

§Examples

Test whether each string occurs in its allowed-values list. The prepare closure builds one lookup table for a batch-constant list. The row closure scans the current list from the input column directly.

visitor.visit_prepared::<
    (StringRow, StringListRow),
    bool,
    Option<PreparedAllowedValues>,
>(
    |(_value, allowed_values)| allowed_values.map(PreparedAllowedValues::new),
    |prepared_allowed_values, (value, allowed_values)| {
        match prepared_allowed_values {
            Some(allowed_values) => allowed_values.contains(value),
            None => allowed_values.iter().any(|allowed| allowed == value),
        }
    },
)
Source

fn visit_prepared_into<Args, Sink, Prepared, ApplyResult>( self, prepare: impl FnOnce(Args::ConstElems<'_>) -> Prepared, apply: impl Fn(&Prepared, Args::Elems<'_>, <Sink as OutputSink<Options>>::Row<'_>) -> ApplyResult, ) -> VortexResult<Self::VisitResult>
where Args: ElementTuple, Sink: OutputSink<Options>, ApplyResult: SinkResult<WriteToken = <Sink as OutputSink<Options>>::WriteToken>,

The prepared form of visit_into, with the same prerequisites.

§Examples

Compute the cosine similarity of each vector pair: their dot product divided by their magnitudes. The prepare closure computes each batch-constant vector’s magnitude once.

visitor.visit_prepared_into::<
    (TensorRow<T>, TensorRow<T>),
    UninitElementSink<T>,
    ConstVectorMagnitudes<T>,
    InitializedElement,
>(
    |(lhs, rhs)| ConstVectorMagnitudes {
        lhs: lhs.map(vector_magnitude),
        rhs: rhs.map(vector_magnitude),
    },
    |const_magnitudes, (lhs, rhs), output| {
        let similarity =
            cosine_similarity_with_const_magnitudes(const_magnitudes, lhs, rhs);

        // SAFETY: `output` is the `UninitElementSink` row supplied for this callback.
        unsafe { InitializedElement::write(output, similarity) }
    },
)
Source

fn visit_prepared_deferred<Args, Out, Prepared, Fail>( self, prepare: impl FnOnce(Args::ConstElems<'_>) -> Prepared, apply: impl Fn(&Prepared, Args::Elems<'_>) -> (Out, Fail), finish_failure: impl FnOnce(Fail) -> VortexResult<()>, ) -> VortexResult<Self::VisitResult>

The prepared form of visit_deferred, with the same prerequisites.

§Examples

Rescale each unscaled decimal by multiplying it by 10^scale. The prepare closure computes the multiplier once for a batch-constant scale. Each row returns the rescaled value and an overflow flag, which the executor reduces after the loop.

#[cold]
#[inline(never)]
fn decimal_rescaling_overflow() -> VortexError {
    vortex_err!(InvalidArgument: "decimal rescaling overflowed")
}

visitor.visit_prepared_deferred::<
    (i64, DecimalScale),
    i64,
    Option<PreparedDecimalScale>,
    bool,
>(
    |(_value, scale)| scale.map(PreparedDecimalScale::new),
    |prepared_scale, (value, scale)| match prepared_scale {
        Some(scale) => scale.apply_checked(value),
        None => PreparedDecimalScale::new(scale).apply_checked(value),
    },
    |overflowed| {
        if overflowed {
            return Err(decimal_rescaling_overflow());
        }

        Ok(())
    },
)

Provided Methods§

Source

fn visit<Args, Out>( self, apply: impl Fn(Args::Elems<'_>) -> Out, ) -> VortexResult<Self::VisitResult>

Visit an infallible row computation that returns one output value per row.

apply must not panic or have side effects. Dense execution can pass unspecified values from null rows.

The framework verifies that Out does not require drop glue.

§Examples

Apply infallible wrapping arithmetic.

visitor.visit::<(i64, i64), i64>(|(lhs, rhs)| lhs.wrapping_add(rhs))

Dispatch an equality helper over its primitive element type.

fn visit_equal<T, Options, V>(visitor: V) -> VortexResult<V::VisitResult>
where
    T: NativePType,
    V: RowVisitor<Options>,
{
    visitor.visit::<(T, T), bool>(|(lhs, rhs)| lhs.is_eq(rhs))
}
Source

fn visit_into<Args, Sink, ApplyResult>( self, apply: impl Fn(Args::Elems<'_>, <Sink as OutputSink<Options>>::Row<'_>) -> ApplyResult, ) -> VortexResult<Self::VisitResult>
where Args: ElementTuple, Sink: OutputSink<Options>, ApplyResult: SinkResult<WriteToken = <Sink as OutputSink<Options>>::WriteToken>,

Visit a row computation that writes through a row handle from an output sink.

apply must not panic or have side effects except for writes to the supplied row handle. Dense execution can pass unspecified values from null rows.

On success, apply must return the write token for the supplied row handle. A token from another row, sink, or local cell can violate the safety contract of OutputSink::finish.

A fallible ApplyResult requires RowFn::INFALLIBLE to be false.

§Examples

Checked integer division reports errors immediately and writes successful rows into uninitialized output. The cold, non-inlined helper keeps error construction out of the row callback.

#[cold]
#[inline(never)]
fn integer_division_error() -> VortexError {
    vortex_err!(InvalidArgument: "integer division by zero or overflow")
}

visitor.visit_into::<(i64, i64), UninitElementSink<i64>, _>(
    |(lhs, rhs), output| {
        let Some(value) = lhs.checked_div(rhs) else {
            return Err(integer_division_error());
        };

        // SAFETY: `output` is the `UninitElementSink` row supplied for this callback.
        Ok(unsafe { InitializedElement::write(output, value) })
    },
)
Source

fn visit_deferred<Args, Out, Fail>( self, apply: impl Fn(Args::Elems<'_>) -> (Out, Fail), finish_failure: impl FnOnce(Fail) -> VortexResult<()>, ) -> VortexResult<Self::VisitResult>

Visit a row computation that returns an owned output value and deferred failure evidence.

apply must not panic or have side effects. Dense execution can pass unspecified values from null rows.

The executor OR-reduces FailureEvidence across rows and passes the result to finish_failure.

RowFn::INFALLIBLE must be false. Out must not require drop glue. Fail must be no wider than Out, or failure tracking reduces the vector width. The framework checks these requirements.

§Examples

Checked addition returns a wrapping value and compact overflow flag without branching. The executor reduces the flags after the loop. The cold, non-inlined helper keeps error construction out of the row loop.

#[cold]
#[inline(never)]
fn integer_addition_error() -> VortexError {
    vortex_err!(InvalidArgument: "integer overflow in checked add")
}

visitor.visit_deferred::<(i64, i64), i64, bool>(
    // `overflowing_add` returns `(i64, bool)`.
    |(lhs, rhs)| lhs.overflowing_add(rhs),
    |overflowed| {
        if overflowed {
            return Err(integer_addition_error());
        }

        Ok(())
    },
)

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§