refactor(compress): move CCtx estimate tier policy to Rust

Move the fixed source-size tier traversal used by
ZSTD_estimateCCtxSize_internal() into Rust.  C retains the authoritative
parameter lookup and per-tier workspace estimator behind callbacks, while Rust
owns the tier ordering and maximum-selection policy.  The projection includes
ABI layout assertions and tests for callback order, level propagation, and
error-valued maxima.

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:
2026-07-20 09:49:37 +02:00
parent dd87b328a4
commit 4409ef1e16
2 changed files with 161 additions and 10 deletions
+44 -10
View File
@@ -1880,6 +1880,28 @@ size_t ZSTD_rust_estimateCCtxWorkspaceSize(
size_t ZSTD_rust_planCCtxReset(const ZSTD_rustCCtxResetState* state);
size_t ZSTD_rust_maxEstimateCCtxSize(size_t estimate0, size_t estimate1,
size_t estimate2, size_t estimate3);
typedef ZSTD_compressionParameters (*ZSTD_rust_estimateCCtxSizeGetCParams_f)(
void* context, int compressionLevel, U64 srcSizeHint);
typedef size_t (*ZSTD_rust_estimateCCtxSizeEstimate_f)(
void* context, ZSTD_compressionParameters cParams);
typedef struct {
void* callbackContext;
int compressionLevel;
ZSTD_rust_estimateCCtxSizeGetCParams_f getCParams;
ZSTD_rust_estimateCCtxSizeEstimate_f estimate;
} ZSTD_rust_estimateCCtxSizeState;
typedef char ZSTD_rust_estimate_cctx_size_state_layout[
(offsetof(ZSTD_rust_estimateCCtxSizeState, callbackContext) == 0
&& offsetof(ZSTD_rust_estimateCCtxSizeState, compressionLevel)
== sizeof(void*)
&& offsetof(ZSTD_rust_estimateCCtxSizeState, getCParams)
== 2 * sizeof(void*)
&& offsetof(ZSTD_rust_estimateCCtxSizeState, estimate)
== 3 * sizeof(void*)
&& sizeof(ZSTD_rust_estimateCCtxSizeState) == 4 * sizeof(void*))
? 1 : -1];
size_t ZSTD_rust_estimateCCtxSizeInternal(
const ZSTD_rust_estimateCCtxSizeState* state);
ZSTD_inBuffer ZSTD_rust_inBufferForEndFlush(int inBufferMode,
const void* expectedSrc,
size_t expectedSize,
@@ -4114,18 +4136,30 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
}
}
static ZSTD_compressionParameters ZSTD_rust_estimateCCtxSize_getCParams(
void* context, int compressionLevel, U64 srcSizeHint)
{
(void)context;
return ZSTD_getCParams_internal(
compressionLevel, srcSizeHint, 0, ZSTD_cpm_noAttachDict);
}
static size_t ZSTD_rust_estimateCCtxSize_estimate(
void* context, ZSTD_compressionParameters cParams)
{
(void)context;
return ZSTD_estimateCCtxSize_usingCParams(cParams);
}
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
{
int tier = 0;
size_t estimates[4];
static const unsigned long long srcSizeTiers[4] = {16 KB, 128 KB, 256 KB, ZSTD_CONTENTSIZE_UNKNOWN};
for (; tier < 4; ++tier) {
/* Choose the set of cParams for a given level across all srcSizes that give the largest cctxSize */
ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeTiers[tier], 0, ZSTD_cpm_noAttachDict);
estimates[tier] = ZSTD_estimateCCtxSize_usingCParams(cParams);
}
return ZSTD_rust_maxEstimateCCtxSize(
estimates[0], estimates[1], estimates[2], estimates[3]);
ZSTD_rust_estimateCCtxSizeState const state = {
NULL,
compressionLevel,
ZSTD_rust_estimateCCtxSize_getCParams,
ZSTD_rust_estimateCCtxSize_estimate
};
return ZSTD_rust_estimateCCtxSizeInternal(&state);
}
size_t ZSTD_estimateCCtxSize(int compressionLevel)