1use crate::builder::{PrimitiveDictionaryBuilder, StringDictionaryBuilder};
19use crate::cast::AsArray;
20use crate::iterator::ArrayIter;
21use crate::types::*;
22use crate::{
23 Array, ArrayAccessor, ArrayRef, ArrowNativeTypeOp, PrimitiveArray, Scalar, StringArray,
24 make_array,
25};
26use arrow_buffer::bit_util::set_bit;
27use arrow_buffer::buffer::NullBuffer;
28use arrow_buffer::{ArrowNativeType, BooleanBuffer, BooleanBufferBuilder, ScalarBuffer};
29use arrow_data::ArrayData;
30use arrow_schema::{ArrowError, DataType};
31use std::any::Any;
32use std::sync::Arc;
33
34pub type Int8DictionaryArray = DictionaryArray<Int8Type>;
49
50pub type Int16DictionaryArray = DictionaryArray<Int16Type>;
65
66pub type Int32DictionaryArray = DictionaryArray<Int32Type>;
81
82pub type Int64DictionaryArray = DictionaryArray<Int64Type>;
97
98pub type UInt8DictionaryArray = DictionaryArray<UInt8Type>;
113
114pub type UInt16DictionaryArray = DictionaryArray<UInt16Type>;
129
130pub type UInt32DictionaryArray = DictionaryArray<UInt32Type>;
145
146pub type UInt64DictionaryArray = DictionaryArray<UInt64Type>;
161
162pub struct DictionaryArray<K: ArrowDictionaryKeyType> {
244 data_type: DataType,
245
246 keys: PrimitiveArray<K>,
251
252 values: ArrayRef,
254
255 is_ordered: bool,
257}
258
259impl<K: ArrowDictionaryKeyType> Clone for DictionaryArray<K> {
260 fn clone(&self) -> Self {
261 Self {
262 data_type: self.data_type.clone(),
263 keys: self.keys.clone(),
264 values: self.values.clone(),
265 is_ordered: self.is_ordered,
266 }
267 }
268}
269
270impl<K: ArrowDictionaryKeyType> DictionaryArray<K> {
271 pub fn new(keys: PrimitiveArray<K>, values: ArrayRef) -> Self {
279 Self::try_new(keys, values).unwrap()
280 }
281
282 pub fn try_new(keys: PrimitiveArray<K>, values: ArrayRef) -> Result<Self, ArrowError> {
290 let data_type = DataType::Dictionary(
291 Box::new(keys.data_type().clone()),
292 Box::new(values.data_type().clone()),
293 );
294
295 let all_null = keys.null_count() == keys.len();
297
298 if !all_null {
299 let zero = K::Native::usize_as(0);
300 let values_len = values.len();
301
302 if let Some((idx, v)) = keys.values().iter().enumerate().find(|(idx, v)| {
303 (v.is_lt(zero) || v.as_usize() >= values_len) && keys.is_valid(*idx)
304 }) {
305 return Err(ArrowError::InvalidArgumentError(format!(
306 "Invalid dictionary key {v:?} at index {idx}, expected 0 <= key < {values_len}",
307 )));
308 }
309 }
310
311 Ok(Self {
312 data_type,
313 keys,
314 values,
315 is_ordered: false,
316 })
317 }
318
319 pub fn new_scalar<T: Array + 'static>(value: Scalar<T>) -> Scalar<Self> {
321 Scalar::new(Self::new(
322 PrimitiveArray::new(vec![K::Native::usize_as(0)].into(), None),
323 Arc::new(value.into_inner()),
324 ))
325 }
326
327 pub unsafe fn new_unchecked(keys: PrimitiveArray<K>, values: ArrayRef) -> Self {
333 if cfg!(feature = "force_validate") {
334 return Self::new(keys, values);
335 }
336
337 let data_type = DataType::Dictionary(
338 Box::new(keys.data_type().clone()),
339 Box::new(values.data_type().clone()),
340 );
341
342 Self {
343 data_type,
344 keys,
345 values,
346 is_ordered: false,
347 }
348 }
349
350 pub fn into_parts(self) -> (PrimitiveArray<K>, ArrayRef) {
352 (self.keys, self.values)
353 }
354
355 pub fn keys(&self) -> &PrimitiveArray<K> {
357 &self.keys
358 }
359
360 pub fn lookup_key(&self, value: &str) -> Option<K::Native> {
367 let rd_buf: &StringArray = self.values.as_any().downcast_ref::<StringArray>().unwrap();
368
369 (0..rd_buf.len())
370 .position(|i| rd_buf.value(i) == value)
371 .and_then(K::Native::from_usize)
372 }
373
374 pub fn values(&self) -> &ArrayRef {
376 &self.values
377 }
378
379 pub fn value_type(&self) -> DataType {
381 self.values.data_type().clone()
382 }
383
384 pub fn len(&self) -> usize {
386 self.keys.len()
387 }
388
389 pub fn is_empty(&self) -> bool {
391 self.keys.is_empty()
392 }
393
394 pub fn is_ordered(&self) -> bool {
396 self.is_ordered
397 }
398
399 pub fn keys_iter(&self) -> impl Iterator<Item = Option<usize>> + '_ {
401 self.keys.iter().map(|key| key.map(|k| k.as_usize()))
402 }
403
404 pub fn key(&self, i: usize) -> Option<usize> {
410 self.keys.is_valid(i).then(|| self.keys.value(i).as_usize())
411 }
412
413 pub fn slice(&self, offset: usize, length: usize) -> Self {
418 Self {
419 data_type: self.data_type.clone(),
420 keys: self.keys.slice(offset, length),
421 values: self.values.clone(),
422 is_ordered: self.is_ordered,
423 }
424 }
425
426 pub fn downcast_dict<V: 'static>(&self) -> Option<TypedDictionaryArray<'_, K, V>> {
440 let values = self.values.as_any().downcast_ref()?;
441 Some(TypedDictionaryArray {
442 dictionary: self,
443 values,
444 })
445 }
446
447 pub fn with_values(&self, values: ArrayRef) -> Self {
485 assert!(values.len() >= self.values.len());
486 let data_type =
487 DataType::Dictionary(Box::new(K::DATA_TYPE), Box::new(values.data_type().clone()));
488 Self {
489 data_type,
490 keys: self.keys.clone(),
491 values,
492 is_ordered: false,
493 }
494 }
495
496 #[expect(clippy::result_large_err)]
499 pub fn into_primitive_dict_builder<V>(self) -> Result<PrimitiveDictionaryBuilder<K, V>, Self>
500 where
501 V: ArrowPrimitiveType,
502 {
503 if !self.value_type().is_primitive() {
504 return Err(self);
505 }
506
507 let key_array = self.keys().clone();
508 let value_array = self.values().as_primitive::<V>().clone();
509
510 drop(self.keys);
511 drop(self.values);
512
513 let key_builder = key_array.into_builder();
514 let value_builder = value_array.into_builder();
515
516 match (key_builder, value_builder) {
517 (Ok(key_builder), Ok(value_builder)) => Ok(unsafe {
518 PrimitiveDictionaryBuilder::new_from_builders(key_builder, value_builder)
519 }),
520 (Err(key_array), Ok(mut value_builder)) => {
521 Err(Self::try_new(key_array, Arc::new(value_builder.finish())).unwrap())
522 }
523 (Ok(mut key_builder), Err(value_array)) => {
524 Err(Self::try_new(key_builder.finish(), Arc::new(value_array)).unwrap())
525 }
526 (Err(key_array), Err(value_array)) => {
527 Err(Self::try_new(key_array, Arc::new(value_array)).unwrap())
528 }
529 }
530 }
531
532 #[expect(clippy::result_large_err)]
556 pub fn unary_mut<F, V>(self, op: F) -> Result<DictionaryArray<K>, DictionaryArray<K>>
557 where
558 V: ArrowPrimitiveType,
559 F: Fn(V::Native) -> V::Native,
560 {
561 let mut builder: PrimitiveDictionaryBuilder<K, V> = self.into_primitive_dict_builder()?;
562 builder
563 .values_slice_mut()
564 .iter_mut()
565 .for_each(|v| *v = op(*v));
566 Ok(builder.finish())
567 }
568
569 pub fn occupancy(&self) -> BooleanBuffer {
574 let len = self.values.len();
575 let mut builder = BooleanBufferBuilder::new(len);
576 builder.resize(len);
577 let slice = builder.as_slice_mut();
578 match self.keys.nulls().filter(|n| n.null_count() > 0) {
579 Some(n) => {
580 let v = self.keys.values();
581 n.valid_indices()
582 .for_each(|idx| set_bit(slice, v[idx].as_usize()))
583 }
584 None => {
585 let v = self.keys.values();
586 v.iter().for_each(|v| set_bit(slice, v.as_usize()))
587 }
588 }
589 builder.finish()
590 }
591}
592
593impl<T: ArrowDictionaryKeyType> From<ArrayData> for DictionaryArray<T> {
595 fn from(data: ArrayData) -> Self {
596 let (data_type, len, nulls, offset, mut buffers, mut child_data) = data.into_parts();
597
598 assert_eq!(
599 buffers.len(),
600 1,
601 "DictionaryArray data should contain a single buffer only (keys)."
602 );
603 let buffer = buffers.pop().expect("checked above");
604 assert_eq!(
605 child_data.len(),
606 1,
607 "DictionaryArray should contain a single child array (values)."
608 );
609 let cd = child_data.pop().expect("checked above");
610
611 if let DataType::Dictionary(key_data_type, _) = &data_type {
612 assert_eq!(
613 &T::DATA_TYPE,
614 key_data_type.as_ref(),
615 "DictionaryArray's data type must match, expected {} got {}",
616 T::DATA_TYPE,
617 key_data_type
618 );
619
620 let values = make_array(cd);
621
622 let keys = PrimitiveArray::<T>::new(ScalarBuffer::new(buffer, offset, len), nulls);
624
625 Self {
626 data_type,
627 keys,
628 values,
629 is_ordered: false,
630 }
631 } else {
632 panic!("DictionaryArray must have Dictionary data type.")
633 }
634 }
635}
636
637impl<T: ArrowDictionaryKeyType> From<DictionaryArray<T>> for ArrayData {
638 fn from(array: DictionaryArray<T>) -> Self {
639 let builder = array
640 .keys
641 .into_data()
642 .into_builder()
643 .data_type(array.data_type)
644 .child_data(vec![array.values.to_data()]);
645
646 unsafe { builder.build_unchecked() }
647 }
648}
649
650impl<'a, T: ArrowDictionaryKeyType> FromIterator<Option<&'a str>> for DictionaryArray<T> {
667 fn from_iter<I: IntoIterator<Item = Option<&'a str>>>(iter: I) -> Self {
668 let it = iter.into_iter();
669 let (lower, _) = it.size_hint();
670 let mut builder = StringDictionaryBuilder::with_capacity(lower, 256, 1024);
671 builder.extend(it);
672 builder.finish()
673 }
674}
675
676impl<'a, T: ArrowDictionaryKeyType> FromIterator<&'a str> for DictionaryArray<T> {
691 fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
692 let it = iter.into_iter();
693 let (lower, _) = it.size_hint();
694 let mut builder = StringDictionaryBuilder::with_capacity(lower, 256, 1024);
695 it.for_each(|i| {
696 builder
697 .append(i)
698 .expect("Unable to append a value to a dictionary array.");
699 });
700
701 builder.finish()
702 }
703}
704
705unsafe impl<T: ArrowDictionaryKeyType> Array for DictionaryArray<T> {
707 fn as_any(&self) -> &dyn Any {
708 self
709 }
710
711 fn to_data(&self) -> ArrayData {
712 self.clone().into()
713 }
714
715 fn into_data(self) -> ArrayData {
716 self.into()
717 }
718
719 fn data_type(&self) -> &DataType {
720 &self.data_type
721 }
722
723 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
724 Arc::new(self.slice(offset, length))
725 }
726
727 fn len(&self) -> usize {
728 self.keys.len()
729 }
730
731 fn is_empty(&self) -> bool {
732 self.keys.is_empty()
733 }
734
735 fn shrink_to_fit(&mut self) {
736 self.keys.shrink_to_fit();
737 self.values.shrink_to_fit();
738 }
739
740 fn offset(&self) -> usize {
741 self.keys.offset()
742 }
743
744 fn nulls(&self) -> Option<&NullBuffer> {
745 self.keys.nulls()
746 }
747
748 fn logical_nulls(&self) -> Option<NullBuffer> {
749 match self.values.logical_nulls() {
750 None => self.nulls().cloned(),
751 Some(value_nulls) => {
752 let mut builder = BooleanBufferBuilder::new(self.len());
753 match self.keys.nulls() {
754 Some(n) => builder.append_buffer(n.inner()),
755 None => builder.append_n(self.len(), true),
756 }
757 for (idx, k) in self.keys.values().iter().enumerate() {
758 let k = k.as_usize();
759 if k < value_nulls.len() && value_nulls.is_null(k) {
761 builder.set_bit(idx, false);
762 }
763 }
764 Some(builder.finish().into())
765 }
766 }
767 }
768
769 fn logical_null_count(&self) -> usize {
770 match (self.keys.nulls(), self.values.logical_nulls()) {
771 (None, None) => 0,
772 (Some(key_nulls), None) => key_nulls.null_count(),
773 (None, Some(value_nulls)) => self
774 .keys
775 .values()
776 .iter()
777 .filter(|k| value_nulls.is_null(k.as_usize()))
778 .count(),
779 (Some(key_nulls), Some(value_nulls)) => self
780 .keys
781 .values()
782 .iter()
783 .enumerate()
784 .filter(|(idx, k)| key_nulls.is_null(*idx) || value_nulls.is_null(k.as_usize()))
785 .count(),
786 }
787 }
788
789 fn is_nullable(&self) -> bool {
790 !self.is_empty() && (self.nulls().is_some() || self.values.is_nullable())
791 }
792
793 fn get_buffer_memory_size(&self) -> usize {
794 self.keys.get_buffer_memory_size() + self.values.get_buffer_memory_size()
795 }
796
797 fn get_array_memory_size(&self) -> usize {
798 std::mem::size_of::<Self>()
799 + self.keys.get_buffer_memory_size()
800 + self.values.get_array_memory_size()
801 }
802
803 #[cfg(feature = "pool")]
804 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
805 self.keys.claim(pool);
806 self.values.claim(pool);
807 }
808}
809
810impl<T: ArrowDictionaryKeyType> std::fmt::Debug for DictionaryArray<T> {
811 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
812 writeln!(
813 f,
814 "DictionaryArray {{keys: {:?} values: {:?}}}",
815 self.keys, self.values
816 )
817 }
818}
819
820pub struct TypedDictionaryArray<'a, K: ArrowDictionaryKeyType, V> {
838 dictionary: &'a DictionaryArray<K>,
840 values: &'a V,
842}
843
844impl<K: ArrowDictionaryKeyType, V> Clone for TypedDictionaryArray<'_, K, V> {
846 fn clone(&self) -> Self {
847 *self
848 }
849}
850
851impl<K: ArrowDictionaryKeyType, V> Copy for TypedDictionaryArray<'_, K, V> {}
852
853impl<K: ArrowDictionaryKeyType, V> std::fmt::Debug for TypedDictionaryArray<'_, K, V> {
854 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
855 writeln!(f, "TypedDictionaryArray({:?})", self.dictionary)
856 }
857}
858
859impl<'a, K: ArrowDictionaryKeyType, V> TypedDictionaryArray<'a, K, V> {
860 pub fn keys(&self) -> &'a PrimitiveArray<K> {
862 self.dictionary.keys()
863 }
864
865 pub fn values(&self) -> &'a V {
867 self.values
868 }
869}
870
871unsafe impl<K: ArrowDictionaryKeyType, V: Sync> Array for TypedDictionaryArray<'_, K, V> {
872 fn as_any(&self) -> &dyn Any {
873 self.dictionary
874 }
875
876 fn to_data(&self) -> ArrayData {
877 self.dictionary.to_data()
878 }
879
880 fn into_data(self) -> ArrayData {
881 self.dictionary.into_data()
882 }
883
884 fn data_type(&self) -> &DataType {
885 self.dictionary.data_type()
886 }
887
888 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
889 Arc::new(self.dictionary.slice(offset, length))
890 }
891
892 fn len(&self) -> usize {
893 self.dictionary.len()
894 }
895
896 fn is_empty(&self) -> bool {
897 self.dictionary.is_empty()
898 }
899
900 fn offset(&self) -> usize {
901 self.dictionary.offset()
902 }
903
904 fn nulls(&self) -> Option<&NullBuffer> {
905 self.dictionary.nulls()
906 }
907
908 fn logical_nulls(&self) -> Option<NullBuffer> {
909 self.dictionary.logical_nulls()
910 }
911
912 fn logical_null_count(&self) -> usize {
913 self.dictionary.logical_null_count()
914 }
915
916 fn is_nullable(&self) -> bool {
917 self.dictionary.is_nullable()
918 }
919
920 fn get_buffer_memory_size(&self) -> usize {
921 self.dictionary.get_buffer_memory_size()
922 }
923
924 fn get_array_memory_size(&self) -> usize {
925 self.dictionary.get_array_memory_size()
926 }
927
928 #[cfg(feature = "pool")]
929 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
930 self.dictionary.claim(pool);
931 }
932}
933
934impl<K, V> IntoIterator for TypedDictionaryArray<'_, K, V>
935where
936 K: ArrowDictionaryKeyType,
937 Self: ArrayAccessor,
938{
939 type Item = Option<<Self as ArrayAccessor>::Item>;
940 type IntoIter = ArrayIter<Self>;
941
942 fn into_iter(self) -> Self::IntoIter {
943 ArrayIter::new(self)
944 }
945}
946
947impl<'a, K, V> ArrayAccessor for TypedDictionaryArray<'a, K, V>
948where
949 K: ArrowDictionaryKeyType,
950 V: Sync + Send,
951 &'a V: ArrayAccessor,
952 <&'a V as ArrayAccessor>::Item: Default,
953{
954 type Item = <&'a V as ArrayAccessor>::Item;
955
956 fn value(&self, index: usize) -> Self::Item {
957 assert!(
958 index < self.len(),
959 "Trying to access an element at index {} from a TypedDictionaryArray of length {}",
960 index,
961 self.len()
962 );
963 unsafe { self.value_unchecked(index) }
964 }
965
966 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
967 let val = unsafe { self.dictionary.keys.value_unchecked(index) };
968 let value_idx = val.as_usize();
969
970 match value_idx < self.values.len() {
973 true => unsafe { self.values.value_unchecked(value_idx) },
974 false => Default::default(),
975 }
976 }
977}
978
979pub trait AnyDictionaryArray: Array {
1024 fn keys(&self) -> &dyn Array;
1026
1027 fn values(&self) -> &ArrayRef;
1029
1030 fn normalized_keys(&self) -> Vec<usize>;
1039
1040 fn with_values(&self, values: ArrayRef) -> ArrayRef;
1044}
1045
1046impl<K: ArrowDictionaryKeyType> AnyDictionaryArray for DictionaryArray<K> {
1047 fn keys(&self) -> &dyn Array {
1048 &self.keys
1049 }
1050
1051 fn values(&self) -> &ArrayRef {
1052 self.values()
1053 }
1054
1055 fn normalized_keys(&self) -> Vec<usize> {
1056 let v_len = self.values().len();
1057 assert_ne!(v_len, 0);
1058 let iter = self.keys().values().iter();
1059 iter.map(|x| x.as_usize().min(v_len - 1)).collect()
1060 }
1061
1062 fn with_values(&self, values: ArrayRef) -> ArrayRef {
1063 Arc::new(self.with_values(values))
1064 }
1065}
1066
1067#[cfg(test)]
1068mod tests {
1069 use super::*;
1070 use crate::cast::as_dictionary_array;
1071 use crate::{Int8Array, Int16Array, Int32Array, RunArray, UInt8Array};
1072 use arrow_buffer::{Buffer, ToByteSlice};
1073
1074 #[test]
1075 fn test_dictionary_array() {
1076 let value_data = ArrayData::builder(DataType::Int8)
1078 .len(8)
1079 .add_buffer(Buffer::from(
1080 [10_i8, 11, 12, 13, 14, 15, 16, 17].to_byte_slice(),
1081 ))
1082 .build()
1083 .unwrap();
1084
1085 let keys = Buffer::from([2_i16, 3, 4].to_byte_slice());
1087
1088 let key_type = DataType::Int16;
1090 let value_type = DataType::Int8;
1091 let dict_data_type = DataType::Dictionary(Box::new(key_type), Box::new(value_type));
1092 let dict_data = ArrayData::builder(dict_data_type.clone())
1093 .len(3)
1094 .add_buffer(keys.clone())
1095 .add_child_data(value_data.clone())
1096 .build()
1097 .unwrap();
1098 let dict_array = Int16DictionaryArray::from(dict_data);
1099
1100 let values = dict_array.values();
1101 assert_eq!(value_data, values.to_data());
1102 assert_eq!(DataType::Int8, dict_array.value_type());
1103 assert_eq!(3, dict_array.len());
1104
1105 assert_eq!(0, dict_array.null_count());
1107 assert_eq!(0, dict_array.values().null_count());
1108 assert_eq!(dict_array.keys(), &Int16Array::from(vec![2_i16, 3, 4]));
1109
1110 let dict_data = ArrayData::builder(dict_data_type)
1112 .len(2)
1113 .offset(1)
1114 .add_buffer(keys)
1115 .add_child_data(value_data.clone())
1116 .build()
1117 .unwrap();
1118 let dict_array = Int16DictionaryArray::from(dict_data);
1119
1120 let values = dict_array.values();
1121 assert_eq!(value_data, values.to_data());
1122 assert_eq!(DataType::Int8, dict_array.value_type());
1123 assert_eq!(2, dict_array.len());
1124 assert_eq!(dict_array.keys(), &Int16Array::from(vec![3_i16, 4]));
1125 }
1126
1127 #[test]
1128 fn test_dictionary_builder_append_many() {
1129 let mut builder = PrimitiveDictionaryBuilder::<UInt8Type, UInt32Type>::new();
1130
1131 builder.append(1).unwrap();
1132 builder.append_n(2, 2).unwrap();
1133 builder.append_options(None, 2);
1134 builder.append_options(Some(3), 3);
1135
1136 let array = builder.finish();
1137
1138 let values = array
1139 .values()
1140 .as_primitive::<UInt32Type>()
1141 .iter()
1142 .map(Option::unwrap)
1143 .collect::<Vec<_>>();
1144 assert_eq!(values, &[1, 2, 3]);
1145 let keys = array.keys().iter().collect::<Vec<_>>();
1146 assert_eq!(
1147 keys,
1148 &[
1149 Some(0),
1150 Some(1),
1151 Some(1),
1152 None,
1153 None,
1154 Some(2),
1155 Some(2),
1156 Some(2)
1157 ]
1158 );
1159 }
1160
1161 #[test]
1162 fn test_string_dictionary_builder_append_many() {
1163 let mut builder = StringDictionaryBuilder::<Int8Type>::new();
1164
1165 builder.append("a").unwrap();
1166 builder.append_n("b", 2).unwrap();
1167 builder.append_options(None::<&str>, 2);
1168 builder.append_options(Some("c"), 3);
1169
1170 let array = builder.finish();
1171
1172 let values = array
1173 .values()
1174 .as_string::<i32>()
1175 .iter()
1176 .map(Option::unwrap)
1177 .collect::<Vec<_>>();
1178 assert_eq!(values, &["a", "b", "c"]);
1179 let keys = array.keys().iter().collect::<Vec<_>>();
1180 assert_eq!(
1181 keys,
1182 &[
1183 Some(0),
1184 Some(1),
1185 Some(1),
1186 None,
1187 None,
1188 Some(2),
1189 Some(2),
1190 Some(2)
1191 ]
1192 );
1193 }
1194
1195 #[test]
1196 fn test_dictionary_array_fmt_debug() {
1197 let mut builder = PrimitiveDictionaryBuilder::<UInt8Type, UInt32Type>::with_capacity(3, 2);
1198 builder.append(12345678).unwrap();
1199 builder.append_null();
1200 builder.append(22345678).unwrap();
1201 let array = builder.finish();
1202 assert_eq!(
1203 "DictionaryArray {keys: PrimitiveArray<UInt8>\n[\n 0,\n null,\n 1,\n] values: PrimitiveArray<UInt32>\n[\n 12345678,\n 22345678,\n]}\n",
1204 format!("{array:?}")
1205 );
1206
1207 let mut builder = PrimitiveDictionaryBuilder::<UInt8Type, UInt32Type>::with_capacity(20, 2);
1208 for _ in 0..20 {
1209 builder.append(1).unwrap();
1210 }
1211 let array = builder.finish();
1212 assert_eq!(
1213 "DictionaryArray {keys: PrimitiveArray<UInt8>\n[\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n] values: PrimitiveArray<UInt32>\n[\n 1,\n]}\n",
1214 format!("{array:?}")
1215 );
1216 }
1217
1218 #[test]
1219 fn test_dictionary_array_from_iter() {
1220 let test = vec!["a", "a", "b", "c"];
1221 let array: DictionaryArray<Int8Type> = test
1222 .iter()
1223 .map(|&x| if x == "b" { None } else { Some(x) })
1224 .collect();
1225 assert_eq!(
1226 "DictionaryArray {keys: PrimitiveArray<Int8>\n[\n 0,\n 0,\n null,\n 1,\n] values: StringArray\n[\n \"a\",\n \"c\",\n]}\n",
1227 format!("{array:?}")
1228 );
1229
1230 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1231 assert_eq!(
1232 "DictionaryArray {keys: PrimitiveArray<Int8>\n[\n 0,\n 0,\n 1,\n 2,\n] values: StringArray\n[\n \"a\",\n \"b\",\n \"c\",\n]}\n",
1233 format!("{array:?}")
1234 );
1235 }
1236
1237 #[test]
1238 fn test_dictionary_array_reverse_lookup_key() {
1239 let test = vec!["a", "a", "b", "c"];
1240 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1241
1242 assert_eq!(array.lookup_key("c"), Some(2));
1243
1244 let test = vec!["t3", "t3", "t2", "t2", "t1", "t3", "t4", "t1", "t0"];
1246 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1247
1248 assert_eq!(array.lookup_key("t1"), Some(2));
1249 assert_eq!(array.lookup_key("non-existent"), None);
1250 }
1251
1252 #[test]
1253 fn test_dictionary_keys_as_primitive_array() {
1254 let test = vec!["a", "b", "c", "a"];
1255 let array: DictionaryArray<Int8Type> = test.into_iter().collect();
1256
1257 let keys = array.keys();
1258 assert_eq!(&DataType::Int8, keys.data_type());
1259 assert_eq!(0, keys.null_count());
1260 assert_eq!(&[0, 1, 2, 0], keys.values());
1261 }
1262
1263 #[test]
1264 fn test_dictionary_keys_as_primitive_array_with_null() {
1265 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1266 let array: DictionaryArray<Int32Type> = test.into_iter().collect();
1267
1268 let keys = array.keys();
1269 assert_eq!(&DataType::Int32, keys.data_type());
1270 assert_eq!(3, keys.null_count());
1271
1272 assert!(keys.is_valid(0));
1273 assert!(!keys.is_valid(1));
1274 assert!(keys.is_valid(2));
1275 assert!(!keys.is_valid(3));
1276 assert!(!keys.is_valid(4));
1277 assert!(keys.is_valid(5));
1278
1279 assert_eq!(0, keys.value(0));
1280 assert_eq!(1, keys.value(2));
1281 assert_eq!(0, keys.value(5));
1282 }
1283
1284 #[test]
1285 fn test_dictionary_all_nulls() {
1286 let test = vec![None, None, None];
1287 let array: DictionaryArray<Int32Type> = test.into_iter().collect();
1288 array
1289 .into_data()
1290 .validate_full()
1291 .expect("All null array has valid array data");
1292 }
1293
1294 #[test]
1295 fn test_dictionary_iter() {
1296 let values = Int8Array::from_iter_values([10_i8, 11, 12, 13, 14, 15, 16, 17]);
1298 let keys = Int16Array::from_iter_values([2_i16, 3, 4]);
1299
1300 let dict_array = DictionaryArray::new(keys, Arc::new(values));
1302
1303 let mut key_iter = dict_array.keys_iter();
1304 assert_eq!(2, key_iter.next().unwrap().unwrap());
1305 assert_eq!(3, key_iter.next().unwrap().unwrap());
1306 assert_eq!(4, key_iter.next().unwrap().unwrap());
1307 assert!(key_iter.next().is_none());
1308
1309 let mut iter = dict_array
1310 .values()
1311 .as_any()
1312 .downcast_ref::<Int8Array>()
1313 .unwrap()
1314 .take_iter(dict_array.keys_iter());
1315
1316 assert_eq!(12, iter.next().unwrap().unwrap());
1317 assert_eq!(13, iter.next().unwrap().unwrap());
1318 assert_eq!(14, iter.next().unwrap().unwrap());
1319 assert!(iter.next().is_none());
1320 }
1321
1322 #[test]
1323 fn test_dictionary_iter_with_null() {
1324 let test = vec![Some("a"), None, Some("b"), None, None, Some("a")];
1325 let array: DictionaryArray<Int32Type> = test.into_iter().collect();
1326
1327 let mut iter = array
1328 .values()
1329 .as_any()
1330 .downcast_ref::<StringArray>()
1331 .unwrap()
1332 .take_iter(array.keys_iter());
1333
1334 assert_eq!("a", iter.next().unwrap().unwrap());
1335 assert!(iter.next().unwrap().is_none());
1336 assert_eq!("b", iter.next().unwrap().unwrap());
1337 assert!(iter.next().unwrap().is_none());
1338 assert!(iter.next().unwrap().is_none());
1339 assert_eq!("a", iter.next().unwrap().unwrap());
1340 assert!(iter.next().is_none());
1341 }
1342
1343 #[test]
1344 fn test_dictionary_key() {
1345 let keys = Int8Array::from(vec![Some(2), None, Some(1)]);
1346 let values = StringArray::from(vec!["foo", "bar", "baz", "blarg"]);
1347
1348 let array = DictionaryArray::new(keys, Arc::new(values));
1349 assert_eq!(array.key(0), Some(2));
1350 assert_eq!(array.key(1), None);
1351 assert_eq!(array.key(2), Some(1));
1352 }
1353
1354 #[test]
1355 fn test_try_new() {
1356 let values: StringArray = [Some("foo"), Some("bar"), Some("baz")]
1357 .into_iter()
1358 .collect();
1359 let keys: Int32Array = [Some(0), Some(2), None, Some(1)].into_iter().collect();
1360
1361 let array = DictionaryArray::new(keys, Arc::new(values));
1362 assert_eq!(array.keys().data_type(), &DataType::Int32);
1363 assert_eq!(array.values().data_type(), &DataType::Utf8);
1364
1365 assert_eq!(array.null_count(), 1);
1366 assert_eq!(array.logical_null_count(), 1);
1367
1368 assert!(array.keys().is_valid(0));
1369 assert!(array.keys().is_valid(1));
1370 assert!(array.keys().is_null(2));
1371 assert!(array.keys().is_valid(3));
1372
1373 assert_eq!(array.keys().value(0), 0);
1374 assert_eq!(array.keys().value(1), 2);
1375 assert_eq!(array.keys().value(3), 1);
1376
1377 assert_eq!(
1378 "DictionaryArray {keys: PrimitiveArray<Int32>\n[\n 0,\n 2,\n null,\n 1,\n] values: StringArray\n[\n \"foo\",\n \"bar\",\n \"baz\",\n]}\n",
1379 format!("{array:?}")
1380 );
1381 }
1382
1383 #[test]
1384 #[should_panic(expected = "Invalid dictionary key 3 at index 1, expected 0 <= key < 2")]
1385 fn test_try_new_index_too_large() {
1386 let values: StringArray = [Some("foo"), Some("bar")].into_iter().collect();
1387 let keys: Int32Array = [Some(0), Some(3)].into_iter().collect();
1389 DictionaryArray::new(keys, Arc::new(values));
1390 }
1391
1392 #[test]
1393 #[should_panic(expected = "Invalid dictionary key -100 at index 0, expected 0 <= key < 2")]
1394 fn test_try_new_index_too_small() {
1395 let values: StringArray = [Some("foo"), Some("bar")].into_iter().collect();
1396 let keys: Int32Array = std::iter::once(Some(-100)).collect();
1397 DictionaryArray::new(keys, Arc::new(values));
1398 }
1399
1400 #[test]
1401 #[should_panic(expected = "DictionaryArray's data type must match, expected Int64 got Int32")]
1402 fn test_from_array_data_validation() {
1403 let a = DictionaryArray::<Int32Type>::from_iter(["32"]);
1404 let _ = DictionaryArray::<Int64Type>::from(a.into_data());
1405 }
1406
1407 #[test]
1408 fn test_into_primitive_dict_builder() {
1409 let values = Int32Array::from_iter_values([10_i32, 12, 15]);
1410 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1411
1412 let dict_array = DictionaryArray::new(keys, Arc::new(values));
1413
1414 let boxed: ArrayRef = Arc::new(dict_array);
1415 let col: DictionaryArray<Int8Type> = as_dictionary_array(&boxed).clone();
1416
1417 drop(boxed);
1418
1419 let mut builder = col.into_primitive_dict_builder::<Int32Type>().unwrap();
1420
1421 let slice = builder.values_slice_mut();
1422 assert_eq!(slice, &[10, 12, 15]);
1423
1424 slice[0] = 4;
1425 slice[1] = 2;
1426 slice[2] = 1;
1427
1428 let values = Int32Array::from_iter_values([4_i32, 2, 1]);
1429 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1430
1431 let expected = DictionaryArray::new(keys, Arc::new(values));
1432
1433 let new_array = builder.finish();
1434 assert_eq!(expected, new_array);
1435 }
1436
1437 #[test]
1438 fn test_into_primitive_dict_builder_cloned_array() {
1439 let values = Int32Array::from_iter_values([10_i32, 12, 15]);
1440 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1441
1442 let dict_array = DictionaryArray::new(keys, Arc::new(values));
1443
1444 let boxed: ArrayRef = Arc::new(dict_array);
1445
1446 let col: DictionaryArray<Int8Type> = DictionaryArray::<Int8Type>::from(boxed.to_data());
1447 let err = col.into_primitive_dict_builder::<Int32Type>();
1448
1449 let returned = err.unwrap_err();
1450
1451 let values = Int32Array::from_iter_values([10_i32, 12, 15]);
1452 let keys = Int8Array::from_iter_values([1_i8, 0, 2, 0]);
1453
1454 let expected = DictionaryArray::new(keys, Arc::new(values));
1455 assert_eq!(expected, returned);
1456 }
1457
1458 #[test]
1459 fn test_occupancy() {
1460 let keys = Int32Array::new((100..200).collect(), None);
1461 let values = Int32Array::from(vec![0; 1024]);
1462 let dict = DictionaryArray::new(keys, Arc::new(values));
1463 for (idx, v) in dict.occupancy().iter().enumerate() {
1464 let expected = (100..200).contains(&idx);
1465 assert_eq!(v, expected, "{idx}");
1466 }
1467
1468 let keys = Int32Array::new(
1469 (0..100).collect(),
1470 Some((0..100).map(|x| x % 4 == 0).collect()),
1471 );
1472 let values = Int32Array::from(vec![0; 1024]);
1473 let dict = DictionaryArray::new(keys, Arc::new(values));
1474 for (idx, v) in dict.occupancy().iter().enumerate() {
1475 let expected = idx % 4 == 0 && idx < 100;
1476 assert_eq!(v, expected, "{idx}");
1477 }
1478 }
1479
1480 #[test]
1481 fn test_iterator_nulls() {
1482 let keys = Int32Array::new(
1483 vec![0, 700, 1, 2].into(),
1484 Some(NullBuffer::from(vec![true, false, true, true])),
1485 );
1486 let values = Int32Array::from(vec![Some(50), None, Some(2)]);
1487 let dict = DictionaryArray::new(keys, Arc::new(values));
1488 let values: Vec<_> = dict
1489 .downcast_dict::<Int32Array>()
1490 .unwrap()
1491 .into_iter()
1492 .collect();
1493 assert_eq!(values, &[Some(50), None, None, Some(2)])
1494 }
1495
1496 #[test]
1497 fn test_logical_nulls() -> Result<(), ArrowError> {
1498 let values = Arc::new(RunArray::try_new(
1499 &Int32Array::from(vec![1, 3, 7]),
1500 &Int32Array::from(vec![Some(1), None, Some(3)]),
1501 )?) as ArrayRef;
1502
1503 assert_eq!(values.null_count(), 0);
1505 assert_eq!(values.logical_null_count(), 2);
1506
1507 let dictionary = DictionaryArray::<Int8Type>::try_new(
1509 Int8Array::from((0..values.len()).map(|i| i as i8).collect::<Vec<_>>()),
1510 Arc::clone(&values),
1511 )?;
1512
1513 assert_eq!(dictionary.null_count(), 0);
1515 assert_eq!(dictionary.logical_null_count(), values.logical_null_count());
1517 assert_eq!(dictionary.logical_nulls(), values.logical_nulls());
1518 assert!(dictionary.is_nullable());
1519
1520 let dictionary = DictionaryArray::<Int8Type>::try_new(
1522 Int8Array::from(
1523 (0..values.len())
1524 .map(|i| i as i8)
1525 .map(|i| if i == 0 { None } else { Some(i) })
1526 .collect::<Vec<_>>(),
1527 ),
1528 Arc::clone(&values),
1529 )?;
1530
1531 assert_eq!(dictionary.null_count(), 1);
1533
1534 assert_eq!(
1536 dictionary.logical_null_count(),
1537 values.logical_null_count() + 1
1538 );
1539 assert!(dictionary.is_nullable());
1540
1541 Ok(())
1542 }
1543
1544 #[test]
1545 fn test_normalized_keys() {
1546 let values = vec![132, 0, 1].into();
1547 let nulls = NullBuffer::from(vec![false, true, true]);
1548 let keys = Int32Array::new(values, Some(nulls));
1549 let dictionary = DictionaryArray::new(keys, Arc::new(Int32Array::new_null(2)));
1550 assert_eq!(&dictionary.normalized_keys(), &[1, 0, 1])
1551 }
1552
1553 #[test]
1554 fn test_all_null_dict() {
1555 let all_null_dict_arr = DictionaryArray::try_new(
1556 UInt8Array::new_null(10),
1557 Arc::new(StringArray::from_iter_values(["a"])),
1558 );
1559 assert!(all_null_dict_arr.is_ok())
1560 }
1561}