vortex_array/arrays/slice/
vtable.rs1use std::fmt::Debug;
5use std::fmt::Formatter;
6use std::hash::Hash;
7use std::hash::Hasher;
8use std::ops::Range;
9use std::sync::Arc;
10
11use vortex_error::VortexExpect;
12use vortex_error::VortexResult;
13use vortex_error::vortex_bail;
14use vortex_error::vortex_ensure;
15use vortex_error::vortex_panic;
16use vortex_session::VortexSession;
17
18use crate::AnyCanonical;
19use crate::ArrayEq;
20use crate::ArrayHash;
21use crate::ArrayRef;
22use crate::Canonical;
23use crate::DynArray;
24use crate::Precision;
25use crate::arrays::slice::array::SliceArray;
26use crate::arrays::slice::rules::PARENT_RULES;
27use crate::buffer::BufferHandle;
28use crate::dtype::DType;
29use crate::executor::ExecutionCtx;
30use crate::executor::ExecutionResult;
31use crate::scalar::Scalar;
32use crate::serde::ArrayChildren;
33use crate::stats::StatsSetRef;
34use crate::validity::Validity;
35use crate::vtable;
36use crate::vtable::Array;
37use crate::vtable::ArrayId;
38use crate::vtable::OperationsVTable;
39use crate::vtable::VTable;
40use crate::vtable::ValidityVTable;
41
42vtable!(Slice);
43
44#[derive(Clone, Debug)]
45pub struct Slice;
46
47impl Slice {
48 pub const ID: ArrayId = ArrayId::new_ref("vortex.slice");
49}
50
51impl VTable for Slice {
52 type Array = SliceArray;
53 type Metadata = SliceMetadata;
54 type OperationsVTable = Self;
55 type ValidityVTable = Self;
56 fn vtable(_array: &Self::Array) -> &Self {
57 &Slice
58 }
59
60 fn id(&self) -> ArrayId {
61 Slice::ID
62 }
63
64 fn len(array: &SliceArray) -> usize {
65 array.range.len()
66 }
67
68 fn dtype(array: &SliceArray) -> &DType {
69 array.child.dtype()
70 }
71
72 fn stats(array: &SliceArray) -> StatsSetRef<'_> {
73 array.stats.to_ref(array.as_ref())
74 }
75
76 fn array_hash<H: Hasher>(array: &SliceArray, state: &mut H, precision: Precision) {
77 array.child.array_hash(state, precision);
78 array.range.start.hash(state);
79 array.range.end.hash(state);
80 }
81
82 fn array_eq(array: &SliceArray, other: &SliceArray, precision: Precision) -> bool {
83 array.child.array_eq(&other.child, precision) && array.range == other.range
84 }
85
86 fn nbuffers(_array: &Self::Array) -> usize {
87 0
88 }
89
90 fn buffer(_array: &Self::Array, _idx: usize) -> BufferHandle {
91 vortex_panic!("SliceArray has no buffers")
92 }
93
94 fn buffer_name(_array: &Self::Array, _idx: usize) -> Option<String> {
95 None
96 }
97
98 fn nchildren(_array: &Self::Array) -> usize {
99 1
100 }
101
102 fn child(array: &Self::Array, idx: usize) -> ArrayRef {
103 match idx {
104 0 => array.child.clone(),
105 _ => vortex_panic!("SliceArray child index {idx} out of bounds"),
106 }
107 }
108
109 fn child_name(_array: &Self::Array, idx: usize) -> String {
110 match idx {
111 0 => "child".to_string(),
112 _ => vortex_panic!("SliceArray child_name index {idx} out of bounds"),
113 }
114 }
115
116 fn metadata(array: &Self::Array) -> VortexResult<Self::Metadata> {
117 Ok(SliceMetadata(array.range.clone()))
118 }
119
120 fn serialize(_metadata: Self::Metadata) -> VortexResult<Option<Vec<u8>>> {
121 vortex_bail!("Slice array is not serializable")
123 }
124
125 fn deserialize(
126 _bytes: &[u8],
127 _dtype: &DType,
128 _len: usize,
129 _buffers: &[BufferHandle],
130 _session: &VortexSession,
131 ) -> VortexResult<Self::Metadata> {
132 vortex_bail!("Slice array is not serializable")
133 }
134
135 fn build(
136 dtype: &DType,
137 len: usize,
138 metadata: &SliceMetadata,
139 _buffers: &[BufferHandle],
140 children: &dyn ArrayChildren,
141 ) -> VortexResult<Self::Array> {
142 assert_eq!(len, metadata.0.len());
143 let child = children.get(0, dtype, metadata.0.end)?;
144 Ok(SliceArray {
145 child,
146 range: metadata.0.clone(),
147 stats: Default::default(),
148 })
149 }
150
151 fn with_children(array: &mut Self::Array, children: Vec<ArrayRef>) -> VortexResult<()> {
152 vortex_ensure!(
153 children.len() == 1,
154 "SliceArray expects exactly 1 child, got {}",
155 children.len()
156 );
157 array.child = children
158 .into_iter()
159 .next()
160 .vortex_expect("children length already validated");
161 Ok(())
162 }
163
164 fn execute(array: Arc<Array<Self>>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
165 let Some(canonical) = array.child.as_opt::<AnyCanonical>() else {
167 return array
169 .child
170 .clone()
171 .execute::<ArrayRef>(ctx)?
172 .slice(array.slice_range().clone())
173 .map(ExecutionResult::done);
174 };
175
176 Canonical::from(canonical)
178 .as_ref()
179 .slice(array.range.clone())
180 .map(ExecutionResult::done)
181 }
182
183 fn reduce_parent(
184 array: &Array<Self>,
185 parent: &ArrayRef,
186 child_idx: usize,
187 ) -> VortexResult<Option<ArrayRef>> {
188 PARENT_RULES.evaluate(array, parent, child_idx)
189 }
190}
191impl OperationsVTable<Slice> for Slice {
192 fn scalar_at(
193 array: &SliceArray,
194 index: usize,
195 _ctx: &mut ExecutionCtx,
196 ) -> VortexResult<Scalar> {
197 array.child.scalar_at(array.range.start + index)
198 }
199}
200
201impl ValidityVTable<Slice> for Slice {
202 fn validity(array: &SliceArray) -> VortexResult<Validity> {
203 array.child.validity()?.slice(array.range.clone())
204 }
205}
206
207pub struct SliceMetadata(pub(super) Range<usize>);
208
209impl Debug for SliceMetadata {
210 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
211 write!(f, "{}..{}", self.0.start, self.0.end)
212 }
213}
214
215#[cfg(test)]
216mod tests {
217 use vortex_error::VortexResult;
218
219 use crate::DynArray;
220 use crate::IntoArray;
221 use crate::arrays::PrimitiveArray;
222 use crate::arrays::SliceArray;
223 use crate::assert_arrays_eq;
224
225 #[test]
226 fn test_slice_slice() -> VortexResult<()> {
227 let arr = PrimitiveArray::from_iter(0i32..10).into_array();
229 let inner_slice = SliceArray::new(arr, 2..8).into_array();
230 let slice = inner_slice.slice(1..4)?;
231
232 assert_arrays_eq!(slice, PrimitiveArray::from_iter([3i32, 4, 5]));
233
234 Ok(())
235 }
236}