arrow_data/equal/byte_view.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::{ArrayData, ByteView};
19
20pub(super) fn byte_view_equal(
21 lhs: &ArrayData,
22 rhs: &ArrayData,
23 lhs_start: usize,
24 rhs_start: usize,
25 len: usize,
26) -> bool {
27 let lhs_views = &lhs.buffer::<u128>(0)[lhs_start..lhs_start + len];
28 let lhs_buffers = &lhs.buffers()[1..];
29 let rhs_views = &rhs.buffer::<u128>(0)[rhs_start..rhs_start + len];
30 let rhs_buffers = &rhs.buffers()[1..];
31
32 for (idx, (l, r)) in lhs_views.iter().zip(rhs_views).enumerate() {
33 // Only checking one null mask here because by the time the control flow reaches
34 // this point, the equality of the two masks would have already been verified.
35 // `idx` counts from `lhs_start`, so offset it to index the null mask.
36 if lhs.is_null(lhs_start + idx) {
37 continue;
38 }
39
40 let l_len_prefix = *l as u64;
41 let r_len_prefix = *r as u64;
42 // short-circuit, check length and prefix
43 if l_len_prefix != r_len_prefix {
44 return false;
45 }
46
47 let len = l_len_prefix as u32;
48 // for inline storage, only need check view
49 if len <= 12 {
50 if l != r {
51 return false;
52 }
53 continue;
54 }
55
56 // check buffers
57 let l_view = ByteView::from(*l);
58 let r_view = ByteView::from(*r);
59
60 let l_buffer = &lhs_buffers[l_view.buffer_index as usize];
61 let r_buffer = &rhs_buffers[r_view.buffer_index as usize];
62
63 // prefixes are already known to be equal; skip checking them
64 let len = len as usize - 4;
65 let l_offset = l_view.offset as usize + 4;
66 let r_offset = r_view.offset as usize + 4;
67 if l_buffer[l_offset..l_offset + len] != r_buffer[r_offset..r_offset + len] {
68 return false;
69 }
70 }
71 true
72}