Skip to main content

vortex_fastlanes/delta/vtable/
operations.rs

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