refactor(compress): move LDM fast-table policy to Rust
Move the strategy classification that decides whether LDM preparation fills fast or double-fast tables into Rust. C retains the private match-state, configuration-specific table-fill leaves, and the existing excluded-DFAST assertion. Add enum-value ABI checks plus focused tests for valid and invalid strategy classifications. Test Plan: - `ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check` - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` - `ulimit -v 41943040; make -j1` - `ulimit -v 41943040; make -j1 -C tests test` - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings` - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets` The integrated checks ran at the combined working-tree tip under a serial 40 GiB virtual-memory limit. Standalone root Rust unit linking remains unavailable because the crate imports C-owned bridge symbols without a Cargo build/link setup.
This commit is contained in:
+14
-10
@@ -248,6 +248,8 @@ ZSTD_RUST_LDM_OFFSET_CHECK(
|
|||||||
|
|
||||||
#undef ZSTD_RUST_LDM_OFFSET_CHECK
|
#undef ZSTD_RUST_LDM_OFFSET_CHECK
|
||||||
typedef char ZSTD_rust_ldm_rep_count[(ZSTD_REP_NUM == 3) ? 1 : -1];
|
typedef char ZSTD_rust_ldm_rep_count[(ZSTD_REP_NUM == 3) ? 1 : -1];
|
||||||
|
typedef char ZSTD_rust_ldm_strategy_values_check[
|
||||||
|
(ZSTD_fast == 1 && ZSTD_dfast == 2 && ZSTD_btultra2 == 9) ? 1 : -1];
|
||||||
|
|
||||||
void ZSTD_rust_ldm_adjustParameters(
|
void ZSTD_rust_ldm_adjustParameters(
|
||||||
void* params, U32 windowLog, int strategy,
|
void* params, U32 windowLog, int strategy,
|
||||||
@@ -270,6 +272,14 @@ size_t ZSTD_rust_ldm_blockCompress(
|
|||||||
const void* src, size_t srcSize, U32 minMatch, int strategy);
|
const void* src, size_t srcSize, U32 minMatch, int strategy);
|
||||||
U32 ZSTD_rust_ldm_limitTableUpdate(U32 curr, U32 nextToUpdate);
|
U32 ZSTD_rust_ldm_limitTableUpdate(U32 curr, U32 nextToUpdate);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ZSTD_RUST_LDM_FAST_TABLES_NONE = 0,
|
||||||
|
ZSTD_RUST_LDM_FAST_TABLES_FAST = 1,
|
||||||
|
ZSTD_RUST_LDM_FAST_TABLES_DFAST = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
int ZSTD_rust_ldm_fastTableKind(int strategy);
|
||||||
|
|
||||||
const U64* ZSTD_ldm_rust_gearTable(void);
|
const U64* ZSTD_ldm_rust_gearTable(void);
|
||||||
void ZSTD_ldm_rust_prepareBlock(void* blockContext, const void* anchor);
|
void ZSTD_ldm_rust_prepareBlock(void* blockContext, const void* anchor);
|
||||||
size_t ZSTD_ldm_rust_compressLiterals(
|
size_t ZSTD_ldm_rust_compressLiterals(
|
||||||
@@ -289,24 +299,18 @@ typedef struct {
|
|||||||
|
|
||||||
static void ZSTD_rust_ldm_fillFastTables(ZSTD_MatchState_t* ms, const BYTE* end)
|
static void ZSTD_rust_ldm_fillFastTables(ZSTD_MatchState_t* ms, const BYTE* end)
|
||||||
{
|
{
|
||||||
switch (ms->cParams.strategy) {
|
switch (ZSTD_rust_ldm_fastTableKind((int)ms->cParams.strategy)) {
|
||||||
case ZSTD_fast:
|
case ZSTD_RUST_LDM_FAST_TABLES_FAST:
|
||||||
ZSTD_fillHashTable(ms, end, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx);
|
ZSTD_fillHashTable(ms, end, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx);
|
||||||
break;
|
break;
|
||||||
case ZSTD_dfast:
|
case ZSTD_RUST_LDM_FAST_TABLES_DFAST:
|
||||||
#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR
|
#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR
|
||||||
ZSTD_fillDoubleHashTable(ms, end, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx);
|
ZSTD_fillDoubleHashTable(ms, end, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx);
|
||||||
#else
|
#else
|
||||||
assert(0);
|
assert(0);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case ZSTD_greedy:
|
case ZSTD_RUST_LDM_FAST_TABLES_NONE:
|
||||||
case ZSTD_lazy:
|
|
||||||
case ZSTD_lazy2:
|
|
||||||
case ZSTD_btlazy2:
|
|
||||||
case ZSTD_btopt:
|
|
||||||
case ZSTD_btultra:
|
|
||||||
case ZSTD_btultra2:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|||||||
@@ -23,8 +23,16 @@ const LDM_MIN_MATCH_LENGTH: u32 = 64;
|
|||||||
const HASH_READ_SIZE: usize = 8;
|
const HASH_READ_SIZE: usize = 8;
|
||||||
const ZSTD_REP_NUM: usize = 3;
|
const ZSTD_REP_NUM: usize = 3;
|
||||||
const ZSTD_WINDOW_START_INDEX: u32 = 2;
|
const ZSTD_WINDOW_START_INDEX: u32 = 2;
|
||||||
|
const ZSTD_FAST_STRATEGY: c_int = 1;
|
||||||
|
const ZSTD_DFAST_STRATEGY: c_int = 2;
|
||||||
|
const ZSTD_STRATEGY_MAX: c_int = 9;
|
||||||
const ZSTD_BTOPT: c_int = 7;
|
const ZSTD_BTOPT: c_int = 7;
|
||||||
|
|
||||||
|
const LDM_FAST_TABLES_NONE: c_int = 0;
|
||||||
|
const LDM_FAST_TABLES_FAST: c_int = 1;
|
||||||
|
const LDM_FAST_TABLES_DFAST: c_int = 2;
|
||||||
|
const LDM_FAST_TABLES_INVALID: c_int = -1;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct LdmEntry {
|
struct LdmEntry {
|
||||||
@@ -196,6 +204,20 @@ pub extern "C" fn ZSTD_rust_ldm_limitTableUpdate(curr: u32, next_to_update: u32)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Classify the C-owned table update needed before an LDM literal segment.
|
||||||
|
///
|
||||||
|
/// The table fill itself stays in C because it owns the private match state;
|
||||||
|
/// Rust owns only this deterministic strategy policy.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ZSTD_rust_ldm_fastTableKind(strategy: c_int) -> c_int {
|
||||||
|
match strategy {
|
||||||
|
ZSTD_FAST_STRATEGY => LDM_FAST_TABLES_FAST,
|
||||||
|
ZSTD_DFAST_STRATEGY => LDM_FAST_TABLES_DFAST,
|
||||||
|
3..=ZSTD_STRATEGY_MAX => LDM_FAST_TABLES_NONE,
|
||||||
|
_ => LDM_FAST_TABLES_INVALID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn ldm_bucket(hash_table: *mut LdmEntry, hash: u32, bucket_size_log: u32) -> *mut LdmEntry {
|
unsafe fn ldm_bucket(hash_table: *mut LdmEntry, hash: u32, bucket_size_log: u32) -> *mut LdmEntry {
|
||||||
unsafe { hash_table.add((hash as usize) << bucket_size_log) }
|
unsafe { hash_table.add((hash as usize) << bucket_size_log) }
|
||||||
@@ -1075,6 +1097,31 @@ mod tests {
|
|||||||
assert!(use_optimal_parser(9));
|
assert!(use_optimal_parser(9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fast_table_kind_preserves_c_strategy_dispatch() {
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_ldm_fastTableKind(ZSTD_FAST_STRATEGY),
|
||||||
|
LDM_FAST_TABLES_FAST
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_ldm_fastTableKind(ZSTD_DFAST_STRATEGY),
|
||||||
|
LDM_FAST_TABLES_DFAST
|
||||||
|
);
|
||||||
|
for strategy in 3..=ZSTD_STRATEGY_MAX {
|
||||||
|
assert_eq!(ZSTD_rust_ldm_fastTableKind(strategy), LDM_FAST_TABLES_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fast_table_kind_rejects_invalid_strategy_values() {
|
||||||
|
assert_eq!(ZSTD_rust_ldm_fastTableKind(0), LDM_FAST_TABLES_INVALID);
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_ldm_fastTableKind(ZSTD_STRATEGY_MAX + 1),
|
||||||
|
LDM_FAST_TABLES_INVALID
|
||||||
|
);
|
||||||
|
assert_eq!(ZSTD_rust_ldm_fastTableKind(-1), LDM_FAST_TABLES_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_sequence_skipping_merges_short_tail_matches() {
|
fn raw_sequence_skipping_merges_short_tail_matches() {
|
||||||
let mut sequences = [
|
let mut sequences = [
|
||||||
|
|||||||
Reference in New Issue
Block a user