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