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>
impl<'a, 'b, Factory0: GeometryFactory, Factory1: GeometryFactory> GenericExecutor<'a, 'b, Factory0, Factory1>
Sourcepub fn new(arg_types: &'a [SedonaType], args: &'b [ColumnarValue]) -> Self
pub fn new(arg_types: &'a [SedonaType], args: &'b [ColumnarValue]) -> Self
Create a new GenericExecutor
Sourcepub fn num_iterations(&self) -> usize
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.
Sourcepub fn execute_wkb_void<F: FnMut(Option<Factory0::Geom<'b>>) -> Result<()>>(
&self,
func: F,
) -> Result<()>
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.
Sourcepub fn execute_wkb_wkb_void<F: FnMut(Option<&Factory0::Geom<'b>>, Option<&Factory1::Geom<'b>>) -> Result<()>>(
&self,
func: F,
) -> Result<()>
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.
Sourcepub fn finish(&self, out: ArrayRef) -> Result<ColumnarValue>
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>
impl<'a, 'b, Factory0, Factory1> !RefUnwindSafe for GenericExecutor<'a, 'b, Factory0, Factory1>
impl<'a, 'b, Factory0, Factory1> Send for GenericExecutor<'a, 'b, Factory0, Factory1>
impl<'a, 'b, Factory0, Factory1> Sync for GenericExecutor<'a, 'b, Factory0, Factory1>
impl<'a, 'b, Factory0, Factory1> Unpin for GenericExecutor<'a, 'b, Factory0, Factory1>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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