Skip to main content

GenericExecutor

Struct GenericExecutor 

Source
pub struct GenericExecutor<'a, 'b, Factory0, Factory1> {
    pub arg_types: &'a [SedonaType],
    pub args: &'b [ColumnarValue],
    /* private fields */
}
Expand description

Helper for writing general kernel implementations with geometry

The GenericExecutor wraps a set of arguments and their types and provides helpers to make writing general compute functions less verbose. Broadly, kernel implementations must consider multiple input data types (e.g., Wkb/WkbView or Float32/Float64) and multiple combinations of Array or ScalarValue inputs. This executor is generic on a GeometryFactory to support iterating over geometries from multiple libraries; however, the most commonly used version is the WkbExecutor.

The pattern supported by the GenericExecutor is:

  • Create a GenericExecutor with new()
  • Create an Arrow builder of the appropriate output type using with_capacity(executor.num_iterations()
  • Use execute_wkb() with a lambda whose contents appends to the builder
  • Use finish() to build the output ColumnarValue.

When all arguments are scalars, execute_wkb() will perform one iteration and finish() will return a ColumnarValue::Scalar. Otherwise, the output will be a ColumnarValue::Array built from num_iterations() iterations. This is true even if a geometry scalar is passed with a non-geometry argument. Non-geometry arrays are typically cheaper to cast to a concrete type (e.g., cast a numeric to float64 or an integer to int64) and cheaper to access by element or iterator compared to most geometry operations that require them.

The GenericExecutor is not built to be completely general and UDF implementers are free to use other mechanisms to implement UDFs with geometry arguments. The balance between optimizing iteration speed, minimizing dispatch overhead, and maximizing readability of kernel implementations is difficult to achieve and future utilities may provide alternatives optimized for a different balance than was chosen here.

This executor accepts two factories (supporting kernels accepting 0, 1, or 2 geometry arguments), which can also support implementations that wish to “prepare” one side or the other (e.g., for binary predicates).

A critical optimization is iterating over two arguments where one argument is a scalar. In this case, GeometryFactory::try_from_wkb is called exactly once on the scalar side (e.g., whatever parsing needs to occur for the scalar only occurs once).

Fields§

§arg_types: &'a [SedonaType]§args: &'b [ColumnarValue]

Implementations§

Source§

impl<'a, 'b, Factory0: GeometryFactory, Factory1: GeometryFactory> GenericExecutor<'a, 'b, Factory0, Factory1>

Source

pub fn new(arg_types: &'a [SedonaType], args: &'b [ColumnarValue]) -> Self

Create a new GenericExecutor

Source

pub fn num_iterations(&self) -> usize

Return the number of iterations that will be performed execute_*() methods

If all arguments are ColumnarValue::Scalars, this will be one iteration. Otherwise, it will be the length of the first array.

Source

pub fn execute_wkb_void<F: FnMut(Option<Factory0::Geom<'b>>) -> Result<()>>( &self, func: F, ) -> Result<()>

Execute a function by iterating over Wkb scalars in the first argument

Provides a mechanism to iterate over a geometry array by converting each to a Wkb scalar. For SedonaType::Wkb and SedonaType::WkbView arrays, this is the conversion that would normally happen. For other future supported geometry array types, this may incur a cast of item-wise conversion overhead.

Source

pub fn execute_wkb_wkb_void<F: FnMut(Option<&Factory0::Geom<'b>>, Option<&Factory1::Geom<'b>>) -> Result<()>>( &self, func: F, ) -> Result<()>

Execute a binary geometry function by iterating over Wkb scalars in the first two arguments

Provides a mechanism to iterate over two geometry arrays as pairs of Wkb scalars. SedonaType::Wkb and SedonaType::WkbView arrays are iterated over in place; however, future supported geometry array types may incur conversion overhead.

Source

pub fn finish(&self, out: ArrayRef) -> Result<ColumnarValue>

Finish an ArrayRef output as the appropriate ColumnarValue

Converts the output of finish()ing an Arrow builder into a ColumnarValue::Scalar if all arguments were scalars, or a ColumnarValue::Array otherwise.

Auto Trait Implementations§

§

impl<'a, 'b, Factory0, Factory1> Freeze for GenericExecutor<'a, 'b, Factory0, Factory1>
where Factory0: Freeze, Factory1: Freeze,

§

impl<'a, 'b, Factory0, Factory1> !RefUnwindSafe for GenericExecutor<'a, 'b, Factory0, Factory1>

§

impl<'a, 'b, Factory0, Factory1> Send for GenericExecutor<'a, 'b, Factory0, Factory1>
where Factory0: Send, Factory1: Send,

§

impl<'a, 'b, Factory0, Factory1> Sync for GenericExecutor<'a, 'b, Factory0, Factory1>
where Factory0: Sync, Factory1: Sync,

§

impl<'a, 'b, Factory0, Factory1> Unpin for GenericExecutor<'a, 'b, Factory0, Factory1>
where Factory0: Unpin, Factory1: Unpin,

§

impl<'a, 'b, Factory0, Factory1> UnsafeUnpin for GenericExecutor<'a, 'b, Factory0, Factory1>
where Factory0: UnsafeUnpin, Factory1: UnsafeUnpin,

§

impl<'a, 'b, Factory0, Factory1> !UnwindSafe for GenericExecutor<'a, 'b, Factory0, Factory1>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V