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