/* * 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. */ #include "config.h" /* Define a config for each fast level we want to test with. */ #define FAST_LEVEL(x) \ param_value_t const level_fast##x##_param_values[] = { \ {.param = ZSTD_c_compressionLevel, .value = -x}, \ }; \ config_t const level_fast##x = { \ .name = "level -" #x, \ .cli_args = "--fast=" #x, \ .param_values = PARAM_VALUES(level_fast##x##_param_values), \ }; \ config_t const level_fast##x##_dict = { \ .name = "level -" #x " with dict", \ .cli_args = "--fast=" #x, \ .param_values = PARAM_VALUES(level_fast##x##_param_values), \ .use_dictionary = 1, \ }; /* Define a config for each level we want to test with. */ #define LEVEL(x) \ param_value_t const level_##x##_param_values[] = { \ {.param = ZSTD_c_compressionLevel, .value = x}, \ }; \ param_value_t const level_##x##_param_values_dms[] = { \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \ }; \ param_value_t const level_##x##_param_values_dds[] = { \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 1}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \ }; \ param_value_t const level_##x##_param_values_dictcopy[] = { \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceCopy}, \ }; \ param_value_t const level_##x##_param_values_dictload[] = { \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceLoad}, \ }; \ config_t const level_##x = { \ .name = "level " #x, \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(level_##x##_param_values), \ }; \ config_t const level_##x##_dict = { \ .name = "level " #x " with dict", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(level_##x##_param_values), \ .use_dictionary = 1, \ }; \ config_t const level_##x##_dict_dms = { \ .name = "level " #x " with dict dms", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(level_##x##_param_values_dms), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; \ config_t const level_##x##_dict_dds = { \ .name = "level " #x " with dict dds", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(level_##x##_param_values_dds), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; \ config_t const level_##x##_dict_copy = { \ .name = "level " #x " with dict copy", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(level_##x##_param_values_dictcopy), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; \ config_t const level_##x##_dict_load = { \ .name = "level " #x " with dict load", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(level_##x##_param_values_dictload), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; /* Define a config specifically to test row hash based levels and settings. */ #define ROW_LEVEL(x, y) \ param_value_t const row_##y##_level_##x##_param_values[] = { \ {.param = ZSTD_c_useRowMatchFinder, .value = y}, \ {.param = ZSTD_c_compressionLevel, .value = x}, \ }; \ param_value_t const row_##y##_level_##x##_param_values_dms[] = { \ {.param = ZSTD_c_useRowMatchFinder, .value = y}, \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \ }; \ param_value_t const row_##y##_level_##x##_param_values_dds[] = { \ {.param = ZSTD_c_useRowMatchFinder, .value = y}, \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 1}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \ }; \ param_value_t const row_##y##_level_##x##_param_values_dictcopy[] = { \ {.param = ZSTD_c_useRowMatchFinder, .value = y}, \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceCopy}, \ }; \ param_value_t const row_##y##_level_##x##_param_values_dictload[] = { \ {.param = ZSTD_c_useRowMatchFinder, .value = y}, \ {.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ {.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceLoad}, \ }; \ config_t const row_##y##_level_##x = { \ .name = "level " #x " row " #y, \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(row_##y##_level_##x##_param_values), \ .advanced_api_only = 1, \ }; \ config_t const row_##y##_level_##x##_dict_dms = { \ .name = "level " #x " row " #y " with dict dms", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dms), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; \ config_t const row_##y##_level_##x##_dict_dds = { \ .name = "level " #x " row " #y " with dict dds", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dds), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; \ config_t const row_##y##_level_##x##_dict_copy = { \ .name = "level " #x " row " #y" with dict copy", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dictcopy), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; \ config_t const row_##y##_level_##x##_dict_load = { \ .name = "level " #x " row " #y " with dict load", \ .cli_args = "-" #x, \ .param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dictload), \ .use_dictionary = 1, \ .advanced_api_only = 1, \ }; #define PARAM_VALUES(pv) \ { .data = pv, .size = sizeof(pv) / sizeof((pv)[0]) } #include "levels.h" #undef LEVEL #undef FAST_LEVEL #undef ROW_LEVEL static config_t no_pledged_src_size = { .name = "no source size", .cli_args = "", .param_values = PARAM_VALUES(level_0_param_values), .no_pledged_src_size = 1, }; static config_t no_pledged_src_size_with_dict = { .name = "no source size with dict", .cli_args = "", .param_values = PARAM_VALUES(level_0_param_values), .no_pledged_src_size = 1, .use_dictionary = 1, }; static param_value_t const ldm_param_values[] = { {.param = ZSTD_c_enableLongDistanceMatching, .value = ZSTD_ps_enable}, }; static config_t ldm = { .name = "long distance mode", .cli_args = "--long", .param_values = PARAM_VALUES(ldm_param_values), }; static param_value_t const mt_param_values[] = { {.param = ZSTD_c_nbWorkers, .value = 2}, }; static config_t mt = { .name = "multithreaded", .cli_args = "-T2", .param_values = PARAM_VALUES(mt_param_values), }; static param_value_t const mt_ldm_param_values[] = { {.param = ZSTD_c_nbWorkers, .value = 2}, {.param = ZSTD_c_enableLongDistanceMatching, .value = ZSTD_ps_enable}, }; static config_t mt_ldm = { .name = "multithreaded long distance mode", .cli_args = "-T2 --long", .param_values = PARAM_VALUES(mt_ldm_param_values), }; static param_value_t mt_advanced_param_values[] = { {.param = ZSTD_c_nbWorkers, .value = 2}, {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_disable}, }; static config_t mt_advanced = { .name = "multithreaded with advanced params", .cli_args = "-T2 --no-compress-literals", .param_values = PARAM_VALUES(mt_advanced_param_values), }; static param_value_t const small_wlog_param_values[] = { {.param = ZSTD_c_windowLog, .value = 10}, }; static config_t small_wlog = { .name = "small window log", .cli_args = "--zstd=wlog=10", .param_values = PARAM_VALUES(small_wlog_param_values), }; static param_value_t const small_hlog_param_values[] = { {.param = ZSTD_c_hashLog, .value = 6}, {.param = ZSTD_c_strategy, .value = (int)ZSTD_btopt}, }; static config_t small_hlog = { .name = "small hash log", .cli_args = "--zstd=hlog=6,strat=7", .param_values = PARAM_VALUES(small_hlog_param_values), }; static param_value_t const small_clog_param_values[] = { {.param = ZSTD_c_chainLog, .value = 6}, {.param = ZSTD_c_strategy, .value = (int)ZSTD_btopt}, }; static config_t small_clog = { .name = "small chain log", .cli_args = "--zstd=clog=6,strat=7", .param_values = PARAM_VALUES(small_clog_param_values), }; static param_value_t const uncompressed_literals_param_values[] = { {.param = ZSTD_c_compressionLevel, .value = 3}, {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_disable}, }; static config_t uncompressed_literals = { .name = "uncompressed literals", .cli_args = "-3 --no-compress-literals", .param_values = PARAM_VALUES(uncompressed_literals_param_values), }; static param_value_t const uncompressed_literals_opt_param_values[] = { {.param = ZSTD_c_compressionLevel, .value = 19}, {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_disable}, }; static config_t uncompressed_literals_opt = { .name = "uncompressed literals optimal", .cli_args = "-19 --no-compress-literals", .param_values = PARAM_VALUES(uncompressed_literals_opt_param_values), }; static param_value_t const huffman_literals_param_values[] = { {.param = ZSTD_c_compressionLevel, .value = -1}, {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_enable}, }; static config_t huffman_literals = { .name = "huffman literals", .cli_args = "--fast=1 --compress-literals", .param_values = PARAM_VALUES(huffman_literals_param_values), }; static param_value_t const explicit_params_param_values[] = { {.param = ZSTD_c_checksumFlag, .value = 1}, {.param = ZSTD_c_contentSizeFlag, .value = 0}, {.param = ZSTD_c_dictIDFlag, .value = 0}, {.param = ZSTD_c_strategy, .value = (int)ZSTD_greedy}, {.param = ZSTD_c_windowLog, .value = 18}, {.param = ZSTD_c_hashLog, .value = 21}, {.param = ZSTD_c_chainLog, .value = 21}, {.param = ZSTD_c_targetLength, .value = 100}, }; static config_t explicit_params = { .name = "explicit params", .cli_args = "--no-check --no-dictID --zstd=strategy=3,wlog=18,hlog=21,clog=21,tlen=100", .param_values = PARAM_VALUES(explicit_params_param_values), }; static config_t const* g_configs[] = { #define FAST_LEVEL(x) &level_fast##x, &level_fast##x##_dict, #define LEVEL(x) &level_##x, &level_##x##_dict, &level_##x##_dict_dms, &level_##x##_dict_dds, &level_##x##_dict_copy, &level_##x##_dict_load, #define ROW_LEVEL(x, y) &row_##y##_level_##x, &row_##y##_level_##x##_dict_dms, &row_##y##_level_##x##_dict_dds, &row_##y##_level_##x##_dict_copy, &row_##y##_level_##x##_dict_load, #include "levels.h" #undef ROW_LEVEL #undef LEVEL #undef FAST_LEVEL &no_pledged_src_size, &no_pledged_src_size_with_dict, &ldm, &mt, &mt_ldm, &small_wlog, &small_hlog, &small_clog, &explicit_params, &uncompressed_literals, &uncompressed_literals_opt, &huffman_literals, &mt_advanced, NULL, }; config_t const* const* configs = g_configs; int config_skip_data(config_t const* config, data_t const* data) { return config->use_dictionary && !data_has_dict(data); } int config_get_level(config_t const* config) { param_values_t const params = config->param_values; size_t i; for (i = 0; i < params.size; ++i) { if (params.data[i].param == ZSTD_c_compressionLevel) return (int)params.data[i].value; } return CONFIG_NO_LEVEL; } ZSTD_parameters config_get_zstd_params( config_t const* config, uint64_t srcSize, size_t dictSize) { ZSTD_parameters zparams = {}; param_values_t const params = config->param_values; int level = config_get_level(config); if (level == CONFIG_NO_LEVEL) level = 3; zparams = ZSTD_getParams( level, config->no_pledged_src_size ? ZSTD_CONTENTSIZE_UNKNOWN : srcSize, dictSize); for (size_t i = 0; i < params.size; ++i) { unsigned const value = params.data[i].value; switch (params.data[i].param) { case ZSTD_c_contentSizeFlag: zparams.fParams.contentSizeFlag = value; break; case ZSTD_c_checksumFlag: zparams.fParams.checksumFlag = value; break; case ZSTD_c_dictIDFlag: zparams.fParams.noDictIDFlag = !value; break; case ZSTD_c_windowLog: zparams.cParams.windowLog = value; break; case ZSTD_c_chainLog: zparams.cParams.chainLog = value; break; case ZSTD_c_hashLog: zparams.cParams.hashLog = value; break; case ZSTD_c_searchLog: zparams.cParams.searchLog = value; break; case ZSTD_c_minMatch: zparams.cParams.minMatch = value; break; case ZSTD_c_targetLength: zparams.cParams.targetLength = value; break; case ZSTD_c_strategy: zparams.cParams.strategy = (ZSTD_strategy)value; break; default: break; } } return zparams; }