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 if run_ends.len() != values.len() {
121 return Err(ArrowError::InvalidArgumentError(format!(
122 "The run_ends array length should be the same as values array length. Run_ends array length is {}, values array length is {}",
123 run_ends.len(),
124 values.len()
125 )));
126 }
127
128 if run_ends.nulls().is_some() {
130 return Err(ArrowError::InvalidArgumentError(
131 "Found null values in run_ends array. The run_ends array should not have null values."
132 .to_string(),
133 ));
134 }
135
136 if let Some(first) = run_ends.values().first() {
138 let mut prev_value = *first;
139 if prev_value <= R::Native::usize_as(0) {
140 return Err(ArrowError::InvalidArgumentError(format!(
141 "The values in run_ends array should be strictly positive. Found value {prev_value:?} at index 0 that does not match the criteria."
142 )));
143 }
144
145 for (ix, &run_end) in run_ends.values().iter().enumerate().skip(1) {
146 if run_end <= prev_value {
147 return Err(ArrowError::InvalidArgumentError(format!(
148 "The values in run_ends array should be strictly increasing. Found value {run_end:?} at index {ix} with previous value {prev_value:?} that does not match the criteria."
149 )));
150 }
151 prev_value = run_end;
152 }
153 }
154
155 let data_type = DataType::RunEndEncoded(
156 Arc::new(Field::new(
157 Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
158 run_ends.data_type().clone(),
159 false,
160 )),
161 Arc::new(Field::new(
162 Field::REE_VALUES_FIELD_DEFAULT_NAME,
163 values.data_type().clone(),
164 true,
165 )),
166 );
167
168 let logical_len = RunArray::logical_len(run_ends);
169 let run_ends_buffer =
172 unsafe { RunEndBuffer::new_unchecked(run_ends.values().clone(), 0, logical_len) };
173
174 Ok(Self {
175 data_type,
176 run_ends: run_ends_buffer,
177 values: values.slice(0, values.len()),
178 })
179 }
180
181 pub unsafe fn new_unchecked(
187 data_type: DataType,
188 run_ends: RunEndBuffer<R::Native>,
189 values: ArrayRef,
190 ) -> Self {
191 if cfg!(feature = "force_validate") {
192 match &data_type {
193 DataType::RunEndEncoded(run_ends, values_field) => {
194 assert!(!run_ends.is_nullable(), "run_ends should not be nullable");
195 assert_eq!(
196 run_ends.data_type(),
197 &R::DATA_TYPE,
198 "Incorrect run ends type"
199 );
200 assert_eq!(
201 values_field.data_type(),
202 values.data_type(),
203 "Incorrect values type"
204 );
205 }
206 _ => {
207 panic!(
208 "Invalid data type {data_type:?} for RunArray. Should be DataType::RunEndEncoded"
209 );
210 }
211 }
212
213 let run_array = Self {
214 data_type,
215 run_ends,
216 values,
217 };
218
219 run_array
226 .to_data()
227 .validate_data()
228 .expect("RunArray data should be valid");
229
230 return run_array;
231 }
232
233 Self {
234 data_type,
235 run_ends,
236 values,
237 }
238 }
239
240 pub fn into_parts(self) -> (DataType, RunEndBuffer<R::Native>, ArrayRef) {
242 (self.data_type, self.run_ends, self.values)
243 }
244
245 pub fn run_ends_field(&self) -> &FieldRef {
247 match &self.data_type {
248 DataType::RunEndEncoded(f, _) => f,
249 _ => unreachable!(),
250 }
251 }
252
253 pub fn values_field(&self) -> &FieldRef {
255 match &self.data_type {
256 DataType::RunEndEncoded(_, f) => f,
257 _ => unreachable!(),
258 }
259 }
260
261 pub fn run_ends(&self) -> &RunEndBuffer<R::Native> {
263 &self.run_ends
264 }
265
266 pub fn values(&self) -> &ArrayRef {
271 &self.values
272 }
273
274 pub fn with_values(&self, values: ArrayRef) -> Self {
300 assert_eq!(values.len(), self.values.len());
301 let (run_ends_field, values_field) = match &self.data_type {
302 DataType::RunEndEncoded(r, v) => {
303 let new_v = Arc::new(Field::new(
304 v.name(),
305 values.data_type().clone(),
306 v.is_nullable(),
307 ));
308 (r, new_v)
309 }
310 _ => unreachable!("RunArray should have type RunEndEncoded"),
311 };
312 let data_type = DataType::RunEndEncoded(Arc::clone(run_ends_field), values_field);
313
314 Self {
315 data_type,
316 run_ends: self.run_ends.clone(),
317 values,
318 }
319 }
320
321 pub fn values_slice(&self) -> ArrayRef {
326 if self.is_empty() {
327 return self.values.slice(0, 0);
328 }
329 let start = self.get_start_physical_index();
330 let end = self.get_end_physical_index();
331 self.values.slice(start, end - start + 1)
332 }
333
334 pub fn get_start_physical_index(&self) -> usize {
338 self.run_ends.get_start_physical_index()
339 }
340
341 pub fn get_end_physical_index(&self) -> usize {
345 self.run_ends.get_end_physical_index()
346 }
347
348 pub fn downcast<V: 'static>(&self) -> Option<TypedRunArray<'_, R, V>> {
361 let values = self.values.as_any().downcast_ref()?;
362 Some(TypedRunArray {
363 run_array: self,
364 values,
365 })
366 }
367
368 pub fn get_physical_index(&self, logical_index: usize) -> usize {
372 self.run_ends.get_physical_index(logical_index)
373 }
374
375 #[inline]
379 pub fn get_physical_indices<I>(&self, logical_indices: &[I]) -> Result<Vec<usize>, ArrowError>
380 where
381 I: ArrowNativeType,
382 {
383 self.run_ends()
384 .get_physical_indices(logical_indices)
385 .map_err(|index| {
386 ArrowError::InvalidArgumentError(format!(
387 "Logical index {} is out of bounds for RunArray of length {}",
388 index.as_usize(),
389 self.len()
390 ))
391 })
392 }
393
394 pub fn slice(&self, offset: usize, length: usize) -> Self {
400 Self {
401 data_type: self.data_type.clone(),
402 run_ends: self.run_ends.slice(offset, length),
403 values: self.values.clone(),
404 }
405 }
406}
407
408impl<R: RunEndIndexType> From<ArrayData> for RunArray<R> {
409 fn from(data: ArrayData) -> Self {
411 let (data_type, len, _nulls, offset, _buffers, child_data) = data.into_parts();
412
413 match &data_type {
414 DataType::RunEndEncoded(_, _) => {}
415 _ => {
416 panic!(
417 "Invalid data type {data_type:?} for RunArray. Should be DataType::RunEndEncoded"
418 );
419 }
420 }
421
422 let [run_end_child, values_child]: [ArrayData; 2] = child_data
423 .try_into()
424 .expect("RunArray data should have exactly two child arrays");
425
426 let (
428 run_end_data_type,
429 run_end_len,
430 _run_end_nulls,
431 run_end_offset,
432 run_end_buffers,
433 _run_end_child_data,
434 ) = run_end_child.into_parts();
435 assert_eq!(run_end_data_type, R::DATA_TYPE, "Incorrect run ends type");
436 let [run_end_buffer]: [arrow_buffer::Buffer; 1] = run_end_buffers
437 .try_into()
438 .expect("Run ends should have exactly one buffer");
439 let scalar = ScalarBuffer::new(run_end_buffer, run_end_offset, run_end_len);
440 let run_ends = unsafe { RunEndBuffer::new_unchecked(scalar, offset, len) };
441
442 let values = make_array(values_child);
443
444 Self {
445 data_type,
446 run_ends,
447 values,
448 }
449 }
450}
451
452impl<R: RunEndIndexType> From<RunArray<R>> for ArrayData {
453 fn from(array: RunArray<R>) -> Self {
454 let len = array.run_ends.len();
455 let offset = array.run_ends.offset();
456
457 let run_ends = ArrayDataBuilder::new(R::DATA_TYPE)
458 .len(array.run_ends.values().len())
459 .buffers(vec![array.run_ends.into_inner().into_inner()]);
460
461 let run_ends = unsafe { run_ends.build_unchecked() };
462
463 let builder = ArrayDataBuilder::new(array.data_type)
464 .len(len)
465 .offset(offset)
466 .child_data(vec![run_ends, array.values.to_data()]);
467
468 unsafe { builder.build_unchecked() }
469 }
470}
471
472unsafe impl<T: RunEndIndexType> Array for RunArray<T> {
474 fn as_any(&self) -> &dyn Any {
475 self
476 }
477
478 fn to_data(&self) -> ArrayData {
479 self.clone().into()
480 }
481
482 fn into_data(self) -> ArrayData {
483 self.into()
484 }
485
486 fn data_type(&self) -> &DataType {
487 &self.data_type
488 }
489
490 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
491 Arc::new(self.slice(offset, length))
492 }
493
494 fn len(&self) -> usize {
495 self.run_ends.len()
496 }
497
498 fn is_empty(&self) -> bool {
499 self.run_ends.is_empty()
500 }
501
502 fn shrink_to_fit(&mut self) {
503 self.run_ends.shrink_to_fit();
504 self.values.shrink_to_fit();
505 }
506
507 fn offset(&self) -> usize {
508 self.run_ends.offset()
509 }
510
511 fn nulls(&self) -> Option<&NullBuffer> {
512 None
513 }
514
515 fn logical_nulls(&self) -> Option<NullBuffer> {
516 let len = self.len();
517 let nulls = self.values.logical_nulls()?;
518 let mut out = BooleanBufferBuilder::new(len);
519 let offset = self.run_ends.offset();
520 let mut valid_start = 0;
521 let mut last_end = 0;
522 for (idx, end) in self.run_ends.values().iter().enumerate() {
523 let end = end.as_usize();
524 if end < offset {
525 continue;
526 }
527 let end = (end - offset).min(len);
528 if nulls.is_null(idx) {
529 if valid_start < last_end {
530 out.append_n(last_end - valid_start, true);
531 }
532 out.append_n(end - last_end, false);
533 valid_start = end;
534 }
535 last_end = end;
536 if end == len {
537 break;
538 }
539 }
540 if valid_start < len {
541 out.append_n(len - valid_start, true)
542 }
543 assert_eq!(out.len(), len);
545 Some(out.finish().into())
546 }
547
548 fn is_nullable(&self) -> bool {
549 !self.is_empty() && self.values.is_nullable()
550 }
551
552 fn get_buffer_memory_size(&self) -> usize {
553 self.run_ends.inner().inner().capacity() + self.values.get_buffer_memory_size()
554 }
555
556 fn get_array_memory_size(&self) -> usize {
557 std::mem::size_of::<Self>()
558 + self.run_ends.inner().inner().capacity()
559 + self.values.get_array_memory_size()
560 }
561
562 #[cfg(feature = "pool")]
563 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
564 self.run_ends.claim(pool);
565 self.values.claim(pool);
566 }
567}
568
569impl<R: RunEndIndexType> std::fmt::Debug for RunArray<R> {
570 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
571 writeln!(
572 f,
573 "RunArray {{run_ends: {:?}, values: {:?}}}",
574 self.run_ends.values(),
575 self.values
576 )
577 }
578}
579
580impl<'a, T: RunEndIndexType> FromIterator<Option<&'a str>> for RunArray<T> {
597 fn from_iter<I: IntoIterator<Item = Option<&'a str>>>(iter: I) -> Self {
598 let it = iter.into_iter();
599 let (lower, _) = it.size_hint();
600 let mut builder = StringRunBuilder::with_capacity(lower, 256);
601 it.for_each(|i| {
602 builder.append_option(i);
603 });
604
605 builder.finish()
606 }
607}
608
609impl<'a, T: RunEndIndexType> FromIterator<&'a str> for RunArray<T> {
624 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
625 let it = iter.into_iter();
626 let (lower, _) = it.size_hint();
627 let mut builder = StringRunBuilder::with_capacity(lower, 256);
628 it.for_each(|i| {
629 builder.append_value(i);
630 });
631
632 builder.finish()
633 }
634}
635
636pub type Int16RunArray = RunArray<Int16Type>;
650
651pub type Int32RunArray = RunArray<Int32Type>;
665
666pub type Int64RunArray = RunArray<Int64Type>;
680
681pub struct TypedRunArray<'a, R: RunEndIndexType, V> {
699 run_array: &'a RunArray<R>,
701
702 values: &'a V,
704}
705
706impl<R: RunEndIndexType, V> Clone for TypedRunArray<'_, R, V> {
708 fn clone(&self) -> Self {
709 *self
710 }
711}
712
713impl<R: RunEndIndexType, V> Copy for TypedRunArray<'_, R, V> {}
714
715impl<R: RunEndIndexType, V> std::fmt::Debug for TypedRunArray<'_, R, V> {
716 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
717 writeln!(f, "TypedRunArray({:?})", self.run_array)
718 }
719}
720
721impl<'a, R: RunEndIndexType, V> TypedRunArray<'a, R, V> {
722 pub fn run_ends(&self) -> &'a RunEndBuffer<R::Native> {
724 self.run_array.run_ends()
725 }
726
727 pub fn values(&self) -> &'a V {
729 self.values
730 }
731
732 pub fn run_array(&self) -> &'a RunArray<R> {
734 self.run_array
735 }
736}
737
738unsafe impl<R: RunEndIndexType, V: Sync> Array for TypedRunArray<'_, R, V> {
740 fn as_any(&self) -> &dyn Any {
741 self.run_array
742 }
743
744 fn to_data(&self) -> ArrayData {
745 self.run_array.to_data()
746 }
747
748 fn into_data(self) -> ArrayData {
749 self.run_array.into_data()
750 }
751
752 fn data_type(&self) -> &DataType {
753 self.run_array.data_type()
754 }
755
756 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
757 Arc::new(self.run_array.slice(offset, length))
758 }
759
760 fn len(&self) -> usize {
761 self.run_array.len()
762 }
763
764 fn is_empty(&self) -> bool {
765 self.run_array.is_empty()
766 }
767
768 fn offset(&self) -> usize {
769 self.run_array.offset()
770 }
771
772 fn nulls(&self) -> Option<&NullBuffer> {
773 self.run_array.nulls()
774 }
775
776 fn logical_nulls(&self) -> Option<NullBuffer> {
777 self.run_array.logical_nulls()
778 }
779
780 fn logical_null_count(&self) -> usize {
781 self.run_array.logical_null_count()
782 }
783
784 fn is_nullable(&self) -> bool {
785 self.run_array.is_nullable()
786 }
787
788 fn get_buffer_memory_size(&self) -> usize {
789 self.run_array.get_buffer_memory_size()
790 }
791
792 fn get_array_memory_size(&self) -> usize {
793 self.run_array.get_array_memory_size()
794 }
795
796 #[cfg(feature = "pool")]
797 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
798 self.run_array.claim(pool);
799 }
800}
801
802impl<'a, R, V> ArrayAccessor for TypedRunArray<'a, R, V>
805where
806 R: RunEndIndexType,
807 V: Sync + Send,
808 &'a V: ArrayAccessor,
809 <&'a V as ArrayAccessor>::Item: Default,
810{
811 type Item = <&'a V as ArrayAccessor>::Item;
812
813 fn value(&self, logical_index: usize) -> Self::Item {
814 assert!(
815 logical_index < self.len(),
816 "Trying to access an element at index {} from a TypedRunArray of length {}",
817 logical_index,
818 self.len()
819 );
820 unsafe { self.value_unchecked(logical_index) }
821 }
822
823 unsafe fn value_unchecked(&self, logical_index: usize) -> Self::Item {
824 let physical_index = self.run_array.get_physical_index(logical_index);
825 unsafe { self.values().value_unchecked(physical_index) }
826 }
827}
828
829impl<'a, R, V> IntoIterator for TypedRunArray<'a, R, V>
830where
831 R: RunEndIndexType,
832 V: Sync + Send,
833 &'a V: ArrayAccessor,
834 <&'a V as ArrayAccessor>::Item: Default,
835{
836 type Item = Option<<&'a V as ArrayAccessor>::Item>;
837 type IntoIter = RunArrayIter<'a, R, V>;
838
839 fn into_iter(self) -> Self::IntoIter {
840 RunArrayIter::new(self)
841 }
842}
843pub trait AnyRunEndArray: Array {
848 fn values(&self) -> &Arc<dyn Array>;
850
851 fn with_values(&self, values: ArrayRef) -> ArrayRef;
854}
855
856impl<R: RunEndIndexType> AnyRunEndArray for RunArray<R> {
857 fn values(&self) -> &Arc<dyn Array> {
858 &self.values
859 }
860
861 fn with_values(&self, values: ArrayRef) -> ArrayRef {
862 Arc::new(RunArray::<R>::with_values(self, values))
863 }
864}
865
866#[cfg(test)]
867mod tests {
868 use rand::RngExt;
869 use rand::rng;
870 use rand::seq::SliceRandom;
871
872 use super::*;
873 use crate::Float32Array;
874 use crate::Int64Array;
875 use crate::builder::PrimitiveRunBuilder;
876 use crate::cast::AsArray;
877 use crate::new_empty_array;
878 use crate::types::{Int8Type, UInt32Type};
879 use crate::{Int16Array, Int32Array, StringArray};
880
881 fn build_input_array(size: usize) -> Vec<Option<i32>> {
882 let mut seed: Vec<Option<i32>> = vec![
885 None,
886 None,
887 None,
888 Some(1),
889 Some(2),
890 Some(3),
891 Some(4),
892 Some(5),
893 Some(6),
894 Some(7),
895 Some(8),
896 Some(9),
897 ];
898 let mut result: Vec<Option<i32>> = Vec::with_capacity(size);
899 let mut ix = 0;
900 let mut rng = rng();
901 let max_run_length = 8_usize.min(1_usize.max(size / 2));
903 while result.len() < size {
904 if ix == 0 {
906 seed.shuffle(&mut rng);
907 }
908 let num = max_run_length.min(rng.random_range(1..=max_run_length));
910 for _ in 0..num {
911 result.push(seed[ix]);
912 }
913 ix += 1;
914 if ix == seed.len() {
915 ix = 0
916 }
917 }
918 result.resize(size, None);
919 result
920 }
921
922 fn compare_logical_and_physical_indices(
924 logical_indices: &[u32],
925 logical_array: &[Option<i32>],
926 physical_indices: &[usize],
927 physical_array: &PrimitiveArray<Int32Type>,
928 ) {
929 assert_eq!(logical_indices.len(), physical_indices.len());
930
931 logical_indices
933 .iter()
934 .map(|f| f.as_usize())
935 .zip(physical_indices.iter())
936 .for_each(|(logical_ix, physical_ix)| {
937 let expected = logical_array[logical_ix];
938 match expected {
939 Some(val) => {
940 assert!(physical_array.is_valid(*physical_ix));
941 let actual = physical_array.value(*physical_ix);
942 assert_eq!(val, actual);
943 }
944 None => {
945 assert!(physical_array.is_null(*physical_ix))
946 }
947 }
948 });
949 }
950 #[test]
951 fn test_run_array() {
952 let value_data =
954 PrimitiveArray::<Int8Type>::from_iter_values([10_i8, 11, 12, 13, 14, 15, 16, 17]);
955
956 let run_ends_values = [4_i16, 6, 7, 9, 13, 18, 20, 22];
958 let run_ends_data =
959 PrimitiveArray::<Int16Type>::from_iter_values(run_ends_values.iter().copied());
960
961 let ree_array = RunArray::<Int16Type>::try_new(&run_ends_data, &value_data).unwrap();
963
964 assert_eq!(ree_array.len(), 22);
965 assert_eq!(ree_array.null_count(), 0);
966
967 let values = ree_array.values();
968 assert_eq!(value_data.into_data(), values.to_data());
969 assert_eq!(&DataType::Int8, values.data_type());
970
971 let run_ends = ree_array.run_ends();
972 assert_eq!(run_ends.values(), &run_ends_values);
973 }
974
975 #[test]
976 fn test_run_array_empty() {
977 let runs = new_empty_array(&DataType::Int16);
978 let runs = runs.as_primitive::<Int16Type>();
979 let values = new_empty_array(&DataType::Int64);
980 let array = RunArray::try_new(runs, &values).unwrap();
981
982 fn assertions(array: &RunArray<Int16Type>) {
983 assert!(array.is_empty());
984 assert_eq!(array.get_start_physical_index(), 0);
985 assert_eq!(array.get_end_physical_index(), 0);
986 assert!(array.get_physical_indices::<i16>(&[]).unwrap().is_empty());
987 assert!(array.run_ends().is_empty());
988 assert_eq!(array.run_ends().sliced_values().count(), 0);
989 }
990
991 assertions(&array);
992 assertions(&array.slice(0, 0));
993 }
994
995 #[test]
996 fn test_run_array_fmt_debug() {
997 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::with_capacity(3);
998 builder.append_value(12345678);
999 builder.append_null();
1000 builder.append_value(22345678);
1001 let array = builder.finish();
1002 assert_eq!(
1003 "RunArray {run_ends: [1, 2, 3], values: PrimitiveArray<UInt32>\n[\n 12345678,\n null,\n 22345678,\n]}\n",
1004 format!("{array:?}")
1005 );
1006
1007 let mut builder = PrimitiveRunBuilder::<Int16Type, UInt32Type>::with_capacity(20);
1008 for _ in 0..20 {
1009 builder.append_value(1);
1010 }
1011 let array = builder.finish();
1012
1013 assert_eq!(array.len(), 20);
1014 assert_eq!(array.null_count(), 0);
1015 assert_eq!(array.logical_null_count(), 0);
1016
1017 assert_eq!(
1018 "RunArray {run_ends: [20], values: PrimitiveArray<UInt32>\n[\n 1,\n]}\n",
1019 format!("{array:?}")
1020 );
1021 }
1022
1023 #[test]
1024 fn test_run_array_from_iter() {
1025 let test = vec!["a", "a", "b", "c"];
1026 let array: RunArray<Int16Type> = test
1027 .iter()
1028 .map(|&x| if x == "b" { None } else { Some(x) })
1029 .collect();
1030 assert_eq!(
1031 "RunArray {run_ends: [2, 3, 4], values: StringArray\n[\n \"a\",\n null,\n \"c\",\n]}\n",
1032 format!("{array:?}")
1033 );
1034
1035 assert_eq!(array.len(), 4);
1036 assert_eq!(array.null_count(), 0);
1037 assert_eq!(array.logical_null_count(), 1);
1038
1039 let array: RunArray<Int16Type> = test.into_iter().collect();
1040 assert_eq!(
1041 "RunArray {run_ends: [2, 3, 4], values: StringArray\n[\n \"a\",\n \"b\",\n \"c\",\n]}\n",
1042 format!("{array:?}")
1043 );
1044 }
1045
1046 #[test]
1047 fn test_run_array_run_ends_as_primitive_array() {
1048 let test = vec!["a", "b", "c", "a"];
1049 let array: RunArray<Int16Type> = test.into_iter().collect();
1050
1051 assert_eq!(array.len(), 4);
1052 assert_eq!(array.null_count(), 0);
1053 assert_eq!(array.logical_null_count(), 0);
1054
1055 let run_ends = array.run_ends();
1056 assert_eq!(&[1, 2, 3, 4], run_ends.values());
1057 }
1058
1059 #[test]
1060 fn test_run_array_as_primitive_array_with_null() {
1061 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1062 let array: RunArray<Int32Type> = test.into_iter().collect();
1063
1064 assert_eq!(array.len(), 6);
1065 assert_eq!(array.null_count(), 0);
1066 assert_eq!(array.logical_null_count(), 3);
1067
1068 let run_ends = array.run_ends();
1069 assert_eq!(&[1, 2, 3, 5, 6], run_ends.values());
1070
1071 let values_data = array.values();
1072 assert_eq!(2, values_data.null_count());
1073 assert_eq!(5, values_data.len());
1074 }
1075
1076 #[test]
1077 fn test_run_array_all_nulls() {
1078 let test = vec![None, None, None];
1079 let array: RunArray<Int32Type> = test.into_iter().collect();
1080
1081 assert_eq!(array.len(), 3);
1082 assert_eq!(array.null_count(), 0);
1083 assert_eq!(array.logical_null_count(), 3);
1084
1085 let run_ends = array.run_ends();
1086 assert_eq!(3, run_ends.len());
1087 assert_eq!(&[3], run_ends.values());
1088
1089 let values_data = array.values();
1090 assert_eq!(1, values_data.null_count());
1091 }
1092
1093 #[test]
1094 fn test_run_array_try_new() {
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), Some(4)].into_iter().collect();
1099
1100 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1101 assert_eq!(array.values().data_type(), &DataType::Utf8);
1102
1103 assert_eq!(array.null_count(), 0);
1104 assert_eq!(array.logical_null_count(), 1);
1105 assert_eq!(array.len(), 4);
1106 assert_eq!(array.values().null_count(), 1);
1107
1108 assert_eq!(
1109 "RunArray {run_ends: [1, 2, 3, 4], values: StringArray\n[\n \"foo\",\n \"bar\",\n null,\n \"baz\",\n]}\n",
1110 format!("{array:?}")
1111 );
1112 }
1113
1114 #[test]
1115 fn test_run_array_int16_type_definition() {
1116 let array: Int16RunArray = vec!["a", "a", "b", "c", "c"].into_iter().collect();
1117 let values: Arc<dyn Array> = Arc::new(StringArray::from(vec!["a", "b", "c"]));
1118 assert_eq!(array.run_ends().values(), &[2, 3, 5]);
1119 assert_eq!(array.values(), &values);
1120 }
1121
1122 #[test]
1123 fn test_run_array_empty_string() {
1124 let array: Int16RunArray = vec!["a", "a", "", "", "c"].into_iter().collect();
1125 let values: Arc<dyn Array> = Arc::new(StringArray::from(vec!["a", "", "c"]));
1126 assert_eq!(array.run_ends().values(), &[2, 4, 5]);
1127 assert_eq!(array.values(), &values);
1128 }
1129
1130 #[test]
1131 fn test_run_array_length_mismatch() {
1132 let values: StringArray = [Some("foo"), Some("bar"), None, Some("baz")]
1133 .into_iter()
1134 .collect();
1135 let run_ends: Int32Array = [Some(1), Some(2), Some(3)].into_iter().collect();
1136
1137 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1138 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());
1139 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1140 }
1141 #[test]
1142 fn test_run_array_with_values_changes_value_type() {
1143 let values = StringArray::from(vec!["foo", "bar", "baz"]);
1144 let run_ends: Int32Array = [Some(1), Some(2), Some(3)].into_iter().collect();
1145 let ree = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1146
1147 let new_values = Int64Array::from(vec![10, 20, 30]);
1148 let result = ree.with_values(Arc::new(new_values));
1149
1150 match result.data_type() {
1151 DataType::RunEndEncoded(_, v) => {
1152 assert_eq!(v.data_type(), &DataType::Int64);
1153 }
1154 other => panic!("expected RunEndEncoded, got {other:?}"),
1155 }
1156
1157 assert_eq!(result.values().data_type(), &DataType::Int64);
1158 assert_eq!(result.values().len(), 3);
1159 }
1160
1161 #[test]
1162 fn test_run_array_run_ends_with_null() {
1163 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1164 .into_iter()
1165 .collect();
1166 let run_ends: Int32Array = [Some(1), None, Some(3)].into_iter().collect();
1167
1168 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1169 let expected = ArrowError::InvalidArgumentError(
1170 "Found null values in run_ends array. The run_ends array should not have null values."
1171 .to_string(),
1172 );
1173 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1174 }
1175
1176 #[test]
1177 fn test_run_array_run_ends_with_zeroes() {
1178 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1179 .into_iter()
1180 .collect();
1181 let run_ends: Int32Array = [Some(0), Some(1), Some(3)].into_iter().collect();
1182
1183 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1184 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());
1185 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1186 }
1187
1188 #[test]
1189 fn test_run_array_run_ends_non_increasing() {
1190 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1191 .into_iter()
1192 .collect();
1193 let run_ends: Int32Array = [Some(1), Some(4), Some(4)].into_iter().collect();
1194
1195 let actual = RunArray::<Int32Type>::try_new(&run_ends, &values);
1196 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());
1197 assert_eq!(expected.to_string(), actual.err().unwrap().to_string());
1198 }
1199
1200 #[test]
1201 #[should_panic(expected = "Incorrect run ends type")]
1202 fn test_run_array_run_ends_data_type_mismatch() {
1203 let a = RunArray::<Int32Type>::from_iter(["32"]);
1204 let _ = RunArray::<Int64Type>::from(a.into_data());
1205 }
1206
1207 #[test]
1208 fn test_ree_array_accessor() {
1209 let input_array = build_input_array(256);
1210
1211 let mut builder =
1213 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
1214 builder.extend(input_array.iter().copied());
1215 let run_array = builder.finish();
1216 let typed = run_array.downcast::<PrimitiveArray<Int32Type>>().unwrap();
1217
1218 for (i, inp_val) in input_array.iter().enumerate() {
1220 if let Some(val) = inp_val {
1221 let actual = typed.value(i);
1222 assert_eq!(*val, actual)
1223 } else {
1224 let physical_ix = run_array.get_physical_index(i);
1225 assert!(typed.values().is_null(physical_ix));
1226 }
1227 }
1228 }
1229
1230 #[test]
1231 #[cfg_attr(miri, ignore)] fn test_get_physical_indices() {
1233 for logical_len in (0..250).step_by(10) {
1235 let input_array = build_input_array(logical_len);
1236
1237 let mut builder = PrimitiveRunBuilder::<Int32Type, Int32Type>::new();
1239 builder.extend(input_array.clone());
1240
1241 let run_array = builder.finish();
1242 let physical_values_array = run_array.values().as_primitive::<Int32Type>();
1243
1244 let mut logical_indices: Vec<u32> = (0_u32..(logical_len as u32)).collect();
1246 logical_indices.append(&mut logical_indices.clone());
1248 let mut rng = rng();
1249 logical_indices.shuffle(&mut rng);
1250
1251 let physical_indices = run_array.get_physical_indices(&logical_indices).unwrap();
1252
1253 assert_eq!(logical_indices.len(), physical_indices.len());
1254
1255 compare_logical_and_physical_indices(
1257 &logical_indices,
1258 &input_array,
1259 &physical_indices,
1260 physical_values_array,
1261 );
1262 }
1263 }
1264
1265 #[test]
1266 #[cfg_attr(miri, ignore)] fn test_get_physical_indices_sliced() {
1268 let total_len = 80;
1269 let input_array = build_input_array(total_len);
1270
1271 let mut builder =
1273 PrimitiveRunBuilder::<Int16Type, Int32Type>::with_capacity(input_array.len());
1274 builder.extend(input_array.iter().copied());
1275 let run_array = builder.finish();
1276 let physical_values_array = run_array.values().as_primitive::<Int32Type>();
1277
1278 for slice_len in 1..=total_len {
1280 let mut logical_indices: Vec<u32> = (0_u32..(slice_len as u32)).collect();
1282 logical_indices.append(&mut logical_indices.clone());
1284 let mut rng = rng();
1285 logical_indices.shuffle(&mut rng);
1286
1287 let sliced_input_array = &input_array[0..slice_len];
1290
1291 let sliced_run_array: RunArray<Int16Type> =
1293 run_array.slice(0, slice_len).into_data().into();
1294
1295 let physical_indices = sliced_run_array
1297 .get_physical_indices(&logical_indices)
1298 .unwrap();
1299
1300 compare_logical_and_physical_indices(
1301 &logical_indices,
1302 sliced_input_array,
1303 &physical_indices,
1304 physical_values_array,
1305 );
1306
1307 let sliced_input_array = &input_array[total_len - slice_len..total_len];
1310
1311 let sliced_run_array: RunArray<Int16Type> = run_array
1313 .slice(total_len - slice_len, slice_len)
1314 .into_data()
1315 .into();
1316
1317 let physical_indices = sliced_run_array
1319 .get_physical_indices(&logical_indices)
1320 .unwrap();
1321
1322 compare_logical_and_physical_indices(
1323 &logical_indices,
1324 sliced_input_array,
1325 &physical_indices,
1326 physical_values_array,
1327 );
1328 }
1329 }
1330
1331 #[test]
1332 fn test_logical_nulls() {
1333 let run = Int32Array::from(vec![3, 6, 9, 12]);
1334 let values = Int32Array::from(vec![Some(0), None, Some(1), None]);
1335 let array = RunArray::try_new(&run, &values).unwrap();
1336
1337 let expected = [
1338 true, true, true, false, false, false, true, true, true, false, false, false,
1339 ];
1340
1341 let n = array.logical_nulls().unwrap();
1342 assert_eq!(n.null_count(), 6);
1343
1344 let slices = [(0, 12), (0, 2), (2, 5), (3, 0), (3, 3), (3, 4), (4, 8)];
1345 for (offset, length) in slices {
1346 let a = array.slice(offset, length);
1347 let n = a.logical_nulls().unwrap();
1348 let n = n.into_iter().collect::<Vec<_>>();
1349 assert_eq!(&n, &expected[offset..offset + length], "{offset} {length}");
1350 }
1351 }
1352
1353 #[test]
1354 fn test_run_array_eq_identical() {
1355 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1356 let values1 = StringArray::from(vec!["a", "b", "c"]);
1357 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1358
1359 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1360 let values2 = StringArray::from(vec!["a", "b", "c"]);
1361 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1362
1363 assert_eq!(array1, array2);
1364 }
1365
1366 #[test]
1367 fn test_run_array_ne_different_run_ends() {
1368 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1369 let values1 = StringArray::from(vec!["a", "b", "c"]);
1370 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1371
1372 let run_ends2 = Int32Array::from(vec![1, 4, 6]);
1373 let values2 = StringArray::from(vec!["a", "b", "c"]);
1374 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1375
1376 assert_ne!(array1, array2);
1377 }
1378
1379 #[test]
1380 fn test_run_array_ne_different_values() {
1381 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1382 let values1 = StringArray::from(vec!["a", "b", "c"]);
1383 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1384
1385 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1386 let values2 = StringArray::from(vec!["a", "b", "d"]);
1387 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1388
1389 assert_ne!(array1, array2);
1390 }
1391
1392 #[test]
1393 fn test_run_array_eq_with_nulls() {
1394 let run_ends1 = Int32Array::from(vec![2, 4, 6]);
1395 let values1 = StringArray::from(vec![Some("a"), None, Some("c")]);
1396 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1397
1398 let run_ends2 = Int32Array::from(vec![2, 4, 6]);
1399 let values2 = StringArray::from(vec![Some("a"), None, Some("c")]);
1400 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1401
1402 assert_eq!(array1, array2);
1403 }
1404
1405 #[test]
1406 fn test_run_array_eq_different_run_end_types() {
1407 let run_ends_i16_1 = Int16Array::from(vec![2_i16, 4, 6]);
1408 let values_i16_1 = StringArray::from(vec!["a", "b", "c"]);
1409 let array_i16_1 = RunArray::<Int16Type>::try_new(&run_ends_i16_1, &values_i16_1).unwrap();
1410
1411 let run_ends_i16_2 = Int16Array::from(vec![2_i16, 4, 6]);
1412 let values_i16_2 = StringArray::from(vec!["a", "b", "c"]);
1413 let array_i16_2 = RunArray::<Int16Type>::try_new(&run_ends_i16_2, &values_i16_2).unwrap();
1414
1415 assert_eq!(array_i16_1, array_i16_2);
1416 }
1417
1418 #[test]
1419 fn test_run_array_values_slice() {
1420 let run_ends: PrimitiveArray<Int32Type> = vec![2, 5, 20].into();
1422 let values: PrimitiveArray<Int32Type> = vec![0, 1, 2].into();
1423 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1424
1425 let slice = array.slice(1, 4); assert_eq!(slice.get_start_physical_index(), 0);
1432 assert_eq!(slice.get_end_physical_index(), 1);
1433
1434 let values_slice = slice.values_slice();
1435 let values_slice = values_slice.as_primitive::<Int32Type>();
1436 assert_eq!(values_slice.values(), &[0, 1]);
1437
1438 let slice2 = array.slice(2, 3); assert_eq!(slice2.get_start_physical_index(), 1);
1442 assert_eq!(slice2.get_end_physical_index(), 1);
1443
1444 let values_slice2 = slice2.values_slice();
1445 let values_slice2 = values_slice2.as_primitive::<Int32Type>();
1446 assert_eq!(values_slice2.values(), &[1]);
1447 }
1448
1449 #[test]
1450 fn test_run_array_values_slice_empty() {
1451 let run_ends = Int32Array::from(vec![2, 5, 10]);
1452 let values = StringArray::from(vec!["a", "b", "c"]);
1453 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1454
1455 let slice = array.slice(0, 0);
1456 assert_eq!(slice.len(), 0);
1457
1458 let values_slice = slice.values_slice();
1459 assert_eq!(values_slice.len(), 0);
1460 assert_eq!(values_slice.data_type(), &DataType::Utf8);
1461 }
1462
1463 #[test]
1464 fn test_run_array_eq_empty() {
1465 let run_ends = Int32Array::from(vec![2, 5, 10]);
1466 let values = StringArray::from(vec!["a", "b", "c"]);
1467 let array = RunArray::<Int32Type>::try_new(&run_ends, &values).unwrap();
1468
1469 let slice1 = array.slice(0, 0);
1470 let slice2 = array.slice(1, 0);
1471 let slice3 = array.slice(10, 0);
1472
1473 assert_eq!(slice1, slice2);
1474 assert_eq!(slice2, slice3);
1475
1476 let empty_array = new_empty_array(array.data_type());
1477 let empty_array = crate::cast::as_run_array::<Int32Type>(empty_array.as_ref());
1478
1479 assert_eq!(&slice1, empty_array);
1480 }
1481
1482 #[test]
1483 fn test_run_array_eq_diff_physical_same_logical() {
1484 let run_ends1 = Int32Array::from(vec![1, 3, 6]);
1485 let values1 = StringArray::from(vec!["a", "b", "c"]);
1486 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1487
1488 let run_ends2 = Int32Array::from(vec![1, 2, 3, 4, 5, 6]);
1489 let values2 = StringArray::from(vec!["a", "b", "b", "c", "c", "c"]);
1490 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1491
1492 assert_eq!(array1, array2);
1493 }
1494
1495 #[test]
1496 fn test_run_array_eq_sliced() {
1497 let run_ends1 = Int32Array::from(vec![2, 5, 10]);
1498 let values1 = StringArray::from(vec!["a", "b", "c"]);
1499 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1500 let slice1 = array1.slice(1, 6);
1503 let run_ends2 = Int32Array::from(vec![1, 4, 6]);
1506 let values2 = StringArray::from(vec!["a", "b", "c"]);
1507 let array2 = RunArray::<Int32Type>::try_new(&run_ends2, &values2).unwrap();
1508 assert_eq!(slice1, array2);
1511
1512 let slice2 = array1.slice(2, 3);
1513 let run_ends3 = Int32Array::from(vec![3]);
1515 let values3 = StringArray::from(vec!["b"]);
1516 let array3 = RunArray::<Int32Type>::try_new(&run_ends3, &values3).unwrap();
1517 assert_eq!(slice2, array3);
1518 }
1519
1520 #[test]
1521 fn test_run_array_eq_sliced_different_offsets() {
1522 let run_ends1 = Int32Array::from(vec![2, 5, 10]);
1523 let values1 = StringArray::from(vec!["a", "b", "c"]);
1524 let array1 = RunArray::<Int32Type>::try_new(&run_ends1, &values1).unwrap();
1525 let array2 = array1.clone();
1526 assert_eq!(array1, array2);
1527
1528 let slice1 = array1.slice(1, 4); let slice2 = array1.slice(1, 4);
1530 assert_eq!(slice1, slice2);
1531
1532 let slice3 = array1.slice(0, 4); assert_ne!(slice1, slice3);
1534 }
1535
1536 #[test]
1537 #[cfg(not(feature = "force_validate"))]
1538 fn allow_to_create_invalid_array_using_new_unchecked() {
1539 let valid = RunArray::<Int32Type>::from_iter(["32"]);
1540 let (_, buffer, values) = valid.into_parts();
1541
1542 let _ = unsafe {
1543 RunArray::<Int32Type>::new_unchecked(DataType::Int64, buffer, values)
1545 };
1546 }
1547
1548 #[test]
1549 #[should_panic(
1550 expected = "Invalid data type Int64 for RunArray. Should be DataType::RunEndEncoded"
1551 )]
1552 #[cfg(feature = "force_validate")]
1553 fn should_not_be_able_to_create_invalid_array_using_new_unchecked_when_force_validate_is_enabled()
1554 {
1555 let valid = RunArray::<Int32Type>::from_iter(["32"]);
1556 let (_, buffer, values) = valid.into_parts();
1557
1558 let _ = unsafe {
1559 RunArray::<Int32Type>::new_unchecked(DataType::Int64, buffer, values)
1561 };
1562 }
1563
1564 #[test]
1565 fn test_run_array_roundtrip() {
1566 let run = Int32Array::from(vec![3, 6, 9, 12]);
1567 let values = Int32Array::from(vec![Some(0), None, Some(1), None]);
1568 let array = RunArray::try_new(&run, &values).unwrap();
1569
1570 let (dt, buffer, values) = array.clone().into_parts();
1571 let created_from_parts =
1572 unsafe { RunArray::<Int32Type>::new_unchecked(dt, buffer, values) };
1573 assert_eq!(array, created_from_parts);
1574 }
1575
1576 #[test]
1577 fn test_from_array_data_offset() {
1578 let dt = DataType::RunEndEncoded(
1579 Arc::new(Field::new(
1580 Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
1581 DataType::Int32,
1582 false,
1583 )),
1584 Arc::new(Field::new(
1585 Field::REE_VALUES_FIELD_DEFAULT_NAME,
1586 DataType::Float32,
1587 true,
1588 )),
1589 );
1590
1591 let runs = ArrayData::builder(DataType::Int32)
1592 .len(2)
1593 .offset(2)
1594 .add_buffer(vec![-10_i32, -20, 1_i32, 4, 0, 100].into())
1595 .build()
1596 .unwrap();
1597 let values = Float32Array::from(vec![1.5, 2.5]);
1598
1599 let data = ArrayDataBuilder::new(dt)
1600 .len(3)
1601 .child_data(vec![runs, values.to_data()])
1602 .build()
1603 .unwrap();
1604 let array = RunArray::<Int32Type>::from(data);
1605 let array = array.downcast::<Float32Array>().unwrap();
1606
1607 assert_eq!(array.value(0), 1.5);
1608 assert_eq!(array.value(1), 2.5);
1609 assert_eq!(array.value(2), 2.5);
1610 }
1611}