vortex_fastlanes/delta/vtable/
operations.rs1use vortex_array::ArrayView;
5use vortex_array::ExecutionCtx;
6use vortex_array::IntoArray;
7use vortex_array::arrays::PrimitiveArray;
8use vortex_array::scalar::Scalar;
9use vortex_array::vtable::OperationsVTable;
10use vortex_error::VortexResult;
11
12use super::Delta;
13impl OperationsVTable<Delta> for Delta {
14 fn scalar_at(
15 array: ArrayView<'_, Delta>,
16 index: usize,
17 ctx: &mut ExecutionCtx,
18 ) -> VortexResult<Scalar> {
19 let decompressed = array
20 .array()
21 .slice(index..index + 1)?
22 .execute::<PrimitiveArray>(ctx)?;
23 decompressed.into_array().execute_scalar(0, ctx)
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use std::sync::LazyLock;
30
31 use rstest::rstest;
32 use vortex_array::IntoArray;
33 use vortex_array::VortexSessionExecute;
34 use vortex_array::array_session;
35 use vortex_array::arrays::PrimitiveArray;
36 use vortex_array::assert_arrays_eq;
37 use vortex_array::compute::conformance::binary_numeric::test_binary_numeric_array;
38 use vortex_array::compute::conformance::consistency::test_array_consistency;
39 use vortex_array::validity::Validity;
40 use vortex_buffer::buffer;
41 use vortex_error::VortexExpect;
42 use vortex_session::VortexSession;
43
44 use crate::Delta;
45 use crate::DeltaArray;
46
47 static SESSION: LazyLock<VortexSession> = LazyLock::new(|| {
48 let session = array_session();
49 crate::initialize(&session);
50 session
51 });
52
53 fn da(array: &PrimitiveArray) -> DeltaArray {
54 Delta::try_from_primitive_array(array, &mut SESSION.create_execution_ctx())
55 .vortex_expect("Delta array construction should succeed")
56 }
57
58 #[test]
59 fn test_slice_non_jagged_array_first_chunk_of_two() {
60 let delta = da(&(0u32..2048).collect());
61
62 let actual = delta.slice(10..250).unwrap();
63 let expected = PrimitiveArray::from_iter(10u32..250).into_array();
64 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
65 }
66
67 #[test]
68 fn test_slice_non_jagged_array_second_chunk_of_two() {
69 let delta = da(&(0u32..2048).collect());
70
71 let actual = delta.slice(1024 + 10..1024 + 250).unwrap();
72 let expected = PrimitiveArray::from_iter((1024 + 10u32)..(1024 + 250)).into_array();
73 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
74 }
75
76 #[test]
77 fn test_slice_non_jagged_array_span_two_chunks_chunk_of_two() {
78 let delta = da(&(0u32..2048).collect());
79
80 let actual = delta.slice(1000..1048).unwrap();
81 let expected = PrimitiveArray::from_iter(1000u32..1048).into_array();
82 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
83 }
84
85 #[test]
86 fn test_slice_non_jagged_array_span_two_chunks_chunk_of_four() {
87 let delta = da(&(0u32..4096).collect());
88
89 let actual = delta.slice(2040..2050).unwrap();
90 let expected = PrimitiveArray::from_iter(2040u32..2050).into_array();
91 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
92 }
93
94 #[test]
95 fn test_slice_non_jagged_array_whole() {
96 let delta = da(&(0u32..4096).collect());
97
98 let actual = delta.slice(0..4096).unwrap();
99 let expected = PrimitiveArray::from_iter(0u32..4096).into_array();
100 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
101 }
102
103 #[test]
104 fn test_slice_non_jagged_array_empty() {
105 let delta = da(&(0u32..4096).collect());
106
107 let actual = delta.slice(0..0).unwrap();
108 let expected = PrimitiveArray::from_iter(Vec::<u32>::new()).into_array();
109 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
110
111 let actual = delta.slice(4096..4096).unwrap();
112 let expected = PrimitiveArray::from_iter(Vec::<u32>::new()).into_array();
113 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
114
115 let actual = delta.slice(1024..1024).unwrap();
116 let expected = PrimitiveArray::from_iter(Vec::<u32>::new()).into_array();
117 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
118 }
119
120 #[test]
121 fn test_slice_jagged_array_second_chunk_of_two() {
122 let delta = da(&(0u32..2000).collect());
123
124 let actual = delta.slice(1024 + 10..1024 + 250).unwrap();
125 let expected = PrimitiveArray::from_iter((1024 + 10u32)..(1024 + 250)).into_array();
126 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
127 }
128
129 #[test]
130 fn test_slice_jagged_array_empty() {
131 let delta = da(&(0u32..4000).collect());
132
133 let actual = delta.slice(0..0).unwrap();
134 let expected = PrimitiveArray::from_iter(Vec::<u32>::new()).into_array();
135 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
136
137 let actual = delta.slice(4000..4000).unwrap();
138 let expected = PrimitiveArray::from_iter(Vec::<u32>::new()).into_array();
139 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
140
141 let actual = delta.slice(1024..1024).unwrap();
142 let expected = PrimitiveArray::from_iter(Vec::<u32>::new()).into_array();
143 assert_arrays_eq!(actual, expected, &mut SESSION.create_execution_ctx());
144 }
145
146 #[test]
147 fn test_slice_of_slice_of_non_jagged() {
148 let delta = da(&(0u32..2048).collect());
149
150 let sliced = delta.slice(10..1013).unwrap();
151 let sliced_again = sliced.slice(0..2).unwrap();
152
153 let expected = PrimitiveArray::from_iter(vec![10u32, 11]).into_array();
154 assert_arrays_eq!(sliced_again, expected, &mut SESSION.create_execution_ctx());
155 }
156
157 #[test]
158 fn test_slice_of_slice_of_jagged() {
159 let delta = da(&(0u32..2000).collect());
160
161 let sliced = delta.slice(10..1013).unwrap();
162 let sliced_again = sliced.slice(0..2).unwrap();
163
164 let expected = PrimitiveArray::from_iter(vec![10u32, 11]).into_array();
165 assert_arrays_eq!(sliced_again, expected, &mut SESSION.create_execution_ctx());
166 }
167
168 #[test]
169 fn test_slice_of_slice_second_chunk_of_non_jagged() {
170 let delta = da(&(0u32..2048).collect());
171
172 let sliced = delta.slice(1034..1050).unwrap();
173 let sliced_again = sliced.slice(0..2).unwrap();
174
175 let expected = PrimitiveArray::from_iter(vec![1034u32, 1035]).into_array();
176 assert_arrays_eq!(sliced_again, expected, &mut SESSION.create_execution_ctx());
177 }
178
179 #[test]
180 fn test_slice_of_slice_second_chunk_of_jagged() {
181 let delta = da(&(0u32..2000).collect());
182
183 let sliced = delta.slice(1034..1050).unwrap();
184 let sliced_again = sliced.slice(0..2).unwrap();
185
186 let expected = PrimitiveArray::from_iter(vec![1034u32, 1035]).into_array();
187 assert_arrays_eq!(sliced_again, expected, &mut SESSION.create_execution_ctx());
188 }
189
190 #[test]
191 fn test_slice_of_slice_spanning_two_chunks_of_non_jagged() {
192 let delta = da(&(0u32..2048).collect());
193
194 let sliced = delta.slice(1010..1050).unwrap();
195 let sliced_again = sliced.slice(5..20).unwrap();
196
197 let expected = PrimitiveArray::from_iter(1015u32..1030).into_array();
198 assert_arrays_eq!(sliced_again, expected, &mut SESSION.create_execution_ctx());
199 }
200
201 #[test]
202 fn test_slice_of_slice_spanning_two_chunks_of_jagged() {
203 let delta = da(&(0u32..2000).collect());
204
205 let sliced = delta.slice(1010..1050).unwrap();
206 let sliced_again = sliced.slice(5..20).unwrap();
207
208 let expected = PrimitiveArray::from_iter(1015u32..1030).into_array();
209 assert_arrays_eq!(sliced_again, expected, &mut SESSION.create_execution_ctx());
210 }
211
212 #[test]
213 fn test_scalar_at_non_jagged_array() {
214 let delta = da(&(0u32..2048).collect()).into_array();
215
216 let expected = PrimitiveArray::from_iter(0u32..2048).into_array();
217 assert_arrays_eq!(delta, expected, &mut SESSION.create_execution_ctx());
218 }
219
220 #[test]
221 #[should_panic]
222 fn test_scalar_at_non_jagged_array_oob() {
223 let delta = da(&(0u32..2048).collect()).into_array();
224 delta
225 .execute_scalar(2048, &mut SESSION.create_execution_ctx())
226 .unwrap();
227 }
228 #[test]
229 fn test_scalar_at_jagged_array() {
230 let delta = da(&(0u32..2000).collect()).into_array();
231
232 let expected = PrimitiveArray::from_iter(0u32..2000).into_array();
233 assert_arrays_eq!(delta, expected, &mut SESSION.create_execution_ctx());
234 }
235
236 #[test]
237 #[should_panic]
238 fn test_scalar_at_jagged_array_oob() {
239 let delta = da(&(0u32..2000).collect()).into_array();
240 delta
241 .execute_scalar(2000, &mut SESSION.create_execution_ctx())
242 .unwrap();
243 }
244
245 #[rstest]
246 #[case::delta_u32((0u32..100).collect())]
248 #[case::delta_u64((0..100).map(|i| i as u64 * 10).collect())]
249 #[case::delta_large_u32((0u32..2048).collect())]
251 #[case::delta_large_u64((0u64..2048).collect())]
252 #[case::delta_single(PrimitiveArray::new(buffer![42u32], Validity::NonNullable))]
254 #[case::delta_i32_crossing_zero((-100i32..100).collect())]
256 #[case::delta_i64_negative((0i64..100).map(|i| -i * 10).collect())]
257 #[case::delta_large_i32((-1024i32..1024).collect())]
258 #[case::delta_single_negative(PrimitiveArray::new(buffer![-42i32], Validity::NonNullable))]
259 fn test_delta_consistency(#[case] array: PrimitiveArray) {
260 test_array_consistency(
261 &da(&array).into_array(),
262 &mut SESSION.create_execution_ctx(),
263 );
264 }
265
266 #[rstest]
267 #[case::delta_u8_basic(PrimitiveArray::new(buffer![1u8, 1, 1, 1, 1], Validity::NonNullable))]
268 #[case::delta_u16_basic(PrimitiveArray::new(buffer![1u16, 1, 1, 1, 1], Validity::NonNullable))]
269 #[case::delta_u32_basic(PrimitiveArray::new(buffer![1u32, 1, 1, 1, 1], Validity::NonNullable))]
270 #[case::delta_u64_basic(PrimitiveArray::new(buffer![1u64, 1, 1, 1, 1], Validity::NonNullable))]
271 #[case::delta_u32_large(PrimitiveArray::new(buffer![1u32; 100], Validity::NonNullable))]
272 #[case::delta_i8_basic(PrimitiveArray::new(buffer![-1i8, -1, -1, -1, -1], Validity::NonNullable))]
273 #[case::delta_i32_basic(PrimitiveArray::new(buffer![-1i32, -1, -1, -1, -1], Validity::NonNullable))]
274 fn test_delta_binary_numeric(#[case] array: PrimitiveArray) {
275 test_binary_numeric_array(
276 &da(&array).into_array(),
277 &mut SESSION.create_execution_ctx(),
278 );
279 }
280}