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