+
Skip to content

RFC: Accelerate xdiff and begin its rustification #1980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,11 @@ TEST_SHELL_PATH = $(SHELL_PATH)

LIB_FILE = libgit.a
XDIFF_LIB = xdiff/lib.a
ifeq ($(DEBUG), 1)
RUST_LIB = rust/target/debug/libxdiff.a
else
RUST_LIB = rust/target/release/libxdiff.a
endif
REFTABLE_LIB = reftable/libreftable.a

GENERATED_H += command-list.h
Expand Down Expand Up @@ -1392,6 +1397,8 @@ UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-reftable.o
GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE)
EXTLIBS =

GITLIBS += $(RUST_LIB)

GIT_USER_AGENT = git/$(GIT_VERSION)

ifeq ($(wildcard sha1collisiondetection/lib/sha1.h),sha1collisiondetection/lib/sha1.h)
Expand Down Expand Up @@ -2925,6 +2932,14 @@ $(LIB_FILE): $(LIB_OBJS)
$(XDIFF_LIB): $(XDIFF_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^

.PHONY: $(RUST_LIB)
$(RUST_LIB):
ifeq ($(DEBUG), 1)
cd rust && RUSTFLAGS="-Aunused_imports -Adead_code" cargo build --verbose
else
cd rust && RUSTFLAGS="-Aunused_imports -Adead_code" cargo build --verbose --release
endif

$(REFTABLE_LIB): $(REFTABLE_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^

Expand Down Expand Up @@ -3756,7 +3771,10 @@ cocciclean:
$(RM) -r .build/contrib/coccinelle
$(RM) contrib/coccinelle/*.cocci.patch

clean: profile-clean coverage-clean cocciclean
rustclean:
cd rust && cargo clean

clean: profile-clean coverage-clean cocciclean rustclean
$(RM) -r .build $(UNIT_TEST_BIN)
$(RM) GIT-TEST-SUITES
$(RM) po/git.pot po/git-core.pot
Expand Down
14 changes: 14 additions & 0 deletions ci/install-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,18 @@ else
echo >&2 "::warning:: JGit wasn't installed, see above for clues why"
fi

if type rustc >/dev/null 2>&1
then
echo "$(tput setaf6)Rust & Cargo Versions$(tput sgr0)"
rustc --version
cargo --version
else
echo >&2 "WARNING: Rust wasn't installed, see above for clues why"
fi

curl https://sh.rustup.rs -sSf | sh -s -- -y --profile default --default-toolchain 1.87.0
export PATH="$HOME/.cargo/bin:$PATH"
"$HOME"/.cargo/bin/cargo --version
echo "cargo installed at: $(command -v cargo)"

end_group "Install dependencies"
17 changes: 17 additions & 0 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,23 @@ static inline int is_xplatform_dir_sep(int c)
#include "compat/msvc.h"
#endif

/* rust types */
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;

typedef float f32;
typedef double f64;

typedef size_t usize;
typedef ptrdiff_t isize;

/* used on Mac OS X */
#ifdef PRECOMPOSE_UNICODE
#include "compat/precompose_utf8.h"
Expand Down
32 changes: 32 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,36 @@ version_gen_environment.set('GIT_DATE', get_option('build_date'))
version_gen_environment.set('GIT_USER_AGENT', get_option('user_agent'))
version_gen_environment.set('GIT_VERSION', get_option('version'))

if get_option('optimization') in ['2', '3', 's', 'z']
rust_target = 'release'
rust_args = ['--release']
rustflags = '-Aunused_imports -Adead_code'
else
rust_target = 'debug'
rust_args = []
rustflags = '-Aunused_imports -Adead_code -C debuginfo=2 -C opt-level=1 -C force-frame-pointers=yes'
endif


rust_leaf = custom_target('rust_leaf',
output: 'libxdiff.a',
build_by_default: true,
build_always_stale: true,
command: ['cargo', 'build',
'--manifest-path', meson.project_source_root() / 'rust/Cargo.toml'
] + rust_args,
env: {
'RUSTFLAGS': rustflags,
},
install: false,
)

rust_xdiff_dep = declare_dependency(
link_args: ['-L' + meson.project_source_root() / 'rust/target' / rust_target, '-lxdiff'],
# include_directories: include_directories('xdiff/include'), # Adjust if you expose headers
)


compiler = meson.get_compiler('c')

libgit_sources = [
Expand Down Expand Up @@ -1677,6 +1707,8 @@ version_def_h = custom_target(
)
libgit_sources += version_def_h

libgit_dependencies += rust_xdiff_dep

libgit = declare_dependency(
link_with: static_library('git',
sources: libgit_sources,
Expand Down
21 changes: 21 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[workspace]
members = [
"xdiff",
"interop",
]
resolver = "2"
14 changes: 14 additions & 0 deletions rust/interop/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "interop"
version = "0.1.0"
edition = "2021"

[lib]
name = "interop"
path = "src/lib.rs"
## staticlib to generate xdiff.a for use by gcc
## cdylib (optional) to generate xdiff.so for use by gcc
## rlib is required by the rust unit tests
crate-type = ["staticlib", "rlib"]

[dependencies]
Empty file added rust/interop/src/lib.rs
Empty file.
16 changes: 16 additions & 0 deletions rust/xdiff/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "xdiff"
version = "0.1.0"
edition = "2021"

[lib]
name = "xdiff"
path = "src/lib.rs"
## staticlib to generate xdiff.a for use by gcc
## cdylib (optional) to generate xdiff.so for use by gcc
## rlib is required by the rust unit tests
crate-type = ["staticlib", "rlib"]

[dependencies]
interop = { path = "../interop" }
xxhash-rust = { version = "0.8.15", features = ["xxh3"] }
7 changes: 7 additions & 0 deletions rust/xdiff/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@


#[no_mangle]
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)
}
8 changes: 4 additions & 4 deletions xdiff/xdiffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ static int get_indent(xrecord_t *rec)
long i;
int ret = 0;

for (i = 0; i < rec->size; i++) {
for (i = 0; i < (long) rec->size; i++) {
char c = rec->ptr[i];

if (!XDL_ISSPACE(c))
Expand Down Expand Up @@ -1005,11 +1005,11 @@ static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags)

rec = &xe->xdf1.recs[xch->i1];
for (i = 0; i < xch->chg1 && ignore; i++)
ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
ignore = xdl_blankline((const char*) rec[i]->ptr, rec[i]->size, flags);

rec = &xe->xdf2.recs[xch->i2];
for (i = 0; i < xch->chg2 && ignore; i++)
ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
ignore = xdl_blankline((const char*)rec[i]->ptr, rec[i]->size, flags);

xch->ignore = ignore;
}
Expand All @@ -1020,7 +1020,7 @@ static int record_matches_regex(xrecord_t *rec, xpparam_t const *xpp) {
size_t i;

for (i = 0; i < xpp->ignore_regex_nr; i++)
if (!regexec_buf(xpp->ignore_regex[i], rec->ptr, rec->size, 1,
if (!regexec_buf(xpp->ignore_regex[i], (const char*) rec->ptr, rec->size, 1,
&regmatch, 0))
return 1;

Expand Down
2 changes: 1 addition & 1 deletion xdiff/xemit.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {

*rec = xdf->recs[ri]->ptr;
*rec = (char const*) xdf->recs[ri]->ptr;

return xdf->recs[ri]->size;
}
Expand Down
14 changes: 7 additions & 7 deletions xdiff/xmerge.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ static int xdl_merge_cmp_lines(xdfenv_t *xe1, int i1, xdfenv_t *xe2, int i2,
xrecord_t **rec2 = xe2->xdf2.recs + i2;

for (i = 0; i < line_count; i++) {
int result = xdl_recmatch(rec1[i]->ptr, rec1[i]->size,
rec2[i]->ptr, rec2[i]->size, flags);
int result = xdl_recmatch((const char*) rec1[i]->ptr, rec1[i]->size,
(const char*) rec2[i]->ptr, rec2[i]->size, flags);
if (!result)
return -1;
}
Expand Down Expand Up @@ -324,8 +324,8 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,

static int recmatch(xrecord_t *rec1, xrecord_t *rec2, unsigned long flags)
{
return xdl_recmatch(rec1->ptr, rec1->size,
rec2->ptr, rec2->size, flags);
return xdl_recmatch((char const*) rec1->ptr, rec1->size,
(char const*) rec2->ptr, rec2->size, flags);
}

/*
Expand Down Expand Up @@ -383,10 +383,10 @@ static int xdl_refine_conflicts(xdfenv_t *xe1, xdfenv_t *xe2, xdmerge_t *m,
*/
t1.ptr = (char *)xe1->xdf2.recs[m->i1]->ptr;
t1.size = xe1->xdf2.recs[m->i1 + m->chg1 - 1]->ptr
+ xe1->xdf2.recs[m->i1 + m->chg1 - 1]->size - t1.ptr;
+ xe1->xdf2.recs[m->i1 + m->chg1 - 1]->size - (u8 const*) t1.ptr;
t2.ptr = (char *)xe2->xdf2.recs[m->i2]->ptr;
t2.size = xe2->xdf2.recs[m->i2 + m->chg2 - 1]->ptr
+ xe2->xdf2.recs[m->i2 + m->chg2 - 1]->size - t2.ptr;
+ xe2->xdf2.recs[m->i2 + m->chg2 - 1]->size - (u8 const*) t2.ptr;
if (xdl_do_diff(&t1, &t2, xpp, &xe) < 0)
return -1;
if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
Expand Down Expand Up @@ -440,7 +440,7 @@ static int line_contains_alnum(const char *ptr, long size)
static int lines_contain_alnum(xdfenv_t *xe, int i, int chg)
{
for (; chg; chg--, i++)
if (line_contains_alnum(xe->xdf2.recs[i]->ptr,
if (line_contains_alnum((char const*) xe->xdf2.recs[i]->ptr,
xe->xdf2.recs[i]->size))
return 1;
return 0;
Expand Down
2 changes: 1 addition & 1 deletion xdiff/xpatience.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
return;
map->entries[index].line1 = line;
map->entries[index].hash = record->ha;
map->entries[index].anchor = is_anchor(xpp, map->env->xdf1.recs[line - 1]->ptr);
map->entries[index].anchor = is_anchor(xpp, (const char*) map->env->xdf1.recs[line - 1]->ptr);
if (!map->first)
map->first = map->entries + index;
if (map->last) {
Expand Down
Loading
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载