arrow_data/equal/
fixed_binary.rs1use crate::bit_iterator::BitSliceIterator;
6use crate::contains_nulls;
7use crate::data::{ArrayData, get_fixed_size_binary_width};
8use crate::equal::primitive::NULL_SLICES_SELECTIVITY_THRESHOLD;
9
10use super::utils::equal_len;
11
12pub(super) fn fixed_binary_equal(
13 lhs: &ArrayData,
14 rhs: &ArrayData,
15 lhs_start: usize,
16 rhs_start: usize,
17 len: usize,
18) -> bool {
19 let size = get_fixed_size_binary_width(lhs.data_type());
20
21 let lhs_values = &lhs.buffers()[0].as_slice()[lhs.offset() * size..];
22 let rhs_values = &rhs.buffers()[0].as_slice()[rhs.offset() * size..];
23
24 if !contains_nulls(lhs.nulls(), lhs_start, len) {
27 equal_len(
28 lhs_values,
29 rhs_values,
30 size * lhs_start,
31 size * rhs_start,
32 size * len,
33 )
34 } else {
35 let selectivity_frac = lhs.null_count() as f64 / lhs.len() as f64;
36
37 let lhs_nulls = lhs.nulls().unwrap();
39 let rhs_nulls = rhs.nulls().unwrap();
40
41 if selectivity_frac >= NULL_SLICES_SELECTIVITY_THRESHOLD {
42 (0..len).all(|i| {
44 let lhs_pos = lhs_start + i;
45 let rhs_pos = rhs_start + i;
46
47 let lhs_is_null = lhs_nulls.is_null(lhs_pos);
48 let rhs_is_null = rhs_nulls.is_null(rhs_pos);
49
50 lhs_is_null
51 || (lhs_is_null == rhs_is_null)
52 && equal_len(
53 lhs_values,
54 rhs_values,
55 lhs_pos * size,
56 rhs_pos * size,
57 size, )
59 })
60 } else {
61 let lhs_slices_iter =
62 BitSliceIterator::new(lhs_nulls.validity(), lhs_start + lhs_nulls.offset(), len);
63 let rhs_slices_iter =
64 BitSliceIterator::new(rhs_nulls.validity(), rhs_start + rhs_nulls.offset(), len);
65
66 lhs_slices_iter
67 .zip(rhs_slices_iter)
68 .all(|((l_start, l_end), (r_start, r_end))| {
69 l_start == r_start
70 && l_end == r_end
71 && equal_len(
72 lhs_values,
73 rhs_values,
74 (lhs_start + l_start) * size,
75 (rhs_start + r_start) * size,
76 (l_end - l_start) * size,
77 )
78 })
79 }
80 }
81}