From: Ezekiel Newren <ezekielnewren@xxxxxxxxx> These functions use the whitespace iterator, when applicable, to hash, and compare lines. Signed-off-by: Ezekiel Newren <ezekielnewren@xxxxxxxxx> --- rust/xdiff/src/lib.rs | 19 +++++++++++++++++++ rust/xdiff/src/xutils.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/rust/xdiff/src/lib.rs b/rust/xdiff/src/lib.rs index 9cf0462bcdb9..809c5573c6e7 100644 --- a/rust/xdiff/src/lib.rs +++ b/rust/xdiff/src/lib.rs @@ -1,3 +1,7 @@ +use std::hash::Hasher; +use xxhash_rust::xxh3::Xxh3Default; +use crate::xutils::*; + pub mod xutils; pub const XDF_IGNORE_WHITESPACE: u64 = 1 << 1; @@ -15,3 +19,18 @@ unsafe extern "C" fn xxh3_64(ptr: *const u8, size: usize) -> u64 { let slice = std::slice::from_raw_parts(ptr, size); xxhash_rust::xxh3::xxh3_64(slice) } + +#[no_mangle] +unsafe extern "C" fn xdl_line_hash(ptr: *const u8, size: usize, flags: u64) -> u64 { + let line = std::slice::from_raw_parts(ptr, size); + + line_hash(line, flags) +} + +#[no_mangle] +unsafe extern "C" fn xdl_line_equal(lhs: *const u8, lhs_len: usize, rhs: *const u8, rhs_len: usize, flags: u64) -> bool { + let lhs_line = std::slice::from_raw_parts(lhs, lhs_len); + let rhs_line = std::slice::from_raw_parts(rhs, rhs_len); + + line_equal(lhs_line, rhs_line, flags) +} diff --git a/rust/xdiff/src/xutils.rs b/rust/xdiff/src/xutils.rs index 38126b47292f..796a5708b6bf 100644 --- a/rust/xdiff/src/xutils.rs +++ b/rust/xdiff/src/xutils.rs @@ -1,4 +1,5 @@ use crate::*; +use xxhash_rust::xxh3::xxh3_64; pub(crate) fn xdl_isspace(v: u8) -> bool { match v { @@ -151,6 +152,33 @@ where run_option0.is_none() && run_option1.is_none() } + +pub fn line_hash(line: &[u8], flags: u64) -> u64 { + if (flags & XDF_WHITESPACE_FLAGS) == 0 { + return xxh3_64(line); + } + + let mut hasher = Xxh3Default::new(); + for chunk in WhitespaceIter::new(line, flags) { + hasher.update(chunk); + } + + hasher.finish() +} + + +pub fn line_equal(lhs: &[u8], rhs: &[u8], flags: u64) -> bool { + if (flags & XDF_WHITESPACE_FLAGS) == 0 { + return lhs == rhs; + } + + let lhs_it = WhitespaceIter::new(lhs, flags); + let rhs_it = WhitespaceIter::new(rhs, flags); + + chunked_iter_equal(lhs_it, rhs_it) +} + + #[cfg(test)] mod tests { use crate::*; -- gitgitgadget