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