Move fast hash-table filling and no-dictionary, external-dictionary, and
attached-CDict match loops into Rust. The C shim keeps `ZSTD_MatchState_t`
opaque, extracts only its needed fields, and asserts the mirrored SeqStore
leaf layout so existing compression dispatch remains ABI-compatible.
Test Plan:
- cargo clippy
- cargo clippy --benches
- cargo clippy --tests
- cargo +nightly fmt
- cargo test zstd_fast::tests -- --nocapture
- cargo test --target i686-unknown-linux-gnu zstd_fast::tests -- --nocapture
- byte-identical C-control frames for dictionary and streaming variants
- fuzzer -s2066 -i5 --no-big-tests
- invalidDictionaries and zstreamtest -i1
Refs: Rust superblock port fde1d70c
96 lines
4.3 KiB
C
96 lines
4.3 KiB
C
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under both the BSD-style license (found in the
|
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
* in the COPYING file in the root directory of this source tree).
|
|
* You may select, at your option, one of the above-listed licenses.
|
|
*/
|
|
|
|
/* The matching algorithms live in rust/src/zstd_fast.rs. Keep match-state
|
|
* extraction here: it is a large private structure whose layout should not be
|
|
* duplicated in Rust. */
|
|
#include "zstd_compress_internal.h"
|
|
#include "zstd_fast.h"
|
|
|
|
typedef char ZSTD_rust_fast_seqdef_layout[(sizeof(SeqDef) == 8) ? 1 : -1];
|
|
typedef char ZSTD_rust_fast_seqstore_long_length_pos[
|
|
(offsetof(SeqStore_t, longLengthPos) == 9 * sizeof(size_t) + 4) ? 1 : -1];
|
|
typedef char ZSTD_rust_fast_seqstore_layout[
|
|
(sizeof(SeqStore_t) == 9 * sizeof(size_t) + 8) ? 1 : -1];
|
|
typedef char ZSTD_rust_fast_rep_count[(ZSTD_REP_NUM == 3) ? 1 : -1];
|
|
|
|
void ZSTD_rust_fillHashTable(U32* hashTable, const BYTE* base, U32 nextToUpdate,
|
|
const void* end, U32 hashLog, U32 minMatch,
|
|
int fullTableLoad, int forCDict);
|
|
|
|
size_t ZSTD_rust_compressBlock_fast(
|
|
U32* hashTable, const BYTE* base, U32 dictLimit, U32 loadedDictEnd,
|
|
U32 hashLog, U32 minMatch, U32 targetLength, U32 windowLog,
|
|
void* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize);
|
|
|
|
size_t ZSTD_rust_compressBlock_fast_dictMatchState(
|
|
U32* hashTable, const BYTE* base, U32 prefixStartIndex,
|
|
U32 hashLog, U32 minMatch, U32 targetLength,
|
|
void* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize,
|
|
const U32* dictHashTable, const BYTE* dictBase, U32 dictStartIndex,
|
|
const BYTE* dictEnd, U32 dictHashLog, int prefetchCDictTables);
|
|
|
|
size_t ZSTD_rust_compressBlock_fast_extDict(
|
|
U32* hashTable, const BYTE* base, const BYTE* dictBase,
|
|
U32 dictLimit, U32 lowLimit, U32 loadedDictEnd,
|
|
U32 hashLog, U32 minMatch, U32 targetLength, U32 windowLog,
|
|
void* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize);
|
|
|
|
void ZSTD_fillHashTable(ZSTD_MatchState_t* ms,
|
|
const void* end,
|
|
ZSTD_dictTableLoadMethod_e dtlm,
|
|
ZSTD_tableFillPurpose_e tfp)
|
|
{
|
|
assert((tfp == ZSTD_tfp_forCDict && dtlm == ZSTD_dtlm_full)
|
|
|| (tfp != ZSTD_tfp_forCDict && dtlm == ZSTD_dtlm_fast));
|
|
ZSTD_rust_fillHashTable(ms->hashTable, ms->window.base, ms->nextToUpdate,
|
|
end, ms->cParams.hashLog, ms->cParams.minMatch,
|
|
dtlm == ZSTD_dtlm_full, tfp == ZSTD_tfp_forCDict);
|
|
}
|
|
|
|
size_t ZSTD_compressBlock_fast(
|
|
ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
const void* src, size_t srcSize)
|
|
{
|
|
assert(ms->dictMatchState == NULL);
|
|
return ZSTD_rust_compressBlock_fast(
|
|
ms->hashTable, ms->window.base, ms->window.dictLimit, ms->loadedDictEnd,
|
|
ms->cParams.hashLog, ms->cParams.minMatch,
|
|
ms->cParams.targetLength, ms->cParams.windowLog,
|
|
seqStore, rep, src, srcSize);
|
|
}
|
|
|
|
size_t ZSTD_compressBlock_fast_dictMatchState(
|
|
ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
const void* src, size_t srcSize)
|
|
{
|
|
const ZSTD_MatchState_t* const dms = ms->dictMatchState;
|
|
assert(dms != NULL);
|
|
return ZSTD_rust_compressBlock_fast_dictMatchState(
|
|
ms->hashTable, ms->window.base, ms->window.dictLimit,
|
|
ms->cParams.hashLog, ms->cParams.minMatch, ms->cParams.targetLength,
|
|
seqStore, rep, src, srcSize,
|
|
dms->hashTable, dms->window.base, dms->window.dictLimit,
|
|
dms->window.nextSrc, dms->cParams.hashLog, ms->prefetchCDictTables);
|
|
}
|
|
|
|
size_t ZSTD_compressBlock_fast_extDict(
|
|
ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
const void* src, size_t srcSize)
|
|
{
|
|
assert(ms->dictMatchState == NULL);
|
|
return ZSTD_rust_compressBlock_fast_extDict(
|
|
ms->hashTable, ms->window.base, ms->window.dictBase,
|
|
ms->window.dictLimit, ms->window.lowLimit, ms->loadedDictEnd,
|
|
ms->cParams.hashLog, ms->cParams.minMatch,
|
|
ms->cParams.targetLength, ms->cParams.windowLog,
|
|
seqStore, rep, src, srcSize);
|
|
}
|