use crate::data::{contains_nulls, ArrayData};
use arrow_buffer::ArrowNativeType;
use num::Integer;
use super::utils::equal_len;
fn offset_value_equal<T: ArrowNativeType + Integer>(
lhs_values: &[u8],
rhs_values: &[u8],
lhs_offsets: &[T],
rhs_offsets: &[T],
lhs_pos: usize,
rhs_pos: usize,
len: usize,
) -> bool {
let lhs_start = lhs_offsets[lhs_pos].as_usize();
let rhs_start = rhs_offsets[rhs_pos].as_usize();
let lhs_len = (lhs_offsets[lhs_pos + len] - lhs_offsets[lhs_pos])
.to_usize()
.unwrap();
let rhs_len = (rhs_offsets[rhs_pos + len] - rhs_offsets[rhs_pos])
.to_usize()
.unwrap();
if lhs_len == 0 && rhs_len == 0 {
return true;
}
lhs_len == rhs_len && equal_len(lhs_values, rhs_values, lhs_start, rhs_start, lhs_len)
}
pub(super) fn variable_sized_equal<T: ArrowNativeType + Integer>(
lhs: &ArrayData,
rhs: &ArrayData,
lhs_start: usize,
rhs_start: usize,
len: usize,
) -> bool {
let lhs_offsets = lhs.buffer::<T>(0);
let rhs_offsets = rhs.buffer::<T>(0);
let lhs_values = lhs.buffers()[1].as_slice();
let rhs_values = rhs.buffers()[1].as_slice();
if !contains_nulls(lhs.nulls(), lhs_start, len) {
offset_value_equal(
lhs_values,
rhs_values,
lhs_offsets,
rhs_offsets,
lhs_start,
rhs_start,
len,
)
} else {
(0..len).all(|i| {
let lhs_pos = lhs_start + i;
let rhs_pos = rhs_start + i;
let lhs_is_null = lhs.nulls().map(|v| v.is_null(lhs_pos)).unwrap_or_default();
let rhs_is_null = rhs.nulls().map(|v| v.is_null(rhs_pos)).unwrap_or_default();
lhs_is_null
|| (lhs_is_null == rhs_is_null)
&& offset_value_equal(
lhs_values,
rhs_values,
lhs_offsets,
rhs_offsets,
lhs_pos,
rhs_pos,
1,
)
})
}
}