Skip to main content

arrow_data/equal/
structure.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::data::{ArrayData, contains_nulls};
6
7use super::equal_range;
8
9/// Compares the values of two [ArrayData] starting at `lhs_start` and `rhs_start` respectively
10/// for `len` slots.
11fn equal_child_values(
12    lhs: &ArrayData,
13    rhs: &ArrayData,
14    lhs_start: usize,
15    rhs_start: usize,
16    len: usize,
17) -> bool {
18    let lhs_start = lhs_start + lhs.offset();
19    let rhs_start = rhs_start + rhs.offset();
20
21    lhs.child_data()
22        .iter()
23        .zip(rhs.child_data())
24        .all(|(lhs_values, rhs_values)| {
25            equal_range(lhs_values, rhs_values, lhs_start, rhs_start, len)
26        })
27}
28
29pub(super) fn struct_equal(
30    lhs: &ArrayData,
31    rhs: &ArrayData,
32    lhs_start: usize,
33    rhs_start: usize,
34    len: usize,
35) -> bool {
36    // Only checking one null mask here because by the time the control flow reaches
37    // this point, the equality of the two masks would have already been verified.
38    if !contains_nulls(lhs.nulls(), lhs_start, len) {
39        equal_child_values(lhs, rhs, lhs_start, rhs_start, len)
40    } else {
41        // get a ref of the null buffer bytes, to use in testing for nullness
42        let lhs_nulls = lhs.nulls().unwrap();
43        let rhs_nulls = rhs.nulls().unwrap();
44        // with nulls, we need to compare item by item whenever it is not null
45        (0..len).all(|i| {
46            let lhs_pos = lhs_start + i;
47            let rhs_pos = rhs_start + i;
48            // if both struct and child had no null buffers,
49            let lhs_is_null = lhs_nulls.is_null(lhs_pos);
50            let rhs_is_null = rhs_nulls.is_null(rhs_pos);
51
52            if lhs_is_null != rhs_is_null {
53                return false;
54            }
55
56            lhs_is_null || equal_child_values(lhs, rhs, lhs_pos, rhs_pos, 1)
57        })
58    }
59}