(
array: &UnionArray,
union_fields: &UnionFields,
random_state: &RandomState,
hashes_buffer: &mut [u64],
)
| 783 | /// the default approach of hashing all children (same as dense unions). |
| 784 | #[cfg(not(feature = "force_hash_collisions"))] |
| 785 | fn hash_sparse_union_array( |
| 786 | array: &UnionArray, |
| 787 | union_fields: &UnionFields, |
| 788 | random_state: &RandomState, |
| 789 | hashes_buffer: &mut [u64], |
| 790 | ) -> Result<()> { |
| 791 | use std::collections::HashMap; |
| 792 | |
| 793 | // For 1-2 types, the take/scatter overhead isn't worth it. |
| 794 | // Fall back to the default approach (same as dense union). |
| 795 | if union_fields.len() <= 2 { |
| 796 | return hash_union_array_default( |
| 797 | array, |
| 798 | union_fields, |
| 799 | random_state, |
| 800 | hashes_buffer, |
| 801 | ); |
| 802 | } |
| 803 | |
| 804 | let type_ids = array.type_ids(); |
| 805 | |
| 806 | // Group indices by type_id |
| 807 | let mut indices_by_type: HashMap<i8, Vec<u32>> = HashMap::new(); |
| 808 | for (i, &type_id) in type_ids.iter().enumerate() { |
| 809 | indices_by_type.entry(type_id).or_default().push(i as u32); |
| 810 | } |
| 811 | |
| 812 | // For each type, extract only the needed elements, hash them, and scatter back |
| 813 | for (type_id, _field) in union_fields.iter() { |
| 814 | if let Some(indices) = indices_by_type.get(&type_id) { |
| 815 | if indices.is_empty() { |
| 816 | continue; |
| 817 | } |
| 818 | |
| 819 | let child = array.child(type_id); |
| 820 | let indices_array = UInt32Array::from(indices.clone()); |
| 821 | |
| 822 | // Extract only the elements we need using take() |
| 823 | let filtered = take(child.as_ref(), &indices_array, None)?; |
| 824 | |
| 825 | // Hash the filtered array |
| 826 | let mut filtered_hashes = vec![0u64; filtered.len()]; |
| 827 | create_hashes([&filtered], random_state, &mut filtered_hashes)?; |
| 828 | |
| 829 | // Scatter hashes back to correct positions |
| 830 | for (hash, &idx) in filtered_hashes.iter().zip(indices.iter()) { |
| 831 | hashes_buffer[idx as usize] = |
| 832 | combine_hashes(hashes_buffer[idx as usize], *hash); |
| 833 | } |
| 834 | } |
| 835 | } |
| 836 | |
| 837 | Ok(()) |
| 838 | } |
| 839 | |
| 840 | #[cfg(not(feature = "force_hash_collisions"))] |
| 841 | fn hash_fixed_list_array( |
no test coverage detected
searching dependent graphs…