/* * 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 lazy matchers are implemented in rust/src/zstd_lazy.rs. Keep only the * private match-state projection and the established C entry points here. */ #include "zstd_compress_internal.h" #include "zstd_lazy.h" #if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) typedef char ZSTD_rust_lazy_seqdef_layout[(sizeof(SeqDef) == 8) ? 1 : -1]; typedef char ZSTD_rust_lazy_seqstore_long_length_pos[ (offsetof(SeqStore_t, longLengthPos) == 9 * sizeof(size_t) + 4) ? 1 : -1]; typedef char ZSTD_rust_lazy_seqstore_layout[ (sizeof(SeqStore_t) == 9 * sizeof(size_t) + 8) ? 1 : -1]; typedef char ZSTD_rust_lazy_rep_count[(ZSTD_REP_NUM == 3) ? 1 : -1]; /* This must remain in lock-step with `ZSTD_RustLazyState` in Rust. The large * and private `ZSTD_MatchState_t` itself deliberately never crosses FFI. */ typedef struct ZSTD_RustLazyState_s { U32* hashTable; U32* chainTable; BYTE* tagTable; U32* hashCache; const BYTE* base; const BYTE* dictBase; const BYTE* nextSrc; U32 dictLimit; U32 lowLimit; U32 loadedDictEnd; U32* nextToUpdate; int* lazySkipping; U32 hashLog; U32 chainLog; U32 minMatch; U32 searchLog; U32 windowLog; U32 rowHashLog; U64 hashSalt; U32* hashSaltEntropy; const struct ZSTD_RustLazyState_s* dictMatchState; } ZSTD_RustLazyState; U32 ZSTD_rust_lazy_insertAndFindFirstIndex(ZSTD_RustLazyState* state, const void* ip); void ZSTD_rust_lazy_row_update(ZSTD_RustLazyState* state, const void* ip); void ZSTD_rust_lazy_loadDedicatedDict(ZSTD_RustLazyState* state, const void* ip); size_t ZSTD_rust_compressBlock_lazy( ZSTD_RustLazyState* state, void* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize, int searchMethod, U32 depth, int dictMode); enum { ZSTD_rust_search_hashChain = 0, ZSTD_rust_search_binaryTree = 1, ZSTD_rust_search_rowHash = 2, }; enum { ZSTD_rust_dict_noDict = 0, ZSTD_rust_dict_extDict = 1, ZSTD_rust_dict_dictMatchState = 2, ZSTD_rust_dict_dedicatedDictSearch = 3, }; static void ZSTD_rustLazyState_init( ZSTD_RustLazyState* const out, ZSTD_MatchState_t* const ms, const ZSTD_RustLazyState* const dms) { out->hashTable = ms->hashTable; out->chainTable = ms->chainTable; out->tagTable = ms->tagTable; out->hashCache = ms->hashCache; out->base = ms->window.base; out->dictBase = ms->window.dictBase; out->nextSrc = ms->window.nextSrc; out->dictLimit = ms->window.dictLimit; out->lowLimit = ms->window.lowLimit; out->loadedDictEnd = ms->loadedDictEnd; out->nextToUpdate = &ms->nextToUpdate; out->lazySkipping = &ms->lazySkipping; out->hashLog = ms->cParams.hashLog; out->chainLog = ms->cParams.chainLog; out->minMatch = ms->cParams.minMatch; out->searchLog = ms->cParams.searchLog; out->windowLog = ms->cParams.windowLog; out->rowHashLog = ms->rowHashLog; out->hashSalt = ms->hashSalt; out->hashSaltEntropy = &ms->hashSaltEntropy; out->dictMatchState = dms; } /* Dictionary match states are searched but never updated by this module. */ static void ZSTD_rustLazyState_initDict( ZSTD_RustLazyState* const out, const ZSTD_MatchState_t* const ms) { out->hashTable = ms->hashTable; out->chainTable = ms->chainTable; out->tagTable = ms->tagTable; out->hashCache = NULL; out->base = ms->window.base; out->dictBase = ms->window.dictBase; out->nextSrc = ms->window.nextSrc; out->dictLimit = ms->window.dictLimit; out->lowLimit = ms->window.lowLimit; out->loadedDictEnd = ms->loadedDictEnd; out->nextToUpdate = NULL; out->lazySkipping = NULL; out->hashLog = ms->cParams.hashLog; out->chainLog = ms->cParams.chainLog; out->minMatch = ms->cParams.minMatch; out->searchLog = ms->cParams.searchLog; out->windowLog = ms->cParams.windowLog; out->rowHashLog = ms->rowHashLog; out->hashSalt = ms->hashSalt; out->hashSaltEntropy = NULL; out->dictMatchState = NULL; } static size_t ZSTD_rust_compressBlock_lazy_call( ZSTD_MatchState_t* const ms, SeqStore_t* const seqStore, U32 rep[ZSTD_REP_NUM], const void* const src, size_t const srcSize, int const searchMethod, U32 const depth, int const dictMode) { ZSTD_RustLazyState state; ZSTD_RustLazyState dictState; const ZSTD_RustLazyState* dms = NULL; if (dictMode == ZSTD_rust_dict_dictMatchState || dictMode == ZSTD_rust_dict_dedicatedDictSearch) { const ZSTD_MatchState_t* const rawDms = ms->dictMatchState; assert(rawDms != NULL); ZSTD_rustLazyState_initDict(&dictState, rawDms); dms = &dictState; } ZSTD_rustLazyState_init(&state, ms, dms); return ZSTD_rust_compressBlock_lazy( &state, seqStore, rep, src, srcSize, searchMethod, depth, dictMode); } U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip) { ZSTD_RustLazyState state; ZSTD_rustLazyState_init(&state, ms, NULL); return ZSTD_rust_lazy_insertAndFindFirstIndex(&state, ip); } void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* const ip) { ZSTD_RustLazyState state; ZSTD_rustLazyState_init(&state, ms, NULL); ZSTD_rust_lazy_row_update(&state, ip); } void ZSTD_dedicatedDictSearch_lazy_loadDictionary( ZSTD_MatchState_t* ms, const BYTE* const ip) { ZSTD_RustLazyState state; ZSTD_rustLazyState_init(&state, ms, NULL); ZSTD_rust_lazy_loadDedicatedDict(&state, ip); } #define ZSTD_RUST_LAZY_WRAPPER(name, method, parserDepth, mode) \ size_t name( \ ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ const void* src, size_t srcSize) \ { \ return ZSTD_rust_compressBlock_lazy_call( \ ms, seqStore, rep, src, srcSize, method, parserDepth, mode); \ } #ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy, ZSTD_rust_search_hashChain, 0, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_dictMatchState, ZSTD_rust_search_hashChain, 0, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_dedicatedDictSearch, ZSTD_rust_search_hashChain, 0, ZSTD_rust_dict_dedicatedDictSearch) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_row, ZSTD_rust_search_rowHash, 0, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_dictMatchState_row, ZSTD_rust_search_rowHash, 0, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_dedicatedDictSearch_row, ZSTD_rust_search_rowHash, 0, ZSTD_rust_dict_dedicatedDictSearch) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_extDict, ZSTD_rust_search_hashChain, 0, ZSTD_rust_dict_extDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_greedy_extDict_row, ZSTD_rust_search_rowHash, 0, ZSTD_rust_dict_extDict) #endif #ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy, ZSTD_rust_search_hashChain, 1, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_dictMatchState, ZSTD_rust_search_hashChain, 1, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_dedicatedDictSearch, ZSTD_rust_search_hashChain, 1, ZSTD_rust_dict_dedicatedDictSearch) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_row, ZSTD_rust_search_rowHash, 1, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_dictMatchState_row, ZSTD_rust_search_rowHash, 1, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_dedicatedDictSearch_row, ZSTD_rust_search_rowHash, 1, ZSTD_rust_dict_dedicatedDictSearch) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_extDict, ZSTD_rust_search_hashChain, 1, ZSTD_rust_dict_extDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy_extDict_row, ZSTD_rust_search_rowHash, 1, ZSTD_rust_dict_extDict) #endif #ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2, ZSTD_rust_search_hashChain, 2, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_dictMatchState, ZSTD_rust_search_hashChain, 2, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_dedicatedDictSearch, ZSTD_rust_search_hashChain, 2, ZSTD_rust_dict_dedicatedDictSearch) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_row, ZSTD_rust_search_rowHash, 2, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_dictMatchState_row, ZSTD_rust_search_rowHash, 2, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_dedicatedDictSearch_row, ZSTD_rust_search_rowHash, 2, ZSTD_rust_dict_dedicatedDictSearch) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_extDict, ZSTD_rust_search_hashChain, 2, ZSTD_rust_dict_extDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_lazy2_extDict_row, ZSTD_rust_search_rowHash, 2, ZSTD_rust_dict_extDict) #endif #ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_btlazy2, ZSTD_rust_search_binaryTree, 2, ZSTD_rust_dict_noDict) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_btlazy2_dictMatchState, ZSTD_rust_search_binaryTree, 2, ZSTD_rust_dict_dictMatchState) ZSTD_RUST_LAZY_WRAPPER(ZSTD_compressBlock_btlazy2_extDict, ZSTD_rust_search_binaryTree, 2, ZSTD_rust_dict_extDict) #endif #undef ZSTD_RUST_LAZY_WRAPPER #endif /* lazy matcher build exclusions */