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;
16use vortex_session::registry::CachedId;
17
18use crate::AnyCanonical;
19use crate::ArrayEq;
20use crate::ArrayHash;
21use crate::ArrayParts;
22use crate::ArrayRef;
23use crate::EqMode;
24use crate::array::Array;
25use crate::array::ArrayId;
26use crate::array::ArrayView;
27use crate::array::OperationsVTable;
28use crate::array::VTable;
29use crate::array::ValidityVTable;
30use crate::array::with_empty_buffers;
31use crate::arrays::slice::SliceArrayExt;
32use crate::arrays::slice::array::CHILD_SLOT;
33use crate::arrays::slice::array::SLOT_NAMES;
34use crate::arrays::slice::array::SliceData;
35use crate::arrays::slice::rules::PARENT_RULES;
36use crate::buffer::BufferHandle;
37use crate::dtype::DType;
38use crate::executor::ExecutionCtx;
39use crate::executor::ExecutionResult;
40use crate::require_child;
41use crate::scalar::Scalar;
42use crate::serde::ArrayChildren;
43use crate::validity::Validity;
44
45pub type SliceArray = Array<Slice>;
47
48#[derive(Clone, Debug)]
49pub struct Slice;
50
51impl ArrayHash for SliceData {
52 fn array_hash<H: Hasher>(&self, state: &mut H, _accuracy: EqMode) {
53 self.range.start.hash(state);
54 self.range.end.hash(state);
55 }
56}
57
58impl ArrayEq for SliceData {
59 fn array_eq(&self, other: &Self, _accuracy: EqMode) -> bool {
60 self.range == other.range
61 }
62}
63
64impl VTable for Slice {
65 type TypedArrayData = SliceData;
66 type OperationsVTable = Self;
67 type ValidityVTable = Self;
68 fn id(&self) -> ArrayId {
69 static ID: CachedId = CachedId::new("vortex.slice");
70 *ID
71 }
72
73 fn validate(
74 &self,
75 data: &Self::TypedArrayData,
76 dtype: &DType,
77 len: usize,
78 slots: &[Option<ArrayRef>],
79 ) -> VortexResult<()> {
80 vortex_ensure!(
81 slots[CHILD_SLOT].is_some(),
82 "SliceArray child slot must be present"
83 );
84 let child = slots[CHILD_SLOT]
85 .as_ref()
86 .vortex_expect("validated child slot");
87 vortex_ensure!(
88 child.dtype() == dtype,
89 "SliceArray dtype {} does not match outer dtype {}",
90 child.dtype(),
91 dtype
92 );
93 vortex_ensure!(
94 data.len() == len,
95 "SliceArray length {} does not match outer length {}",
96 data.len(),
97 len
98 );
99 vortex_ensure!(
100 data.range.end <= child.len(),
101 "SliceArray range {:?} exceeds child length {}",
102 data.range,
103 child.len()
104 );
105 Ok(())
106 }
107
108 fn nbuffers(_array: ArrayView<'_, Self>) -> usize {
109 0
110 }
111
112 fn buffer(_array: ArrayView<'_, Self>, _idx: usize) -> BufferHandle {
113 vortex_panic!("SliceArray has no buffers")
114 }
115
116 fn buffer_name(_array: ArrayView<'_, Self>, _idx: usize) -> Option<String> {
117 None
118 }
119
120 fn with_buffers(
121 &self,
122 array: ArrayView<'_, Self>,
123 buffers: &[BufferHandle],
124 ) -> VortexResult<ArrayParts<Self>> {
125 with_empty_buffers(self, array, buffers)
126 }
127
128 fn slot_name(_array: ArrayView<'_, Self>, idx: usize) -> String {
129 SLOT_NAMES[idx].to_string()
130 }
131
132 fn serialize(
133 _array: ArrayView<'_, Self>,
134 _session: &VortexSession,
135 ) -> VortexResult<Option<Vec<u8>>> {
136 vortex_bail!("Slice array is not serializable")
138 }
139
140 fn deserialize(
141 &self,
142 _dtype: &DType,
143 _len: usize,
144 _metadata: &[u8],
145
146 _buffers: &[BufferHandle],
147 _children: &dyn ArrayChildren,
148 _session: &VortexSession,
149 ) -> VortexResult<ArrayParts<Self>> {
150 vortex_bail!("Slice array is not serializable")
151 }
152
153 fn execute(array: Array<Self>, _ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
154 let array = require_child!(array, array.child(), CHILD_SLOT => AnyCanonical);
155
156 debug_assert!(array.child().is_canonical());
157 array
159 .child()
160 .slice(array.range.clone())
161 .map(ExecutionResult::done)
162 }
163
164 fn reduce_parent(
165 array: ArrayView<'_, Self>,
166 parent: &ArrayRef,
167 child_idx: usize,
168 ) -> VortexResult<Option<ArrayRef>> {
169 PARENT_RULES.evaluate(array, parent, child_idx)
170 }
171}
172impl OperationsVTable<Slice> for Slice {
173 fn scalar_at(
174 array: ArrayView<'_, Slice>,
175 index: usize,
176 ctx: &mut ExecutionCtx,
177 ) -> VortexResult<Scalar> {
178 array.child().execute_scalar(array.range.start + index, ctx)
179 }
180}
181
182impl ValidityVTable<Slice> for Slice {
183 fn validity(array: ArrayView<'_, Slice>) -> VortexResult<Validity> {
184 array.child().validity()?.slice(array.range.clone())
185 }
186}
187
188pub struct SliceMetadata(pub(super) Range<usize>);
189
190impl Debug for SliceMetadata {
191 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
192 write!(f, "{}..{}", self.0.start, self.0.end)
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use vortex_error::VortexResult;
199
200 use crate::IntoArray;
201 use crate::VortexSessionExecute;
202 use crate::array_session;
203 use crate::arrays::PrimitiveArray;
204 use crate::arrays::SliceArray;
205 use crate::assert_arrays_eq;
206
207 #[test]
208 fn test_slice_slice() -> VortexResult<()> {
209 let mut ctx = array_session().create_execution_ctx();
210 let arr = PrimitiveArray::from_iter(0i32..10).into_array();
212 let inner_slice = SliceArray::new(arr, 2..8).into_array();
213 let slice = inner_slice.slice(1..4)?;
214
215 assert_arrays_eq!(slice, PrimitiveArray::from_iter([3i32, 4, 5]), &mut ctx);
216
217 Ok(())
218 }
219}