/* * 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 or both of these licenses. */ /* The optimal parser is implemented in rust/src/zstd_opt.rs. Keep the * private ZSTD_MatchState_t and entropy-table layouts on the C side: this * translation unit only projects the leaves Rust needs and preserves the * established C entry points. */ #include "zstd_compress_internal.h" #include "zstd_opt.h" #if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) typedef struct { U32* hashTable; U32* chainTable; const BYTE* base; const BYTE* dictBase; U32 dictLimit; U32 lowLimit; U32 loadedDictEnd; U32* nextToUpdate; U32 hashLog; U32 chainLog; U32 searchLog; U32 windowLog; int useCPredict; U32* hashTable3; U32 hashLog3; const BYTE* nextSrc; U32 minMatch; U32 targetLength; optState_t* opt; const void* dictMatchState; const RawSeqStore_t* ldmSeqStore; const BYTE** windowBase; U32* windowDictLimit; U32* windowLowLimit; const size_t* hufCTable; int hufRepeatValid; const U32* fseLitLengthCTable; const U32* fseMatchLengthCTable; const U32* fseOffCodeCTable; } ZSTD_RustOptState; typedef char ZSTD_rust_opt_seqdef_layout[(sizeof(SeqDef) == 8) ? 1 : -1]; typedef char ZSTD_rust_opt_match_layout[(sizeof(ZSTD_match_t) == 8) ? 1 : -1]; typedef char ZSTD_rust_opt_rawseq_layout[(sizeof(rawSeq) == 12) ? 1 : -1]; typedef char ZSTD_rust_opt_seqstore_layout[ (offsetof(SeqStore_t, longLengthPos) == 9 * sizeof(size_t) + 4) ? 1 : -1]; typedef char ZSTD_rust_optimal_layout[ (sizeof(ZSTD_optimal_t) == 4 * sizeof(U32) + sizeof(U32) * ZSTD_REP_NUM) ? 1 : -1]; typedef char ZSTD_rust_opt_rep_count[(ZSTD_REP_NUM == 3) ? 1 : -1]; static void ZSTD_rustOptState_init( ZSTD_RustOptState* const out, ZSTD_MatchState_t* const ms, const ZSTD_RustOptState* const dms) { out->hashTable = ms->hashTable; out->chainTable = ms->chainTable; out->base = ms->window.base; out->dictBase = ms->window.dictBase; out->dictLimit = ms->window.dictLimit; out->lowLimit = ms->window.lowLimit; out->loadedDictEnd = ms->loadedDictEnd; out->nextToUpdate = &ms->nextToUpdate; out->hashLog = ms->cParams.hashLog; out->chainLog = ms->cParams.chainLog; out->searchLog = ms->cParams.searchLog; #ifdef ZSTD_C_PREDICT out->useCPredict = 1; #else out->useCPredict = 0; #endif out->windowLog = ms->cParams.windowLog; out->hashTable3 = ms->hashTable3; out->hashLog3 = ms->hashLog3; out->nextSrc = ms->window.nextSrc; out->minMatch = ms->cParams.minMatch; out->targetLength = ms->cParams.targetLength; out->opt = &ms->opt; out->dictMatchState = dms; out->ldmSeqStore = ms->ldmSeqStore; out->windowBase = &ms->window.base; out->windowDictLimit = &ms->window.dictLimit; out->windowLowLimit = &ms->window.lowLimit; out->hufCTable = NULL; out->hufRepeatValid = 0; out->fseLitLengthCTable = NULL; out->fseMatchLengthCTable = NULL; out->fseOffCodeCTable = NULL; } static void ZSTD_rustOptState_projectCosts( ZSTD_RustOptState* const out, ZSTD_MatchState_t* const ms) { const ZSTD_entropyCTables_t* const costs = ms->opt.symbolCosts; out->hufCTable = costs ? costs->huf.CTable : NULL; out->hufRepeatValid = costs && costs->huf.repeatMode == HUF_repeat_valid; out->fseLitLengthCTable = costs ? costs->fse.litlengthCTable : NULL; out->fseMatchLengthCTable = costs ? costs->fse.matchlengthCTable : NULL; out->fseOffCodeCTable = costs ? costs->fse.offcodeCTable : NULL; } static void ZSTD_rustOptState_init_with_dict( ZSTD_RustOptState* const out, ZSTD_MatchState_t* const ms) { ZSTD_rustOptState_init(out, ms, NULL); } static void ZSTD_rustOptState_init_with_costs( ZSTD_RustOptState* const out, ZSTD_MatchState_t* const ms, const ZSTD_RustOptState* const dms) { ZSTD_rustOptState_init(out, ms, dms); ZSTD_rustOptState_projectCosts(out, ms); } void ZSTD_rust_opt_updateTree( ZSTD_RustOptState* state, const void* ip, const void* iend, U32 mls, int dictMode); size_t ZSTD_rust_compressBlock_opt( ZSTD_RustOptState* state, void* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize, int optLevel, int dictMode); void ZSTD_rust_initStats_ultra( ZSTD_RustOptState* state, void* seqStore, const U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize); size_t ZSTD_rust_compressBlock_btultra2( ZSTD_RustOptState* state, void* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize); enum { ZSTD_rust_dict_noDict = 0, ZSTD_rust_dict_extDict = 1, ZSTD_rust_dict_dictMatchState = 2, }; void ZSTD_updateTree(ZSTD_MatchState_t* const ms, const BYTE* const ip, const BYTE* const iend) { ZSTD_RustOptState state; ZSTD_rustOptState_init_with_dict(&state, ms); ZSTD_rust_opt_updateTree(&state, ip, iend, ms->cParams.minMatch, ZSTD_rust_dict_noDict); } #ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_btopt( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_rustOptState_init_with_costs(&state, ms, NULL); return ZSTD_rust_compressBlock_opt(&state, seqStore, rep, src, srcSize, 0, ZSTD_rust_dict_noDict); } size_t ZSTD_compressBlock_btopt_dictMatchState( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_RustOptState dictState; ZSTD_MatchState_t dictCopy = *ms->dictMatchState; ZSTD_rustOptState_init(&dictState, &dictCopy, NULL); ZSTD_rustOptState_init_with_costs(&state, ms, &dictState); return ZSTD_rust_compressBlock_opt(&state, seqStore, rep, src, srcSize, 0, ZSTD_rust_dict_dictMatchState); } size_t ZSTD_compressBlock_btopt_extDict( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_rustOptState_init_with_costs(&state, ms, NULL); return ZSTD_rust_compressBlock_opt(&state, seqStore, rep, src, srcSize, 0, ZSTD_rust_dict_extDict); } #endif #ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR size_t ZSTD_compressBlock_btultra( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_rustOptState_init_with_costs(&state, ms, NULL); return ZSTD_rust_compressBlock_opt(&state, seqStore, rep, src, srcSize, 2, ZSTD_rust_dict_noDict); } size_t ZSTD_compressBlock_btultra_dictMatchState( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_RustOptState dictState; ZSTD_MatchState_t dictCopy = *ms->dictMatchState; ZSTD_rustOptState_init(&dictState, &dictCopy, NULL); ZSTD_rustOptState_init_with_costs(&state, ms, &dictState); return ZSTD_rust_compressBlock_opt(&state, seqStore, rep, src, srcSize, 2, ZSTD_rust_dict_dictMatchState); } size_t ZSTD_compressBlock_btultra_extDict( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_rustOptState_init_with_costs(&state, ms, NULL); return ZSTD_rust_compressBlock_opt(&state, seqStore, rep, src, srcSize, 2, ZSTD_rust_dict_extDict); } size_t ZSTD_compressBlock_btultra2( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize) { ZSTD_RustOptState state; ZSTD_rustOptState_init_with_costs(&state, ms, NULL); return ZSTD_rust_compressBlock_btultra2(&state, seqStore, rep, src, srcSize); } #endif #endif /* any optimal parser entry point is enabled */