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