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, FieldRef};
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_field(&self) -> &FieldRef {
211 match &self.data_type {
212 DataType::RunEndEncoded(f, _) => f,
213 _ => unreachable!(),
214 }
215 }
216
217 pub fn values_field(&self) -> &FieldRef {
219 match &self.data_type {
220 DataType::RunEndEncoded(_, f) => f,
221 _ => unreachable!(),
222 }
223 }
224
225 pub fn run_ends(&self) -> &RunEndBuffer<R::Native> {
227 &self.run_ends
228 }
229
230 pub fn values(&self) -> &ArrayRef {
235 &self.values
236 }
237
238 pub fn with_values(&self, values: ArrayRef) -> Self {
264 assert_eq!(values.len(), self.values.len());
265 let (run_ends_field, values_field) = match &self.data_type {
266 DataType::RunEndEncoded(r, v) => {
267 let new_v = Arc::new(Field::new(
268 v.name(),
269 values.data_type().clone(),
270 v.is_nullable(),
271 ));
272 (r, new_v)
273 }
274 _ => unreachable!("RunArray should have type RunEndEncoded"),
275 };
276 let data_type = DataType::RunEndEncoded(Arc::clone(run_ends_field), values_field);
277
278 Self {
279 data_type,
280 run_ends: self.run_ends.clone(),
281 values,
282 }
283 }
284
285 pub fn values_slice(&self) -> ArrayRef {
290 if self.is_empty() {
291 return self.values.slice(0, 0);
292 }
293 let start = self.get_start_physical_index();
294 let end = self.get_end_physical_index();
295 self.values.slice(start, end - start + 1)
296 }
297
298 pub fn get_start_physical_index(&self) -> usize {
302 self.run_ends.get_start_physical_index()
303 }
304
305 pub fn get_end_physical_index(&self) -> usize {
309 self.run_ends.get_end_physical_index()
310 }
311
312 pub fn downcast<V: 'static>(&self) -> Option<TypedRunArray<'_, R, V>> {
325 let values = self.values.as_any().downcast_ref()?;
326 Some(TypedRunArray {
327 run_array: self,
328 values,
329 })
330 }
331
332 pub fn get_physical_index(&self, logical_index: usize) -> usize {
336 self.run_ends.get_physical_index(logical_index)
337 }
338
339 #[inline]
343 pub fn get_physical_indices<I>(&self, logical_indices: &[I]) -> Result<Vec<usize>, ArrowError>
344 where
345 I: ArrowNativeType,
346 {
347 self.run_ends()
348 .get_physical_indices(logical_indices)
349 .map_err(|index| {
350 ArrowError::InvalidArgumentError(format!(
351 "Logical index {} is out of bounds for RunArray of length {}",
352 index.as_usize(),
353 self.len()
354 ))
355 })
356 }
357
358 pub fn slice(&self, offset: usize, length: usize) -> Self {
364 Self {
365 data_type: self.data_type.clone(),
366 run_ends: self.run_ends.slice(offset, length),
367 values: self.values.clone(),
368 }
369 }
370}
371
372impl<R: RunEndIndexType> From<ArrayData> for RunArray<R> {
373 fn from(data: ArrayData) -> Self {
375 let (data_type, len, _nulls, offset, _buffers, child_data) = data.into_parts();
376
377 match &data_type {
378 DataType::RunEndEncoded(_, _) => {}
379 _ => {
380 panic!(
381 "Invalid data type {data_type:?} for RunArray. Should be DataType::RunEndEncoded"
382 );
383 }
384 }
385
386 let [run_end_child, values_child]: [ArrayData; 2] = child_data
387 .try_into()
388 .expect("RunArray data should have exactly two child arrays");
389
390 let (
392 run_end_data_type,
393 _run_end_len,
394 _run_end_nulls,
395 _run_end_offset,
396 run_end_buffers,
397 _run_end_child_data,
398 ) = run_end_child.into_parts();
399 assert_eq!(run_end_data_type, R::DATA_TYPE, "Incorrect run ends type");
400 let [run_end_buffer]: [arrow_buffer::Buffer; 1] = run_end_buffers
401 .try_into()
402 .expect("Run ends should have exactly one buffer");
403 let scalar = ScalarBuffer::from(run_end_buffer);
404 let run_ends = unsafe { RunEndBuffer::new_unchecked(scalar, offset, len) };
405
406 let values = make_array(values_child);
407
408 Self {
409 data_type,
410 run_ends,
411 values,
412 }
413 }
414}
415
416impl<R: RunEndIndexType> From<RunArray<R>> for ArrayData {
417 fn from(array: RunArray<R>) -> Self {
418 let len = array.run_ends.len();
419 let offset = array.run_ends.offset();
420
421 let run_ends = ArrayDataBuilder::new(R::DATA_TYPE)
422 .len(array.run_ends.values().len())
423 .buffers(vec![array.run_ends.into_inner().into_inner()]);
424
425 let run_ends = unsafe { run_ends.build_unchecked() };
426
427 let builder = ArrayDataBuilder::new(array.data_type)
428 .len(len)
429 .offset(offset)
430 .child_data(vec![run_ends, array.values.to_data()]);
431
432 unsafe { builder.build_unchecked() }
433 }
434}
435
436unsafe impl<T: RunEndIndexType> Array for RunArray<T> {
438 fn as_any(&self) -> &dyn Any {
439 self
440 }
441
442 fn to_data(&self) -> ArrayData {
443 self.clone().into()
444 }
445
446 fn into_data(self) -> ArrayData {
447 self.into()
448 }
449
450 fn data_type(&self) -> &DataType {
451 &self.data_type
452 }
453
454 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
455 Arc::new(self.slice(offset, length))
456 }
457
458 fn len(&self) -> usize {
459 self.run_ends.len()
460 }
461
462 fn is_empty(&self) -> bool {
463 self.run_ends.is_empty()
464 }
465
466 fn shrink_to_fit(&mut self) {
467 self.run_ends.shrink_to_fit();
468 self.values.shrink_to_fit();
469 }
470
471 fn offset(&self) -> usize {
472 self.run_ends.offset()
473 }
474
475 fn nulls(&self) -> Option<&NullBuffer> {
476 None
477 }
478
479 fn logical_nulls(&self) -> Option<NullBuffer> {
480 let len = self.len();
481 let nulls = self.values.logical_nulls()?;
482 let mut out = BooleanBufferBuilder::new(len);
483 let offset = self.run_ends.offset();
484 let mut valid_start = 0;
485 let mut last_end = 0;
486 for (idx, end) in self.run_ends.values().iter().enumerate() {
487 let end = end.as_usize();
488 if end < offset {
489 continue;
490 }
491 let end = (end - offset).min(len);
492 if nulls.is_null(idx) {
493 if valid_start < last_end {
494 out.append_n(last_end - valid_start, true);
495 }
496 out.append_n(end - last_end, false);
497 valid_start = end;
498 }
499 last_end = end;
500 if end == len {
501 break;
502 }
503 }
504 if valid_start < len {
505 out.append_n(len - valid_start, true)
506 }
507 assert_eq!(out.len(), len);
509 Some(out.finish().into())
510 }
511
512 fn is_nullable(&self) -> bool {
513 !self.is_empty() && self.values.is_nullable()
514 }
515
516 fn get_buffer_memory_size(&self) -> usize {
517 self.run_ends.inner().inner().capacity() + self.values.get_buffer_memory_size()
518 }
519
520 fn get_array_memory_size(&self) -> usize {
521 std::mem::size_of::<Self>()
522 + self.run_ends.inner().inner().capacity()
523 + self.values.get_array_memory_size()
524 }
525
526 #[cfg(feature = "pool")]
527 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
528 self.run_ends.claim(pool);
529 self.values.claim(pool);
530 }
531}
532
533impl<R: RunEndIndexType> std::fmt::Debug for RunArray<R> {
534 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
535 writeln!(
536 f,
537 "RunArray {{run_ends: {:?}, values: {:?}}}",
538 self.run_ends.values(),
539 self.values
540 )
541 }
542}
543
544impl<'a, T: RunEndIndexType> FromIterator<Option<&'a str>> for RunArray<T> {
561 fn from_iter<I: IntoIterator<Item = Option<&'a str>>>(iter: I) -> Self {
562 let it = iter.into_iter();
563 let (lower, _) = it.size_hint();
564 let mut builder = StringRunBuilder::with_capacity(lower, 256);
565 it.for_each(|i| {
566 builder.append_option(i);
567 });
568
569 builder.finish()
570 }
571}
572
573impl<'a, T: RunEndIndexType> FromIterator<&'a str> for RunArray<T> {
588 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
589 let it = iter.into_iter();
590 let (lower, _) = it.size_hint();
591 let mut builder = StringRunBuilder::with_capacity(lower, 256);
592 it.for_each(|i| {
593 builder.append_value(i);
594 });
595
596 builder.finish()
597 }
598}
599
600pub type Int16RunArray = RunArray<Int16Type>;
614
615pub type Int32RunArray = RunArray<Int32Type>;
629
630pub type Int64RunArray = RunArray<Int64Type>;
644
645pub struct TypedRunArray<'a, R: RunEndIndexType, V> {
663 run_array: &'a RunArray<R>,
665
666 values: &'a V,
668}
669
670impl<R: RunEndIndexType, V> Clone for TypedRunArray<'_, R, V> {
672 fn clone(&self) -> Self {
673 *self
674 }
675}
676
677impl<R: RunEndIndexType, V> Copy for TypedRunArray<'_, R, V> {}
678
679impl<R: RunEndIndexType, V> std::fmt::Debug for TypedRunArray<'_, R, V> {
680 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
681 writeln!(f, "TypedRunArray({:?})", self.run_array)
682 }
683}
684
685impl<'a, R: RunEndIndexType, V> TypedRunArray<'a, R, V> {
686 pub fn run_ends(&self) -> &'a RunEndBuffer<R::Native> {
688 self.run_array.run_ends()
689 }
690
691 pub fn values(&self) -> &'a V {
693 self.values
694 }
695
696 pub fn run_array(&self) -> &'a RunArray<R> {
698 self.run_array
699 }
700}
701
702unsafe impl<R: RunEndIndexType, V: Sync> Array for TypedRunArray<'_, R, V> {
704 fn as_any(&self) -> &dyn Any {
705 self.run_array
706 }
707
708 fn to_data(&self) -> ArrayData {
709 self.run_array.to_data()
710 }
711
712 fn into_data(self) -> ArrayData {
713 self.run_array.into_data()
714 }
715
716 fn data_type(&self) -> &DataType {
717 self.run_array.data_type()
718 }
719
720 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
721 Arc::new(self.run_array.slice(offset, length))
722 }
723
724 fn len(&self) -> usize {
725 self.run_array.len()
726 }
727
728 fn is_empty(&self) -> bool {
729 self.run_array.is_empty()
730 }
731
732 fn offset(&self) -> usize {
733 self.run_array.offset()
734 }
735
736 fn nulls(&self) -> Option<&NullBuffer> {
737 self.run_array.nulls()
738 }
739
740 fn logical_nulls(&self) -> Option<NullBuffer> {
741 self.run_array.logical_nulls()
742 }
743
744 fn logical_null_count(&self) -> usize {
745 self.run_array.logical_null_count()
746 }
747
748 fn is_nullable(&self) -> bool {
749 self.run_array.is_nullable()
750 }
751
752 fn get_buffer_memory_size(&self) -> usize {
753 self.run_array.get_buffer_memory_size()
754 }
755
756 fn get_array_memory_size(&self) -> usize {
757 self.run_array.get_array_memory_size()
758 }
759
760 #[cfg(feature = "pool")]
761 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
762 self.run_array.claim(pool);
763 }
764}
765
766impl<'a, R, V> ArrayAccessor for TypedRunArray<'a, R, V>
769where
770 R: RunEndIndexType,
771 V: Sync + Send,
772 &'a V: ArrayAccessor,
773 <&'a V as ArrayAccessor>::Item: Default,
774{
775 type Item = <&'a V as ArrayAccessor>::Item;
776
777 fn value(&self, logical_index: usize) -> Self::Item {
778 assert!(
779 logical_index < self.len(),
780 "Trying to access an element at index {} from a TypedRunArray of length {}",
781 logical_index,
782 self.len()
783 );
784 unsafe { self.value_unchecked(logical_index) }
785 }
786
787 unsafe fn value_unchecked(&self, logical_index: usize) -> Self::Item {
788 let physical_index = self.run_array.get_physical_index(logical_index);
789 unsafe { self.values().value_unchecked(physical_index) }
790 }
791}
792
793impl<'a, R, V> IntoIterator for TypedRunArray<'a, R, V>
794where
795 R: RunEndIndexType,
796 V: Sync + Send,
797 &'a V: ArrayAccessor,
798 <&'a V as ArrayAccessor>::Item: Default,
799{
800 type Item = Option<<&'a V as ArrayAccessor>::Item>;
801 type IntoIter = RunArrayIter<'a, R, V>;
802
803 fn into_iter(self) -> Self::IntoIter {
804 RunArrayIter::new(self)
805 }
806}
807pub trait AnyRunEndArray: Array {
812 fn values(&self) -> &Arc<dyn Array>;
814
815 fn with_values(&self, values: ArrayRef) -> ArrayRef;
818}
819
820impl<R: RunEndIndexType> AnyRunEndArray for RunArray<R> {
821 fn values(&self) -> &Arc<dyn Array> {
822 &self.values
823 }
824
825 fn with_values(&self, values: ArrayRef) -> ArrayRef {
826 Arc::new(RunArray::<R>::with_values(self, values))
827 }
828}
829
830#[cfg(test)]
831mod tests {
832 use rand::RngExt;
833 use rand::rng;
834 use rand::seq::SliceRandom;
835
836 use super::*;
837 use crate::Int64Array;
838 use crate::builder::PrimitiveRunBuilder;
839 use crate::cast::AsArray;
840 use crate::new_empty_array;
841 use crate::types::{Int8Type, UInt32Type};
842 use crate::{Int16Array, Int32Array, StringArray};
843
844 fn build_input_array(size: usize) -> Vec<Option<i32>> {
845 let mut seed: Vec<Option<i32>> = vec![
848 None,
849 None,
850 None,
851 Some(1),
852 Some(2),
853 Some(3),
854 Some(4),
855 Some(5),
856 Some(6),
857 Some(7),
858 Some(8),
859 Some(9),
860 ];
861 let mut result: Vec<Option<i32>> = Vec::with_capacity(size);
862 let mut ix = 0;
863 let mut rng = rng();
864 let max_run_length = 8_usize.min(1_usize.max(size / 2));
866 while result.len() < size {
867 if ix == 0 {
869 seed.shuffle(&mut rng);
870 }
871 let num = max_run_length.min(rng.random_range(1..=max_run_length));
873 for _ in 0..num {
874 result.push(seed[ix]);
875 }
876 ix += 1;
877 if ix == seed.len() {
878 ix = 0
879 }
880 }
881 result.resize(size, None);
882 result
883 }
884
885 fn compare_logical_and_physical_indices(
887 logical_indices: &[u32],
888 logical_array: &[Option<i32>],
889 physical_indices: &[usize],
890 physical_array: &PrimitiveArray<Int32Type>,
891 ) {
892 assert_eq!(logical_indices.len(), physical_indices.len());
893
894 logical_indices
896 .iter()
897 .map(|f| f.as_usize())
898 .zip(physical_indices.iter())
899 .for_each(|(logical_ix, physical_ix)| {
900 let expected = logical_array[logical_ix];
901 match expected {
902 Some(val) => {
903 assert!(physical_array.is_valid(*physical_ix));
904 let actual = physical_array.value(*physical_ix);
905 assert_eq!(val, actual);
906 }
907 None => {
908 assert!(physical_array.is_null(*physical_ix))
909 }
910 };
911 });
912 }
913 #[test]
914 fn test_run_array() {
915 let value_data =
917 PrimitiveArray::<Int8Type>::from_iter_values([10_i8, 11, 12, 13, 14, 15, 16, 17]);
918
919 let run_ends_values = [4_i16, 6, 7, 9, 13, 18, 20, 22];
921 let run_ends_data =
922 PrimitiveArray::<Int16Type>::from_iter_values(run_ends_values.iter().copied());
923
924 let ree_array = RunArray::<Int16Type>::try_new(&run_ends_data, &value_data).unwrap();
926
927 assert_eq!(ree_array.len(), 22);
928 assert_eq!(ree_array.null_count(), 0);
929
930 let values = ree_array.values();
931 assert_eq!(value_data.into_data(), values.to_data());
932 assert_eq!(&DataType::Int8, values.data_type());
933
934 let run_ends = ree_array.run_ends();
935 assert_eq!(run_ends.values(), &run_ends_values);
936 }
937
938 #[test]
939 fn test_run_array_empty() {
940 let runs = new_empty_array(&DataType::Int16);
941 let runs = runs.as_primitive::<Int16Type>();
942 let values = new_empty_array(&DataType::Int64);
943 let array = RunArray::try_new(runs, &values).unwrap();
944
945 fn assertions(array: &RunArray<Int16Type>) {
946 assert!(array.is_empty());
947 assert_eq!(array.get_start_physical_index(), 0);
948 assert_eq!(array.get_end_physical_index(), 0);
949 assert!(array.get_physical_indices::<i16>(&[]).unwrap().is_empty());
950 assert!(array.run_ends().is_empty());
951 assert_eq!(array.run_ends().sliced_values().count(), 0);
952 }
953
954 assertions(&array);
955 assertions(&array.slice(0, 0));
956 }
957
958 #[test]
959 fn test_run_array_fmt_debug() {
960 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::with_capacity(3);
961 builder.append_value(12345678);
962 builder.append_null();
963 builder.append_value(22345678);
964 let array = builder.finish();
965 assert_eq!(
966 "RunArray {run_ends: [1, 2, 3], values: PrimitiveArray<UInt32>\n[\n 12345678,\n null,\n 22345678,\n]}\n",
967 format!("{array:?}")
968 );
969
970 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::with_capacity(20);
971 for _ in 0..20 {
972 builder.append_value(1);
973 }
974 let array = builder.finish();
975
976 assert_eq!(array.len(), 20);
977 assert_eq!(array.null_count(), 0);
978 assert_eq!(array.logical_null_count(), 0);
979
980 assert_eq!(
981 "RunArray {run_ends: [20], values: PrimitiveArray<UInt32>\n[\n 1,\n]}\n",
982 format!("{array:?}")
983 );
984 }
985
986 #[test]
987 fn test_run_array_from_iter() {
988 let test = vec!["a", "a", "b", "c"];
989 let array: RunArray<Int16Type> = test
990 .iter()
991 .map(|&x| if x == "b" { None } else { Some(x) })
992 .collect();
993 assert_eq!(
994 "RunArray {run_ends: [2, 3, 4], values: StringArray\n[\n \"a\",\n null,\n \"c\",\n]}\n",
995 format!("{array:?}")
996 );
997
998 assert_eq!(array.len(), 4);
999 assert_eq!(array.null_count(), 0);
1000 assert_eq!(array.logical_null_count(), 1);
1001
1002 let array: RunArray<Int16Type> = test.into_iter().collect();
1003 assert_eq!(
1004 "RunArray {run_ends: [2, 3, 4], values: StringArray\n[\n \"a\",\n \"b\",\n \"c\",\n]}\n",
1005 format!("{array:?}")
1006 );
1007 }
1008
1009 #[test]
1010 fn test_run_array_run_ends_as_primitive_array() {
1011 let test = vec!["a", "b", "c", "a"];
1012 let array: RunArray<Int16Type> = test.into_iter().collect();
1013
1014 assert_eq!(array.len(), 4);
1015 assert_eq!(array.null_count(), 0);
1016 assert_eq!(array.logical_null_count(), 0);
1017
1018 let run_ends = array.run_ends();
1019 assert_eq!(&[1, 2, 3, 4], run_ends.values());
1020 }
1021
1022 #[test]
1023 fn test_run_array_as_primitive_array_with_null() {
1024 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1025 let array: RunArray<Int32Type> = test.into_iter().collect();
1026
1027 assert_eq!(array.len(), 6);
1028 assert_eq!(array.null_count(), 0);
1029 assert_eq!(array.logical_null_count(), 3);
1030
1031 let run_ends = array.run_ends();
1032 assert_eq!(&[1, 2, 3, 5, 6], run_ends.values());
1033
1034 let values_data = array.values();
1035 assert_eq!(2, values_data.null_count());
1036 assert_eq!(5, values_data.len());
1037 }
1038
1039 #[test]
1040 fn test_run_array_all_nulls() {
1041 let test = vec![None, None, None];
1042 let array: RunArray<Int32Type> = test.into_iter().collect();
1043
1044 assert_eq!(array.len(), 3);
1045 assert_eq!(array.null_count(), 0);
1046 assert_eq!(array.logical_null_count(), 3);
1047
1048 let run_ends = array.run_ends();
1049 assert_eq!(3, run_ends.len());
1050 assert_eq!(&[3], run_ends.values());
1051
1052 let values_data = array.values();
1053 assert_eq!(1, values_data.null_count());
1054 }
1055
1056 #[test]
1057 fn test_run_array_try_new() {
1058 let values: StringArray = [Some("foo"), Some("bar"), None, Some("baz")]
1059 .into_iter()
1060 .collect();
1061 let run_ends: Int32Array = [Some(1), Some(2), Some(3), Some(4)].into_iter().collect();
1062
1063 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1064 assert_eq!(array.values().data_type(), &DataType::Utf8);
1065
1066 assert_eq!(array.null_count(), 0);
1067 assert_eq!(array.logical_null_count(), 1);
1068 assert_eq!(array.len(), 4);
1069 assert_eq!(array.values().null_count(), 1);
1070
1071 assert_eq!(
1072 "RunArray {run_ends: [1, 2, 3, 4], values: StringArray\n[\n \"foo\",\n \"bar\",\n null,\n \"baz\",\n]}\n",
1073 format!("{array:?}")
1074 );
1075 }
1076
1077 #[test]
1078 fn test_run_array_int16_type_definition() {
1079 let array: Int16RunArray = vec!["a", "a", "b", "c", "c"].into_iter().collect();
1080 let values: Arc<dyn Array> = Arc::new(StringArray::from(vec!["a", "b", "c"]));
1081 assert_eq!(array.run_ends().values(), &[2, 3, 5]);
1082 assert_eq!(array.values(), &values);
1083 }
1084
1085 #[test]
1086 fn test_run_array_empty_string() {
1087 let array: Int16RunArray = vec!["a", "a", "", "", "c"].into_iter().collect();
1088 let values: Arc<dyn Array> = Arc::new(StringArray::from(vec!["a", "", "c"]));
1089 assert_eq!(array.run_ends().values(), &[2, 4, 5]);
1090 assert_eq!(array.values(), &values);
1091 }
1092
1093 #[test]
1094 fn test_run_array_length_mismatch() {
1095 let values: StringArray = [Some("foo"), Some("bar"), None, Some("baz")]
1096 .into_iter()
1097 .collect();
1098 let run_ends: Int32Array = [Some(1), Some(2), Some(3)].into_iter().collect();
1099
1100 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1101 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());
1102 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1103 }
1104 #[test]
1105 fn test_run_array_with_values_changes_value_type() {
1106 let values = StringArray::from(vec!["foo", "bar", "baz"]);
1107 let run_ends: Int32Array = [Some(1), Some(2), Some(3)].into_iter().collect();
1108 let ree = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1109
1110 let new_values = Int64Array::from(vec![10, 20, 30]);
1111 let result = ree.with_values(Arc::new(new_values));
1112
1113 match result.data_type() {
1114 DataType::RunEndEncoded(_, v) => {
1115 assert_eq!(v.data_type(), &DataType::Int64);
1116 }
1117 other => panic!("expected RunEndEncoded, got {other:?}"),
1118 }
1119
1120 assert_eq!(result.values().data_type(), &DataType::Int64);
1121 assert_eq!(result.values().len(), 3);
1122 }
1123
1124 #[test]
1125 fn test_run_array_run_ends_with_null() {
1126 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1127 .into_iter()
1128 .collect();
1129 let run_ends: Int32Array = [Some(1), None, Some(3)].into_iter().collect();
1130
1131 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1132 let expected = ArrowError::InvalidArgumentError(
1133 "Found null values in run_ends array. The run_ends array should not have null values."
1134 .to_string(),
1135 );
1136 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1137 }
1138
1139 #[test]
1140 fn test_run_array_run_ends_with_zeroes() {
1141 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1142 .into_iter()
1143 .collect();
1144 let run_ends: Int32Array = [Some(0), Some(1), Some(3)].into_iter().collect();
1145
1146 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1147 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());
1148 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1149 }
1150
1151 #[test]
1152 fn test_run_array_run_ends_non_increasing() {
1153 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1154 .into_iter()
1155 .collect();
1156 let run_ends: Int32Array = [Some(1), Some(4), Some(4)].into_iter().collect();
1157
1158 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1159 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());
1160 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1161 }
1162
1163 #[test]
1164 #[should_panic(expected = "Incorrect run ends type")]
1165 fn test_run_array_run_ends_data_type_mismatch() {
1166 let a = RunArray::<Int32Type>::from_iter(["32"]);
1167 let _ = RunArray::<Int64Type>::from(a.into_data());
1168 }
1169
1170 #[test]
1171 fn test_ree_array_accessor() {
1172 let input_array = build_input_array(256);
1173
1174 let mut builder =
1176 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
1177 builder.extend(input_array.iter().copied());
1178 let run_array = builder.finish();
1179 let typed = run_array.downcast::<PrimitiveArray<Int32Type>>().unwrap();
1180
1181 for (i, inp_val) in input_array.iter().enumerate() {
1183 if let Some(val) = inp_val {
1184 let actual = typed.value(i);
1185 assert_eq!(*val, actual)
1186 } else {
1187 let physical_ix = run_array.get_physical_index(i);
1188 assert!(typed.values().is_null(physical_ix));
1189 };
1190 }
1191 }
1192
1193 #[test]
1194 #[cfg_attr(miri, ignore)] fn test_get_physical_indices() {
1196 for logical_len in (0..250).step_by(10) {
1198 let input_array = build_input_array(logical_len);
1199
1200 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
1202 builder.extend(input_array.clone());
1203
1204 let run_array = builder.finish();
1205 let physical_values_array = run_array.values().as_primitive::<Int32Type>();
1206
1207 let mut logical_indices: Vec<u32> = (0_u32..(logical_len as u32)).collect();
1209 logical_indices.append(&mut logical_indices.clone());
1211 let mut rng = rng();
1212 logical_indices.shuffle(&mut rng);
1213
1214 let physical_indices = run_array.get_physical_indices(&logical_indices).unwrap();
1215
1216 assert_eq!(logical_indices.len(), physical_indices.len());
1217
1218 compare_logical_and_physical_indices(
1220 &logical_indices,
1221 &input_array,
1222 &physical_indices,
1223 physical_values_array,
1224 );
1225 }
1226 }
1227
1228 #[test]
1229 #[cfg_attr(miri, ignore)] fn test_get_physical_indices_sliced() {
1231 let total_len = 80;
1232 let input_array = build_input_array(total_len);
1233
1234 let mut builder =
1236 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
1237 builder.extend(input_array.iter().copied());
1238 let run_array = builder.finish();
1239 let physical_values_array = run_array.values().as_primitive::<Int32Type>();
1240
1241 for slice_len in 1..=total_len {
1243 let mut logical_indices: Vec<u32> = (0_u32..(slice_len as u32)).collect();
1245 logical_indices.append(&mut logical_indices.clone());
1247 let mut rng = rng();
1248 logical_indices.shuffle(&mut rng);
1249
1250 let sliced_input_array = &input_array[0..slice_len];
1253
1254 let sliced_run_array: RunArray<Int16Type> =
1256 run_array.slice(0, slice_len).into_data().into();
1257
1258 let physical_indices = sliced_run_array
1260 .get_physical_indices(&logical_indices)
1261 .unwrap();
1262
1263 compare_logical_and_physical_indices(
1264 &logical_indices,
1265 sliced_input_array,
1266 &physical_indices,
1267 physical_values_array,
1268 );
1269
1270 let sliced_input_array = &input_array[total_len - slice_len..total_len];
1273
1274 let sliced_run_array: RunArray<Int16Type> = run_array
1276 .slice(total_len - slice_len, slice_len)
1277 .into_data()
1278 .into();
1279
1280 let physical_indices = sliced_run_array
1282 .get_physical_indices(&logical_indices)
1283 .unwrap();
1284
1285 compare_logical_and_physical_indices(
1286 &logical_indices,
1287 sliced_input_array,
1288 &physical_indices,
1289 physical_values_array,
1290 );
1291 }
1292 }
1293
1294 #[test]
1295 fn test_logical_nulls() {
1296 let run = Int32Array::from(vec![3, 6, 9, 12]);
1297 let values = Int32Array::from(vec![Some(0), None, Some(1), None]);
1298 let array = RunArray::try_new(&run, &values).unwrap();
1299
1300 let expected = [
1301 true, true, true, false, false, false, true, true, true, false, false, false,
1302 ];
1303
1304 let n = array.logical_nulls().unwrap();
1305 assert_eq!(n.null_count(), 6);
1306
1307 let slices = [(0, 12), (0, 2), (2, 5), (3, 0), (3, 3), (3, 4), (4, 8)];
1308 for (offset, length) in slices {
1309 let a = array.slice(offset, length);
1310 let n = a.logical_nulls().unwrap();
1311 let n = n.into_iter().collect::<Vec<_>>();
1312 assert_eq!(&n, &expected[offset..offset + length], "{offset} {length}");
1313 }
1314 }
1315
1316 #[test]
1317 fn test_run_array_eq_identical() {
1318 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1319 let values1 = StringArray::from(vec!["a", "b", "c"]);
1320 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1321
1322 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1323 let values2 = StringArray::from(vec!["a", "b", "c"]);
1324 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1325
1326 assert_eq!(array1, array2);
1327 }
1328
1329 #[test]
1330 fn test_run_array_ne_different_run_ends() {
1331 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1332 let values1 = StringArray::from(vec!["a", "b", "c"]);
1333 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1334
1335 let run_ends2 = Int32Array::from(vec![1, 4, 6]);
1336 let values2 = StringArray::from(vec!["a", "b", "c"]);
1337 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1338
1339 assert_ne!(array1, array2);
1340 }
1341
1342 #[test]
1343 fn test_run_array_ne_different_values() {
1344 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1345 let values1 = StringArray::from(vec!["a", "b", "c"]);
1346 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1347
1348 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1349 let values2 = StringArray::from(vec!["a", "b", "d"]);
1350 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1351
1352 assert_ne!(array1, array2);
1353 }
1354
1355 #[test]
1356 fn test_run_array_eq_with_nulls() {
1357 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1358 let values1 = StringArray::from(vec![Some("a"), None, Some("c")]);
1359 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1360
1361 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1362 let values2 = StringArray::from(vec![Some("a"), None, Some("c")]);
1363 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1364
1365 assert_eq!(array1, array2);
1366 }
1367
1368 #[test]
1369 fn test_run_array_eq_different_run_end_types() {
1370 let run_ends_i16_1 = Int16Array::from(vec![2_i16, 4, 6]);
1371 let values_i16_1 = StringArray::from(vec!["a", "b", "c"]);
1372 let array_i16_1 = RunArray::<Int16Type>::try_new(&run_ends_i16_1, &values_i16_1).unwrap();
1373
1374 let run_ends_i16_2 = Int16Array::from(vec![2_i16, 4, 6]);
1375 let values_i16_2 = StringArray::from(vec!["a", "b", "c"]);
1376 let array_i16_2 = RunArray::<Int16Type>::try_new(&run_ends_i16_2, &values_i16_2).unwrap();
1377
1378 assert_eq!(array_i16_1, array_i16_2);
1379 }
1380
1381 #[test]
1382 fn test_run_array_values_slice() {
1383 let run_ends: PrimitiveArray<Int32Type> = vec![2, 5, 20].into();
1385 let values: PrimitiveArray<Int32Type> = vec![0, 1, 2].into();
1386 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1387
1388 let slice = array.slice(1, 4); assert_eq!(slice.get_start_physical_index(), 0);
1395 assert_eq!(slice.get_end_physical_index(), 1);
1396
1397 let values_slice = slice.values_slice();
1398 let values_slice = values_slice.as_primitive::<Int32Type>();
1399 assert_eq!(values_slice.values(), &[0, 1]);
1400
1401 let slice2 = array.slice(2, 3); assert_eq!(slice2.get_start_physical_index(), 1);
1405 assert_eq!(slice2.get_end_physical_index(), 1);
1406
1407 let values_slice2 = slice2.values_slice();
1408 let values_slice2 = values_slice2.as_primitive::<Int32Type>();
1409 assert_eq!(values_slice2.values(), &[1]);
1410 }
1411
1412 #[test]
1413 fn test_run_array_values_slice_empty() {
1414 let run_ends = Int32Array::from(vec![2, 5, 10]);
1415 let values = StringArray::from(vec!["a", "b", "c"]);
1416 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1417
1418 let slice = array.slice(0, 0);
1419 assert_eq!(slice.len(), 0);
1420
1421 let values_slice = slice.values_slice();
1422 assert_eq!(values_slice.len(), 0);
1423 assert_eq!(values_slice.data_type(), &DataType::Utf8);
1424 }
1425
1426 #[test]
1427 fn test_run_array_eq_empty() {
1428 let run_ends = Int32Array::from(vec![2, 5, 10]);
1429 let values = StringArray::from(vec!["a", "b", "c"]);
1430 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1431
1432 let slice1 = array.slice(0, 0);
1433 let slice2 = array.slice(1, 0);
1434 let slice3 = array.slice(10, 0);
1435
1436 assert_eq!(slice1, slice2);
1437 assert_eq!(slice2, slice3);
1438
1439 let empty_array = new_empty_array(array.data_type());
1440 let empty_array = crate::cast::as_run_array::<Int32Type>(empty_array.as_ref());
1441
1442 assert_eq!(&slice1, empty_array);
1443 }
1444
1445 #[test]
1446 fn test_run_array_eq_diff_physical_same_logical() {
1447 let run_ends1 = Int32Array::from(vec![1, 3, 6]);
1448 let values1 = StringArray::from(vec!["a", "b", "c"]);
1449 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1450
1451 let run_ends2 = Int32Array::from(vec![1, 2, 3, 4, 5, 6]);
1452 let values2 = StringArray::from(vec!["a", "b", "b", "c", "c", "c"]);
1453 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1454
1455 assert_eq!(array1, array2);
1456 }
1457
1458 #[test]
1459 fn test_run_array_eq_sliced() {
1460 let run_ends1 = Int32Array::from(vec![2, 5, 10]);
1461 let values1 = StringArray::from(vec!["a", "b", "c"]);
1462 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1463 let slice1 = array1.slice(1, 6);
1466 let run_ends2 = Int32Array::from(vec![1, 4, 6]);
1469 let values2 = StringArray::from(vec!["a", "b", "c"]);
1470 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1471 assert_eq!(slice1, array2);
1474
1475 let slice2 = array1.slice(2, 3);
1476 let run_ends3 = Int32Array::from(vec![3]);
1478 let values3 = StringArray::from(vec!["b"]);
1479 let array3 = RunArray::<Int32Type>::try_new(&run_ends3, &values3).unwrap();
1480 assert_eq!(slice2, array3);
1481 }
1482
1483 #[test]
1484 fn test_run_array_eq_sliced_different_offsets() {
1485 let run_ends1 = Int32Array::from(vec![2, 5, 10]);
1486 let values1 = StringArray::from(vec!["a", "b", "c"]);
1487 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1488 let array2 = array1.clone();
1489 assert_eq!(array1, array2);
1490
1491 let slice1 = array1.slice(1, 4); let slice2 = array1.slice(1, 4);
1493 assert_eq!(slice1, slice2);
1494
1495 let slice3 = array1.slice(0, 4); assert_ne!(slice1, slice3);
1497 }
1498
1499 #[test]
1500 #[cfg(not(feature = "force_validate"))]
1501 fn allow_to_create_invalid_array_using_new_unchecked() {
1502 let valid = RunArray::<Int32Type>::from_iter(["32"]);
1503 let (_, buffer, values) = valid.into_parts();
1504
1505 let _ = unsafe {
1506 RunArray::<Int32Type>::new_unchecked(DataType::Int64, buffer, values)
1508 };
1509 }
1510
1511 #[test]
1512 #[should_panic(
1513 expected = "Invalid data type Int64 for RunArray. Should be DataType::RunEndEncoded"
1514 )]
1515 #[cfg(feature = "force_validate")]
1516 fn should_not_be_able_to_create_invalid_array_using_new_unchecked_when_force_validate_is_enabled()
1517 {
1518 let valid = RunArray::<Int32Type>::from_iter(["32"]);
1519 let (_, buffer, values) = valid.into_parts();
1520
1521 let _ = unsafe {
1522 RunArray::<Int32Type>::new_unchecked(DataType::Int64, buffer, values)
1524 };
1525 }
1526
1527 #[test]
1528 fn test_run_array_roundtrip() {
1529 let run = Int32Array::from(vec![3, 6, 9, 12]);
1530 let values = Int32Array::from(vec![Some(0), None, Some(1), None]);
1531 let array = RunArray::try_new(&run, &values).unwrap();
1532
1533 let (dt, buffer, values) = array.clone().into_parts();
1534 let created_from_parts =
1535 unsafe { RunArray::<Int32Type>::new_unchecked(dt, buffer, values) };
1536 assert_eq!(array, created_from_parts);
1537 }
1538}