Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ Watch for these accessors inside `for i in 0..n { ... }`:

| Per-element accessor | Hidden cost | Bulk replacement |
| --- | --- | --- |
| `Validity::is_valid(i)` / `is_null(i)` | Array-backed validity allocates an `ExecutionCtx` and runs a scalar lookup per call. | Call `validity.execute_mask(len, ctx)?` once, then read the materialized mask. |
| `array.scalar_at(i)` / `array.execute_scalar(i, ctx)` | Executes through the compute stack per element. | Canonicalize once with `execute::<PrimitiveArray>` or `as_slice`, then index. |
| `Validity::execute_is_valid(i, ctx)` / `execute_is_null(i, ctx)` | Array-backed validity runs a scalar lookup per call. | Call `validity.execute_mask(len, ctx)?` once, then read the materialized mask. |
| `array.execute_scalar(i, ctx)` | Executes through the compute stack per element. | Canonicalize once with `execute::<PrimitiveArray>` or `as_slice`, then index. |
| `BitBuffer::value(i)` / `Mask::value(i)` accumulated into a count | Recomputes the byte address and defeats popcount. | Use `true_count()`, `BitBuffer::count_range(start, end)`, or `set_indices()`. |
| `BitIterator::next()` accumulated into a rank or prefix count | Processes one bit at a time. | Use `count_range` over each gap. |
| Re-deriving a value such as `self.validity()?` | Repeats the derivation for every element. | Hoist the derivation above the loop. |
Expand Down
10 changes: 0 additions & 10 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,4 @@ disallowed-methods = [
{ path = "std::thread::available_parallelism", reason = "This function might do an unbounded amount of work, use `vortex_utils::parallelism::get_available_parallelism instead" },
{ path = "vortex_session::registry::Id::new", reason = "Interning a static id on every call grabs the interner lock (#8380). Use a `CachedId` static for static ids; for a dynamic string, annotate the call with `#[expect(clippy::disallowed_methods)]`.", allow-invalid = true },
{ path = "vortex_session::registry::Id::new_static", reason = "Interning a static id on every call grabs the interner lock; use a `CachedId` static instead (#8380).", allow-invalid = true },
{ path = "vortex_array::legacy_session", reason = "Relies on the hidden global session; thread an explicit `VortexSession`/`ExecutionCtx` through instead" },
{ path = "vortex_array::ToCanonical::to_null", reason = "This function doesn't take the context, use `array.execute::<NullArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_bool", reason = "This function doesn't take the context, use `array.execute::<BoolArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_primitive", reason = "This function doesn't take the context, use `array.execute::<PrimitiveArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_decimal", reason = "This function doesn't take the context, use `array.execute::<DecimalArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_struct", reason = "This function doesn't take the context, use `array.execute::<StructArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_listview", reason = "This function doesn't take the context, use `array.execute::<ListViewArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_fixed_size_list", reason = "This function doesn't take the context, use `array.execute::<FixedSizeListArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_varbinview", reason = "This function doesn't take the context, use `array.execute::<VarBinViewArray>(ctx)` instead", allow-invalid = true },
{ path = "vortex_array::ToCanonical::to_extension", reason = "This function doesn't take the context, use `array.execute::<ExtensionArray>(ctx)` instead", allow-invalid = true },
]
12 changes: 7 additions & 5 deletions docs/developer-guide/benchmarking.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ Return values are automatically black-boxed. You only need explicit
`black_box` for side-effect-free results inside manual loops:

```rust
bencher.with_inputs(|| &array).bench_refs(|array| {
for idx in 0..len {
divan::black_box(array.scalar_at(idx).unwrap());
}
});
bencher
.with_inputs(|| (&array, SESSION.create_execution_ctx()))
.bench_refs(|(array, ctx)| {
for idx in 0..len {
divan::black_box(array.execute_scalar(idx, ctx).unwrap());
}
});
```

### Use deterministic, seeded RNG
Expand Down
7 changes: 5 additions & 2 deletions encodings/fastlanes/src/delta/compute/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mod tests {
use std::sync::LazyLock;

use rstest::rstest;
use vortex_array::Canonical;
use vortex_array::IntoArray;
use vortex_array::VortexSessionExecute;
use vortex_array::arrays::PrimitiveArray;
Expand Down Expand Up @@ -173,11 +174,13 @@ mod tests {
let array = Delta::try_from_primitive_array(&values, &mut SESSION.create_execution_ctx())?;

// The cast is lazy; the nullability check fires when it is executed.
#[expect(deprecated)]
let result = array
.into_array()
.cast(DType::Primitive(PType::U32, Nullability::NonNullable))
.and_then(|a| a.to_canonical().map(|c| c.into_array()));
.and_then(|a| {
a.execute::<Canonical>(&mut SESSION.create_execution_ctx())
.map(|c| c.into_array())
});

assert!(
result.is_err(),
Expand Down
27 changes: 0 additions & 27 deletions vortex-array/src/array/erased.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use crate::ExecutionCtx;
use crate::ExecutionResult;
use crate::IntoArray;
use crate::VTable;
use crate::VortexSessionExecute;
use crate::aggregate_fn::fns::sum::sum;
use crate::array::ArrayData;
use crate::array::ArrayId;
Expand All @@ -48,7 +47,6 @@ use crate::dtype::DType;
use crate::expr::stats::Precision;
use crate::expr::stats::Stat;
use crate::expr::stats::StatsProviderExt;
use crate::legacy_session;
use crate::matcher::Matcher;
use crate::optimizer::ArrayOptimizer;
use crate::scalar::Scalar;
Expand Down Expand Up @@ -266,16 +264,6 @@ impl ArrayRef {
.optimize()
}

/// Fetch the scalar at the given index.
#[deprecated(
note = "Use `execute_scalar` instead, which allows passing an execution context for more \
efficient execution when fetching multiple scalars from the same array."
)]
#[allow(clippy::disallowed_methods)]
pub fn scalar_at(&self, index: usize) -> VortexResult<Scalar> {
self.execute_scalar(index, &mut legacy_session().create_execution_ctx())
}

/// Execute the array to extract a scalar at the given index.
///
/// A one-off read; the same as `self.probe().execute_scalar(index, ctx)`.
Expand Down Expand Up @@ -399,21 +387,6 @@ impl ArrayRef {
self.0.data.validity(self)
}

/// Returns the canonical representation of the array.
#[deprecated(note = "use `array.execute::<Canonical>(ctx)` instead")]
#[allow(clippy::disallowed_methods)]
pub fn into_canonical(self) -> VortexResult<Canonical> {
self.execute(&mut legacy_session().create_execution_ctx())
}

/// Returns the canonical representation of the array.
#[deprecated(note = "use `array.execute::<Canonical>(ctx)` instead")]
pub fn to_canonical(&self) -> VortexResult<Canonical> {
#[expect(deprecated)]
let result = self.clone().into_canonical();
result
}

/// Writes the array into the canonical builder.
pub fn append_to_builder(
&self,
Expand Down
19 changes: 0 additions & 19 deletions vortex-array/src/array/typed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ use crate::ArrayRef;
use crate::ArraySlots;
use crate::ExecutionCtx;
use crate::IntoArray;
use crate::VortexSessionExecute;
use crate::array::ArrayId;
use crate::array::ArrayView;
use crate::array::VTable;
use crate::dtype::DType;
use crate::legacy_session;
use crate::stats::ArrayStats;
use crate::stats::StatsSet;
use crate::stats::StatsSetRef;
Expand Down Expand Up @@ -413,16 +411,6 @@ impl<V: VTable> Array<V> {
self.inner.slice(range)
}

#[deprecated(
note = "Use `execute_scalar` instead, which allows passing an execution context for more \
efficient execution when fetching multiple scalars from the same array."
)]
#[allow(clippy::disallowed_methods)]
pub fn scalar_at(&self, index: usize) -> VortexResult<crate::scalar::Scalar> {
self.inner
.execute_scalar(index, &mut legacy_session().create_execution_ctx())
}

/// Execute the array to extract a scalar at the given index.
pub fn execute_scalar(
&self,
Expand Down Expand Up @@ -467,13 +455,6 @@ impl<V: VTable> Array<V> {
self.inner.all_invalid(ctx)
}

#[deprecated(note = "Use Array::<V>::execute::<Canonical>() instead")]
pub fn to_canonical(&self) -> VortexResult<crate::Canonical> {
#[expect(deprecated)]
let result = self.inner.to_canonical();
result
}

/// Returns the estimated physical bytes owned or referenced by this array tree.
pub fn nbytes(&self) -> u64 {
self.inner.nbytes()
Expand Down
19 changes: 13 additions & 6 deletions vortex-array/src/arrays/primitive/compute/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ mod test {
use vortex_mask::Mask;

use crate::ArrayRef;
use crate::Canonical;
use crate::IntoArray;
use crate::VortexSessionExecute;
use crate::array_session;
Expand Down Expand Up @@ -1081,10 +1082,12 @@ mod test {
#[test]
fn cast_i32_u32() {
let arr = buffer![-1i32].into_array();
#[expect(deprecated)]
let error = arr
.cast(PType::U32.into())
.and_then(|a| a.to_canonical().map(|c| c.into_array()))
.and_then(|a| {
a.execute::<Canonical>(&mut array_session().create_execution_ctx())
.map(|c| c.into_array())
})
.unwrap_err();
assert!(matches!(error, VortexError::Compute(..)));
assert!(error.to_string().contains("values exceed target range"));
Expand All @@ -1093,11 +1096,13 @@ mod test {
#[test]
fn cast_array_with_nulls_to_nonnullable() {
let arr = PrimitiveArray::from_option_iter([Some(-1i32), None, Some(10)]);
#[expect(deprecated)]
let err = arr
.into_array()
.cast(PType::I32.into())
.and_then(|a| a.to_canonical().map(|c| c.into_array()))
.and_then(|a| {
a.execute::<Canonical>(&mut array_session().create_execution_ctx())
.map(|c| c.into_array())
})
.unwrap_err();

assert!(matches!(err, VortexError::InvalidArgument(..)));
Expand Down Expand Up @@ -1157,10 +1162,12 @@ mod test {
#[test]
fn cast_same_width_int_out_of_range_errors() {
let arr = buffer![u32::MAX].into_array();
#[expect(deprecated)]
let err = arr
.cast(PType::I32.into())
.and_then(|a| a.to_canonical().map(|c| c.into_array()))
.and_then(|a| {
a.execute::<Canonical>(&mut array_session().create_execution_ctx())
.map(|c| c.into_array())
})
.unwrap_err();
assert!(matches!(err, VortexError::Compute(..)));
}
Expand Down
117 changes: 0 additions & 117 deletions vortex-array/src/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,123 +493,6 @@ impl IntoArray for Canonical {
}
}

/// Trait for types that can be converted from an owned type into an owned array variant.
///
/// # Canonicalization
///
/// This trait has a blanket implementation for all types implementing [ToCanonical].
#[deprecated(note = "use `array.execute::<T>(ctx)` instead")]
pub trait ToCanonical {
/// Canonicalize into a [`NullArray`] if the target is [`Null`](DType::Null) typed.
#[deprecated(note = "use `array.execute::<NullArray>(ctx)` instead")]
fn to_null(&self) -> NullArray;

/// Canonicalize into a [`BoolArray`] if the target is [`Bool`](DType::Bool) typed.
#[deprecated(note = "use `array.execute::<BoolArray>(ctx)` instead")]
fn to_bool(&self) -> BoolArray;

/// Canonicalize into a [`PrimitiveArray`] if the target is [`Primitive`](DType::Primitive)
/// typed.
#[deprecated(note = "use `array.execute::<PrimitiveArray>(ctx)` instead")]
fn to_primitive(&self) -> PrimitiveArray;

/// Canonicalize into a [`DecimalArray`] if the target is [`Decimal`](DType::Decimal)
/// typed.
#[deprecated(note = "use `array.execute::<DecimalArray>(ctx)` instead")]
fn to_decimal(&self) -> DecimalArray;

/// Canonicalize into a [`StructArray`] if the target is [`Struct`](DType::Struct) typed.
#[deprecated(note = "use `array.execute::<StructArray>(ctx)` instead")]
fn to_struct(&self) -> StructArray;

/// Canonicalize into a [`ListViewArray`] if the target is [`List`](DType::List) typed.
#[deprecated(note = "use `array.execute::<ListViewArray>(ctx)` instead")]
fn to_listview(&self) -> ListViewArray;

/// Canonicalize into a [`MapArray`] if the target is [`Map`](DType::Map) typed.
#[deprecated(note = "use `array.execute::<MapArray>(ctx)` instead")]
fn to_map(&self) -> MapArray;

/// Canonicalize into a [`FixedSizeListArray`] if the target is [`List`](DType::FixedSizeList)
/// typed.
#[deprecated(note = "use `array.execute::<FixedSizeListArray>(ctx)` instead")]
fn to_fixed_size_list(&self) -> FixedSizeListArray;

/// Canonicalize into a [`VarBinViewArray`] if the target is [`Utf8`](DType::Utf8)
/// or [`Binary`](DType::Binary) typed.
#[deprecated(note = "use `array.execute::<VarBinViewArray>(ctx)` instead")]
fn to_varbinview(&self) -> VarBinViewArray;

/// Canonicalize into an [`ExtensionArray`] if the array is [`Extension`](DType::Extension)
/// typed.
#[deprecated(note = "use `array.execute::<ExtensionArray>(ctx)` instead")]
fn to_extension(&self) -> ExtensionArray;
}

// Blanket impl for all Array encodings.
#[expect(deprecated)]
impl ToCanonical for ArrayRef {
fn to_null(&self) -> NullArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_null()
}

fn to_bool(&self) -> BoolArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_bool()
}

fn to_primitive(&self) -> PrimitiveArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_primitive()
}

fn to_decimal(&self) -> DecimalArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_decimal()
}

fn to_struct(&self) -> StructArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_struct()
}

fn to_listview(&self) -> ListViewArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_listview()
}

fn to_map(&self) -> MapArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_map()
}

fn to_fixed_size_list(&self) -> FixedSizeListArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_fixed_size_list()
}

fn to_varbinview(&self) -> VarBinViewArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_varbinview()
}

fn to_extension(&self) -> ExtensionArray {
#[expect(deprecated)]
let result = self.to_canonical().vortex_expect("to_canonical failed");
result.into_extension()
}
}

impl From<Canonical> for ArrayRef {
fn from(value: Canonical) -> Self {
match_each_canonical!(value, |arr| arr.into_array())
Expand Down
13 changes: 0 additions & 13 deletions vortex-array/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@

extern crate self as vortex_array;

use std::sync::LazyLock;

pub use array::*;
pub use canonical::*;
pub use columnar::*;
Expand Down Expand Up @@ -177,15 +175,4 @@ pub fn array_session() -> VortexSession {
.with::<MemorySession>()
}

// TODO(ngates): canonicalize doesn't currently take a session, therefore we cannot invoke execute
// from the new array encodings to support back-compat for legacy encodings. So we hold a session
// here...
/// Returns the hidden global [`VortexSession`] used as a back-compat shim for code paths that
/// cannot yet thread an explicit session through.
#[inline]
pub fn legacy_session() -> &'static VortexSession {
static LEGACY_SESSION: LazyLock<VortexSession> = LazyLock::new(array_session);
&LEGACY_SESSION
}

pub type ArrayContext = Interner;
4 changes: 2 additions & 2 deletions vortex-array/src/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ mod tests {
use super::NormalizeOptions;
use super::Operation;
use crate::ArrayRef;
use crate::Canonical;
use crate::IntoArray;
use crate::VortexSessionExecute;
use crate::array::VTable;
Expand Down Expand Up @@ -229,8 +230,7 @@ mod tests {
assert_eq!(normalized.len(), 3);

// Verify the data: codes [1,0,1] -> values [20, 10, 20]
#[expect(deprecated)]
let normalized_canonical = normalized.to_canonical()?;
let normalized_canonical = normalized.execute::<Canonical>(&mut ctx)?;
assert_arrays_eq!(
normalized_canonical,
PrimitiveArray::from_iter(vec![20i32, 10, 20]),
Expand Down
Loading
Loading