Skip to main content

arrow_data/equal/
boolean.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: See the NOTICE file distributed with this work for additional information regarding copyright ownership
3// SPDX-FileContributor: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements
4
5use crate::bit_iterator::BitIndexIterator;
6use crate::data::{ArrayData, contains_nulls};
7use arrow_buffer::bit_util::get_bit;
8
9use super::utils::{equal_bits, equal_len};
10
11/// Returns true if the value data for the arrays is equal, assuming the null masks have
12/// already been checked for equality
13pub(super) fn boolean_equal(
14    lhs: &ArrayData,
15    rhs: &ArrayData,
16    mut lhs_start: usize,
17    mut rhs_start: usize,
18    mut len: usize,
19) -> bool {
20    let lhs_values = lhs.buffers()[0].as_slice();
21    let rhs_values = rhs.buffers()[0].as_slice();
22
23    let contains_nulls = contains_nulls(lhs.nulls(), lhs_start, len);
24
25    if !contains_nulls {
26        // Optimize performance for starting offset at u8 boundary.
27        if lhs_start.is_multiple_of(8)
28            && rhs_start.is_multiple_of(8)
29            && lhs.offset().is_multiple_of(8)
30            && rhs.offset().is_multiple_of(8)
31        {
32            let quot = len / 8;
33            if quot > 0
34                && !equal_len(
35                    lhs_values,
36                    rhs_values,
37                    lhs_start / 8 + lhs.offset() / 8,
38                    rhs_start / 8 + rhs.offset() / 8,
39                    quot,
40                )
41            {
42                return false;
43            }
44
45            // Calculate for suffix bits.
46            let rem = len % 8;
47            if rem == 0 {
48                return true;
49            }
50
51            let aligned_bits = len - rem;
52            lhs_start += aligned_bits;
53            rhs_start += aligned_bits;
54            len = rem;
55        }
56
57        equal_bits(
58            lhs_values,
59            rhs_values,
60            lhs_start + lhs.offset(),
61            rhs_start + rhs.offset(),
62            len,
63        )
64    } else {
65        // get a ref of the null buffer bytes, to use in testing for nullness
66        let lhs_nulls = lhs.nulls().unwrap();
67
68        BitIndexIterator::new(lhs_nulls.validity(), lhs_start + lhs_nulls.offset(), len).all(|i| {
69            let lhs_pos = lhs_start + lhs.offset() + i;
70            let rhs_pos = rhs_start + rhs.offset() + i;
71            get_bit(lhs_values, lhs_pos) == get_bit(rhs_values, rhs_pos)
72        })
73    }
74}