(
lhs: &ArrayData,
rhs: &ArrayData,
lhs_start: usize,
rhs_start: usize,
len: usize,
)
| 18 | use crate::{ArrayData, ByteView}; |
| 19 | |
| 20 | pub(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 | if lhs.is_null(idx) { |
| 36 | continue; |
| 37 | } |
| 38 | |
| 39 | let l_len_prefix = *l as u64; |
| 40 | let r_len_prefix = *r as u64; |
| 41 | // short-circuit, check length and prefix |
| 42 | if l_len_prefix != r_len_prefix { |
| 43 | return false; |
| 44 | } |
| 45 | |
| 46 | let len = l_len_prefix as u32; |
| 47 | // for inline storage, only need check view |
| 48 | if len <= 12 { |
| 49 | if l != r { |
| 50 | return false; |
| 51 | } |
| 52 | continue; |
| 53 | } |
| 54 | |
| 55 | // check buffers |
| 56 | let l_view = ByteView::from(*l); |
| 57 | let r_view = ByteView::from(*r); |
| 58 | |
| 59 | let l_buffer = &lhs_buffers[l_view.buffer_index as usize]; |
| 60 | let r_buffer = &rhs_buffers[r_view.buffer_index as usize]; |
| 61 | |
| 62 | // prefixes are already known to be equal; skip checking them |
| 63 | let len = len as usize - 4; |
| 64 | let l_offset = l_view.offset as usize + 4; |
| 65 | let r_offset = r_view.offset as usize + 4; |
| 66 | if l_buffer[l_offset..l_offset + len] != r_buffer[r_offset..r_offset + len] { |
| 67 | return false; |
| 68 | } |
| 69 | } |
| 70 | true |
| 71 | } |
no test coverage detected