1use vortex_array::ArrayRef;
5use vortex_array::ArrayView;
6use vortex_array::ExecutionCtx;
7use vortex_array::scalar::PValue;
8use vortex_array::scalar::Scalar;
9use vortex_array::search_sorted::SearchResult;
10use vortex_array::search_sorted::SearchSorted;
11use vortex_array::search_sorted::SearchSortedSide;
12use vortex_array::vtable::OperationsVTable;
13use vortex_error::VortexResult;
14
15use crate::RunEnd;
16use crate::array::RunEndArrayExt;
17
18impl OperationsVTable<RunEnd> for RunEnd {
19 fn scalar_at(
20 array: ArrayView<'_, RunEnd>,
21 index: usize,
22 ctx: &mut ExecutionCtx,
23 ) -> VortexResult<Scalar> {
24 array
25 .values()
26 .execute_scalar(array.find_physical_index(index)?, ctx)
27 }
28}
29
30pub(crate) fn find_slice_end_index(array: &ArrayRef, index: usize) -> VortexResult<usize> {
35 let result = array
36 .as_primitive_typed()
37 .search_sorted(&PValue::from(index), SearchSortedSide::Right)?;
38 Ok(match result {
39 SearchResult::Found(i) => i,
40 SearchResult::NotFound(i) => {
41 if i == array.len() {
42 i
43 } else {
44 i + 1
45 }
46 }
47 })
48}
49
50#[cfg(test)]
51mod tests {
52
53 use vortex_array::IntoArray;
54 use vortex_array::LEGACY_SESSION;
55 use vortex_array::VortexSessionExecute;
56 use vortex_array::aggregate_fn::fns::is_constant::is_constant;
57 use vortex_array::arrays::PrimitiveArray;
58 use vortex_array::assert_arrays_eq;
59 use vortex_array::dtype::DType;
60 use vortex_array::dtype::Nullability;
61 use vortex_array::dtype::PType;
62 use vortex_buffer::buffer;
63
64 use crate::RunEnd;
65
66 #[test]
67 fn slice_array() {
68 let mut ctx = LEGACY_SESSION.create_execution_ctx();
69 let arr = RunEnd::try_new(
70 buffer![2u32, 5, 10].into_array(),
71 buffer![1i32, 2, 3].into_array(),
72 &mut ctx,
73 )
74 .unwrap()
75 .slice(3..8)
76 .unwrap();
77 assert_eq!(
78 arr.dtype(),
79 &DType::Primitive(PType::I32, Nullability::NonNullable)
80 );
81 assert_eq!(arr.len(), 5);
82
83 let expected = PrimitiveArray::from_iter(vec![2i32, 2, 3, 3, 3]).into_array();
84 assert_arrays_eq!(arr, expected);
85 }
86
87 #[test]
88 fn double_slice() {
89 let mut ctx = LEGACY_SESSION.create_execution_ctx();
90 let arr = RunEnd::try_new(
91 buffer![2u32, 5, 10].into_array(),
92 buffer![1i32, 2, 3].into_array(),
93 &mut ctx,
94 )
95 .unwrap()
96 .slice(3..8)
97 .unwrap();
98 assert_eq!(arr.len(), 5);
99
100 let doubly_sliced = arr.slice(0..3).unwrap();
101
102 let expected = PrimitiveArray::from_iter(vec![2i32, 2, 3]).into_array();
103 assert_arrays_eq!(doubly_sliced, expected);
104 }
105
106 #[test]
107 fn slice_end_inclusive() {
108 let mut ctx = LEGACY_SESSION.create_execution_ctx();
109 let arr = RunEnd::try_new(
110 buffer![2u32, 5, 10].into_array(),
111 buffer![1i32, 2, 3].into_array(),
112 &mut ctx,
113 )
114 .unwrap()
115 .slice(4..10)
116 .unwrap();
117 assert_eq!(
118 arr.dtype(),
119 &DType::Primitive(PType::I32, Nullability::NonNullable)
120 );
121 assert_eq!(arr.len(), 6);
122
123 let expected = PrimitiveArray::from_iter(vec![2i32, 3, 3, 3, 3, 3]).into_array();
124 assert_arrays_eq!(arr, expected);
125 }
126
127 #[test]
128 fn slice_at_end() {
129 let mut ctx = LEGACY_SESSION.create_execution_ctx();
130 let re_array = RunEnd::try_new(
131 buffer![7_u64, 10].into_array(),
132 buffer![2_u64, 3].into_array(),
133 &mut ctx,
134 )
135 .unwrap();
136
137 assert_eq!(re_array.len(), 10);
138
139 let sliced_array = re_array.slice(re_array.len()..re_array.len()).unwrap();
140 assert!(sliced_array.is_empty());
141 }
142
143 #[test]
144 fn slice_single_end() {
145 let mut ctx = LEGACY_SESSION.create_execution_ctx();
146 let re_array = RunEnd::try_new(
147 buffer![7_u64, 10].into_array(),
148 buffer![2_u64, 3].into_array(),
149 &mut ctx,
150 )
151 .unwrap();
152
153 assert_eq!(re_array.len(), 10);
154
155 let sliced_array = re_array.slice(2..5).unwrap();
156
157 assert!(is_constant(&sliced_array, &mut ctx).unwrap())
158 }
159
160 #[test]
161 fn ree_scalar_at_end() {
162 let mut ctx = LEGACY_SESSION.create_execution_ctx();
163 let scalar = RunEnd::encode(
164 buffer![1, 1, 1, 4, 4, 4, 2, 2, 5, 5, 5, 5].into_array(),
165 &mut ctx,
166 )
167 .unwrap()
168 .execute_scalar(11, &mut ctx)
169 .unwrap();
170 assert_eq!(scalar, 5.into());
171 }
172
173 #[test]
174 fn slice_along_run_boundaries() {
175 let mut ctx = LEGACY_SESSION.create_execution_ctx();
176 let arr = RunEnd::try_new(
179 buffer![3u32, 6, 8, 12].into_array(),
180 buffer![1i32, 4, 2, 5].into_array(),
181 &mut ctx,
182 )
183 .unwrap();
184
185 let slice1 = arr.slice(0..3).unwrap();
187 assert_eq!(slice1.len(), 3);
188 let expected = PrimitiveArray::from_iter(vec![1i32, 1, 1]).into_array();
189 assert_arrays_eq!(slice1, expected);
190
191 let slice2 = arr.slice(3..6).unwrap();
193 assert_eq!(slice2.len(), 3);
194 let expected = PrimitiveArray::from_iter(vec![4i32, 4, 4]).into_array();
195 assert_arrays_eq!(slice2, expected);
196
197 let slice3 = arr.slice(6..8).unwrap();
199 assert_eq!(slice3.len(), 2);
200 let expected = PrimitiveArray::from_iter(vec![2i32, 2]).into_array();
201 assert_arrays_eq!(slice3, expected);
202
203 let slice4 = arr.slice(8..12).unwrap();
205 assert_eq!(slice4.len(), 4);
206 let expected = PrimitiveArray::from_iter(vec![5i32, 5, 5, 5]).into_array();
207 assert_arrays_eq!(slice4, expected);
208
209 let slice5 = arr.slice(3..8).unwrap();
211 assert_eq!(slice5.len(), 5);
212 let expected = PrimitiveArray::from_iter(vec![4i32, 4, 4, 2, 2]).into_array();
213 assert_arrays_eq!(slice5, expected);
214
215 let slice6 = arr.slice(1..6).unwrap();
217 assert_eq!(slice6.len(), 5);
218 let expected = PrimitiveArray::from_iter(vec![1i32, 1, 4, 4, 4]).into_array();
219 assert_arrays_eq!(slice6, expected);
220
221 let slice7 = arr.slice(3..7).unwrap();
223 assert_eq!(slice7.len(), 4);
224 let expected = PrimitiveArray::from_iter(vec![4i32, 4, 4, 2]).into_array();
225 assert_arrays_eq!(slice7, expected);
226 }
227}