Port sequence-decoder selection and offset-history policy into Rust. The Rust block decoder now handles short/long selection, offset-table analysis, history thresholds, and prefetch sequencing; C projects only the decoder mode and private context fields required by the ABI. Test Plan: - cargo test --manifest-path rust/Cargo.toml --all-targets -- --test-threads=1 - cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - make -B -C lib -j2 lib ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT=1 ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG=0 - make -B -C lib -j2 lib ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT=0 ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG=1 - make -B -C tests -j2 test-zstd
175 lines
6.4 KiB
C
175 lines
6.4 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.
|
|
*/
|
|
|
|
/*
|
|
* Compressed-block decoding is implemented in
|
|
* rust/src/zstd_decompress_block.rs. Keep `ZSTD_DCtx` C-owned: it has
|
|
* optional build-dependent fields, while this small view contains only the
|
|
* leaves read or written by the Rust decoder. No decoder algorithm remains
|
|
* in this translation unit.
|
|
*/
|
|
#include "../common/zstd_deps.h"
|
|
#include "../common/zstd_internal.h"
|
|
#include "zstd_decompress_internal.h"
|
|
#include "zstd_decompress_block.h"
|
|
|
|
#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
|
|
defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
|
#error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!"
|
|
#endif
|
|
|
|
#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT)
|
|
#define ZSTD_RUST_SEQUENCE_DECODER_MODE 1
|
|
#elif defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
|
#define ZSTD_RUST_SEQUENCE_DECODER_MODE 2
|
|
#else
|
|
#define ZSTD_RUST_SEQUENCE_DECODER_MODE 0
|
|
#endif
|
|
|
|
typedef char ZSTD_rust_block_seq_symbol_layout[(sizeof(ZSTD_seqSymbol) == 8) ? 1 : -1];
|
|
typedef char ZSTD_rust_block_entropy_rep_offset[
|
|
(offsetof(ZSTD_entropyDTables_t, rep) == 26652) ? 1 : -1];
|
|
typedef char ZSTD_rust_block_entropy_workspace_offset[
|
|
(offsetof(ZSTD_entropyDTables_t, workspace) == 26664) ? 1 : -1];
|
|
|
|
typedef struct {
|
|
const ZSTD_seqSymbol** lltPtr;
|
|
const ZSTD_seqSymbol** mltPtr;
|
|
const ZSTD_seqSymbol** oftPtr;
|
|
const HUF_DTable** hufPtr;
|
|
ZSTD_entropyDTables_t* entropy;
|
|
U32* workspace;
|
|
size_t workspaceSize;
|
|
const void** previousDstEnd;
|
|
const void** prefixStart;
|
|
const void** virtualStart;
|
|
const void** dictEnd;
|
|
size_t blockSizeMax;
|
|
int* isFrameDecompression;
|
|
U32* litEntropy;
|
|
U32* fseEntropy;
|
|
int bmi2;
|
|
int* ddictIsCold;
|
|
int disableHufAsm;
|
|
const BYTE** litPtr;
|
|
size_t* litSize;
|
|
size_t* rleSize;
|
|
BYTE** litBuffer;
|
|
const BYTE** litBufferEnd;
|
|
ZSTD_litLocation_e* litBufferLocation;
|
|
BYTE* litExtraBuffer;
|
|
size_t litExtraBufferSize;
|
|
int sequenceDecoderMode;
|
|
} ZSTD_rustBlockCtx;
|
|
|
|
static ZSTD_rustBlockCtx ZSTD_rust_block_context(ZSTD_DCtx* dctx)
|
|
{
|
|
ZSTD_rustBlockCtx ctx;
|
|
ctx.lltPtr = &dctx->LLTptr;
|
|
ctx.mltPtr = &dctx->MLTptr;
|
|
ctx.oftPtr = &dctx->OFTptr;
|
|
ctx.hufPtr = &dctx->HUFptr;
|
|
ctx.entropy = &dctx->entropy;
|
|
ctx.workspace = dctx->workspace;
|
|
ctx.workspaceSize = sizeof(dctx->workspace);
|
|
ctx.previousDstEnd = &dctx->previousDstEnd;
|
|
ctx.prefixStart = &dctx->prefixStart;
|
|
ctx.virtualStart = &dctx->virtualStart;
|
|
ctx.dictEnd = &dctx->dictEnd;
|
|
ctx.blockSizeMax = dctx->fParams.blockSizeMax;
|
|
ctx.isFrameDecompression = &dctx->isFrameDecompression;
|
|
ctx.litEntropy = &dctx->litEntropy;
|
|
ctx.fseEntropy = &dctx->fseEntropy;
|
|
ctx.bmi2 = ZSTD_DCtx_get_bmi2(dctx);
|
|
ctx.ddictIsCold = &dctx->ddictIsCold;
|
|
ctx.disableHufAsm = dctx->disableHufAsm;
|
|
ctx.litPtr = &dctx->litPtr;
|
|
ctx.litSize = &dctx->litSize;
|
|
ctx.rleSize = &dctx->rleSize;
|
|
ctx.litBuffer = &dctx->litBuffer;
|
|
ctx.litBufferEnd = &dctx->litBufferEnd;
|
|
ctx.litBufferLocation = &dctx->litBufferLocation;
|
|
ctx.litExtraBuffer = dctx->litExtraBuffer;
|
|
ctx.litExtraBufferSize = ZSTD_LITBUFFEREXTRASIZE;
|
|
ctx.sequenceDecoderMode = ZSTD_RUST_SEQUENCE_DECODER_MODE;
|
|
return ctx;
|
|
}
|
|
|
|
size_t ZSTD_rust_decodeLiteralsBlock_wrapper(
|
|
ZSTD_rustBlockCtx* ctx,
|
|
const void* src, size_t srcSize,
|
|
void* dst, size_t dstCapacity);
|
|
size_t ZSTD_rust_decodeSeqHeaders(
|
|
ZSTD_rustBlockCtx* ctx, int* nbSeqPtr,
|
|
const void* src, size_t srcSize);
|
|
size_t ZSTD_rust_decompressBlock_internal(
|
|
ZSTD_rustBlockCtx* ctx,
|
|
void* dst, size_t dstCapacity,
|
|
const void* src, size_t srcSize, int streaming);
|
|
void ZSTD_rust_checkContinuity(
|
|
ZSTD_rustBlockCtx* ctx, const void* dst, size_t dstSize);
|
|
size_t ZSTD_rust_decompressBlock_deprecated(
|
|
ZSTD_rustBlockCtx* ctx,
|
|
void* dst, size_t dstCapacity,
|
|
const void* src, size_t srcSize);
|
|
|
|
/* Hidden declaration for fullbench. */
|
|
size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
|
|
const void* src, size_t srcSize,
|
|
void* dst, size_t dstCapacity);
|
|
size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
|
|
const void* src, size_t srcSize,
|
|
void* dst, size_t dstCapacity)
|
|
{
|
|
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
|
|
return ZSTD_rust_decodeLiteralsBlock_wrapper(
|
|
&ctx, src, srcSize, dst, dstCapacity);
|
|
}
|
|
|
|
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|
const void* src, size_t srcSize)
|
|
{
|
|
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
|
|
return ZSTD_rust_decodeSeqHeaders(&ctx, nbSeqPtr, src, srcSize);
|
|
}
|
|
|
|
size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|
void* dst, size_t dstCapacity,
|
|
const void* src, size_t srcSize,
|
|
const streaming_operation streaming)
|
|
{
|
|
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
|
|
return ZSTD_rust_decompressBlock_internal(&ctx, dst, dstCapacity, src, srcSize,
|
|
(int)streaming);
|
|
}
|
|
|
|
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
|
|
{
|
|
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
|
|
ZSTD_rust_checkContinuity(&ctx, dst, dstSize);
|
|
}
|
|
|
|
size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx,
|
|
void* dst, size_t dstCapacity,
|
|
const void* src, size_t srcSize)
|
|
{
|
|
ZSTD_rustBlockCtx ctx = ZSTD_rust_block_context(dctx);
|
|
return ZSTD_rust_decompressBlock_deprecated(&ctx,
|
|
dst, dstCapacity, src, srcSize);
|
|
}
|
|
|
|
/* NOTE: Must just wrap ZSTD_decompressBlock_deprecated(). */
|
|
size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
|
|
void* dst, size_t dstCapacity,
|
|
const void* src, size_t srcSize)
|
|
{
|
|
return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize);
|
|
}
|