1use crate::{Array, TypedRunArray, array::ArrayAccessor, types::RunEndIndexType};
8use arrow_buffer::ArrowNativeType;
9
10#[derive(Debug)]
23pub struct RunArrayIter<'a, R, V>
24where
25 R: RunEndIndexType,
26 V: Sync + Send,
27 &'a V: ArrayAccessor,
28 <&'a V as ArrayAccessor>::Item: Default,
29{
30 array: TypedRunArray<'a, R, V>,
31 current_front_logical: usize,
32 current_front_physical: usize,
33 current_back_logical: usize,
34 current_back_physical: usize,
35}
36
37impl<'a, R, V> RunArrayIter<'a, R, V>
38where
39 R: RunEndIndexType,
40 V: Sync + Send,
41 &'a V: ArrayAccessor,
42 <&'a V as ArrayAccessor>::Item: Default,
43{
44 pub fn new(array: TypedRunArray<'a, R, V>) -> Self {
46 let current_front_physical = array.run_array().get_start_physical_index();
47 let current_back_physical = array.run_array().get_end_physical_index() + 1;
48 RunArrayIter {
49 array,
50 current_front_logical: array.offset(),
51 current_front_physical,
52 current_back_logical: array.offset() + array.len(),
53 current_back_physical,
54 }
55 }
56}
57
58impl<'a, R, V> Iterator for RunArrayIter<'a, R, V>
59where
60 R: RunEndIndexType,
61 V: Sync + Send,
62 &'a V: ArrayAccessor,
63 <&'a V as ArrayAccessor>::Item: Default,
64{
65 type Item = Option<<&'a V as ArrayAccessor>::Item>;
66
67 #[inline]
68 fn next(&mut self) -> Option<Self::Item> {
69 if self.current_front_logical == self.current_back_logical {
70 return None;
71 }
72
73 let run_ends = self.array.run_ends().values();
76 if self.current_front_logical >= run_ends[self.current_front_physical].as_usize() {
77 self.current_front_physical += 1;
81 }
82 if self.array.values().is_null(self.current_front_physical) {
83 self.current_front_logical += 1;
84 Some(None)
85 } else {
86 self.current_front_logical += 1;
87 unsafe {
92 Some(Some(
93 self.array
94 .values()
95 .value_unchecked(self.current_front_physical),
96 ))
97 }
98 }
99 }
100
101 fn size_hint(&self) -> (usize, Option<usize>) {
102 (
103 self.current_back_logical - self.current_front_logical,
104 Some(self.current_back_logical - self.current_front_logical),
105 )
106 }
107}
108
109impl<'a, R, V> DoubleEndedIterator for RunArrayIter<'a, R, V>
110where
111 R: RunEndIndexType,
112 V: Sync + Send,
113 &'a V: ArrayAccessor,
114 <&'a V as ArrayAccessor>::Item: Default,
115{
116 fn next_back(&mut self) -> Option<Self::Item> {
117 if self.current_back_logical == self.current_front_logical {
118 return None;
119 }
120
121 self.current_back_logical -= 1;
122
123 let run_ends = self.array.run_ends().values();
124 if self.current_back_physical > 0
125 && self.current_back_logical < run_ends[self.current_back_physical - 1].as_usize()
126 {
127 self.current_back_physical -= 1;
131 }
132 Some(if self.array.values().is_null(self.current_back_physical) {
133 None
134 } else {
135 unsafe {
140 Some(
141 self.array
142 .values()
143 .value_unchecked(self.current_back_physical),
144 )
145 }
146 })
147 }
148}
149
150impl<'a, R, V> ExactSizeIterator for RunArrayIter<'a, R, V>
152where
153 R: RunEndIndexType,
154 V: Sync + Send,
155 &'a V: ArrayAccessor,
156 <&'a V as ArrayAccessor>::Item: Default,
157{
158}
159
160#[cfg(test)]
161mod tests {
162 use rand::{RngExt, rng, seq::SliceRandom};
163
164 use crate::{
165 Array, Int64RunArray, PrimitiveArray, RunArray,
166 array::{Int32Array, StringArray},
167 builder::PrimitiveRunBuilder,
168 types::{Int16Type, Int32Type},
169 };
170
171 fn build_input_array(size: usize) -> Vec<Option<i32>> {
172 let mut seed: Vec<Option<i32>> = vec![
175 None,
176 None,
177 None,
178 Some(1),
179 Some(2),
180 Some(3),
181 Some(4),
182 Some(5),
183 Some(6),
184 Some(7),
185 Some(8),
186 Some(9),
187 ];
188 let mut result: Vec<Option<i32>> = Vec::with_capacity(size);
189 let mut ix = 0;
190 let mut rng = rng();
191 let max_run_length = 8_usize.min(1_usize.max(size / 2));
193 while result.len() < size {
194 if ix == 0 {
196 seed.shuffle(&mut rng);
197 }
198 let num = max_run_length.min(rng.random_range(1..=max_run_length));
200 for _ in 0..num {
201 result.push(seed[ix]);
202 }
203 ix += 1;
204 if ix == seed.len() {
205 ix = 0
206 }
207 }
208 result.resize(size, None);
209 result
210 }
211
212 #[test]
213 fn test_primitive_array_iter_round_trip() {
214 let mut input_vec = vec![
215 Some(32),
216 Some(32),
217 None,
218 Some(64),
219 Some(64),
220 Some(64),
221 Some(72),
222 ];
223 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
224 builder.extend(input_vec.iter().copied());
225 let ree_array = builder.finish();
226 let ree_array = ree_array.downcast::<Int32Array>().unwrap();
227
228 let output_vec: Vec<Option<i32>> = ree_array.into_iter().collect();
229 assert_eq!(input_vec, output_vec);
230
231 let rev_output_vec: Vec<Option<i32>> = ree_array.into_iter().rev().collect();
232 input_vec.reverse();
233 assert_eq!(input_vec, rev_output_vec);
234 }
235
236 #[test]
237 fn test_double_ended() {
238 let input_vec = vec![
239 Some(32),
240 Some(32),
241 None,
242 Some(64),
243 Some(64),
244 Some(64),
245 Some(72),
246 ];
247 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
248 builder.extend(input_vec);
249 let ree_array = builder.finish();
250 let ree_array = ree_array.downcast::<Int32Array>().unwrap();
251
252 let mut iter = ree_array.into_iter();
253 assert_eq!(Some(Some(32)), iter.next());
254 assert_eq!(Some(Some(72)), iter.next_back());
255 assert_eq!(Some(Some(32)), iter.next());
256 assert_eq!(Some(Some(64)), iter.next_back());
257 assert_eq!(Some(None), iter.next());
258 assert_eq!(Some(Some(64)), iter.next_back());
259 assert_eq!(Some(Some(64)), iter.next());
260 assert_eq!(None, iter.next_back());
261 assert_eq!(None, iter.next());
262 }
263
264 #[test]
265 fn test_run_iterator_comprehensive() {
266 let logical_lengths = vec![1_usize, 2, 3, 4, 15, 16, 17, 63, 64, 65];
268
269 for logical_len in logical_lengths {
270 let input_array = build_input_array(logical_len);
271
272 let mut run_array_builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
273 run_array_builder.extend(input_array.iter().copied());
274 let run_array = run_array_builder.finish();
275 let typed_array = run_array.downcast::<Int32Array>().unwrap();
276
277 let mut input_iter = input_array.iter().copied();
279 let mut run_array_iter = typed_array.into_iter();
280 for _ in 0..logical_len {
281 assert_eq!(input_iter.next(), run_array_iter.next());
282 }
283 assert_eq!(None, run_array_iter.next());
284
285 let mut input_iter = input_array.iter().rev().copied();
287 let mut run_array_iter = typed_array.into_iter().rev();
288 for _ in 0..logical_len {
289 assert_eq!(input_iter.next(), run_array_iter.next());
290 }
291 assert_eq!(None, run_array_iter.next());
292 }
293 }
294
295 #[test]
296 fn test_string_array_iter_round_trip() {
297 let input_vec = vec!["ab", "ab", "ba", "cc", "cc"];
298 let input_ree_array: Int64RunArray = input_vec.into_iter().collect();
299 let string_ree_array = input_ree_array.downcast::<StringArray>().unwrap();
300
301 let result: Vec<Option<String>> = string_ree_array
303 .into_iter()
304 .map(|e| {
305 e.map(|e| {
306 let mut a = e.to_string();
307 a.push('b');
308 a
309 })
310 })
311 .collect();
312
313 let result_asref: Vec<Option<&str>> = result.iter().map(|f| f.as_deref()).collect();
314
315 let expected_vec = vec![
316 Some("abb"),
317 Some("abb"),
318 Some("bab"),
319 Some("ccb"),
320 Some("ccb"),
321 ];
322
323 assert_eq!(expected_vec, result_asref);
324 }
325
326 #[test]
327 #[cfg_attr(miri, ignore)] fn test_sliced_run_array_iterator() {
329 let total_len = 80;
330 let input_array = build_input_array(total_len);
331
332 let mut builder =
334 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
335 builder.extend(input_array.iter().copied());
336 let run_array = builder.finish();
337
338 for slice_len in 1..=total_len {
340 let sliced_run_array: RunArray<Int16Type> =
342 run_array.slice(0, slice_len).into_data().into();
343 let sliced_typed_run_array = sliced_run_array
344 .downcast::<PrimitiveArray<Int32Type>>()
345 .unwrap();
346
347 let actual: Vec<Option<i32>> = sliced_typed_run_array.into_iter().collect();
349 let expected: Vec<Option<i32>> = input_array.iter().take(slice_len).copied().collect();
350 assert_eq!(expected, actual);
351
352 let sliced_run_array: RunArray<Int16Type> = run_array
354 .slice(total_len - slice_len, slice_len)
355 .into_data()
356 .into();
357 let sliced_typed_run_array = sliced_run_array
358 .downcast::<PrimitiveArray<Int32Type>>()
359 .unwrap();
360
361 let actual: Vec<Option<i32>> = sliced_typed_run_array.into_iter().collect();
363 let expected: Vec<Option<i32>> = input_array
364 .iter()
365 .skip(total_len - slice_len)
366 .copied()
367 .collect();
368 assert_eq!(expected, actual);
369 }
370 }
371}