diff --git a/vortex-row/public-api.lock b/vortex-row/public-api.lock index ed231a1e556..a7221cd91ee 100644 --- a/vortex-row/public-api.lock +++ b/vortex-row/public-api.lock @@ -146,6 +146,18 @@ pub trait vortex_row::encode::RowEncodeKernel: vortex_array::array::vtable::VTab pub fn vortex_row::encode::RowEncodeKernel::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> +impl vortex_row::encode::RowEncodeKernel for vortex_array::arrays::constant::vtable::Constant + +pub fn vortex_array::arrays::constant::vtable::Constant::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::encode::RowEncodeKernel for vortex_array::arrays::dict::vtable::Dict + +pub fn vortex_array::arrays::dict::vtable::Dict::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::encode::RowEncodeKernel for vortex_array::arrays::patched::vtable::Patched + +pub fn vortex_array::arrays::patched::vtable::Patched::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + pub fn vortex_row::encode::dispatch_encode(&vortex_array::array::erased::ArrayRef, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult<()> pub mod vortex_row::options @@ -266,6 +278,18 @@ pub trait vortex_row::size::RowSizeKernel: vortex_array::array::vtable::VTable pub fn vortex_row::size::RowSizeKernel::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> +impl vortex_row::size::RowSizeKernel for vortex_array::arrays::constant::vtable::Constant + +pub fn vortex_array::arrays::constant::vtable::Constant::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::size::RowSizeKernel for vortex_array::arrays::dict::vtable::Dict + +pub fn vortex_array::arrays::dict::vtable::Dict::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::size::RowSizeKernel for vortex_array::arrays::patched::vtable::Patched + +pub fn vortex_array::arrays::patched::vtable::Patched::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + pub fn vortex_row::size::dispatch_size(&vortex_array::array::erased::ArrayRef, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult<()> pub struct vortex_row::RowEncode @@ -412,10 +436,34 @@ pub trait vortex_row::RowEncodeKernel: vortex_array::array::vtable::VTable pub fn vortex_row::RowEncodeKernel::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> +impl vortex_row::encode::RowEncodeKernel for vortex_array::arrays::constant::vtable::Constant + +pub fn vortex_array::arrays::constant::vtable::Constant::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::encode::RowEncodeKernel for vortex_array::arrays::dict::vtable::Dict + +pub fn vortex_array::arrays::dict::vtable::Dict::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::encode::RowEncodeKernel for vortex_array::arrays::patched::vtable::Patched + +pub fn vortex_array::arrays::patched::vtable::Patched::row_encode_into(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &[u32], &mut [u32], &mut [u8], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + pub trait vortex_row::RowSizeKernel: vortex_array::array::vtable::VTable pub fn vortex_row::RowSizeKernel::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> +impl vortex_row::size::RowSizeKernel for vortex_array::arrays::constant::vtable::Constant + +pub fn vortex_array::arrays::constant::vtable::Constant::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::size::RowSizeKernel for vortex_array::arrays::dict::vtable::Dict + +pub fn vortex_array::arrays::dict::vtable::Dict::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + +impl vortex_row::size::RowSizeKernel for vortex_array::arrays::patched::vtable::Patched + +pub fn vortex_array::arrays::patched::vtable::Patched::row_size_contribution(vortex_array::array::view::ArrayView<'_, Self>, vortex_row::options::SortField, &mut [u32], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult> + pub fn vortex_row::compute_row_sizes(&[vortex_array::array::erased::ArrayRef], &[vortex_row::options::SortField], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult pub fn vortex_row::convert_columns(&[vortex_array::array::erased::ArrayRef], &[vortex_row::options::SortField], &mut vortex_array::executor::ExecutionCtx) -> vortex_error::VortexResult diff --git a/vortex-row/src/encode.rs b/vortex-row/src/encode.rs index 1ca24ec378c..7510b78bc9f 100644 --- a/vortex-row/src/encode.rs +++ b/vortex-row/src/encode.rs @@ -25,6 +25,8 @@ use vortex_array::arrays::Constant; use vortex_array::arrays::ListViewArray; use vortex_array::arrays::Primitive; use vortex_array::arrays::PrimitiveArray; +use vortex_array::arrays::dict::Dict; +use vortex_array::arrays::patched::Patched; use vortex_array::dtype::DType; use vortex_array::dtype::Nullability; use vortex_array::dtype::PType; @@ -462,9 +464,9 @@ fn encode_constant_arith( /// Dispatch a single column's encoding into the shared `out` buffer. /// -/// For PR 1 this is just the canonicalize-then-`codec::field_encode` fallback path. -/// In-crate fast paths for `Constant`/`Dict`/`Patched` and the inventory-based registry -/// for downstream encodings are added in PR 3. +/// Tries the in-crate per-encoding fast paths first, then falls back to canonicalization. +/// Per-encoding kernels currently return `Ok(None)` (stubs added alongside the trait); the +/// real impls land in follow-up commits. The downstream-encoding registry is added next. pub fn dispatch_encode( col: &ArrayRef, field: SortField, @@ -473,6 +475,21 @@ pub fn dispatch_encode( out: &mut [u8], ctx: &mut ExecutionCtx, ) -> VortexResult<()> { + if let Some(view) = col.as_opt::() + && Constant::row_encode_into(view, field, offsets, cursors, out, ctx)?.is_some() + { + return Ok(()); + } + if let Some(view) = col.as_opt::() + && Dict::row_encode_into(view, field, offsets, cursors, out, ctx)?.is_some() + { + return Ok(()); + } + if let Some(view) = col.as_opt::() + && Patched::row_encode_into(view, field, offsets, cursors, out, ctx)?.is_some() + { + return Ok(()); + } let canonical = col.clone().execute::(ctx)?; codec::field_encode(&canonical, field, offsets, cursors, out, ctx) } diff --git a/vortex-row/src/kernels/constant.rs b/vortex-row/src/kernels/constant.rs new file mode 100644 index 00000000000..51d54fbf123 --- /dev/null +++ b/vortex-row/src/kernels/constant.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +//! Row-encode kernels for `ConstantArray`. +//! +//! Stubs in this commit return `Ok(None)` so the dispatch loop falls back to +//! canonicalization. The real impls land in a follow-up commit. + +use vortex_array::ArrayView; +use vortex_array::ExecutionCtx; +use vortex_array::arrays::Constant; +use vortex_error::VortexResult; + +use crate::encode::RowEncodeKernel; +use crate::options::SortField; +use crate::size::RowSizeKernel; + +impl RowSizeKernel for Constant { + fn row_size_contribution( + _column: ArrayView<'_, Self>, + _field: SortField, + _sizes: &mut [u32], + _ctx: &mut ExecutionCtx, + ) -> VortexResult> { + Ok(None) + } +} + +impl RowEncodeKernel for Constant { + fn row_encode_into( + _column: ArrayView<'_, Self>, + _field: SortField, + _offsets: &[u32], + _cursors: &mut [u32], + _out: &mut [u8], + _ctx: &mut ExecutionCtx, + ) -> VortexResult> { + Ok(None) + } +} diff --git a/vortex-row/src/kernels/dict.rs b/vortex-row/src/kernels/dict.rs new file mode 100644 index 00000000000..0f576f3372a --- /dev/null +++ b/vortex-row/src/kernels/dict.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +//! Row-encode kernels for `DictArray`. +//! +//! Stubs in this commit return `Ok(None)` so the dispatch loop falls back to +//! canonicalization. The real impls land in a follow-up commit. + +use vortex_array::ArrayView; +use vortex_array::ExecutionCtx; +use vortex_array::arrays::dict::Dict; +use vortex_error::VortexResult; + +use crate::encode::RowEncodeKernel; +use crate::options::SortField; +use crate::size::RowSizeKernel; + +impl RowSizeKernel for Dict { + fn row_size_contribution( + _column: ArrayView<'_, Self>, + _field: SortField, + _sizes: &mut [u32], + _ctx: &mut ExecutionCtx, + ) -> VortexResult> { + Ok(None) + } +} + +impl RowEncodeKernel for Dict { + fn row_encode_into( + _column: ArrayView<'_, Self>, + _field: SortField, + _offsets: &[u32], + _cursors: &mut [u32], + _out: &mut [u8], + _ctx: &mut ExecutionCtx, + ) -> VortexResult> { + Ok(None) + } +} diff --git a/vortex-row/src/kernels/mod.rs b/vortex-row/src/kernels/mod.rs new file mode 100644 index 00000000000..492f619ef0d --- /dev/null +++ b/vortex-row/src/kernels/mod.rs @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +//! Per-encoding fast-path implementations of [`RowSizeKernel`] and [`RowEncodeKernel`] for +//! encodings defined in `vortex-array`. +//! +//! Each impl in this module lives here (rather than under the corresponding encoding's +//! `compute` module in `vortex-array`) so the orphan rule is satisfied: the trait is +//! defined in `vortex-row` and the impl is also in `vortex-row`, while the array type +//! (`Constant`, `Dict`, `Patched`) remains in `vortex-array`. +//! +//! [`RowSizeKernel`]: crate::size::RowSizeKernel +//! [`RowEncodeKernel`]: crate::encode::RowEncodeKernel + +mod constant; +mod dict; +mod patched; diff --git a/vortex-row/src/kernels/patched.rs b/vortex-row/src/kernels/patched.rs new file mode 100644 index 00000000000..2637116afb4 --- /dev/null +++ b/vortex-row/src/kernels/patched.rs @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +//! Row-encode kernels for `Patched`. +//! +//! Stubs in this commit return `Ok(None)` so the dispatch loop falls back to +//! canonicalization. The real impls land in a follow-up commit. + +use vortex_array::ArrayView; +use vortex_array::ExecutionCtx; +use vortex_array::arrays::patched::Patched; +use vortex_error::VortexResult; + +use crate::encode::RowEncodeKernel; +use crate::options::SortField; +use crate::size::RowSizeKernel; + +impl RowSizeKernel for Patched { + fn row_size_contribution( + _column: ArrayView<'_, Self>, + _field: SortField, + _sizes: &mut [u32], + _ctx: &mut ExecutionCtx, + ) -> VortexResult> { + Ok(None) + } +} + +impl RowEncodeKernel for Patched { + fn row_encode_into( + _column: ArrayView<'_, Self>, + _field: SortField, + _offsets: &[u32], + _cursors: &mut [u32], + _out: &mut [u8], + _ctx: &mut ExecutionCtx, + ) -> VortexResult> { + Ok(None) + } +} diff --git a/vortex-row/src/lib.rs b/vortex-row/src/lib.rs index fddcca665c1..2896ae05acf 100644 --- a/vortex-row/src/lib.rs +++ b/vortex-row/src/lib.rs @@ -28,6 +28,7 @@ pub mod codec; pub mod convert; pub mod encode; +mod kernels; pub mod options; pub mod size; diff --git a/vortex-row/src/size.rs b/vortex-row/src/size.rs index bfe5f647dc5..8fb1bdbcf08 100644 --- a/vortex-row/src/size.rs +++ b/vortex-row/src/size.rs @@ -11,9 +11,12 @@ use vortex_array::Canonical; use vortex_array::ExecutionCtx; use vortex_array::IntoArray; use vortex_array::VTable; +use vortex_array::arrays::Constant; use vortex_array::arrays::ConstantArray; use vortex_array::arrays::PrimitiveArray; use vortex_array::arrays::StructArray; +use vortex_array::arrays::dict::Dict; +use vortex_array::arrays::patched::Patched; use vortex_array::dtype::DType; use vortex_array::dtype::FieldName; use vortex_array::dtype::FieldNames; @@ -256,15 +259,30 @@ impl ScalarFnVTable for RowSize { /// Dispatch a single column's per-row size contribution. /// -/// For PR 1 this is just the canonicalize-then-`codec::field_size` fallback path. In-crate -/// fast paths for `Constant`/`Dict`/`Patched` and the inventory-based registry for -/// downstream encodings are added in PR 3. +/// Tries the in-crate per-encoding fast paths first, then falls back to canonicalization. +/// Per-encoding kernels currently return `Ok(None)` (stubs added alongside the trait); the +/// real impls land in follow-up commits. The downstream-encoding registry is added next. pub fn dispatch_size( col: &ArrayRef, field: SortField, sizes: &mut [u32], ctx: &mut ExecutionCtx, ) -> VortexResult<()> { + if let Some(view) = col.as_opt::() + && Constant::row_size_contribution(view, field, sizes, ctx)?.is_some() + { + return Ok(()); + } + if let Some(view) = col.as_opt::() + && Dict::row_size_contribution(view, field, sizes, ctx)?.is_some() + { + return Ok(()); + } + if let Some(view) = col.as_opt::() + && Patched::row_size_contribution(view, field, sizes, ctx)?.is_some() + { + return Ok(()); + } let canonical = col.clone().execute::(ctx)?; codec::field_size(&canonical, field, sizes, ctx) }