feat(compress): move CDict content copy policy into Rust
Move CDict by-reference versus by-copy selection and dictionary-content copying into the Rust initialization leaf. C now exposes only an aligned private-workspace reservation callback, retaining ownership of the opaque workspace layout while Rust owns the content policy and copy operation. Add focused coverage for both by-reference bypass and by-copy reservation, copying, and callback ordering. Test Plan: - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml - 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-zstream ZSTREAM_TESTTIME=-T2s - ulimit -v 41943040 && make -j1 -C tests test-fuzzer FUZZERTEST=-T3s FUZZER_FLAGS=--no-big-tests - ulimit -v 41943040 && cargo fmt --manifest-path rust/Cargo.toml -- --check - git diff --check
This commit is contained in:
@@ -2222,8 +2222,8 @@ typedef char ZSTD_rust_external_sequence_store_state_layout[
|
|||||||
== 5 * sizeof(void*))
|
== 5 * sizeof(void*))
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
|
||||||
typedef size_t (*ZSTD_rust_initCDictAssignContent_f)(
|
typedef void* (*ZSTD_rust_initCDictReserveContent_f)(
|
||||||
void* context, const void* dict, size_t dictSize, int dictLoadMethod);
|
void* context, size_t dictSize);
|
||||||
typedef void* (*ZSTD_rust_initCDictReserveEntropy_f)(void* context);
|
typedef void* (*ZSTD_rust_initCDictReserveEntropy_f)(void* context);
|
||||||
typedef void (*ZSTD_rust_initCDictResetBlockState_f)(void* context);
|
typedef void (*ZSTD_rust_initCDictResetBlockState_f)(void* context);
|
||||||
typedef size_t (*ZSTD_rust_initCDictResetMatchState_f)(
|
typedef size_t (*ZSTD_rust_initCDictResetMatchState_f)(
|
||||||
@@ -2247,7 +2247,7 @@ typedef struct {
|
|||||||
U32* dictID;
|
U32* dictID;
|
||||||
int* compressionLevel;
|
int* compressionLevel;
|
||||||
int* contentSizeFlag;
|
int* contentSizeFlag;
|
||||||
ZSTD_rust_initCDictAssignContent_f assignContent;
|
ZSTD_rust_initCDictReserveContent_f reserveContent;
|
||||||
ZSTD_rust_initCDictReserveEntropy_f reserveEntropy;
|
ZSTD_rust_initCDictReserveEntropy_f reserveEntropy;
|
||||||
ZSTD_rust_initCDictResetBlockState_f resetBlockState;
|
ZSTD_rust_initCDictResetBlockState_f resetBlockState;
|
||||||
ZSTD_rust_initCDictResetMatchState_f resetMatchState;
|
ZSTD_rust_initCDictResetMatchState_f resetMatchState;
|
||||||
@@ -2283,7 +2283,7 @@ typedef char ZSTD_rust_init_cdict_state_layout[
|
|||||||
== 12 * sizeof(void*)
|
== 12 * sizeof(void*)
|
||||||
&& offsetof(ZSTD_rust_initCDictState, contentSizeFlag)
|
&& offsetof(ZSTD_rust_initCDictState, contentSizeFlag)
|
||||||
== 13 * sizeof(void*)
|
== 13 * sizeof(void*)
|
||||||
&& offsetof(ZSTD_rust_initCDictState, assignContent)
|
&& offsetof(ZSTD_rust_initCDictState, reserveContent)
|
||||||
== 14 * sizeof(void*)
|
== 14 * sizeof(void*)
|
||||||
&& offsetof(ZSTD_rust_initCDictState, reserveEntropy)
|
&& offsetof(ZSTD_rust_initCDictState, reserveEntropy)
|
||||||
== 15 * sizeof(void*)
|
== 15 * sizeof(void*)
|
||||||
@@ -6029,20 +6029,11 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
|||||||
ZSTD_loadDictionaryContent_callback);
|
ZSTD_loadDictionaryContent_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_rust_initCDict_assignContent(
|
static void* ZSTD_rust_initCDict_reserveContent(void* context, size_t dictSize)
|
||||||
void* context, const void* dict, size_t dictSize, int dictLoadMethod)
|
|
||||||
{
|
{
|
||||||
ZSTD_CDict* const cdict = (ZSTD_CDict*)context;
|
ZSTD_CDict* const cdict = (ZSTD_CDict*)context;
|
||||||
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
|
return ZSTD_cwksp_reserve_object(
|
||||||
cdict->dictContent = dict;
|
&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
|
||||||
} else {
|
|
||||||
void* const internalBuffer = ZSTD_cwksp_reserve_object(
|
|
||||||
&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
|
|
||||||
RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!");
|
|
||||||
cdict->dictContent = internalBuffer;
|
|
||||||
ZSTD_memcpy(internalBuffer, dict, dictSize);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* ZSTD_rust_initCDict_reserveEntropy(void* context)
|
static void* ZSTD_rust_initCDict_reserveEntropy(void* context)
|
||||||
@@ -6624,7 +6615,7 @@ static size_t ZSTD_initCDict_internal(
|
|||||||
state.dictID = &cdict->dictID;
|
state.dictID = &cdict->dictID;
|
||||||
state.compressionLevel = ¶ms.compressionLevel;
|
state.compressionLevel = ¶ms.compressionLevel;
|
||||||
state.contentSizeFlag = ¶ms.fParams.contentSizeFlag;
|
state.contentSizeFlag = ¶ms.fParams.contentSizeFlag;
|
||||||
state.assignContent = ZSTD_rust_initCDict_assignContent;
|
state.reserveContent = ZSTD_rust_initCDict_reserveContent;
|
||||||
state.reserveEntropy = ZSTD_rust_initCDict_reserveEntropy;
|
state.reserveEntropy = ZSTD_rust_initCDict_reserveEntropy;
|
||||||
state.resetBlockState = ZSTD_rust_initCDict_resetBlockState;
|
state.resetBlockState = ZSTD_rust_initCDict_resetBlockState;
|
||||||
state.resetMatchState = ZSTD_rust_initCDict_resetMatchState;
|
state.resetMatchState = ZSTD_rust_initCDict_resetMatchState;
|
||||||
|
|||||||
@@ -85,8 +85,9 @@ fn dictionary_corrupted() -> usize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ZSTD_CCTX_INIT_STAGE: c_int = 0;
|
const ZSTD_CCTX_INIT_STAGE: c_int = 0;
|
||||||
#[cfg(test)]
|
|
||||||
const ZSTD_DLM_BY_REF: c_int = 1;
|
const ZSTD_DLM_BY_REF: c_int = 1;
|
||||||
|
#[cfg(test)]
|
||||||
|
const ZSTD_DLM_BY_COPY: c_int = 0;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn stage_wrong() -> usize {
|
fn stage_wrong() -> usize {
|
||||||
@@ -857,8 +858,7 @@ pub unsafe extern "C" fn ZSTD_rust_compressBeginUsingDict(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type InitCDictAssignContentFn =
|
type InitCDictReserveContentFn = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
|
||||||
unsafe extern "C" fn(*mut c_void, *const c_void, usize, c_int) -> usize;
|
|
||||||
type InitCDictReserveEntropyFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
type InitCDictReserveEntropyFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||||
type InitCDictResetBlockStateFn = unsafe extern "C" fn(*mut c_void);
|
type InitCDictResetBlockStateFn = unsafe extern "C" fn(*mut c_void);
|
||||||
type InitCDictResetMatchStateFn = unsafe extern "C" fn(*mut c_void, *const c_void, c_int) -> usize;
|
type InitCDictResetMatchStateFn = unsafe extern "C" fn(*mut c_void, *const c_void, c_int) -> usize;
|
||||||
@@ -867,9 +867,10 @@ type InitCDictInsertDictionaryFn =
|
|||||||
|
|
||||||
/// Projection for CDict content/state initialization.
|
/// Projection for CDict content/state initialization.
|
||||||
///
|
///
|
||||||
/// Rust owns the initialization order and scalar field policy. C callbacks
|
/// Rust owns the content branch/copy, initialization order, and scalar field
|
||||||
/// retain workspace allocation, match-state reset, and dictionary insertion
|
/// policy. C callbacks retain private workspace allocation, match-state reset,
|
||||||
/// because those operations use private CDict layouts.
|
/// and dictionary insertion because those operations use private CDict
|
||||||
|
/// layouts.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ZSTD_rust_initCDictState {
|
pub struct ZSTD_rust_initCDictState {
|
||||||
callback_context: *mut c_void,
|
callback_context: *mut c_void,
|
||||||
@@ -886,7 +887,7 @@ pub struct ZSTD_rust_initCDictState {
|
|||||||
dict_id: *mut c_uint,
|
dict_id: *mut c_uint,
|
||||||
compression_level: *mut c_int,
|
compression_level: *mut c_int,
|
||||||
content_size_flag: *mut c_int,
|
content_size_flag: *mut c_int,
|
||||||
assign_content: Option<InitCDictAssignContentFn>,
|
reserve_content: Option<InitCDictReserveContentFn>,
|
||||||
reserve_entropy: Option<InitCDictReserveEntropyFn>,
|
reserve_entropy: Option<InitCDictReserveEntropyFn>,
|
||||||
reset_block_state: Option<InitCDictResetBlockStateFn>,
|
reset_block_state: Option<InitCDictResetBlockStateFn>,
|
||||||
reset_match_state: Option<InitCDictResetMatchStateFn>,
|
reset_match_state: Option<InitCDictResetMatchStateFn>,
|
||||||
@@ -894,7 +895,7 @@ pub struct ZSTD_rust_initCDictState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
assert!(size_of::<InitCDictAssignContentFn>() == size_of::<usize>());
|
assert!(size_of::<InitCDictReserveContentFn>() == size_of::<usize>());
|
||||||
assert!(size_of::<InitCDictReserveEntropyFn>() == size_of::<usize>());
|
assert!(size_of::<InitCDictReserveEntropyFn>() == size_of::<usize>());
|
||||||
assert!(size_of::<InitCDictResetBlockStateFn>() == size_of::<usize>());
|
assert!(size_of::<InitCDictResetBlockStateFn>() == size_of::<usize>());
|
||||||
assert!(size_of::<InitCDictResetMatchStateFn>() == size_of::<usize>());
|
assert!(size_of::<InitCDictResetMatchStateFn>() == size_of::<usize>());
|
||||||
@@ -916,7 +917,7 @@ const _: () = {
|
|||||||
assert!(offset_of!(ZSTD_rust_initCDictState, dict_id) == 11 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, dict_id) == 11 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_initCDictState, compression_level) == 12 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, compression_level) == 12 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_initCDictState, content_size_flag) == 13 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, content_size_flag) == 13 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_initCDictState, assign_content) == 14 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, reserve_content) == 14 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_initCDictState, reserve_entropy) == 15 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, reserve_entropy) == 15 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_initCDictState, reset_block_state) == 16 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, reset_block_state) == 16 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_initCDictState, reset_match_state) == 17 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_initCDictState, reset_match_state) == 17 * size_of::<usize>());
|
||||||
@@ -939,7 +940,7 @@ pub unsafe extern "C" fn ZSTD_rust_initCDict(
|
|||||||
return ERROR(ZstdErrorCode::Generic);
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
}
|
}
|
||||||
let state = unsafe { &*state };
|
let state = unsafe { &*state };
|
||||||
let Some(assign_content) = state.assign_content else {
|
let Some(reserve_content) = state.reserve_content else {
|
||||||
return ERROR(ZstdErrorCode::Generic);
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
};
|
};
|
||||||
let Some(reserve_entropy) = state.reserve_entropy else {
|
let Some(reserve_entropy) = state.reserve_entropy else {
|
||||||
@@ -972,10 +973,17 @@ pub unsafe extern "C" fn ZSTD_rust_initCDict(
|
|||||||
return ERROR(ZstdErrorCode::Generic);
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
let assign_result =
|
if dict_load_method == ZSTD_DLM_BY_REF || dict.is_null() || dict_size == 0 {
|
||||||
unsafe { assign_content(state.callback_context, dict, dict_size, dict_load_method) };
|
unsafe { *state.dict_content = dict };
|
||||||
if ERR_isError(assign_result) {
|
} else {
|
||||||
return assign_result;
|
let internal_buffer = unsafe { reserve_content(state.callback_context, dict_size) };
|
||||||
|
if internal_buffer.is_null() {
|
||||||
|
return ERROR(ZstdErrorCode::MemoryAllocation);
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
ptr::copy_nonoverlapping(dict.cast::<u8>(), internal_buffer.cast::<u8>(), dict_size);
|
||||||
|
*state.dict_content = internal_buffer.cast_const();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -2009,16 +2017,15 @@ mod tests {
|
|||||||
|
|
||||||
struct InitCDictProbe {
|
struct InitCDictProbe {
|
||||||
events: Vec<&'static str>,
|
events: Vec<&'static str>,
|
||||||
assigned_dict: *const c_void,
|
reserved_content_size: usize,
|
||||||
assigned_size: usize,
|
content_storage: [u8; 16],
|
||||||
assigned_load_method: c_int,
|
reserve_content_available: bool,
|
||||||
reset_c_params: ZSTD_compressionParameters,
|
reset_c_params: ZSTD_compressionParameters,
|
||||||
reset_use_row_match_finder: c_int,
|
reset_use_row_match_finder: c_int,
|
||||||
inserted_params: *const c_void,
|
inserted_params: *const c_void,
|
||||||
inserted_dict: *const c_void,
|
inserted_dict: *const c_void,
|
||||||
inserted_size: usize,
|
inserted_size: usize,
|
||||||
inserted_content_type: c_int,
|
inserted_content_type: c_int,
|
||||||
assign_result: usize,
|
|
||||||
entropy_workspace: *mut c_void,
|
entropy_workspace: *mut c_void,
|
||||||
reset_match_result: usize,
|
reset_match_result: usize,
|
||||||
insert_result: usize,
|
insert_result: usize,
|
||||||
@@ -2028,16 +2035,15 @@ mod tests {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
events: Vec::new(),
|
events: Vec::new(),
|
||||||
assigned_dict: ptr::null(),
|
reserved_content_size: 0,
|
||||||
assigned_size: 0,
|
content_storage: [0; 16],
|
||||||
assigned_load_method: 0,
|
reserve_content_available: true,
|
||||||
reset_c_params: ZSTD_compressionParameters::default(),
|
reset_c_params: ZSTD_compressionParameters::default(),
|
||||||
reset_use_row_match_finder: 0,
|
reset_use_row_match_finder: 0,
|
||||||
inserted_params: ptr::null(),
|
inserted_params: ptr::null(),
|
||||||
inserted_dict: ptr::null(),
|
inserted_dict: ptr::null(),
|
||||||
inserted_size: 0,
|
inserted_size: 0,
|
||||||
inserted_content_type: 0,
|
inserted_content_type: 0,
|
||||||
assign_result: 0,
|
|
||||||
entropy_workspace: ptr::null_mut(),
|
entropy_workspace: ptr::null_mut(),
|
||||||
reset_match_result: 0,
|
reset_match_result: 0,
|
||||||
insert_result: 0,
|
insert_result: 0,
|
||||||
@@ -2049,18 +2055,18 @@ mod tests {
|
|||||||
unsafe { &mut *context.cast::<InitCDictProbe>() }
|
unsafe { &mut *context.cast::<InitCDictProbe>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn init_cdict_assign_content(
|
unsafe extern "C" fn init_cdict_reserve_content(
|
||||||
context: *mut c_void,
|
context: *mut c_void,
|
||||||
dict: *const c_void,
|
|
||||||
dict_size: usize,
|
dict_size: usize,
|
||||||
dict_load_method: c_int,
|
) -> *mut c_void {
|
||||||
) -> usize {
|
|
||||||
let probe = unsafe { init_cdict_probe(context) };
|
let probe = unsafe { init_cdict_probe(context) };
|
||||||
probe.events.push("assign");
|
probe.events.push("reserve-content");
|
||||||
probe.assigned_dict = dict;
|
probe.reserved_content_size = dict_size;
|
||||||
probe.assigned_size = dict_size;
|
if !probe.reserve_content_available || dict_size > probe.content_storage.len() {
|
||||||
probe.assigned_load_method = dict_load_method;
|
ptr::null_mut()
|
||||||
probe.assign_result
|
} else {
|
||||||
|
probe.content_storage.as_mut_ptr().cast()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn init_cdict_reserve_entropy(context: *mut c_void) -> *mut c_void {
|
unsafe extern "C" fn init_cdict_reserve_entropy(context: *mut c_void) -> *mut c_void {
|
||||||
@@ -2148,7 +2154,7 @@ mod tests {
|
|||||||
dict_id: &mut dict_id,
|
dict_id: &mut dict_id,
|
||||||
compression_level: &mut compression_level,
|
compression_level: &mut compression_level,
|
||||||
content_size_flag: &mut content_size_flag,
|
content_size_flag: &mut content_size_flag,
|
||||||
assign_content: Some(init_cdict_assign_content),
|
reserve_content: Some(init_cdict_reserve_content),
|
||||||
reserve_entropy: Some(init_cdict_reserve_entropy),
|
reserve_entropy: Some(init_cdict_reserve_entropy),
|
||||||
reset_block_state: Some(init_cdict_reset_block_state),
|
reset_block_state: Some(init_cdict_reset_block_state),
|
||||||
reset_match_state: Some(init_cdict_reset_match_state),
|
reset_match_state: Some(init_cdict_reset_match_state),
|
||||||
@@ -2168,11 +2174,9 @@ mod tests {
|
|||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
probe.events,
|
probe.events,
|
||||||
["assign", "reserve", "reset-block", "reset-match", "insert"]
|
["reserve", "reset-block", "reset-match", "insert"]
|
||||||
);
|
);
|
||||||
assert_eq!(probe.assigned_dict, dictionary.as_ptr().cast());
|
assert_eq!(dict_content, dictionary.as_ptr().cast());
|
||||||
assert_eq!(probe.assigned_size, dictionary.len());
|
|
||||||
assert_eq!(probe.assigned_load_method, ZSTD_DLM_BY_REF);
|
|
||||||
assert_eq!(probe.reset_c_params, c_params);
|
assert_eq!(probe.reset_c_params, c_params);
|
||||||
assert_eq!(probe.reset_use_row_match_finder, use_row_match_finder);
|
assert_eq!(probe.reset_use_row_match_finder, use_row_match_finder);
|
||||||
assert_eq!(probe.inserted_params, params);
|
assert_eq!(probe.inserted_params, params);
|
||||||
@@ -2189,6 +2193,86 @@ mod tests {
|
|||||||
assert_eq!(content_size_flag, 1);
|
assert_eq!(content_size_flag, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cdict_init_copies_by_copy_content_in_rust_after_reserving_storage() {
|
||||||
|
let dictionary = [9u8, 8, 7, 6, 5];
|
||||||
|
let mut probe = InitCDictProbe {
|
||||||
|
entropy_workspace: 0x1000usize as *mut c_void,
|
||||||
|
insert_result: 0x1234,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let c_params = ZSTD_compressionParameters {
|
||||||
|
windowLog: 21,
|
||||||
|
chainLog: 18,
|
||||||
|
hashLog: 19,
|
||||||
|
searchLog: 4,
|
||||||
|
minMatch: 5,
|
||||||
|
targetLength: 16,
|
||||||
|
strategy: 3,
|
||||||
|
};
|
||||||
|
let mut match_state_c_params = ZSTD_compressionParameters::default();
|
||||||
|
let enable_dedicated_dict_search = 1;
|
||||||
|
let use_row_match_finder = 2;
|
||||||
|
let mut dedicated_dict_search = 0;
|
||||||
|
let mut dict_content = ptr::null();
|
||||||
|
let mut dict_content_size = 0;
|
||||||
|
let mut dict_content_type = 0;
|
||||||
|
let mut entropy_workspace = ptr::null_mut();
|
||||||
|
let mut dict_id = 0;
|
||||||
|
let mut compression_level = 99;
|
||||||
|
let mut content_size_flag = 0;
|
||||||
|
let params = 0x2000usize as *const c_void;
|
||||||
|
let callback_context = (&mut probe as *mut InitCDictProbe).cast();
|
||||||
|
let state = ZSTD_rust_initCDictState {
|
||||||
|
callback_context,
|
||||||
|
params,
|
||||||
|
c_params: &c_params,
|
||||||
|
match_state_c_params: &mut match_state_c_params,
|
||||||
|
dedicated_dict_search: &mut dedicated_dict_search,
|
||||||
|
enable_dedicated_dict_search: &enable_dedicated_dict_search,
|
||||||
|
use_row_match_finder: &use_row_match_finder,
|
||||||
|
dict_content: &mut dict_content,
|
||||||
|
dict_content_size: &mut dict_content_size,
|
||||||
|
dict_content_type: &mut dict_content_type,
|
||||||
|
entropy_workspace: &mut entropy_workspace,
|
||||||
|
dict_id: &mut dict_id,
|
||||||
|
compression_level: &mut compression_level,
|
||||||
|
content_size_flag: &mut content_size_flag,
|
||||||
|
reserve_content: Some(init_cdict_reserve_content),
|
||||||
|
reserve_entropy: Some(init_cdict_reserve_entropy),
|
||||||
|
reset_block_state: Some(init_cdict_reset_block_state),
|
||||||
|
reset_match_state: Some(init_cdict_reset_match_state),
|
||||||
|
insert_dictionary: Some(init_cdict_insert_dictionary),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = unsafe {
|
||||||
|
ZSTD_rust_initCDict(
|
||||||
|
&state,
|
||||||
|
dictionary.as_ptr().cast(),
|
||||||
|
dictionary.len(),
|
||||||
|
ZSTD_DLM_BY_COPY,
|
||||||
|
ZSTD_DCT_RAW_CONTENT,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(result, 0);
|
||||||
|
assert_eq!(
|
||||||
|
probe.events,
|
||||||
|
[
|
||||||
|
"reserve-content",
|
||||||
|
"reserve",
|
||||||
|
"reset-block",
|
||||||
|
"reset-match",
|
||||||
|
"insert"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
assert_eq!(probe.reserved_content_size, dictionary.len());
|
||||||
|
assert_eq!(&probe.content_storage[..dictionary.len()], &dictionary);
|
||||||
|
assert_eq!(dict_content, probe.content_storage.as_ptr().cast());
|
||||||
|
assert_eq!(probe.inserted_dict, dict_content);
|
||||||
|
assert_eq!(dict_content_size, dictionary.len());
|
||||||
|
}
|
||||||
|
|
||||||
struct CompressBeginProbe {
|
struct CompressBeginProbe {
|
||||||
events: Vec<&'static str>,
|
events: Vec<&'static str>,
|
||||||
reset_params: *const c_void,
|
reset_params: *const c_void,
|
||||||
|
|||||||
Reference in New Issue
Block a user