diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6b1650b41..53502d9c0 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -50,6 +50,7 @@ size_t ZSTD_rust_resetCCtxForSimpleCompression(void* cctx); size_t ZSTD_rust_prepareCCtxForSimpleCompression(void* cctx, size_t srcSize, int compressionLevel); +int ZSTD_rust_compressCCtxStrategy(size_t srcSize, int compressionLevel); size_t ZSTD_rust_resetCCtxForSimpleCompressionSession(void* cctx); void ZSTD_rust_markSimpleCompression2Complete(void* cctx); size_t ZSTD_compress2_c(ZSTD_CCtx* cctx, @@ -3837,6 +3838,13 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, /* The Rust simple API still needs the C-owned context reset, but does not * cross the private context layout. */ +int ZSTD_rust_compressCCtxStrategy(size_t srcSize, int compressionLevel) +{ + ZSTD_parameters const params = ZSTD_getParams_internal( + compressionLevel, srcSize, 0, ZSTD_cpm_noAttachDict); + return (int)params.cParams.strategy; +} + size_t ZSTD_rust_resetCCtxForSimpleCompression(void* cctx) { return ZSTD_CCtx_reset((ZSTD_CCtx*)cctx, ZSTD_reset_session_and_parameters); diff --git a/rust/src/zstd_compress.rs b/rust/src/zstd_compress.rs index a2226214f..a7b080eca 100644 --- a/rust/src/zstd_compress.rs +++ b/rust/src/zstd_compress.rs @@ -40,9 +40,20 @@ unsafe extern "C" { src_size: usize, compression_level: c_int, ) -> usize; + fn ZSTD_rust_compressCCtxStrategy(src_size: usize, compression_level: c_int) -> c_int; fn ZSTD_rust_resetCCtxForSimpleCompressionSession(cctx: *mut c_void) -> usize; fn ZSTD_rust_markSimpleCompression2Complete(cctx: *mut c_void); fn ZSTD_rust_simpleCompress2Level(cctx: *const c_void) -> c_int; + fn ZSTD_compress_usingDict( + cctx: *mut c_void, + dst: *mut c_void, + dst_capacity: usize, + src: *const c_void, + src_size: usize, + dict: *const c_void, + dict_size: usize, + compression_level: c_int, + ) -> usize; fn ZSTD_rust_simpleCompressStream2Level(cctx: *const c_void) -> c_int; fn ZSTD_compress2_c( cctx: *mut c_void, @@ -565,8 +576,8 @@ pub unsafe extern "C" fn ZSTD_compress( /// /// The public contract deliberately ignores all advanced context parameters. /// C performs the context reset because the private `ZSTD_CCtx_s` layout is -/// still configuration-dependent; the frame compressor itself is entirely -/// Rust-owned and does not inspect the context. +/// still configuration-dependent. Strategies not yet implemented by the +/// Rust frame compressor use the original C simple API before that reset. #[no_mangle] pub unsafe extern "C" fn ZSTD_compressCCtx( cctx: *mut c_void, @@ -581,6 +592,21 @@ pub unsafe extern "C" fn ZSTD_compressCCtx( } #[cfg(not(test))] { + let strategy = unsafe { ZSTD_rust_compressCCtxStrategy(src_size, compression_level) }; + if strategy != ZSTD_FAST && strategy != ZSTD_DFAST { + return unsafe { + ZSTD_compress_usingDict( + cctx, + dst, + dst_capacity, + src, + src_size, + ptr::null(), + 0, + compression_level, + ) + }; + } let reset = unsafe { ZSTD_rust_resetCCtxForSimpleCompression(cctx) }; if ERR_isError(reset) { return reset;