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