refactor(compress): move advanced CDict wrapper policy to Rust
Move advanced CDict parameter preparation and construction ordering into the Rust policy layer while keeping advanced2 allocation, workspace, and private context layout in C. Preserve the existing allocator and callback ABI at the seam. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo +nightly fmt --manifest-path rust/Cargo.toml -- --check - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --all-targets (782 passed) - 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 (179 passed) - ulimit -v 41943040; make -j1 - ulimit -v 41943040; make -j1 -C tests test (all tests completed successfully)
This commit is contained in:
@@ -2224,6 +2224,100 @@ pub unsafe extern "C" fn ZSTD_rust_createCCtx(
|
||||
cctx
|
||||
}
|
||||
|
||||
type CreateCDictAdvancedWrapperInitParamsFn = unsafe extern "C" fn(
|
||||
*mut c_void,
|
||||
*mut c_void,
|
||||
*const ZSTD_compressionParameters,
|
||||
*const c_void,
|
||||
usize,
|
||||
c_int,
|
||||
);
|
||||
type CreateCDictAdvancedWrapperCreateFn = unsafe extern "C" fn(
|
||||
*mut c_void,
|
||||
*const c_void,
|
||||
usize,
|
||||
c_int,
|
||||
c_int,
|
||||
*const c_void,
|
||||
*const c_void,
|
||||
) -> *mut c_void;
|
||||
|
||||
/// Explicit projection for the public heap-CDict wrapper.
|
||||
///
|
||||
/// Rust owns the wrapper's preparation-to-construction ordering and forwards
|
||||
/// the dictionary scalars. C retains the private `ZSTD_CCtx_params` setup and
|
||||
/// the advanced-CDict implementation behind callbacks; allocation and
|
||||
/// workspace ownership stay in the existing advanced2 path.
|
||||
#[repr(C)]
|
||||
pub struct ZSTD_rust_createCDictAdvancedWrapperState {
|
||||
callback_context: *mut c_void,
|
||||
cctx_params: *mut c_void,
|
||||
c_params: *const ZSTD_compressionParameters,
|
||||
custom_mem: *const c_void,
|
||||
init_params: CreateCDictAdvancedWrapperInitParamsFn,
|
||||
create: CreateCDictAdvancedWrapperCreateFn,
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
assert!(offset_of!(ZSTD_rust_createCDictAdvancedWrapperState, callback_context) == 0);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedWrapperState, cctx_params) == size_of::<usize>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedWrapperState, c_params) == 2 * size_of::<usize>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedWrapperState, custom_mem) == 3 * size_of::<usize>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedWrapperState, init_params)
|
||||
== 4 * size_of::<usize>()
|
||||
);
|
||||
assert!(
|
||||
offset_of!(ZSTD_rust_createCDictAdvancedWrapperState, create) == 5 * size_of::<usize>()
|
||||
);
|
||||
assert!(size_of::<ZSTD_rust_createCDictAdvancedWrapperState>() == size_of::<[usize; 6]>());
|
||||
};
|
||||
|
||||
/// Prepare a heap-CDict parameter object, then enter the existing advanced
|
||||
/// construction path in the original callback order.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_createCDictAdvancedWrapper(
|
||||
state: *const ZSTD_rust_createCDictAdvancedWrapperState,
|
||||
dict: *const c_void,
|
||||
dict_size: usize,
|
||||
dict_load_method: c_int,
|
||||
dict_content_type: c_int,
|
||||
) -> *mut c_void {
|
||||
if state.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
let state = unsafe { &*state };
|
||||
if state.cctx_params.is_null() || state.c_params.is_null() || state.custom_mem.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
(state.init_params)(
|
||||
state.callback_context,
|
||||
state.cctx_params,
|
||||
state.c_params,
|
||||
state.custom_mem,
|
||||
dict_size,
|
||||
dict_content_type,
|
||||
);
|
||||
(state.create)(
|
||||
state.callback_context,
|
||||
dict,
|
||||
dict_size,
|
||||
dict_load_method,
|
||||
dict_content_type,
|
||||
state.cctx_params,
|
||||
state.custom_mem,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
type InitStaticCCtxFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||
const ZSTD_STATIC_WORKSPACE_ALIGNMENT: usize = 8;
|
||||
|
||||
@@ -17800,6 +17894,134 @@ mod tests {
|
||||
assert!(context.initialized.is_null());
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct CreateCDictAdvancedWrapperTestContext {
|
||||
events: Vec<&'static str>,
|
||||
init_context: *mut c_void,
|
||||
init_cctx_params: *mut c_void,
|
||||
init_c_params: *const ZSTD_compressionParameters,
|
||||
init_custom_mem: *const c_void,
|
||||
init_dict_size: usize,
|
||||
init_dict_content_type: c_int,
|
||||
create_context: *mut c_void,
|
||||
create_dict: *const c_void,
|
||||
create_dict_size: usize,
|
||||
create_dict_load_method: c_int,
|
||||
create_dict_content_type: c_int,
|
||||
create_cctx_params: *const c_void,
|
||||
create_custom_mem: *const c_void,
|
||||
result: *mut c_void,
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_wrapper_test_init(
|
||||
context: *mut c_void,
|
||||
cctx_params: *mut c_void,
|
||||
c_params: *const ZSTD_compressionParameters,
|
||||
custom_mem: *const c_void,
|
||||
dict_size: usize,
|
||||
dict_content_type: c_int,
|
||||
) {
|
||||
let context = unsafe { &mut *context.cast::<CreateCDictAdvancedWrapperTestContext>() };
|
||||
context.events.push("init");
|
||||
context.init_context = context as *mut _ as *mut c_void;
|
||||
context.init_cctx_params = cctx_params;
|
||||
context.init_c_params = c_params;
|
||||
context.init_custom_mem = custom_mem;
|
||||
context.init_dict_size = dict_size;
|
||||
context.init_dict_content_type = dict_content_type;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn create_cdict_advanced_wrapper_test_create(
|
||||
context: *mut c_void,
|
||||
dict: *const c_void,
|
||||
dict_size: usize,
|
||||
dict_load_method: c_int,
|
||||
dict_content_type: c_int,
|
||||
cctx_params: *const c_void,
|
||||
custom_mem: *const c_void,
|
||||
) -> *mut c_void {
|
||||
let context = unsafe { &mut *context.cast::<CreateCDictAdvancedWrapperTestContext>() };
|
||||
context.events.push("create");
|
||||
context.create_context = context as *mut _ as *mut c_void;
|
||||
context.create_dict = dict;
|
||||
context.create_dict_size = dict_size;
|
||||
context.create_dict_load_method = dict_load_method;
|
||||
context.create_dict_content_type = dict_content_type;
|
||||
context.create_cctx_params = cctx_params;
|
||||
context.create_custom_mem = custom_mem;
|
||||
context.result
|
||||
}
|
||||
|
||||
fn create_cdict_advanced_wrapper_test_state(
|
||||
context: &mut CreateCDictAdvancedWrapperTestContext,
|
||||
cctx_params: *mut c_void,
|
||||
c_params: *const ZSTD_compressionParameters,
|
||||
custom_mem: *const c_void,
|
||||
) -> ZSTD_rust_createCDictAdvancedWrapperState {
|
||||
ZSTD_rust_createCDictAdvancedWrapperState {
|
||||
callback_context: context as *mut _ as *mut c_void,
|
||||
cctx_params,
|
||||
c_params,
|
||||
custom_mem,
|
||||
init_params: create_cdict_advanced_wrapper_test_init,
|
||||
create: create_cdict_advanced_wrapper_test_create,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_cdict_advanced_wrapper_preserves_prepare_then_create_order() {
|
||||
let mut context = CreateCDictAdvancedWrapperTestContext {
|
||||
result: ptr::dangling_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
let cctx_params = ptr::dangling_mut::<c_void>();
|
||||
let c_params = ptr::dangling::<ZSTD_compressionParameters>();
|
||||
let custom_mem = ptr::dangling::<c_void>();
|
||||
let dict = ptr::dangling::<u8>().cast::<c_void>();
|
||||
let state = create_cdict_advanced_wrapper_test_state(
|
||||
&mut context,
|
||||
cctx_params,
|
||||
c_params,
|
||||
custom_mem,
|
||||
);
|
||||
|
||||
let result = unsafe { ZSTD_rust_createCDictAdvancedWrapper(&state, dict, 123, 1, 2) };
|
||||
|
||||
assert_eq!(result, context.result);
|
||||
assert_eq!(context.events, ["init", "create"]);
|
||||
assert_eq!(context.init_context, state.callback_context);
|
||||
assert_eq!(context.init_cctx_params, cctx_params);
|
||||
assert_eq!(context.init_c_params, c_params);
|
||||
assert_eq!(context.init_custom_mem, custom_mem);
|
||||
assert_eq!(context.init_dict_size, 123);
|
||||
assert_eq!(context.init_dict_content_type, 2);
|
||||
assert_eq!(context.create_context, state.callback_context);
|
||||
assert_eq!(context.create_dict, dict);
|
||||
assert_eq!(context.create_dict_size, 123);
|
||||
assert_eq!(context.create_dict_load_method, 1);
|
||||
assert_eq!(context.create_dict_content_type, 2);
|
||||
assert_eq!(context.create_cctx_params, cctx_params);
|
||||
assert_eq!(context.create_custom_mem, custom_mem);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_cdict_advanced_wrapper_rejects_missing_parameter_storage() {
|
||||
let mut context = CreateCDictAdvancedWrapperTestContext::default();
|
||||
let c_params = ptr::dangling::<ZSTD_compressionParameters>();
|
||||
let custom_mem = ptr::dangling::<c_void>();
|
||||
let state = create_cdict_advanced_wrapper_test_state(
|
||||
&mut context,
|
||||
ptr::null_mut(),
|
||||
c_params,
|
||||
custom_mem,
|
||||
);
|
||||
|
||||
let result = unsafe { ZSTD_rust_createCDictAdvancedWrapper(&state, ptr::null(), 0, 0, 0) };
|
||||
|
||||
assert!(result.is_null());
|
||||
assert!(context.events.is_empty());
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct InitCCtxTestContext {
|
||||
events: Vec<&'static str>,
|
||||
|
||||
Reference in New Issue
Block a user