1use std::any::Any;
19use std::sync::Arc;
20
21use arrow_buffer::{ArrowNativeType, BooleanBufferBuilder, NullBuffer, RunEndBuffer, ScalarBuffer};
22use arrow_data::{ArrayData, ArrayDataBuilder};
23use arrow_schema::{ArrowError, DataType, Field};
24
25use crate::{
26 Array, ArrayAccessor, ArrayRef, PrimitiveArray,
27 builder::StringRunBuilder,
28 make_array,
29 run_iterator::RunArrayIter,
30 types::{Int16Type, Int32Type, Int64Type, RunEndIndexType},
31};
32
33#[macro_export]
44macro_rules! ree_map {
45 ($array:expr, $run_type:ty, $func:expr) => {{
46 let ree = $array.as_run_opt::<$run_type>().unwrap();
47 let inner_values = $func(ree.values().as_ref())?;
48 Ok(std::sync::Arc::new(ree.with_values(inner_values)))
49 }};
50}
51
52pub struct RunArray<R: RunEndIndexType> {
85 data_type: DataType,
86 run_ends: RunEndBuffer<R::Native>,
87 values: ArrayRef,
88}
89
90impl<R: RunEndIndexType> Clone for RunArray<R> {
91 fn clone(&self) -> Self {
92 Self {
93 data_type: self.data_type.clone(),
94 run_ends: self.run_ends.clone(),
95 values: self.values.clone(),
96 }
97 }
98}
99
100impl<R: RunEndIndexType> RunArray<R> {
101 pub fn logical_len(run_ends: &PrimitiveArray<R>) -> usize {
104 let len = run_ends.len();
105 if len == 0 {
106 return 0;
107 }
108 run_ends.value(len - 1).as_usize()
109 }
110
111 pub fn try_new(run_ends: &PrimitiveArray<R>, values: &dyn Array) -> Result<Self, ArrowError> {
119 let run_ends_type = run_ends.data_type().clone();
120 let values_type = values.data_type().clone();
121 let ree_array_type = DataType::RunEndEncoded(
122 Arc::new(Field::new("run_ends", run_ends_type, false)),
123 Arc::new(Field::new("values", values_type, true)),
124 );
125 let len = RunArray::logical_len(run_ends);
126 let builder = ArrayDataBuilder::new(ree_array_type)
127 .len(len)
128 .add_child_data(run_ends.to_data())
129 .add_child_data(values.to_data());
130
131 let array_data = unsafe { builder.build_unchecked() };
133
134 array_data.validate_data()?;
141
142 Ok(array_data.into())
143 }
144
145 pub unsafe fn new_unchecked(
151 data_type: DataType,
152 run_ends: RunEndBuffer<R::Native>,
153 values: ArrayRef,
154 ) -> Self {
155 if cfg!(feature = "force_validate") {
156 match &data_type {
157 DataType::RunEndEncoded(run_ends, values_field) => {
158 assert!(!run_ends.is_nullable(), "run_ends should not be nullable");
159 assert_eq!(
160 run_ends.data_type(),
161 &R::DATA_TYPE,
162 "Incorrect run ends type"
163 );
164 assert_eq!(
165 values_field.data_type(),
166 values.data_type(),
167 "Incorrect values type"
168 );
169 }
170 _ => {
171 panic!(
172 "Invalid data type {data_type:?} for RunArray. Should be DataType::RunEndEncoded"
173 );
174 }
175 }
176
177 let run_array = Self {
178 data_type,
179 run_ends,
180 values,
181 };
182
183 run_array
190 .to_data()
191 .validate_data()
192 .expect("RunArray data should be valid");
193
194 return run_array;
195 }
196
197 Self {
198 data_type,
199 run_ends,
200 values,
201 }
202 }
203
204 pub fn into_parts(self) -> (DataType, RunEndBuffer<R::Native>, ArrayRef) {
206 (self.data_type, self.run_ends, self.values)
207 }
208
209 pub fn run_ends(&self) -> &RunEndBuffer<R::Native> {
211 &self.run_ends
212 }
213
214 pub fn values(&self) -> &ArrayRef {
219 &self.values
220 }
221
222 pub fn with_values(&self, values: ArrayRef) -> Self {
248 assert_eq!(values.len(), self.values.len());
249 let (run_ends_field, values_field) = match &self.data_type {
250 DataType::RunEndEncoded(r, v) => {
251 let new_v = Arc::new(Field::new(
252 v.name(),
253 values.data_type().clone(),
254 v.is_nullable(),
255 ));
256 (r, new_v)
257 }
258 _ => unreachable!("RunArray should have type RunEndEncoded"),
259 };
260 let data_type = DataType::RunEndEncoded(Arc::clone(run_ends_field), values_field);
261
262 Self {
263 data_type,
264 run_ends: self.run_ends.clone(),
265 values,
266 }
267 }
268
269 pub fn values_slice(&self) -> ArrayRef {
274 if self.is_empty() {
275 return self.values.slice(0, 0);
276 }
277 let start = self.get_start_physical_index();
278 let end = self.get_end_physical_index();
279 self.values.slice(start, end - start + 1)
280 }
281
282 pub fn get_start_physical_index(&self) -> usize {
286 self.run_ends.get_start_physical_index()
287 }
288
289 pub fn get_end_physical_index(&self) -> usize {
293 self.run_ends.get_end_physical_index()
294 }
295
296 pub fn downcast<V: 'static>(&self) -> Option<TypedRunArray<'_, R, V>> {
309 let values = self.values.as_any().downcast_ref()?;
310 Some(TypedRunArray {
311 run_array: self,
312 values,
313 })
314 }
315
316 pub fn get_physical_index(&self, logical_index: usize) -> usize {
320 self.run_ends.get_physical_index(logical_index)
321 }
322
323 #[inline]
327 pub fn get_physical_indices<I>(&self, logical_indices: &[I]) -> Result<Vec<usize>, ArrowError>
328 where
329 I: ArrowNativeType,
330 {
331 self.run_ends()
332 .get_physical_indices(logical_indices)
333 .map_err(|index| {
334 ArrowError::InvalidArgumentError(format!(
335 "Logical index {} is out of bounds for RunArray of length {}",
336 index.as_usize(),
337 self.len()
338 ))
339 })
340 }
341
342 pub fn slice(&self, offset: usize, length: usize) -> Self {
348 Self {
349 data_type: self.data_type.clone(),
350 run_ends: self.run_ends.slice(offset, length),
351 values: self.values.clone(),
352 }
353 }
354}
355
356impl<R: RunEndIndexType> From<ArrayData> for RunArray<R> {
357 fn from(data: ArrayData) -> Self {
359 let (data_type, len, _nulls, offset, _buffers, child_data) = data.into_parts();
360
361 match &data_type {
362 DataType::RunEndEncoded(_, _) => {}
363 _ => {
364 panic!(
365 "Invalid data type {data_type:?} for RunArray. Should be DataType::RunEndEncoded"
366 );
367 }
368 }
369
370 let [run_end_child, values_child]: [ArrayData; 2] = child_data
371 .try_into()
372 .expect("RunArray data should have exactly two child arrays");
373
374 let (
376 run_end_data_type,
377 run_end_len,
378 _run_end_nulls,
379 run_end_offset,
380 run_end_buffers,
381 _run_end_child_data,
382 ) = run_end_child.into_parts();
383 assert_eq!(run_end_data_type, R::DATA_TYPE, "Incorrect run ends type");
384 let [run_end_buffer]: [arrow_buffer::Buffer; 1] = run_end_buffers
385 .try_into()
386 .expect("Run ends should have exactly one buffer");
387 let scalar = ScalarBuffer::new(run_end_buffer, run_end_offset, run_end_len);
388 let run_ends = unsafe { RunEndBuffer::new_unchecked(scalar, offset, len) };
389
390 let values = make_array(values_child);
391
392 Self {
393 data_type,
394 run_ends,
395 values,
396 }
397 }
398}
399
400impl<R: RunEndIndexType> From<RunArray<R>> for ArrayData {
401 fn from(array: RunArray<R>) -> Self {
402 let len = array.run_ends.len();
403 let offset = array.run_ends.offset();
404
405 let run_ends = ArrayDataBuilder::new(R::DATA_TYPE)
406 .len(array.run_ends.values().len())
407 .buffers(vec![array.run_ends.into_inner().into_inner()]);
408
409 let run_ends = unsafe { run_ends.build_unchecked() };
410
411 let builder = ArrayDataBuilder::new(array.data_type)
412 .len(len)
413 .offset(offset)
414 .child_data(vec![run_ends, array.values.to_data()]);
415
416 unsafe { builder.build_unchecked() }
417 }
418}
419
420unsafe impl<T: RunEndIndexType> Array for RunArray<T> {
422 fn as_any(&self) -> &dyn Any {
423 self
424 }
425
426 fn to_data(&self) -> ArrayData {
427 self.clone().into()
428 }
429
430 fn into_data(self) -> ArrayData {
431 self.into()
432 }
433
434 fn data_type(&self) -> &DataType {
435 &self.data_type
436 }
437
438 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
439 Arc::new(self.slice(offset, length))
440 }
441
442 fn len(&self) -> usize {
443 self.run_ends.len()
444 }
445
446 fn is_empty(&self) -> bool {
447 self.run_ends.is_empty()
448 }
449
450 fn shrink_to_fit(&mut self) {
451 self.run_ends.shrink_to_fit();
452 self.values.shrink_to_fit();
453 }
454
455 fn offset(&self) -> usize {
456 self.run_ends.offset()
457 }
458
459 fn nulls(&self) -> Option<&NullBuffer> {
460 None
461 }
462
463 fn logical_nulls(&self) -> Option<NullBuffer> {
464 let len = self.len();
465 let nulls = self.values.logical_nulls()?;
466 let mut out = BooleanBufferBuilder::new(len);
467 let offset = self.run_ends.offset();
468 let mut valid_start = 0;
469 let mut last_end = 0;
470 for (idx, end) in self.run_ends.values().iter().enumerate() {
471 let end = end.as_usize();
472 if end < offset {
473 continue;
474 }
475 let end = (end - offset).min(len);
476 if nulls.is_null(idx) {
477 if valid_start < last_end {
478 out.append_n(last_end - valid_start, true);
479 }
480 out.append_n(end - last_end, false);
481 valid_start = end;
482 }
483 last_end = end;
484 if end == len {
485 break;
486 }
487 }
488 if valid_start < len {
489 out.append_n(len - valid_start, true)
490 }
491 assert_eq!(out.len(), len);
493 Some(out.finish().into())
494 }
495
496 fn is_nullable(&self) -> bool {
497 !self.is_empty() && self.values.is_nullable()
498 }
499
500 fn get_buffer_memory_size(&self) -> usize {
501 self.run_ends.inner().inner().capacity() + self.values.get_buffer_memory_size()
502 }
503
504 fn get_array_memory_size(&self) -> usize {
505 std::mem::size_of::<Self>()
506 + self.run_ends.inner().inner().capacity()
507 + self.values.get_array_memory_size()
508 }
509
510 #[cfg(feature = "pool")]
511 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
512 self.run_ends.claim(pool);
513 self.values.claim(pool);
514 }
515}
516
517impl<R: RunEndIndexType> std::fmt::Debug for RunArray<R> {
518 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
519 writeln!(
520 f,
521 "RunArray {{run_ends: {:?}, values: {:?}}}",
522 self.run_ends.values(),
523 self.values
524 )
525 }
526}
527
528impl<'a, T: RunEndIndexType> FromIterator<Option<&'a str>> for RunArray<T> {
545 fn from_iter<I: IntoIterator<Item = Option<&'a str>>>(iter: I) -> Self {
546 let it = iter.into_iter();
547 let (lower, _) = it.size_hint();
548 let mut builder = StringRunBuilder::with_capacity(lower, 256);
549 it.for_each(|i| {
550 builder.append_option(i);
551 });
552
553 builder.finish()
554 }
555}
556
557impl<'a, T: RunEndIndexType> FromIterator<&'a str> for RunArray<T> {
572 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
573 let it = iter.into_iter();
574 let (lower, _) = it.size_hint();
575 let mut builder = StringRunBuilder::with_capacity(lower, 256);
576 it.for_each(|i| {
577 builder.append_value(i);
578 });
579
580 builder.finish()
581 }
582}
583
584pub type Int16RunArray = RunArray<Int16Type>;
598
599pub type Int32RunArray = RunArray<Int32Type>;
613
614pub type Int64RunArray = RunArray<Int64Type>;
628
629pub struct TypedRunArray<'a, R: RunEndIndexType, V> {
647 run_array: &'a RunArray<R>,
649
650 values: &'a V,
652}
653
654impl<R: RunEndIndexType, V> Clone for TypedRunArray<'_, R, V> {
656 fn clone(&self) -> Self {
657 *self
658 }
659}
660
661impl<R: RunEndIndexType, V> Copy for TypedRunArray<'_, R, V> {}
662
663impl<R: RunEndIndexType, V> std::fmt::Debug for TypedRunArray<'_, R, V> {
664 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
665 writeln!(f, "TypedRunArray({:?})", self.run_array)
666 }
667}
668
669impl<'a, R: RunEndIndexType, V> TypedRunArray<'a, R, V> {
670 pub fn run_ends(&self) -> &'a RunEndBuffer<R::Native> {
672 self.run_array.run_ends()
673 }
674
675 pub fn values(&self) -> &'a V {
677 self.values
678 }
679
680 pub fn run_array(&self) -> &'a RunArray<R> {
682 self.run_array
683 }
684}
685
686unsafe impl<R: RunEndIndexType, V: Sync> Array for TypedRunArray<'_, R, V> {
688 fn as_any(&self) -> &dyn Any {
689 self.run_array
690 }
691
692 fn to_data(&self) -> ArrayData {
693 self.run_array.to_data()
694 }
695
696 fn into_data(self) -> ArrayData {
697 self.run_array.into_data()
698 }
699
700 fn data_type(&self) -> &DataType {
701 self.run_array.data_type()
702 }
703
704 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
705 Arc::new(self.run_array.slice(offset, length))
706 }
707
708 fn len(&self) -> usize {
709 self.run_array.len()
710 }
711
712 fn is_empty(&self) -> bool {
713 self.run_array.is_empty()
714 }
715
716 fn offset(&self) -> usize {
717 self.run_array.offset()
718 }
719
720 fn nulls(&self) -> Option<&NullBuffer> {
721 self.run_array.nulls()
722 }
723
724 fn logical_nulls(&self) -> Option<NullBuffer> {
725 self.run_array.logical_nulls()
726 }
727
728 fn logical_null_count(&self) -> usize {
729 self.run_array.logical_null_count()
730 }
731
732 fn is_nullable(&self) -> bool {
733 self.run_array.is_nullable()
734 }
735
736 fn get_buffer_memory_size(&self) -> usize {
737 self.run_array.get_buffer_memory_size()
738 }
739
740 fn get_array_memory_size(&self) -> usize {
741 self.run_array.get_array_memory_size()
742 }
743
744 #[cfg(feature = "pool")]
745 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
746 self.run_array.claim(pool);
747 }
748}
749
750impl<'a, R, V> ArrayAccessor for TypedRunArray<'a, R, V>
753where
754 R: RunEndIndexType,
755 V: Sync + Send,
756 &'a V: ArrayAccessor,
757 <&'a V as ArrayAccessor>::Item: Default,
758{
759 type Item = <&'a V as ArrayAccessor>::Item;
760
761 fn value(&self, logical_index: usize) -> Self::Item {
762 assert!(
763 logical_index < self.len(),
764 "Trying to access an element at index {} from a TypedRunArray of length {}",
765 logical_index,
766 self.len()
767 );
768 unsafe { self.value_unchecked(logical_index) }
769 }
770
771 unsafe fn value_unchecked(&self, logical_index: usize) -> Self::Item {
772 let physical_index = self.run_array.get_physical_index(logical_index);
773 unsafe { self.values().value_unchecked(physical_index) }
774 }
775}
776
777impl<'a, R, V> IntoIterator for TypedRunArray<'a, R, V>
778where
779 R: RunEndIndexType,
780 V: Sync + Send,
781 &'a V: ArrayAccessor,
782 <&'a V as ArrayAccessor>::Item: Default,
783{
784 type Item = Option<<&'a V as ArrayAccessor>::Item>;
785 type IntoIter = RunArrayIter<'a, R, V>;
786
787 fn into_iter(self) -> Self::IntoIter {
788 RunArrayIter::new(self)
789 }
790}
791pub trait AnyRunEndArray: Array {
796 fn values(&self) -> &Arc<dyn Array>;
798
799 fn with_values(&self, values: ArrayRef) -> ArrayRef;
802}
803
804impl<R: RunEndIndexType> AnyRunEndArray for RunArray<R> {
805 fn values(&self) -> &Arc<dyn Array> {
806 &self.values
807 }
808
809 fn with_values(&self, values: ArrayRef) -> ArrayRef {
810 Arc::new(RunArray::<R>::with_values(self, values))
811 }
812}
813
814#[cfg(test)]
815mod tests {
816 use rand::Rng;
817 use rand::rng;
818 use rand::seq::SliceRandom;
819
820 use super::*;
821 use crate::Float32Array;
822 use crate::Int64Array;
823 use crate::builder::PrimitiveRunBuilder;
824 use crate::cast::AsArray;
825 use crate::new_empty_array;
826 use crate::types::{Int8Type, UInt32Type};
827 use crate::{Int16Array, Int32Array, StringArray};
828
829 fn build_input_array(size: usize) -> Vec<Option<i32>> {
830 let mut seed: Vec<Option<i32>> = vec![
833 None,
834 None,
835 None,
836 Some(1),
837 Some(2),
838 Some(3),
839 Some(4),
840 Some(5),
841 Some(6),
842 Some(7),
843 Some(8),
844 Some(9),
845 ];
846 let mut result: Vec<Option<i32>> = Vec::with_capacity(size);
847 let mut ix = 0;
848 let mut rng = rng();
849 let max_run_length = 8_usize.min(1_usize.max(size / 2));
851 while result.len() < size {
852 if ix == 0 {
854 seed.shuffle(&mut rng);
855 }
856 let num = max_run_length.min(rng.random_range(1..=max_run_length));
858 for _ in 0..num {
859 result.push(seed[ix]);
860 }
861 ix += 1;
862 if ix == seed.len() {
863 ix = 0
864 }
865 }
866 result.resize(size, None);
867 result
868 }
869
870 fn compare_logical_and_physical_indices(
872 logical_indices: &[u32],
873 logical_array: &[Option<i32>],
874 physical_indices: &[usize],
875 physical_array: &PrimitiveArray<Int32Type>,
876 ) {
877 assert_eq!(logical_indices.len(), physical_indices.len());
878
879 logical_indices
881 .iter()
882 .map(|f| f.as_usize())
883 .zip(physical_indices.iter())
884 .for_each(|(logical_ix, physical_ix)| {
885 let expected = logical_array[logical_ix];
886 match expected {
887 Some(val) => {
888 assert!(physical_array.is_valid(*physical_ix));
889 let actual = physical_array.value(*physical_ix);
890 assert_eq!(val, actual);
891 }
892 None => {
893 assert!(physical_array.is_null(*physical_ix))
894 }
895 };
896 });
897 }
898 #[test]
899 fn test_run_array() {
900 let value_data =
902 PrimitiveArray::<Int8Type>::from_iter_values([10_i8, 11, 12, 13, 14, 15, 16, 17]);
903
904 let run_ends_values = [4_i16, 6, 7, 9, 13, 18, 20, 22];
906 let run_ends_data =
907 PrimitiveArray::<Int16Type>::from_iter_values(run_ends_values.iter().copied());
908
909 let ree_array = RunArray::<Int16Type>::try_new(&run_ends_data, &value_data).unwrap();
911
912 assert_eq!(ree_array.len(), 22);
913 assert_eq!(ree_array.null_count(), 0);
914
915 let values = ree_array.values();
916 assert_eq!(value_data.into_data(), values.to_data());
917 assert_eq!(&DataType::Int8, values.data_type());
918
919 let run_ends = ree_array.run_ends();
920 assert_eq!(run_ends.values(), &run_ends_values);
921 }
922
923 #[test]
924 fn test_run_array_empty() {
925 let runs = new_empty_array(&DataType::Int16);
926 let runs = runs.as_primitive::<Int16Type>();
927 let values = new_empty_array(&DataType::Int64);
928 let array = RunArray::try_new(runs, &values).unwrap();
929
930 fn assertions(array: &RunArray<Int16Type>) {
931 assert!(array.is_empty());
932 assert_eq!(array.get_start_physical_index(), 0);
933 assert_eq!(array.get_end_physical_index(), 0);
934 assert!(array.get_physical_indices::<i16>(&[]).unwrap().is_empty());
935 assert!(array.run_ends().is_empty());
936 assert_eq!(array.run_ends().sliced_values().count(), 0);
937 }
938
939 assertions(&array);
940 assertions(&array.slice(0, 0));
941 }
942
943 #[test]
944 fn test_run_array_fmt_debug() {
945 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::with_capacity(3);
946 builder.append_value(12345678);
947 builder.append_null();
948 builder.append_value(22345678);
949 let array = builder.finish();
950 assert_eq!(
951 "RunArray {run_ends: [1, 2, 3], values: PrimitiveArray<UInt32>\n[\n 12345678,\n null,\n 22345678,\n]}\n",
952 format!("{array:?}")
953 );
954
955 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::with_capacity(20);
956 for _ in 0..20 {
957 builder.append_value(1);
958 }
959 let array = builder.finish();
960
961 assert_eq!(array.len(), 20);
962 assert_eq!(array.null_count(), 0);
963 assert_eq!(array.logical_null_count(), 0);
964
965 assert_eq!(
966 "RunArray {run_ends: [20], values: PrimitiveArray<UInt32>\n[\n 1,\n]}\n",
967 format!("{array:?}")
968 );
969 }
970
971 #[test]
972 fn test_run_array_from_iter() {
973 let test = vec!["a", "a", "b", "c"];
974 let array: RunArray<Int16Type> = test
975 .iter()
976 .map(|&x| if x == "b" { None } else { Some(x) })
977 .collect();
978 assert_eq!(
979 "RunArray {run_ends: [2, 3, 4], values: StringArray\n[\n \"a\",\n null,\n \"c\",\n]}\n",
980 format!("{array:?}")
981 );
982
983 assert_eq!(array.len(), 4);
984 assert_eq!(array.null_count(), 0);
985 assert_eq!(array.logical_null_count(), 1);
986
987 let array: RunArray<Int16Type> = test.into_iter().collect();
988 assert_eq!(
989 "RunArray {run_ends: [2, 3, 4], values: StringArray\n[\n \"a\",\n \"b\",\n \"c\",\n]}\n",
990 format!("{array:?}")
991 );
992 }
993
994 #[test]
995 fn test_run_array_run_ends_as_primitive_array() {
996 let test = vec!["a", "b", "c", "a"];
997 let array: RunArray<Int16Type> = test.into_iter().collect();
998
999 assert_eq!(array.len(), 4);
1000 assert_eq!(array.null_count(), 0);
1001 assert_eq!(array.logical_null_count(), 0);
1002
1003 let run_ends = array.run_ends();
1004 assert_eq!(&[1, 2, 3, 4], run_ends.values());
1005 }
1006
1007 #[test]
1008 fn test_run_array_as_primitive_array_with_null() {
1009 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1010 let array: RunArray<Int32Type> = test.into_iter().collect();
1011
1012 assert_eq!(array.len(), 6);
1013 assert_eq!(array.null_count(), 0);
1014 assert_eq!(array.logical_null_count(), 3);
1015
1016 let run_ends = array.run_ends();
1017 assert_eq!(&[1, 2, 3, 5, 6], run_ends.values());
1018
1019 let values_data = array.values();
1020 assert_eq!(2, values_data.null_count());
1021 assert_eq!(5, values_data.len());
1022 }
1023
1024 #[test]
1025 fn test_run_array_all_nulls() {
1026 let test = vec![None, None, None];
1027 let array: RunArray<Int32Type> = test.into_iter().collect();
1028
1029 assert_eq!(array.len(), 3);
1030 assert_eq!(array.null_count(), 0);
1031 assert_eq!(array.logical_null_count(), 3);
1032
1033 let run_ends = array.run_ends();
1034 assert_eq!(3, run_ends.len());
1035 assert_eq!(&[3], run_ends.values());
1036
1037 let values_data = array.values();
1038 assert_eq!(1, values_data.null_count());
1039 }
1040
1041 #[test]
1042 fn test_run_array_try_new() {
1043 let values: StringArray = [Some("foo"), Some("bar"), None, Some("baz")]
1044 .into_iter()
1045 .collect();
1046 let run_ends: Int32Array = [Some(1), Some(2), Some(3), Some(4)].into_iter().collect();
1047
1048 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1049 assert_eq!(array.values().data_type(), &DataType::Utf8);
1050
1051 assert_eq!(array.null_count(), 0);
1052 assert_eq!(array.logical_null_count(), 1);
1053 assert_eq!(array.len(), 4);
1054 assert_eq!(array.values().null_count(), 1);
1055
1056 assert_eq!(
1057 "RunArray {run_ends: [1, 2, 3, 4], values: StringArray\n[\n \"foo\",\n \"bar\",\n null,\n \"baz\",\n]}\n",
1058 format!("{array:?}")
1059 );
1060 }
1061
1062 #[test]
1063 fn test_run_array_int16_type_definition() {
1064 let array: Int16RunArray = vec!["a", "a", "b", "c", "c"].into_iter().collect();
1065 let values: Arc<dyn Array> = Arc::new(StringArray::from(vec!["a", "b", "c"]));
1066 assert_eq!(array.run_ends().values(), &[2, 3, 5]);
1067 assert_eq!(array.values(), &values);
1068 }
1069
1070 #[test]
1071 fn test_run_array_empty_string() {
1072 let array: Int16RunArray = vec!["a", "a", "", "", "c"].into_iter().collect();
1073 let values: Arc<dyn Array> = Arc::new(StringArray::from(vec!["a", "", "c"]));
1074 assert_eq!(array.run_ends().values(), &[2, 4, 5]);
1075 assert_eq!(array.values(), &values);
1076 }
1077
1078 #[test]
1079 fn test_run_array_length_mismatch() {
1080 let values: StringArray = [Some("foo"), Some("bar"), None, Some("baz")]
1081 .into_iter()
1082 .collect();
1083 let run_ends: Int32Array = [Some(1), Some(2), Some(3)].into_iter().collect();
1084
1085 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1086 let expected = ArrowError::InvalidArgumentError("The run_ends array length should be the same as values array length. Run_ends array length is 3, values array length is 4".to_string());
1087 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1088 }
1089 #[test]
1090 fn test_run_array_with_values_changes_value_type() {
1091 let values = StringArray::from(vec!["foo", "bar", "baz"]);
1092 let run_ends: Int32Array = [Some(1), Some(2), Some(3)].into_iter().collect();
1093 let ree = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1094
1095 let new_values = Int64Array::from(vec![10, 20, 30]);
1096 let result = ree.with_values(Arc::new(new_values));
1097
1098 match result.data_type() {
1099 DataType::RunEndEncoded(_, v) => {
1100 assert_eq!(v.data_type(), &DataType::Int64);
1101 }
1102 other => panic!("expected RunEndEncoded, got {other:?}"),
1103 }
1104
1105 assert_eq!(result.values().data_type(), &DataType::Int64);
1106 assert_eq!(result.values().len(), 3);
1107 }
1108
1109 #[test]
1110 fn test_run_array_run_ends_with_null() {
1111 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1112 .into_iter()
1113 .collect();
1114 let run_ends: Int32Array = [Some(1), None, Some(3)].into_iter().collect();
1115
1116 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1117 let expected = ArrowError::InvalidArgumentError(
1118 "Found null values in run_ends array. The run_ends array should not have null values."
1119 .to_string(),
1120 );
1121 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1122 }
1123
1124 #[test]
1125 fn test_run_array_run_ends_with_zeroes() {
1126 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1127 .into_iter()
1128 .collect();
1129 let run_ends: Int32Array = [Some(0), Some(1), Some(3)].into_iter().collect();
1130
1131 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1132 let expected = ArrowError::InvalidArgumentError("The values in run_ends array should be strictly positive. Found value 0 at index 0 that does not match the criteria.".to_string());
1133 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1134 }
1135
1136 #[test]
1137 fn test_run_array_run_ends_non_increasing() {
1138 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1139 .into_iter()
1140 .collect();
1141 let run_ends: Int32Array = [Some(1), Some(4), Some(4)].into_iter().collect();
1142
1143 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1144 let expected = ArrowError::InvalidArgumentError("The values in run_ends array should be strictly increasing. Found value 4 at index 2 with previous value 4 that does not match the criteria.".to_string());
1145 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1146 }
1147
1148 #[test]
1149 #[should_panic(expected = "Incorrect run ends type")]
1150 fn test_run_array_run_ends_data_type_mismatch() {
1151 let a = RunArray::<Int32Type>::from_iter(["32"]);
1152 let _ = RunArray::<Int64Type>::from(a.into_data());
1153 }
1154
1155 #[test]
1156 fn test_ree_array_accessor() {
1157 let input_array = build_input_array(256);
1158
1159 let mut builder =
1161 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
1162 builder.extend(input_array.iter().copied());
1163 let run_array = builder.finish();
1164 let typed = run_array.downcast::<PrimitiveArray<Int32Type>>().unwrap();
1165
1166 for (i, inp_val) in input_array.iter().enumerate() {
1168 if let Some(val) = inp_val {
1169 let actual = typed.value(i);
1170 assert_eq!(*val, actual)
1171 } else {
1172 let physical_ix = run_array.get_physical_index(i);
1173 assert!(typed.values().is_null(physical_ix));
1174 };
1175 }
1176 }
1177
1178 #[test]
1179 #[cfg_attr(miri, ignore)] fn test_get_physical_indices() {
1181 for logical_len in (0..250).step_by(10) {
1183 let input_array = build_input_array(logical_len);
1184
1185 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
1187 builder.extend(input_array.clone());
1188
1189 let run_array = builder.finish();
1190 let physical_values_array = run_array.values().as_primitive::<Int32Type>();
1191
1192 let mut logical_indices: Vec<u32> = (0_u32..(logical_len as u32)).collect();
1194 logical_indices.append(&mut logical_indices.clone());
1196 let mut rng = rng();
1197 logical_indices.shuffle(&mut rng);
1198
1199 let physical_indices = run_array.get_physical_indices(&logical_indices).unwrap();
1200
1201 assert_eq!(logical_indices.len(), physical_indices.len());
1202
1203 compare_logical_and_physical_indices(
1205 &logical_indices,
1206 &input_array,
1207 &physical_indices,
1208 physical_values_array,
1209 );
1210 }
1211 }
1212
1213 #[test]
1214 #[cfg_attr(miri, ignore)] fn test_get_physical_indices_sliced() {
1216 let total_len = 80;
1217 let input_array = build_input_array(total_len);
1218
1219 let mut builder =
1221 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
1222 builder.extend(input_array.iter().copied());
1223 let run_array = builder.finish();
1224 let physical_values_array = run_array.values().as_primitive::<Int32Type>();
1225
1226 for slice_len in 1..=total_len {
1228 let mut logical_indices: Vec<u32> = (0_u32..(slice_len as u32)).collect();
1230 logical_indices.append(&mut logical_indices.clone());
1232 let mut rng = rng();
1233 logical_indices.shuffle(&mut rng);
1234
1235 let sliced_input_array = &input_array[0..slice_len];
1238
1239 let sliced_run_array: RunArray<Int16Type> =
1241 run_array.slice(0, slice_len).into_data().into();
1242
1243 let physical_indices = sliced_run_array
1245 .get_physical_indices(&logical_indices)
1246 .unwrap();
1247
1248 compare_logical_and_physical_indices(
1249 &logical_indices,
1250 sliced_input_array,
1251 &physical_indices,
1252 physical_values_array,
1253 );
1254
1255 let sliced_input_array = &input_array[total_len - slice_len..total_len];
1258
1259 let sliced_run_array: RunArray<Int16Type> = run_array
1261 .slice(total_len - slice_len, slice_len)
1262 .into_data()
1263 .into();
1264
1265 let physical_indices = sliced_run_array
1267 .get_physical_indices(&logical_indices)
1268 .unwrap();
1269
1270 compare_logical_and_physical_indices(
1271 &logical_indices,
1272 sliced_input_array,
1273 &physical_indices,
1274 physical_values_array,
1275 );
1276 }
1277 }
1278
1279 #[test]
1280 fn test_logical_nulls() {
1281 let run = Int32Array::from(vec![3, 6, 9, 12]);
1282 let values = Int32Array::from(vec![Some(0), None, Some(1), None]);
1283 let array = RunArray::try_new(&run, &values).unwrap();
1284
1285 let expected = [
1286 true, true, true, false, false, false, true, true, true, false, false, false,
1287 ];
1288
1289 let n = array.logical_nulls().unwrap();
1290 assert_eq!(n.null_count(), 6);
1291
1292 let slices = [(0, 12), (0, 2), (2, 5), (3, 0), (3, 3), (3, 4), (4, 8)];
1293 for (offset, length) in slices {
1294 let a = array.slice(offset, length);
1295 let n = a.logical_nulls().unwrap();
1296 let n = n.into_iter().collect::<Vec<_>>();
1297 assert_eq!(&n, &expected[offset..offset + length], "{offset} {length}");
1298 }
1299 }
1300
1301 #[test]
1302 fn test_run_array_eq_identical() {
1303 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1304 let values1 = StringArray::from(vec!["a", "b", "c"]);
1305 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1306
1307 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1308 let values2 = StringArray::from(vec!["a", "b", "c"]);
1309 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1310
1311 assert_eq!(array1, array2);
1312 }
1313
1314 #[test]
1315 fn test_run_array_ne_different_run_ends() {
1316 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1317 let values1 = StringArray::from(vec!["a", "b", "c"]);
1318 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1319
1320 let run_ends2 = Int32Array::from(vec![1, 4, 6]);
1321 let values2 = StringArray::from(vec!["a", "b", "c"]);
1322 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1323
1324 assert_ne!(array1, array2);
1325 }
1326
1327 #[test]
1328 fn test_run_array_ne_different_values() {
1329 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1330 let values1 = StringArray::from(vec!["a", "b", "c"]);
1331 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1332
1333 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1334 let values2 = StringArray::from(vec!["a", "b", "d"]);
1335 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1336
1337 assert_ne!(array1, array2);
1338 }
1339
1340 #[test]
1341 fn test_run_array_eq_with_nulls() {
1342 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1343 let values1 = StringArray::from(vec![Some("a"), None, Some("c")]);
1344 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1345
1346 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1347 let values2 = StringArray::from(vec![Some("a"), None, Some("c")]);
1348 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1349
1350 assert_eq!(array1, array2);
1351 }
1352
1353 #[test]
1354 fn test_run_array_eq_different_run_end_types() {
1355 let run_ends_i16_1 = Int16Array::from(vec![2_i16, 4, 6]);
1356 let values_i16_1 = StringArray::from(vec!["a", "b", "c"]);
1357 let array_i16_1 = RunArray::<Int16Type>::try_new(&run_ends_i16_1, &values_i16_1).unwrap();
1358
1359 let run_ends_i16_2 = Int16Array::from(vec![2_i16, 4, 6]);
1360 let values_i16_2 = StringArray::from(vec!["a", "b", "c"]);
1361 let array_i16_2 = RunArray::<Int16Type>::try_new(&run_ends_i16_2, &values_i16_2).unwrap();
1362
1363 assert_eq!(array_i16_1, array_i16_2);
1364 }
1365
1366 #[test]
1367 fn test_run_array_values_slice() {
1368 let run_ends: PrimitiveArray<Int32Type> = vec![2, 5, 20].into();
1370 let values: PrimitiveArray<Int32Type> = vec![0, 1, 2].into();
1371 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1372
1373 let slice = array.slice(1, 4); assert_eq!(slice.get_start_physical_index(), 0);
1380 assert_eq!(slice.get_end_physical_index(), 1);
1381
1382 let values_slice = slice.values_slice();
1383 let values_slice = values_slice.as_primitive::<Int32Type>();
1384 assert_eq!(values_slice.values(), &[0, 1]);
1385
1386 let slice2 = array.slice(2, 3); assert_eq!(slice2.get_start_physical_index(), 1);
1390 assert_eq!(slice2.get_end_physical_index(), 1);
1391
1392 let values_slice2 = slice2.values_slice();
1393 let values_slice2 = values_slice2.as_primitive::<Int32Type>();
1394 assert_eq!(values_slice2.values(), &[1]);
1395 }
1396
1397 #[test]
1398 fn test_run_array_values_slice_empty() {
1399 let run_ends = Int32Array::from(vec![2, 5, 10]);
1400 let values = StringArray::from(vec!["a", "b", "c"]);
1401 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1402
1403 let slice = array.slice(0, 0);
1404 assert_eq!(slice.len(), 0);
1405
1406 let values_slice = slice.values_slice();
1407 assert_eq!(values_slice.len(), 0);
1408 assert_eq!(values_slice.data_type(), &DataType::Utf8);
1409 }
1410
1411 #[test]
1412 fn test_run_array_eq_empty() {
1413 let run_ends = Int32Array::from(vec![2, 5, 10]);
1414 let values = StringArray::from(vec!["a", "b", "c"]);
1415 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1416
1417 let slice1 = array.slice(0, 0);
1418 let slice2 = array.slice(1, 0);
1419 let slice3 = array.slice(10, 0);
1420
1421 assert_eq!(slice1, slice2);
1422 assert_eq!(slice2, slice3);
1423
1424 let empty_array = new_empty_array(array.data_type());
1425 let empty_array = crate::cast::as_run_array::<Int32Type>(empty_array.as_ref());
1426
1427 assert_eq!(&slice1, empty_array);
1428 }
1429
1430 #[test]
1431 fn test_run_array_eq_diff_physical_same_logical() {
1432 let run_ends1 = Int32Array::from(vec![1, 3, 6]);
1433 let values1 = StringArray::from(vec!["a", "b", "c"]);
1434 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1435
1436 let run_ends2 = Int32Array::from(vec![1, 2, 3, 4, 5, 6]);
1437 let values2 = StringArray::from(vec!["a", "b", "b", "c", "c", "c"]);
1438 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1439
1440 assert_eq!(array1, array2);
1441 }
1442
1443 #[test]
1444 fn test_run_array_eq_sliced() {
1445 let run_ends1 = Int32Array::from(vec![2, 5, 10]);
1446 let values1 = StringArray::from(vec!["a", "b", "c"]);
1447 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1448 let slice1 = array1.slice(1, 6);
1451 let run_ends2 = Int32Array::from(vec![1, 4, 6]);
1454 let values2 = StringArray::from(vec!["a", "b", "c"]);
1455 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1456 assert_eq!(slice1, array2);
1459
1460 let slice2 = array1.slice(2, 3);
1461 let run_ends3 = Int32Array::from(vec![3]);
1463 let values3 = StringArray::from(vec!["b"]);
1464 let array3 = RunArray::<Int32Type>::try_new(&run_ends3, &values3).unwrap();
1465 assert_eq!(slice2, array3);
1466 }
1467
1468 #[test]
1469 fn test_run_array_eq_sliced_different_offsets() {
1470 let run_ends1 = Int32Array::from(vec![2, 5, 10]);
1471 let values1 = StringArray::from(vec!["a", "b", "c"]);
1472 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1473 let array2 = array1.clone();
1474 assert_eq!(array1, array2);
1475
1476 let slice1 = array1.slice(1, 4); let slice2 = array1.slice(1, 4);
1478 assert_eq!(slice1, slice2);
1479
1480 let slice3 = array1.slice(0, 4); assert_ne!(slice1, slice3);
1482 }
1483
1484 #[test]
1485 #[cfg(not(feature = "force_validate"))]
1486 fn allow_to_create_invalid_array_using_new_unchecked() {
1487 let valid = RunArray::<Int32Type>::from_iter(["32"]);
1488 let (_, buffer, values) = valid.into_parts();
1489
1490 let _ = unsafe {
1491 RunArray::<Int32Type>::new_unchecked(DataType::Int64, buffer, values)
1493 };
1494 }
1495
1496 #[test]
1497 #[should_panic(
1498 expected = "Invalid data type Int64 for RunArray. Should be DataType::RunEndEncoded"
1499 )]
1500 #[cfg(feature = "force_validate")]
1501 fn should_not_be_able_to_create_invalid_array_using_new_unchecked_when_force_validate_is_enabled()
1502 {
1503 let valid = RunArray::<Int32Type>::from_iter(["32"]);
1504 let (_, buffer, values) = valid.into_parts();
1505
1506 let _ = unsafe {
1507 RunArray::<Int32Type>::new_unchecked(DataType::Int64, buffer, values)
1509 };
1510 }
1511
1512 #[test]
1513 fn test_run_array_roundtrip() {
1514 let run = Int32Array::from(vec![3, 6, 9, 12]);
1515 let values = Int32Array::from(vec![Some(0), None, Some(1), None]);
1516 let array = RunArray::try_new(&run, &values).unwrap();
1517
1518 let (dt, buffer, values) = array.clone().into_parts();
1519 let created_from_parts =
1520 unsafe { RunArray::<Int32Type>::new_unchecked(dt, buffer, values) };
1521 assert_eq!(array, created_from_parts);
1522 }
1523
1524 #[test]
1525 fn test_from_array_data_offset() {
1526 let dt = DataType::RunEndEncoded(
1527 Arc::new(Field::new("run_ends", DataType::Int32, false)),
1528 Arc::new(Field::new("values", DataType::Float32, true)),
1529 );
1530
1531 let runs = ArrayData::builder(DataType::Int32)
1532 .len(2)
1533 .offset(2)
1534 .add_buffer(vec![-10_i32, -20, 1_i32, 4, 0, 100].into())
1535 .build()
1536 .unwrap();
1537 let values = Float32Array::from(vec![1.5, 2.5]);
1538
1539 let data = ArrayDataBuilder::new(dt)
1540 .len(3)
1541 .child_data(vec![runs, values.to_data()])
1542 .build()
1543 .unwrap();
1544 let array = RunArray::<Int32Type>::from(data);
1545 let array = array.downcast::<Float32Array>().unwrap();
1546
1547 assert_eq!(array.value(0), 1.5);
1548 assert_eq!(array.value(1), 2.5);
1549 assert_eq!(array.value(2), 2.5);
1550 }
1551}