From: Ezekiel Newren <ezekielnewren@xxxxxxxxx> Replace the C implementation of xdl_trim_ends() with a Rust implementation. Signed-off-by: Ezekiel Newren <ezekielnewren@xxxxxxxxx> --- rust/xdiff/src/lib.rs | 14 ++++++++++++++ rust/xdiff/src/xprepare.rs | 27 +++++++++++++++++++++++++++ rust/xdiff/src/xtypes.rs | 19 +++++++++++++++++++ xdiff/xprepare.c | 28 +--------------------------- 4 files changed, 61 insertions(+), 27 deletions(-) create mode 100644 rust/xdiff/src/xprepare.rs create mode 100644 rust/xdiff/src/xtypes.rs diff --git a/rust/xdiff/src/lib.rs b/rust/xdiff/src/lib.rs index 8b137891791f..4cc05a7e6b4b 100644 --- a/rust/xdiff/src/lib.rs +++ b/rust/xdiff/src/lib.rs @@ -1 +1,15 @@ +pub mod xprepare; +pub mod xtypes; +use crate::xprepare::trim_ends; +use crate::xtypes::xdfile; + +#[no_mangle] +unsafe extern "C" fn xdl_trim_ends(xdf1: *mut xdfile, xdf2: *mut xdfile) -> i32 { + let xdf1 = xdf1.as_mut().expect("null pointer"); + let xdf2 = xdf2.as_mut().expect("null pointer"); + + trim_ends(xdf1, xdf2); + + 0 +} diff --git a/rust/xdiff/src/xprepare.rs b/rust/xdiff/src/xprepare.rs new file mode 100644 index 000000000000..f64f60c09965 --- /dev/null +++ b/rust/xdiff/src/xprepare.rs @@ -0,0 +1,27 @@ +use crate::xtypes::xdfile; + +/// +/// Early trim initial and terminal matching records. +/// +pub(crate) fn trim_ends(xdf1: &mut xdfile, xdf2: &mut xdfile) { + let mut lim = std::cmp::min(xdf1.record.len(), xdf2.record.len()); + + for i in 0..lim { + if xdf1.record[i].ha != xdf2.record[i].ha { + xdf1.dstart = i as isize; + xdf2.dstart = i as isize; + lim -= i; + break; + } + } + + for i in 0..lim { + let f1i = xdf1.record.len() - 1 - i; + let f2i = xdf2.record.len() - 1 - i; + if xdf1.record[f1i].ha != xdf2.record[f2i].ha { + xdf1.dend = f1i as isize; + xdf2.dend = f2i as isize; + break; + } + } +} diff --git a/rust/xdiff/src/xtypes.rs b/rust/xdiff/src/xtypes.rs new file mode 100644 index 000000000000..3d1ce9742f28 --- /dev/null +++ b/rust/xdiff/src/xtypes.rs @@ -0,0 +1,19 @@ +use interop::ivec::IVec; + +#[repr(C)] +pub(crate) struct xrecord { + pub(crate) ptr: *const u8, + pub(crate) size: usize, + pub(crate) ha: u64, +} + +#[repr(C)] +pub(crate) struct xdfile { + pub(crate) record: IVec<xrecord>, + pub(crate) dstart: isize, + pub(crate) dend: isize, + pub(crate) rchg: *mut u8, + pub(crate) rindex: *mut usize, + pub(crate) nreff: usize, + pub(crate) ha: *mut u64, +} diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index 93370f1c6db4..2c7480875f9f 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -318,33 +318,7 @@ static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xd } -/* - * Early trim initial and terminal matching records. - */ -static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2) { - long i, lim; - xrecord_t *recs1, *recs2; - - recs1 = xdf1->record.ptr; - recs2 = xdf2->record.ptr; - for (i = 0, lim = XDL_MIN(xdf1->record.length, xdf2->record.length); i < lim; - i++, recs1++, recs2++) - if (recs1->ha != recs2->ha) - break; - - xdf1->dstart = xdf2->dstart = i; - - recs1 = xdf1->record.ptr + xdf1->record.length - 1; - recs2 = xdf2->record.ptr + xdf2->record.length - 1; - for (lim -= i, i = 0; i < lim; i++, recs1--, recs2--) - if (recs1->ha != recs2->ha) - break; - - xdf1->dend = xdf1->record.length - i - 1; - xdf2->dend = xdf2->record.length - i - 1; - - return 0; -} +extern i32 xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2); static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) { -- gitgitgadget