Skip to content

Commit f477c96

Browse files
committed
Phase 1b
Signed-off-by: Nicholas Gates <nick@nickgates.com>
1 parent 2bf0f3c commit f477c96

5 files changed

Lines changed: 44 additions & 22 deletions

File tree

vortex-array/src/array/mod.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -632,13 +632,16 @@ impl<V: VTable> DynArray for Array<V> {
632632
fn with_children(&self, children: Vec<ArrayRef>) -> VortexResult<ArrayRef> {
633633
let mut inner = self.array.clone();
634634
V::with_children(&mut inner, children)?;
635-
Ok(Array::new(
636-
self.typed_vtable().clone(),
637-
self.dtype.clone(),
638-
self.len,
639-
inner,
640-
self.stats.clone(),
641-
)
635+
// SAFETY: with_children preserves dtype and len.
636+
Ok(unsafe {
637+
Array::new_unchecked(
638+
self.typed_vtable().clone(),
639+
self.dtype.clone(),
640+
self.len,
641+
inner,
642+
self.stats.clone(),
643+
)
644+
}
642645
.into_array())
643646
}
644647
}

vortex-array/src/vtable/dyn_.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,16 @@ impl<V: VTable> DynVTable for V {
101101
"Array dtype mismatch after building"
102102
);
103103
// Wrap in Array<V> for safe downcasting.
104-
let array = Array::new(
105-
self.clone(),
106-
dtype.clone(),
107-
len,
108-
inner,
109-
ArrayStats::default(),
110-
);
104+
// SAFETY: We just validated that V::len(&inner) == len and V::dtype(&inner) == dtype.
105+
let array = unsafe {
106+
Array::new_unchecked(
107+
self.clone(),
108+
dtype.clone(),
109+
len,
110+
inner,
111+
ArrayStats::default(),
112+
)
113+
};
111114
Ok(array.into_array())
112115
}
113116

vortex-array/src/vtable/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ pub fn patches_child_name(idx: usize) -> &'static str {
238238
/// vtable! macro — generates IntoArray, From, Deref, AsRef for inner array types.
239239
///
240240
/// During the migration, IntoArray creates [`Array<V>`] (the new typed wrapper) while
241-
/// Deref/AsRef go through [`ArrayAdapter`] for backward-compatible DynArray access.
241+
/// Deref/AsRef go through AlsoArrayAdapter for backward-compatible DynArray access.
242242
#[macro_export]
243243
macro_rules! vtable {
244244
($V:ident) => {
@@ -269,7 +269,10 @@ macro_rules! vtable {
269269
let dtype = $VT::dtype(&self).clone();
270270
let len = $VT::len(&self);
271271
let stats = $VT::stats(&self).to_array_stats();
272-
std::sync::Arc::new($crate::vtable::Array::new(vtable, dtype, len, self, stats))
272+
// SAFETY: dtype and len are extracted from `self` via VTable methods.
273+
std::sync::Arc::new(unsafe {
274+
$crate::vtable::Array::new_unchecked(vtable, dtype, len, self, stats)
275+
})
273276
}
274277
}
275278

vortex-array/src/vtable/typed.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,18 @@ pub struct Array<V: VTable> {
3434

3535
#[allow(clippy::same_name_method)]
3636
impl<V: VTable> Array<V> {
37-
/// Create a new typed array.
38-
pub fn new(vtable: V, dtype: DType, len: usize, array: V::Array, stats: ArrayStats) -> Self {
37+
/// Create a new typed array without validating that the inner array's dtype/len match.
38+
///
39+
/// # Safety
40+
///
41+
/// The caller must ensure that `V::dtype(&array) == &dtype` and `V::len(&array) == len`.
42+
pub unsafe fn new_unchecked(
43+
vtable: V,
44+
dtype: DType,
45+
len: usize,
46+
array: V::Array,
47+
stats: ArrayStats,
48+
) -> Self {
3949
Self {
4050
vtable,
4151
dtype,

vortex-python/src/arrays/native.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use vortex::array::arrays::Primitive;
2121
use vortex::array::arrays::Struct;
2222
use vortex::array::arrays::VarBin;
2323
use vortex::array::arrays::VarBinView;
24+
use vortex::array::vtable::Array;
2425
use vortex::array::vtable::VTable;
2526
use vortex::encodings::alp::ALP;
2627
use vortex::encodings::alp::ALPRD;
@@ -251,10 +252,12 @@ pub trait AsArrayRef<T> {
251252

252253
impl<V: EncodingSubclass> AsArrayRef<<V::VTable as VTable>::Array> for PyRef<'_, V> {
253254
fn as_array_ref(&self) -> &<V::VTable as VTable>::Array {
254-
self.as_super()
255-
.inner()
256-
.as_any()
257-
.downcast_ref::<ArrayAdapter<V::VTable>>()
255+
let any = self.as_super().inner().as_any();
256+
// Try new Array<V> path first, then fall back to legacy ArrayAdapter<V>.
257+
if let Some(typed) = any.downcast_ref::<Array<V::VTable>>() {
258+
return typed.inner();
259+
}
260+
any.downcast_ref::<ArrayAdapter<V::VTable>>()
258261
.vortex_expect("Failed to downcast array")
259262
.as_inner()
260263
}

0 commit comments

Comments
 (0)