zstdlib 0.14.0-x86-mingw32 → 0.15.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/ext/zstdlib_c/extconf.rb +1 -1
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/bits.h +92 -87
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/bitstream.h +26 -29
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/compiler.h +36 -22
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/cpu.h +1 -1
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/debug.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/error_private.c +1 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/error_private.h +0 -10
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/fse.h +2 -17
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/fse_decompress.c +2 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/huf.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/mem.h +7 -11
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/pool.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/portability_macros.h +22 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/threading.h +0 -8
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/xxhash.h +93 -19
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_deps.h +12 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_internal.h +1 -69
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_trace.h +5 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/hist.c +10 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/hist.h +7 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress.c +1057 -367
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_internal.h +227 -125
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_literals.c +1 -1
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_sequences.c +7 -7
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_sequences.h +7 -6
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_superblock.c +17 -17
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_cwksp.h +41 -24
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_double_fast.c +58 -50
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_double_fast.h +4 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_fast.c +91 -74
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_fast.h +4 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_lazy.c +64 -64
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_lazy.h +30 -39
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm.c +48 -33
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm.h +6 -14
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_opt.c +55 -51
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_opt.h +8 -16
- data/ext/zstdlib_c/zstd-1.5.7/lib/compress/zstd_preSplit.c +238 -0
- data/ext/zstdlib_c/zstd-1.5.7/lib/compress/zstd_preSplit.h +33 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstdmt_compress.c +134 -93
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstdmt_compress.h +4 -15
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/huf_decompress_amd64.S +10 -3
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress.c +14 -11
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_block.c +6 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_internal.h +5 -5
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zdict.h +15 -8
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zstd.h +241 -132
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zstd_errors.h +1 -8
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzwrite.c +2 -1
- data/lib/2.4/zstdlib_c.so +0 -0
- data/lib/2.5/zstdlib_c.so +0 -0
- data/lib/2.6/zstdlib_c.so +0 -0
- data/lib/2.7/zstdlib_c.so +0 -0
- data/lib/3.0/zstdlib_c.so +0 -0
- data/lib/3.1/zstdlib_c.so +0 -0
- data/lib/3.2/zstdlib_c.so +0 -0
- data/lib/3.3/zstdlib_c.so +0 -0
- data/lib/3.4/zstdlib_c.so +0 -0
- metadata +75 -73
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/allocations.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/debug.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/entropy_common.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/pool.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/threading.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/xxhash.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_common.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/clevels.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/fse_compress.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/huf_compress.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_literals.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_superblock.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm_geartab.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/huf_decompress.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_ddict.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_ddict.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_block.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzclose.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzcompatibility.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzguts.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzlib.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzread.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/zstd_zlibwrapper.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/zstd_zlibwrapper.h +5 -5
| @@ -14,6 +14,7 @@ | |
| 14 14 | 
             
            #include "../common/allocations.h"  /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
         | 
| 15 15 | 
             
            #include "../common/zstd_deps.h"  /* INT_MAX, ZSTD_memset, ZSTD_memcpy */
         | 
| 16 16 | 
             
            #include "../common/mem.h"
         | 
| 17 | 
            +
            #include "../common/error_private.h"
         | 
| 17 18 | 
             
            #include "hist.h"           /* HIST_countFast_wksp */
         | 
| 18 19 | 
             
            #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
         | 
| 19 20 | 
             
            #include "../common/fse.h"
         | 
| @@ -48,7 +49,7 @@ | |
| 48 49 | 
             
             * in log format, aka 17 => 1 << 17 == 128Ki positions.
         | 
| 49 50 | 
             
             * This structure is only used in zstd_opt.
         | 
| 50 51 | 
             
             * Since allocation is centralized for all strategies, it has to be known here.
         | 
| 51 | 
            -
             * The actual (selected) size of the hash table is then stored in  | 
| 52 | 
            +
             * The actual (selected) size of the hash table is then stored in ZSTD_MatchState_t.hashLog3,
         | 
| 52 53 | 
             
             * so that zstd_opt.c doesn't need to know about this constant.
         | 
| 53 54 | 
             
             */
         | 
| 54 55 | 
             
            #ifndef ZSTD_HASHLOG3_MAX
         | 
| @@ -82,12 +83,12 @@ struct ZSTD_CDict_s { | |
| 82 83 | 
             
                ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */
         | 
| 83 84 | 
             
                U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
         | 
| 84 85 | 
             
                ZSTD_cwksp workspace;
         | 
| 85 | 
            -
                 | 
| 86 | 
            +
                ZSTD_MatchState_t matchState;
         | 
| 86 87 | 
             
                ZSTD_compressedBlockState_t cBlockState;
         | 
| 87 88 | 
             
                ZSTD_customMem customMem;
         | 
| 88 89 | 
             
                U32 dictID;
         | 
| 89 90 | 
             
                int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
         | 
| 90 | 
            -
                 | 
| 91 | 
            +
                ZSTD_ParamSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
         | 
| 91 92 | 
             
                                                       * row-based matchfinder. Unless the cdict is reloaded, we will use
         | 
| 92 93 | 
             
                                                       * the same greedy/lazy matchfinder at compression time.
         | 
| 93 94 | 
             
                                                       */
         | 
| @@ -137,11 +138,12 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) | |
| 137 138 | 
             
                ZSTD_cwksp_move(&cctx->workspace, &ws);
         | 
| 138 139 | 
             
                cctx->staticSize = workspaceSize;
         | 
| 139 140 |  | 
| 140 | 
            -
                /* statically sized space.  | 
| 141 | 
            -
                if (!ZSTD_cwksp_check_available(&cctx->workspace,  | 
| 141 | 
            +
                /* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */
         | 
| 142 | 
            +
                if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
         | 
| 142 143 | 
             
                cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
         | 
| 143 144 | 
             
                cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
         | 
| 144 | 
            -
                cctx-> | 
| 145 | 
            +
                cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE);
         | 
| 146 | 
            +
                cctx->tmpWkspSize = TMP_WORKSPACE_SIZE;
         | 
| 145 147 | 
             
                cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
         | 
| 146 148 | 
             
                return cctx;
         | 
| 147 149 | 
             
            }
         | 
| @@ -217,7 +219,7 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) | |
| 217 219 | 
             
            }
         | 
| 218 220 |  | 
| 219 221 | 
             
            /* private API call, for dictBuilder only */
         | 
| 220 | 
            -
            const  | 
| 222 | 
            +
            const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
         | 
| 221 223 |  | 
| 222 224 | 
             
            /* Returns true if the strategy supports using a row based matchfinder */
         | 
| 223 225 | 
             
            static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
         | 
| @@ -227,32 +229,23 @@ static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) { | |
| 227 229 | 
             
            /* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder
         | 
| 228 230 | 
             
             * for this compression.
         | 
| 229 231 | 
             
             */
         | 
| 230 | 
            -
            static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const  | 
| 232 | 
            +
            static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_ParamSwitch_e mode) {
         | 
| 231 233 | 
             
                assert(mode != ZSTD_ps_auto);
         | 
| 232 234 | 
             
                return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable);
         | 
| 233 235 | 
             
            }
         | 
| 234 236 |  | 
| 235 237 | 
             
            /* Returns row matchfinder usage given an initial mode and cParams */
         | 
| 236 | 
            -
            static  | 
| 238 | 
            +
            static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode,
         | 
| 237 239 | 
             
                                                                     const ZSTD_compressionParameters* const cParams) {
         | 
| 238 | 
            -
            #if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON)
         | 
| 239 | 
            -
                int const kHasSIMD128 = 1;
         | 
| 240 | 
            -
            #else
         | 
| 241 | 
            -
                int const kHasSIMD128 = 0;
         | 
| 242 | 
            -
            #endif
         | 
| 243 240 | 
             
                if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
         | 
| 244 241 | 
             
                mode = ZSTD_ps_disable;
         | 
| 245 242 | 
             
                if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
         | 
| 246 | 
            -
                if ( | 
| 247 | 
            -
                    if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
         | 
| 248 | 
            -
                } else {
         | 
| 249 | 
            -
                    if (cParams->windowLog > 17) mode = ZSTD_ps_enable;
         | 
| 250 | 
            -
                }
         | 
| 243 | 
            +
                if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
         | 
| 251 244 | 
             
                return mode;
         | 
| 252 245 | 
             
            }
         | 
| 253 246 |  | 
| 254 247 | 
             
            /* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */
         | 
| 255 | 
            -
            static  | 
| 248 | 
            +
            static ZSTD_ParamSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_ParamSwitch_e mode,
         | 
| 256 249 | 
             
                                                                    const ZSTD_compressionParameters* const cParams) {
         | 
| 257 250 | 
             
                if (mode != ZSTD_ps_auto) return mode;
         | 
| 258 251 | 
             
                return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable;
         | 
| @@ -260,7 +253,7 @@ static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode, | |
| 260 253 |  | 
| 261 254 | 
             
            /* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */
         | 
| 262 255 | 
             
            static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
         | 
| 263 | 
            -
                                               const  | 
| 256 | 
            +
                                               const ZSTD_ParamSwitch_e useRowMatchFinder,
         | 
| 264 257 | 
             
                                               const U32 forDDSDict) {
         | 
| 265 258 | 
             
                assert(useRowMatchFinder != ZSTD_ps_auto);
         | 
| 266 259 | 
             
                /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate.
         | 
| @@ -273,7 +266,7 @@ static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, | |
| 273 266 | 
             
             * enable long distance matching (wlog >= 27, strategy >= btopt).
         | 
| 274 267 | 
             
             * Returns ZSTD_ps_disable otherwise.
         | 
| 275 268 | 
             
             */
         | 
| 276 | 
            -
            static  | 
| 269 | 
            +
            static ZSTD_ParamSwitch_e ZSTD_resolveEnableLdm(ZSTD_ParamSwitch_e mode,
         | 
| 277 270 | 
             
                                             const ZSTD_compressionParameters* const cParams) {
         | 
| 278 271 | 
             
                if (mode != ZSTD_ps_auto) return mode;
         | 
| 279 272 | 
             
                return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable;
         | 
| @@ -292,7 +285,7 @@ static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) { | |
| 292 285 | 
             
                }
         | 
| 293 286 | 
             
            }
         | 
| 294 287 |  | 
| 295 | 
            -
            static  | 
| 288 | 
            +
            static ZSTD_ParamSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_ParamSwitch_e value, int cLevel) {
         | 
| 296 289 | 
             
                if (value != ZSTD_ps_auto) return value;
         | 
| 297 290 | 
             
                if (cLevel < 10) {
         | 
| 298 291 | 
             
                    return ZSTD_ps_disable;
         | 
| @@ -322,7 +315,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( | |
| 322 315 | 
             
                    assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
         | 
| 323 316 | 
             
                    assert(cctxParams.ldmParams.hashRateLog < 32);
         | 
| 324 317 | 
             
                }
         | 
| 325 | 
            -
                cctxParams. | 
| 318 | 
            +
                cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams);
         | 
| 326 319 | 
             
                cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
         | 
| 327 320 | 
             
                cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences);
         | 
| 328 321 | 
             
                cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize);
         | 
| @@ -390,13 +383,13 @@ ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, | |
| 390 383 | 
             
                 */
         | 
| 391 384 | 
             
                cctxParams->compressionLevel = compressionLevel;
         | 
| 392 385 | 
             
                cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams);
         | 
| 393 | 
            -
                cctxParams-> | 
| 386 | 
            +
                cctxParams->postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->postBlockSplitter, ¶ms->cParams);
         | 
| 394 387 | 
             
                cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, ¶ms->cParams);
         | 
| 395 388 | 
             
                cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences);
         | 
| 396 389 | 
             
                cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize);
         | 
| 397 390 | 
             
                cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel);
         | 
| 398 391 | 
             
                DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d",
         | 
| 399 | 
            -
                            cctxParams->useRowMatchFinder, cctxParams-> | 
| 392 | 
            +
                            cctxParams->useRowMatchFinder, cctxParams->postBlockSplitter, cctxParams->ldmParams.enableLdm);
         | 
| 400 393 | 
             
            }
         | 
| 401 394 |  | 
| 402 395 | 
             
            size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
         | 
| @@ -597,11 +590,16 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) | |
| 597 590 | 
             
                    bounds.upperBound = 1;
         | 
| 598 591 | 
             
                    return bounds;
         | 
| 599 592 |  | 
| 600 | 
            -
                case  | 
| 593 | 
            +
                case ZSTD_c_splitAfterSequences:
         | 
| 601 594 | 
             
                    bounds.lowerBound = (int)ZSTD_ps_auto;
         | 
| 602 595 | 
             
                    bounds.upperBound = (int)ZSTD_ps_disable;
         | 
| 603 596 | 
             
                    return bounds;
         | 
| 604 597 |  | 
| 598 | 
            +
                case ZSTD_c_blockSplitterLevel:
         | 
| 599 | 
            +
                    bounds.lowerBound = 0;
         | 
| 600 | 
            +
                    bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX;
         | 
| 601 | 
            +
                    return bounds;
         | 
| 602 | 
            +
             | 
| 605 603 | 
             
                case ZSTD_c_useRowMatchFinder:
         | 
| 606 604 | 
             
                    bounds.lowerBound = (int)ZSTD_ps_auto;
         | 
| 607 605 | 
             
                    bounds.upperBound = (int)ZSTD_ps_disable;
         | 
| @@ -627,7 +625,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) | |
| 627 625 | 
             
                    bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
         | 
| 628 626 | 
             
                    return bounds;
         | 
| 629 627 |  | 
| 630 | 
            -
                case  | 
| 628 | 
            +
                case ZSTD_c_repcodeResolution:
         | 
| 631 629 | 
             
                    bounds.lowerBound = (int)ZSTD_ps_auto;
         | 
| 632 630 | 
             
                    bounds.upperBound = (int)ZSTD_ps_disable;
         | 
| 633 631 | 
             
                    return bounds;
         | 
| @@ -668,6 +666,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) | |
| 668 666 | 
             
                case ZSTD_c_minMatch:
         | 
| 669 667 | 
             
                case ZSTD_c_targetLength:
         | 
| 670 668 | 
             
                case ZSTD_c_strategy:
         | 
| 669 | 
            +
                case ZSTD_c_blockSplitterLevel:
         | 
| 671 670 | 
             
                    return 1;
         | 
| 672 671 |  | 
| 673 672 | 
             
                case ZSTD_c_format:
         | 
| @@ -694,13 +693,13 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) | |
| 694 693 | 
             
                case ZSTD_c_stableOutBuffer:
         | 
| 695 694 | 
             
                case ZSTD_c_blockDelimiters:
         | 
| 696 695 | 
             
                case ZSTD_c_validateSequences:
         | 
| 697 | 
            -
                case  | 
| 696 | 
            +
                case ZSTD_c_splitAfterSequences:
         | 
| 698 697 | 
             
                case ZSTD_c_useRowMatchFinder:
         | 
| 699 698 | 
             
                case ZSTD_c_deterministicRefPrefix:
         | 
| 700 699 | 
             
                case ZSTD_c_prefetchCDictTables:
         | 
| 701 700 | 
             
                case ZSTD_c_enableSeqProducerFallback:
         | 
| 702 701 | 
             
                case ZSTD_c_maxBlockSize:
         | 
| 703 | 
            -
                case  | 
| 702 | 
            +
                case ZSTD_c_repcodeResolution:
         | 
| 704 703 | 
             
                default:
         | 
| 705 704 | 
             
                    return 0;
         | 
| 706 705 | 
             
                }
         | 
| @@ -753,13 +752,14 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) | |
| 753 752 | 
             
                case ZSTD_c_stableOutBuffer:
         | 
| 754 753 | 
             
                case ZSTD_c_blockDelimiters:
         | 
| 755 754 | 
             
                case ZSTD_c_validateSequences:
         | 
| 756 | 
            -
                case  | 
| 755 | 
            +
                case ZSTD_c_splitAfterSequences:
         | 
| 756 | 
            +
                case ZSTD_c_blockSplitterLevel:
         | 
| 757 757 | 
             
                case ZSTD_c_useRowMatchFinder:
         | 
| 758 758 | 
             
                case ZSTD_c_deterministicRefPrefix:
         | 
| 759 759 | 
             
                case ZSTD_c_prefetchCDictTables:
         | 
| 760 760 | 
             
                case ZSTD_c_enableSeqProducerFallback:
         | 
| 761 761 | 
             
                case ZSTD_c_maxBlockSize:
         | 
| 762 | 
            -
                case  | 
| 762 | 
            +
                case ZSTD_c_repcodeResolution:
         | 
| 763 763 | 
             
                    break;
         | 
| 764 764 |  | 
| 765 765 | 
             
                default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
         | 
| @@ -857,7 +857,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 857 857 | 
             
                }
         | 
| 858 858 |  | 
| 859 859 | 
             
                case ZSTD_c_literalCompressionMode : {
         | 
| 860 | 
            -
                    const  | 
| 860 | 
            +
                    const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value;
         | 
| 861 861 | 
             
                    BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm);
         | 
| 862 862 | 
             
                    CCtxParams->literalCompressionMode = lcm;
         | 
| 863 863 | 
             
                    return CCtxParams->literalCompressionMode;
         | 
| @@ -883,7 +883,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 883 883 | 
             
                        value = ZSTDMT_JOBSIZE_MIN;
         | 
| 884 884 | 
             
                    FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
         | 
| 885 885 | 
             
                    assert(value >= 0);
         | 
| 886 | 
            -
                    CCtxParams->jobSize = value;
         | 
| 886 | 
            +
                    CCtxParams->jobSize = (size_t)value;
         | 
| 887 887 | 
             
                    return CCtxParams->jobSize;
         | 
| 888 888 | 
             
            #endif
         | 
| 889 889 |  | 
| @@ -913,7 +913,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 913 913 |  | 
| 914 914 | 
             
                case ZSTD_c_enableLongDistanceMatching :
         | 
| 915 915 | 
             
                    BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value);
         | 
| 916 | 
            -
                    CCtxParams->ldmParams.enableLdm = ( | 
| 916 | 
            +
                    CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value;
         | 
| 917 917 | 
             
                    return CCtxParams->ldmParams.enableLdm;
         | 
| 918 918 |  | 
| 919 919 | 
             
                case ZSTD_c_ldmHashLog :
         | 
| @@ -966,7 +966,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 966 966 |  | 
| 967 967 | 
             
                case ZSTD_c_blockDelimiters:
         | 
| 968 968 | 
             
                    BOUNDCHECK(ZSTD_c_blockDelimiters, value);
         | 
| 969 | 
            -
                    CCtxParams->blockDelimiters = ( | 
| 969 | 
            +
                    CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value;
         | 
| 970 970 | 
             
                    return CCtxParams->blockDelimiters;
         | 
| 971 971 |  | 
| 972 972 | 
             
                case ZSTD_c_validateSequences:
         | 
| @@ -974,14 +974,19 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 974 974 | 
             
                    CCtxParams->validateSequences = value;
         | 
| 975 975 | 
             
                    return (size_t)CCtxParams->validateSequences;
         | 
| 976 976 |  | 
| 977 | 
            -
                case  | 
| 978 | 
            -
                    BOUNDCHECK( | 
| 979 | 
            -
                    CCtxParams-> | 
| 980 | 
            -
                    return CCtxParams-> | 
| 977 | 
            +
                case ZSTD_c_splitAfterSequences:
         | 
| 978 | 
            +
                    BOUNDCHECK(ZSTD_c_splitAfterSequences, value);
         | 
| 979 | 
            +
                    CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value;
         | 
| 980 | 
            +
                    return CCtxParams->postBlockSplitter;
         | 
| 981 | 
            +
             | 
| 982 | 
            +
                case ZSTD_c_blockSplitterLevel:
         | 
| 983 | 
            +
                    BOUNDCHECK(ZSTD_c_blockSplitterLevel, value);
         | 
| 984 | 
            +
                    CCtxParams->preBlockSplitter_level = value;
         | 
| 985 | 
            +
                    return (size_t)CCtxParams->preBlockSplitter_level;
         | 
| 981 986 |  | 
| 982 987 | 
             
                case ZSTD_c_useRowMatchFinder:
         | 
| 983 988 | 
             
                    BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
         | 
| 984 | 
            -
                    CCtxParams->useRowMatchFinder = ( | 
| 989 | 
            +
                    CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value;
         | 
| 985 990 | 
             
                    return CCtxParams->useRowMatchFinder;
         | 
| 986 991 |  | 
| 987 992 | 
             
                case ZSTD_c_deterministicRefPrefix:
         | 
| @@ -991,7 +996,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 991 996 |  | 
| 992 997 | 
             
                case ZSTD_c_prefetchCDictTables:
         | 
| 993 998 | 
             
                    BOUNDCHECK(ZSTD_c_prefetchCDictTables, value);
         | 
| 994 | 
            -
                    CCtxParams->prefetchCDictTables = ( | 
| 999 | 
            +
                    CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value;
         | 
| 995 1000 | 
             
                    return CCtxParams->prefetchCDictTables;
         | 
| 996 1001 |  | 
| 997 1002 | 
             
                case ZSTD_c_enableSeqProducerFallback:
         | 
| @@ -1002,12 +1007,13 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, | |
| 1002 1007 | 
             
                case ZSTD_c_maxBlockSize:
         | 
| 1003 1008 | 
             
                    if (value!=0)    /* 0 ==> default */
         | 
| 1004 1009 | 
             
                        BOUNDCHECK(ZSTD_c_maxBlockSize, value);
         | 
| 1005 | 
            -
                     | 
| 1010 | 
            +
                    assert(value>=0);
         | 
| 1011 | 
            +
                    CCtxParams->maxBlockSize = (size_t)value;
         | 
| 1006 1012 | 
             
                    return CCtxParams->maxBlockSize;
         | 
| 1007 1013 |  | 
| 1008 | 
            -
                case  | 
| 1009 | 
            -
                    BOUNDCHECK( | 
| 1010 | 
            -
                    CCtxParams->searchForExternalRepcodes = ( | 
| 1014 | 
            +
                case ZSTD_c_repcodeResolution:
         | 
| 1015 | 
            +
                    BOUNDCHECK(ZSTD_c_repcodeResolution, value);
         | 
| 1016 | 
            +
                    CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value;
         | 
| 1011 1017 | 
             
                    return CCtxParams->searchForExternalRepcodes;
         | 
| 1012 1018 |  | 
| 1013 1019 | 
             
                default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
         | 
| @@ -1025,7 +1031,7 @@ size_t ZSTD_CCtxParams_getParameter( | |
| 1025 1031 | 
             
                switch(param)
         | 
| 1026 1032 | 
             
                {
         | 
| 1027 1033 | 
             
                case ZSTD_c_format :
         | 
| 1028 | 
            -
                    *value = CCtxParams->format;
         | 
| 1034 | 
            +
                    *value = (int)CCtxParams->format;
         | 
| 1029 1035 | 
             
                    break;
         | 
| 1030 1036 | 
             
                case ZSTD_c_compressionLevel :
         | 
| 1031 1037 | 
             
                    *value = CCtxParams->compressionLevel;
         | 
| @@ -1040,16 +1046,16 @@ size_t ZSTD_CCtxParams_getParameter( | |
| 1040 1046 | 
             
                    *value = (int)CCtxParams->cParams.chainLog;
         | 
| 1041 1047 | 
             
                    break;
         | 
| 1042 1048 | 
             
                case ZSTD_c_searchLog :
         | 
| 1043 | 
            -
                    *value = CCtxParams->cParams.searchLog;
         | 
| 1049 | 
            +
                    *value = (int)CCtxParams->cParams.searchLog;
         | 
| 1044 1050 | 
             
                    break;
         | 
| 1045 1051 | 
             
                case ZSTD_c_minMatch :
         | 
| 1046 | 
            -
                    *value = CCtxParams->cParams.minMatch;
         | 
| 1052 | 
            +
                    *value = (int)CCtxParams->cParams.minMatch;
         | 
| 1047 1053 | 
             
                    break;
         | 
| 1048 1054 | 
             
                case ZSTD_c_targetLength :
         | 
| 1049 | 
            -
                    *value = CCtxParams->cParams.targetLength;
         | 
| 1055 | 
            +
                    *value = (int)CCtxParams->cParams.targetLength;
         | 
| 1050 1056 | 
             
                    break;
         | 
| 1051 1057 | 
             
                case ZSTD_c_strategy :
         | 
| 1052 | 
            -
                    *value = ( | 
| 1058 | 
            +
                    *value = (int)CCtxParams->cParams.strategy;
         | 
| 1053 1059 | 
             
                    break;
         | 
| 1054 1060 | 
             
                case ZSTD_c_contentSizeFlag :
         | 
| 1055 1061 | 
             
                    *value = CCtxParams->fParams.contentSizeFlag;
         | 
| @@ -1064,10 +1070,10 @@ size_t ZSTD_CCtxParams_getParameter( | |
| 1064 1070 | 
             
                    *value = CCtxParams->forceWindow;
         | 
| 1065 1071 | 
             
                    break;
         | 
| 1066 1072 | 
             
                case ZSTD_c_forceAttachDict :
         | 
| 1067 | 
            -
                    *value = CCtxParams->attachDictPref;
         | 
| 1073 | 
            +
                    *value = (int)CCtxParams->attachDictPref;
         | 
| 1068 1074 | 
             
                    break;
         | 
| 1069 1075 | 
             
                case ZSTD_c_literalCompressionMode :
         | 
| 1070 | 
            -
                    *value = CCtxParams->literalCompressionMode;
         | 
| 1076 | 
            +
                    *value = (int)CCtxParams->literalCompressionMode;
         | 
| 1071 1077 | 
             
                    break;
         | 
| 1072 1078 | 
             
                case ZSTD_c_nbWorkers :
         | 
| 1073 1079 | 
             
            #ifndef ZSTD_MULTITHREAD
         | 
| @@ -1101,19 +1107,19 @@ size_t ZSTD_CCtxParams_getParameter( | |
| 1101 1107 | 
             
                    *value = CCtxParams->enableDedicatedDictSearch;
         | 
| 1102 1108 | 
             
                    break;
         | 
| 1103 1109 | 
             
                case ZSTD_c_enableLongDistanceMatching :
         | 
| 1104 | 
            -
                    *value = CCtxParams->ldmParams.enableLdm;
         | 
| 1110 | 
            +
                    *value = (int)CCtxParams->ldmParams.enableLdm;
         | 
| 1105 1111 | 
             
                    break;
         | 
| 1106 1112 | 
             
                case ZSTD_c_ldmHashLog :
         | 
| 1107 | 
            -
                    *value = CCtxParams->ldmParams.hashLog;
         | 
| 1113 | 
            +
                    *value = (int)CCtxParams->ldmParams.hashLog;
         | 
| 1108 1114 | 
             
                    break;
         | 
| 1109 1115 | 
             
                case ZSTD_c_ldmMinMatch :
         | 
| 1110 | 
            -
                    *value = CCtxParams->ldmParams.minMatchLength;
         | 
| 1116 | 
            +
                    *value = (int)CCtxParams->ldmParams.minMatchLength;
         | 
| 1111 1117 | 
             
                    break;
         | 
| 1112 1118 | 
             
                case ZSTD_c_ldmBucketSizeLog :
         | 
| 1113 | 
            -
                    *value = CCtxParams->ldmParams.bucketSizeLog;
         | 
| 1119 | 
            +
                    *value = (int)CCtxParams->ldmParams.bucketSizeLog;
         | 
| 1114 1120 | 
             
                    break;
         | 
| 1115 1121 | 
             
                case ZSTD_c_ldmHashRateLog :
         | 
| 1116 | 
            -
                    *value = CCtxParams->ldmParams.hashRateLog;
         | 
| 1122 | 
            +
                    *value = (int)CCtxParams->ldmParams.hashRateLog;
         | 
| 1117 1123 | 
             
                    break;
         | 
| 1118 1124 | 
             
                case ZSTD_c_targetCBlockSize :
         | 
| 1119 1125 | 
             
                    *value = (int)CCtxParams->targetCBlockSize;
         | 
| @@ -1133,8 +1139,11 @@ size_t ZSTD_CCtxParams_getParameter( | |
| 1133 1139 | 
             
                case ZSTD_c_validateSequences :
         | 
| 1134 1140 | 
             
                    *value = (int)CCtxParams->validateSequences;
         | 
| 1135 1141 | 
             
                    break;
         | 
| 1136 | 
            -
                case  | 
| 1137 | 
            -
                    *value = (int)CCtxParams-> | 
| 1142 | 
            +
                case ZSTD_c_splitAfterSequences :
         | 
| 1143 | 
            +
                    *value = (int)CCtxParams->postBlockSplitter;
         | 
| 1144 | 
            +
                    break;
         | 
| 1145 | 
            +
                case ZSTD_c_blockSplitterLevel :
         | 
| 1146 | 
            +
                    *value = CCtxParams->preBlockSplitter_level;
         | 
| 1138 1147 | 
             
                    break;
         | 
| 1139 1148 | 
             
                case ZSTD_c_useRowMatchFinder :
         | 
| 1140 1149 | 
             
                    *value = (int)CCtxParams->useRowMatchFinder;
         | 
| @@ -1151,7 +1160,7 @@ size_t ZSTD_CCtxParams_getParameter( | |
| 1151 1160 | 
             
                case ZSTD_c_maxBlockSize:
         | 
| 1152 1161 | 
             
                    *value = (int)CCtxParams->maxBlockSize;
         | 
| 1153 1162 | 
             
                    break;
         | 
| 1154 | 
            -
                case  | 
| 1163 | 
            +
                case ZSTD_c_repcodeResolution:
         | 
| 1155 1164 | 
             
                    *value = (int)CCtxParams->searchForExternalRepcodes;
         | 
| 1156 1165 | 
             
                    break;
         | 
| 1157 1166 | 
             
                default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
         | 
| @@ -1186,13 +1195,13 @@ size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams) | |
| 1186 1195 | 
             
                DEBUGLOG(4, "ZSTD_CCtx_setCParams");
         | 
| 1187 1196 | 
             
                /* only update if all parameters are valid */
         | 
| 1188 1197 | 
             
                FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), "");
         | 
| 1189 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, cparams.windowLog), "");
         | 
| 1190 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, cparams.chainLog), "");
         | 
| 1191 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, cparams.hashLog), "");
         | 
| 1192 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, cparams.searchLog), "");
         | 
| 1193 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, cparams.minMatch), "");
         | 
| 1194 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, cparams.targetLength), "");
         | 
| 1195 | 
            -
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, cparams.strategy), "");
         | 
| 1198 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)cparams.windowLog), "");
         | 
| 1199 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, (int)cparams.chainLog), "");
         | 
| 1200 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, (int)cparams.hashLog), "");
         | 
| 1201 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, (int)cparams.searchLog), "");
         | 
| 1202 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, (int)cparams.minMatch), "");
         | 
| 1203 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, (int)cparams.targetLength), "");
         | 
| 1204 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)cparams.strategy), "");
         | 
| 1196 1205 | 
             
                return 0;
         | 
| 1197 1206 | 
             
            }
         | 
| 1198 1207 |  | 
| @@ -1384,7 +1393,7 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) | |
| 1384 1393 | 
             
                BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);
         | 
| 1385 1394 | 
             
                BOUNDCHECK(ZSTD_c_minMatch,  (int)cParams.minMatch);
         | 
| 1386 1395 | 
             
                BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);
         | 
| 1387 | 
            -
                BOUNDCHECK(ZSTD_c_strategy,  cParams.strategy);
         | 
| 1396 | 
            +
                BOUNDCHECK(ZSTD_c_strategy,  (int)cParams.strategy);
         | 
| 1388 1397 | 
             
                return 0;
         | 
| 1389 1398 | 
             
            }
         | 
| 1390 1399 |  | 
| @@ -1457,15 +1466,15 @@ static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize) | |
| 1457 1466 | 
             
             *  optimize `cPar` for a specified input (`srcSize` and `dictSize`).
         | 
| 1458 1467 | 
             
             *  mostly downsize to reduce memory consumption and initialization latency.
         | 
| 1459 1468 | 
             
             * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
         | 
| 1460 | 
            -
             * `mode` is the mode for parameter adjustment. See docs for ` | 
| 1469 | 
            +
             * `mode` is the mode for parameter adjustment. See docs for `ZSTD_CParamMode_e`.
         | 
| 1461 1470 | 
             
             *  note : `srcSize==0` means 0!
         | 
| 1462 1471 | 
             
             *  condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
         | 
| 1463 1472 | 
             
            static ZSTD_compressionParameters
         | 
| 1464 1473 | 
             
            ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
         | 
| 1465 1474 | 
             
                                        unsigned long long srcSize,
         | 
| 1466 1475 | 
             
                                        size_t dictSize,
         | 
| 1467 | 
            -
                                         | 
| 1468 | 
            -
                                         | 
| 1476 | 
            +
                                        ZSTD_CParamMode_e mode,
         | 
| 1477 | 
            +
                                        ZSTD_ParamSwitch_e useRowMatchFinder)
         | 
| 1469 1478 | 
             
            {
         | 
| 1470 1479 | 
             
                const U64 minSrcSize = 513; /* (1<<9) + 1 */
         | 
| 1471 1480 | 
             
                const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
         | 
| @@ -1609,8 +1618,8 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar, | |
| 1609 1618 | 
             
                return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto);
         | 
| 1610 1619 | 
             
            }
         | 
| 1611 1620 |  | 
| 1612 | 
            -
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize,  | 
| 1613 | 
            -
            static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize,  | 
| 1621 | 
            +
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
         | 
| 1622 | 
            +
            static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
         | 
| 1614 1623 |  | 
| 1615 1624 | 
             
            static void ZSTD_overrideCParams(
         | 
| 1616 1625 | 
             
                          ZSTD_compressionParameters* cParams,
         | 
| @@ -1626,11 +1635,12 @@ static void ZSTD_overrideCParams( | |
| 1626 1635 | 
             
            }
         | 
| 1627 1636 |  | 
| 1628 1637 | 
             
            ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
         | 
| 1629 | 
            -
                    const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize,  | 
| 1638 | 
            +
                    const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
         | 
| 1630 1639 | 
             
            {
         | 
| 1631 1640 | 
             
                ZSTD_compressionParameters cParams;
         | 
| 1632 1641 | 
             
                if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
         | 
| 1633 | 
            -
             | 
| 1642 | 
            +
                    assert(CCtxParams->srcSizeHint>=0);
         | 
| 1643 | 
            +
                    srcSizeHint = (U64)CCtxParams->srcSizeHint;
         | 
| 1634 1644 | 
             
                }
         | 
| 1635 1645 | 
             
                cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
         | 
| 1636 1646 | 
             
                if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
         | 
| @@ -1642,8 +1652,8 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( | |
| 1642 1652 |  | 
| 1643 1653 | 
             
            static size_t
         | 
| 1644 1654 | 
             
            ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
         | 
| 1645 | 
            -
                                   const  | 
| 1646 | 
            -
                                   const  | 
| 1655 | 
            +
                                   const ZSTD_ParamSwitch_e useRowMatchFinder,
         | 
| 1656 | 
            +
                                   const int enableDedicatedDictSearch,
         | 
| 1647 1657 | 
             
                                   const U32 forCCtx)
         | 
| 1648 1658 | 
             
            {
         | 
| 1649 1659 | 
             
                /* chain table size should be 0 for fast or row-hash strategies */
         | 
| @@ -1659,14 +1669,14 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, | |
| 1659 1669 | 
             
                                        + hSize * sizeof(U32)
         | 
| 1660 1670 | 
             
                                        + h3Size * sizeof(U32);
         | 
| 1661 1671 | 
             
                size_t const optPotentialSpace =
         | 
| 1662 | 
            -
                     | 
| 1663 | 
            -
                  +  | 
| 1664 | 
            -
                  +  | 
| 1665 | 
            -
                  +  | 
| 1666 | 
            -
                  +  | 
| 1667 | 
            -
                  +  | 
| 1672 | 
            +
                    ZSTD_cwksp_aligned64_alloc_size((MaxML+1) * sizeof(U32))
         | 
| 1673 | 
            +
                  + ZSTD_cwksp_aligned64_alloc_size((MaxLL+1) * sizeof(U32))
         | 
| 1674 | 
            +
                  + ZSTD_cwksp_aligned64_alloc_size((MaxOff+1) * sizeof(U32))
         | 
| 1675 | 
            +
                  + ZSTD_cwksp_aligned64_alloc_size((1<<Litbits) * sizeof(U32))
         | 
| 1676 | 
            +
                  + ZSTD_cwksp_aligned64_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_match_t))
         | 
| 1677 | 
            +
                  + ZSTD_cwksp_aligned64_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
         | 
| 1668 1678 | 
             
                size_t const lazyAdditionalSpace = ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)
         | 
| 1669 | 
            -
                                                        ?  | 
| 1679 | 
            +
                                                        ? ZSTD_cwksp_aligned64_alloc_size(hSize)
         | 
| 1670 1680 | 
             
                                                        : 0;
         | 
| 1671 1681 | 
             
                size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
         | 
| 1672 1682 | 
             
                                            ? optPotentialSpace
         | 
| @@ -1693,7 +1703,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( | |
| 1693 1703 | 
             
                    const ZSTD_compressionParameters* cParams,
         | 
| 1694 1704 | 
             
                    const ldmParams_t* ldmParams,
         | 
| 1695 1705 | 
             
                    const int isStatic,
         | 
| 1696 | 
            -
                    const  | 
| 1706 | 
            +
                    const ZSTD_ParamSwitch_e useRowMatchFinder,
         | 
| 1697 1707 | 
             
                    const size_t buffInSize,
         | 
| 1698 1708 | 
             
                    const size_t buffOutSize,
         | 
| 1699 1709 | 
             
                    const U64 pledgedSrcSize,
         | 
| @@ -1704,16 +1714,16 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( | |
| 1704 1714 | 
             
                size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize);
         | 
| 1705 1715 | 
             
                size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer);
         | 
| 1706 1716 | 
             
                size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
         | 
| 1707 | 
            -
                                        +  | 
| 1717 | 
            +
                                        + ZSTD_cwksp_aligned64_alloc_size(maxNbSeq * sizeof(SeqDef))
         | 
| 1708 1718 | 
             
                                        + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
         | 
| 1709 | 
            -
                size_t const  | 
| 1719 | 
            +
                size_t const tmpWorkSpace = ZSTD_cwksp_alloc_size(TMP_WORKSPACE_SIZE);
         | 
| 1710 1720 | 
             
                size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
         | 
| 1711 1721 | 
             
                size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1);
         | 
| 1712 1722 |  | 
| 1713 1723 | 
             
                size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
         | 
| 1714 1724 | 
             
                size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
         | 
| 1715 1725 | 
             
                size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ?
         | 
| 1716 | 
            -
                     | 
| 1726 | 
            +
                    ZSTD_cwksp_aligned64_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
         | 
| 1717 1727 |  | 
| 1718 1728 |  | 
| 1719 1729 | 
             
                size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
         | 
| @@ -1723,12 +1733,12 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( | |
| 1723 1733 |  | 
| 1724 1734 | 
             
                size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
         | 
| 1725 1735 | 
             
                size_t const externalSeqSpace = useSequenceProducer
         | 
| 1726 | 
            -
                    ?  | 
| 1736 | 
            +
                    ? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
         | 
| 1727 1737 | 
             
                    : 0;
         | 
| 1728 1738 |  | 
| 1729 1739 | 
             
                size_t const neededSpace =
         | 
| 1730 1740 | 
             
                    cctxSpace +
         | 
| 1731 | 
            -
                     | 
| 1741 | 
            +
                    tmpWorkSpace +
         | 
| 1732 1742 | 
             
                    blockStateSpace +
         | 
| 1733 1743 | 
             
                    ldmSpace +
         | 
| 1734 1744 | 
             
                    ldmSeqSpace +
         | 
| @@ -1745,7 +1755,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) | |
| 1745 1755 | 
             
            {
         | 
| 1746 1756 | 
             
                ZSTD_compressionParameters const cParams =
         | 
| 1747 1757 | 
             
                            ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
         | 
| 1748 | 
            -
                 | 
| 1758 | 
            +
                ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
         | 
| 1749 1759 | 
             
                                                                                           &cParams);
         | 
| 1750 1760 |  | 
| 1751 1761 | 
             
                RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
         | 
| @@ -1810,7 +1820,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params) | |
| 1810 1820 | 
             
                    size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
         | 
| 1811 1821 | 
             
                            ? ZSTD_compressBound(blockSize) + 1
         | 
| 1812 1822 | 
             
                            : 0;
         | 
| 1813 | 
            -
                     | 
| 1823 | 
            +
                    ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams);
         | 
| 1814 1824 |  | 
| 1815 1825 | 
             
                    return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
         | 
| 1816 1826 | 
             
                        &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
         | 
| @@ -1920,7 +1930,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) | |
| 1920 1930 | 
             
             *  Invalidate all the matches in the match finder tables.
         | 
| 1921 1931 | 
             
             *  Requires nextSrc and base to be set (can be NULL).
         | 
| 1922 1932 | 
             
             */
         | 
| 1923 | 
            -
            static void ZSTD_invalidateMatchState( | 
| 1933 | 
            +
            static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms)
         | 
| 1924 1934 | 
             
            {
         | 
| 1925 1935 | 
             
                ZSTD_window_clear(&ms->window);
         | 
| 1926 1936 |  | 
| @@ -1967,15 +1977,15 @@ static U64 ZSTD_bitmix(U64 val, U64 len) { | |
| 1967 1977 | 
             
            }
         | 
| 1968 1978 |  | 
| 1969 1979 | 
             
            /* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */
         | 
| 1970 | 
            -
            static void ZSTD_advanceHashSalt( | 
| 1980 | 
            +
            static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) {
         | 
| 1971 1981 | 
             
                ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4);
         | 
| 1972 1982 | 
             
            }
         | 
| 1973 1983 |  | 
| 1974 1984 | 
             
            static size_t
         | 
| 1975 | 
            -
            ZSTD_reset_matchState( | 
| 1985 | 
            +
            ZSTD_reset_matchState(ZSTD_MatchState_t* ms,
         | 
| 1976 1986 | 
             
                                  ZSTD_cwksp* ws,
         | 
| 1977 1987 | 
             
                            const ZSTD_compressionParameters* cParams,
         | 
| 1978 | 
            -
                            const  | 
| 1988 | 
            +
                            const ZSTD_ParamSwitch_e useRowMatchFinder,
         | 
| 1979 1989 | 
             
                            const ZSTD_compResetPolicy_e crp,
         | 
| 1980 1990 | 
             
                            const ZSTD_indexResetPolicy_e forceResetIndex,
         | 
| 1981 1991 | 
             
                            const ZSTD_resetTarget_e forWho)
         | 
| @@ -2029,7 +2039,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, | |
| 2029 2039 | 
             
                        ZSTD_advanceHashSalt(ms);
         | 
| 2030 2040 | 
             
                    } else {
         | 
| 2031 2041 | 
             
                        /* When we are not salting we want to always memset the memory */
         | 
| 2032 | 
            -
                        ms->tagTable = (BYTE*)  | 
| 2042 | 
            +
                        ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned64(ws, tagTableSize);
         | 
| 2033 2043 | 
             
                        ZSTD_memset(ms->tagTable, 0, tagTableSize);
         | 
| 2034 2044 | 
             
                        ms->hashSalt = 0;
         | 
| 2035 2045 | 
             
                    }
         | 
| @@ -2043,12 +2053,12 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, | |
| 2043 2053 | 
             
                /* opt parser space */
         | 
| 2044 2054 | 
             
                if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
         | 
| 2045 2055 | 
             
                    DEBUGLOG(4, "reserving optimal parser space");
         | 
| 2046 | 
            -
                    ms->opt.litFreq = (unsigned*) | 
| 2047 | 
            -
                    ms->opt.litLengthFreq = (unsigned*) | 
| 2048 | 
            -
                    ms->opt.matchLengthFreq = (unsigned*) | 
| 2049 | 
            -
                    ms->opt.offCodeFreq = (unsigned*) | 
| 2050 | 
            -
                    ms->opt.matchTable = (ZSTD_match_t*) | 
| 2051 | 
            -
                    ms->opt.priceTable = (ZSTD_optimal_t*) | 
| 2056 | 
            +
                    ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (1<<Litbits) * sizeof(unsigned));
         | 
| 2057 | 
            +
                    ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxLL+1) * sizeof(unsigned));
         | 
| 2058 | 
            +
                    ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxML+1) * sizeof(unsigned));
         | 
| 2059 | 
            +
                    ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxOff+1) * sizeof(unsigned));
         | 
| 2060 | 
            +
                    ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t));
         | 
| 2061 | 
            +
                    ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
         | 
| 2052 2062 | 
             
                }
         | 
| 2053 2063 |  | 
| 2054 2064 | 
             
                ms->cParams = *cParams;
         | 
| @@ -2096,7 +2106,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 2096 2106 | 
             
            {
         | 
| 2097 2107 | 
             
                ZSTD_cwksp* const ws = &zc->workspace;
         | 
| 2098 2108 | 
             
                DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d",
         | 
| 2099 | 
            -
                            (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params-> | 
| 2109 | 
            +
                            (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->postBlockSplitter);
         | 
| 2100 2110 | 
             
                assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
         | 
| 2101 2111 |  | 
| 2102 2112 | 
             
                zc->isFirstBlock = 1;
         | 
| @@ -2108,7 +2118,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 2108 2118 | 
             
                params = &zc->appliedParams;
         | 
| 2109 2119 |  | 
| 2110 2120 | 
             
                assert(params->useRowMatchFinder != ZSTD_ps_auto);
         | 
| 2111 | 
            -
                assert(params-> | 
| 2121 | 
            +
                assert(params->postBlockSplitter != ZSTD_ps_auto);
         | 
| 2112 2122 | 
             
                assert(params->ldmParams.enableLdm != ZSTD_ps_auto);
         | 
| 2113 2123 | 
             
                assert(params->maxBlockSize != 0);
         | 
| 2114 2124 | 
             
                if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
         | 
| @@ -2164,15 +2174,16 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 2164 2174 |  | 
| 2165 2175 | 
             
                            DEBUGLOG(5, "reserving object space");
         | 
| 2166 2176 | 
             
                            /* Statically sized space.
         | 
| 2167 | 
            -
                             *  | 
| 2177 | 
            +
                             * tmpWorkspace never moves,
         | 
| 2168 2178 | 
             
                             * though prev/next block swap places */
         | 
| 2169 2179 | 
             
                            assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t)));
         | 
| 2170 2180 | 
             
                            zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
         | 
| 2171 2181 | 
             
                            RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
         | 
| 2172 2182 | 
             
                            zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
         | 
| 2173 2183 | 
             
                            RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
         | 
| 2174 | 
            -
                            zc-> | 
| 2175 | 
            -
                            RETURN_ERROR_IF(zc-> | 
| 2184 | 
            +
                            zc->tmpWorkspace = ZSTD_cwksp_reserve_object(ws, TMP_WORKSPACE_SIZE);
         | 
| 2185 | 
            +
                            RETURN_ERROR_IF(zc->tmpWorkspace == NULL, memory_allocation, "couldn't allocate tmpWorkspace");
         | 
| 2186 | 
            +
                            zc->tmpWkspSize = TMP_WORKSPACE_SIZE;
         | 
| 2176 2187 | 
             
                    }   }
         | 
| 2177 2188 |  | 
| 2178 2189 | 
             
                    ZSTD_cwksp_clear(ws);
         | 
| @@ -2187,7 +2198,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 2187 2198 | 
             
                        zc->appliedParams.fParams.contentSizeFlag = 0;
         | 
| 2188 2199 | 
             
                    DEBUGLOG(4, "pledged content size : %u ; flag : %u",
         | 
| 2189 2200 | 
             
                        (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
         | 
| 2190 | 
            -
                    zc-> | 
| 2201 | 
            +
                    zc->blockSizeMax = blockSize;
         | 
| 2191 2202 |  | 
| 2192 2203 | 
             
                    XXH64_reset(&zc->xxhState, 0);
         | 
| 2193 2204 | 
             
                    zc->stage = ZSTDcs_init;
         | 
| @@ -2205,15 +2216,15 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 2205 2216 | 
             
                            needsIndexReset,
         | 
| 2206 2217 | 
             
                            ZSTD_resetTarget_CCtx), "");
         | 
| 2207 2218 |  | 
| 2208 | 
            -
                    zc->seqStore.sequencesStart = ( | 
| 2219 | 
            +
                    zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef));
         | 
| 2209 2220 |  | 
| 2210 2221 | 
             
                    /* ldm hash table */
         | 
| 2211 2222 | 
             
                    if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
         | 
| 2212 2223 | 
             
                        /* TODO: avoid memset? */
         | 
| 2213 2224 | 
             
                        size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog;
         | 
| 2214 | 
            -
                        zc->ldmState.hashTable = (ldmEntry_t*) | 
| 2225 | 
            +
                        zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t));
         | 
| 2215 2226 | 
             
                        ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
         | 
| 2216 | 
            -
                        zc->ldmSequences = (rawSeq*) | 
| 2227 | 
            +
                        zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq));
         | 
| 2217 2228 | 
             
                        zc->maxNbLdmSequences = maxNbLdmSeq;
         | 
| 2218 2229 |  | 
| 2219 2230 | 
             
                        ZSTD_window_init(&zc->ldmState.window);
         | 
| @@ -2225,7 +2236,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 2225 2236 | 
             
                        size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
         | 
| 2226 2237 | 
             
                        zc->extSeqBufCapacity = maxNbExternalSeq;
         | 
| 2227 2238 | 
             
                        zc->extSeqBuf =
         | 
| 2228 | 
            -
                            (ZSTD_Sequence*) | 
| 2239 | 
            +
                            (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
         | 
| 2229 2240 | 
             
                    }
         | 
| 2230 2241 |  | 
| 2231 2242 | 
             
                    /* buffers */
         | 
| @@ -2444,7 +2455,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, | |
| 2444 2455 | 
             
                }
         | 
| 2445 2456 |  | 
| 2446 2457 | 
             
                /* Zero the hashTable3, since the cdict never fills it */
         | 
| 2447 | 
            -
                 | 
| 2458 | 
            +
                assert(cctx->blockState.matchState.hashLog3 <= 31);
         | 
| 2459 | 
            +
                {   U32 const h3log = cctx->blockState.matchState.hashLog3;
         | 
| 2448 2460 | 
             
                    size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
         | 
| 2449 2461 | 
             
                    assert(cdict->matchState.hashLog3 == 0);
         | 
| 2450 2462 | 
             
                    ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
         | 
| @@ -2453,8 +2465,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, | |
| 2453 2465 | 
             
                ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
         | 
| 2454 2466 |  | 
| 2455 2467 | 
             
                /* copy dictionary offsets */
         | 
| 2456 | 
            -
                {    | 
| 2457 | 
            -
                     | 
| 2468 | 
            +
                {   ZSTD_MatchState_t const* srcMatchState = &cdict->matchState;
         | 
| 2469 | 
            +
                    ZSTD_MatchState_t* dstMatchState = &cctx->blockState.matchState;
         | 
| 2458 2470 | 
             
                    dstMatchState->window       = srcMatchState->window;
         | 
| 2459 2471 | 
             
                    dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
         | 
| 2460 2472 | 
             
                    dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
         | 
| @@ -2512,10 +2524,10 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, | |
| 2512 2524 | 
             
                    /* Copy only compression parameters related to tables. */
         | 
| 2513 2525 | 
             
                    params.cParams = srcCCtx->appliedParams.cParams;
         | 
| 2514 2526 | 
             
                    assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto);
         | 
| 2515 | 
            -
                    assert(srcCCtx->appliedParams. | 
| 2527 | 
            +
                    assert(srcCCtx->appliedParams.postBlockSplitter != ZSTD_ps_auto);
         | 
| 2516 2528 | 
             
                    assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto);
         | 
| 2517 2529 | 
             
                    params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder;
         | 
| 2518 | 
            -
                    params. | 
| 2530 | 
            +
                    params.postBlockSplitter = srcCCtx->appliedParams.postBlockSplitter;
         | 
| 2519 2531 | 
             
                    params.ldmParams = srcCCtx->appliedParams.ldmParams;
         | 
| 2520 2532 | 
             
                    params.fParams = fParams;
         | 
| 2521 2533 | 
             
                    params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize;
         | 
| @@ -2538,7 +2550,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, | |
| 2538 2550 | 
             
                                                ? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog)
         | 
| 2539 2551 | 
             
                                                : 0;
         | 
| 2540 2552 | 
             
                    size_t const hSize =  (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
         | 
| 2541 | 
            -
                     | 
| 2553 | 
            +
                    U32 const h3log = srcCCtx->blockState.matchState.hashLog3;
         | 
| 2542 2554 | 
             
                    size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
         | 
| 2543 2555 |  | 
| 2544 2556 | 
             
                    ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable,
         | 
| @@ -2556,8 +2568,8 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, | |
| 2556 2568 |  | 
| 2557 2569 | 
             
                /* copy dictionary offsets */
         | 
| 2558 2570 | 
             
                {
         | 
| 2559 | 
            -
                    const  | 
| 2560 | 
            -
                     | 
| 2571 | 
            +
                    const ZSTD_MatchState_t* srcMatchState = &srcCCtx->blockState.matchState;
         | 
| 2572 | 
            +
                    ZSTD_MatchState_t* dstMatchState = &dstCCtx->blockState.matchState;
         | 
| 2561 2573 | 
             
                    dstMatchState->window       = srcMatchState->window;
         | 
| 2562 2574 | 
             
                    dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
         | 
| 2563 2575 | 
             
                    dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
         | 
| @@ -2606,7 +2618,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa | |
| 2606 2618 | 
             
                /* Protect special index values < ZSTD_WINDOW_START_INDEX. */
         | 
| 2607 2619 | 
             
                U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX;
         | 
| 2608 2620 | 
             
                assert((size & (ZSTD_ROWSIZE-1)) == 0);  /* multiple of ZSTD_ROWSIZE */
         | 
| 2609 | 
            -
                assert(size < (1U<<31));   /* can be  | 
| 2621 | 
            +
                assert(size < (1U<<31));   /* can be cast to int */
         | 
| 2610 2622 |  | 
| 2611 2623 | 
             
            #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
         | 
| 2612 2624 | 
             
                /* To validate that the table reuse logic is sound, and that we don't
         | 
| @@ -2651,7 +2663,7 @@ static void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const | |
| 2651 2663 |  | 
| 2652 2664 | 
             
            /*! ZSTD_reduceIndex() :
         | 
| 2653 2665 | 
             
            *   rescale all indexes to avoid future overflow (indexes are U32) */
         | 
| 2654 | 
            -
            static void ZSTD_reduceIndex ( | 
| 2666 | 
            +
            static void ZSTD_reduceIndex (ZSTD_MatchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
         | 
| 2655 2667 | 
             
            {
         | 
| 2656 2668 | 
             
                {   U32 const hSize = (U32)1 << params->cParams.hashLog;
         | 
| 2657 2669 | 
             
                    ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
         | 
| @@ -2678,9 +2690,9 @@ static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* par | |
| 2678 2690 |  | 
| 2679 2691 | 
             
            /* See doc/zstd_compression_format.md for detailed format description */
         | 
| 2680 2692 |  | 
| 2681 | 
            -
            int ZSTD_seqToCodes(const  | 
| 2693 | 
            +
            int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr)
         | 
| 2682 2694 | 
             
            {
         | 
| 2683 | 
            -
                const  | 
| 2695 | 
            +
                const SeqDef* const sequences = seqStorePtr->sequencesStart;
         | 
| 2684 2696 | 
             
                BYTE* const llCodeTable = seqStorePtr->llCode;
         | 
| 2685 2697 | 
             
                BYTE* const ofCodeTable = seqStorePtr->ofCode;
         | 
| 2686 2698 | 
             
                BYTE* const mlCodeTable = seqStorePtr->mlCode;
         | 
| @@ -2723,9 +2735,9 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) | |
| 2723 2735 | 
             
             * Returns 1 if true, 0 otherwise. */
         | 
| 2724 2736 | 
             
            static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams)
         | 
| 2725 2737 | 
             
            {
         | 
| 2726 | 
            -
                DEBUGLOG(5, "ZSTD_blockSplitterEnabled ( | 
| 2727 | 
            -
                assert(cctxParams-> | 
| 2728 | 
            -
                return (cctxParams-> | 
| 2738 | 
            +
                DEBUGLOG(5, "ZSTD_blockSplitterEnabled (postBlockSplitter=%d)", cctxParams->postBlockSplitter);
         | 
| 2739 | 
            +
                assert(cctxParams->postBlockSplitter != ZSTD_ps_auto);
         | 
| 2740 | 
            +
                return (cctxParams->postBlockSplitter == ZSTD_ps_enable);
         | 
| 2729 2741 | 
             
            }
         | 
| 2730 2742 |  | 
| 2731 2743 | 
             
            /* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types
         | 
| @@ -2749,7 +2761,7 @@ typedef struct { | |
| 2749 2761 | 
             
             */
         | 
| 2750 2762 | 
             
            static ZSTD_symbolEncodingTypeStats_t
         | 
| 2751 2763 | 
             
            ZSTD_buildSequencesStatistics(
         | 
| 2752 | 
            -
                            const  | 
| 2764 | 
            +
                            const SeqStore_t* seqStorePtr, size_t nbSeq,
         | 
| 2753 2765 | 
             
                            const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy,
         | 
| 2754 2766 | 
             
                                  BYTE* dst, const BYTE* const dstEnd,
         | 
| 2755 2767 | 
             
                                  ZSTD_strategy strategy, unsigned* countWorkspace,
         | 
| @@ -2785,7 +2797,7 @@ ZSTD_buildSequencesStatistics( | |
| 2785 2797 | 
             
                    assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
         | 
| 2786 2798 | 
             
                    {   size_t const countSize = ZSTD_buildCTable(
         | 
| 2787 2799 | 
             
                            op, (size_t)(oend - op),
         | 
| 2788 | 
            -
                            CTable_LitLength, LLFSELog, ( | 
| 2800 | 
            +
                            CTable_LitLength, LLFSELog, (SymbolEncodingType_e)stats.LLtype,
         | 
| 2789 2801 | 
             
                            countWorkspace, max, llCodeTable, nbSeq,
         | 
| 2790 2802 | 
             
                            LL_defaultNorm, LL_defaultNormLog, MaxLL,
         | 
| 2791 2803 | 
             
                            prevEntropy->litlengthCTable,
         | 
| @@ -2806,7 +2818,7 @@ ZSTD_buildSequencesStatistics( | |
| 2806 2818 | 
             
                    size_t const mostFrequent = HIST_countFast_wksp(
         | 
| 2807 2819 | 
             
                        countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize);  /* can't fail */
         | 
| 2808 2820 | 
             
                    /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
         | 
| 2809 | 
            -
                     | 
| 2821 | 
            +
                    ZSTD_DefaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
         | 
| 2810 2822 | 
             
                    DEBUGLOG(5, "Building OF table");
         | 
| 2811 2823 | 
             
                    nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
         | 
| 2812 2824 | 
             
                    stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
         | 
| @@ -2817,7 +2829,7 @@ ZSTD_buildSequencesStatistics( | |
| 2817 2829 | 
             
                    assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
         | 
| 2818 2830 | 
             
                    {   size_t const countSize = ZSTD_buildCTable(
         | 
| 2819 2831 | 
             
                            op, (size_t)(oend - op),
         | 
| 2820 | 
            -
                            CTable_OffsetBits, OffFSELog, ( | 
| 2832 | 
            +
                            CTable_OffsetBits, OffFSELog, (SymbolEncodingType_e)stats.Offtype,
         | 
| 2821 2833 | 
             
                            countWorkspace, max, ofCodeTable, nbSeq,
         | 
| 2822 2834 | 
             
                            OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
         | 
| 2823 2835 | 
             
                            prevEntropy->offcodeCTable,
         | 
| @@ -2847,7 +2859,7 @@ ZSTD_buildSequencesStatistics( | |
| 2847 2859 | 
             
                    assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
         | 
| 2848 2860 | 
             
                    {   size_t const countSize = ZSTD_buildCTable(
         | 
| 2849 2861 | 
             
                            op, (size_t)(oend - op),
         | 
| 2850 | 
            -
                            CTable_MatchLength, MLFSELog, ( | 
| 2862 | 
            +
                            CTable_MatchLength, MLFSELog, (SymbolEncodingType_e)stats.MLtype,
         | 
| 2851 2863 | 
             
                            countWorkspace, max, mlCodeTable, nbSeq,
         | 
| 2852 2864 | 
             
                            ML_defaultNorm, ML_defaultNormLog, MaxML,
         | 
| 2853 2865 | 
             
                            prevEntropy->matchlengthCTable,
         | 
| @@ -2874,11 +2886,12 @@ ZSTD_buildSequencesStatistics( | |
| 2874 2886 | 
             
            #define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20
         | 
| 2875 2887 | 
             
            MEM_STATIC size_t
         | 
| 2876 2888 | 
             
            ZSTD_entropyCompressSeqStore_internal(
         | 
| 2877 | 
            -
             | 
| 2889 | 
            +
                                          void* dst, size_t dstCapacity,
         | 
| 2890 | 
            +
                                    const void* literals, size_t litSize,
         | 
| 2891 | 
            +
                                    const SeqStore_t* seqStorePtr,
         | 
| 2878 2892 | 
             
                                    const ZSTD_entropyCTables_t* prevEntropy,
         | 
| 2879 2893 | 
             
                                          ZSTD_entropyCTables_t* nextEntropy,
         | 
| 2880 2894 | 
             
                                    const ZSTD_CCtx_params* cctxParams,
         | 
| 2881 | 
            -
                                          void* dst, size_t dstCapacity,
         | 
| 2882 2895 | 
             
                                          void* entropyWorkspace, size_t entropyWkspSize,
         | 
| 2883 2896 | 
             
                                    const int bmi2)
         | 
| 2884 2897 | 
             
            {
         | 
| @@ -2887,7 +2900,7 @@ ZSTD_entropyCompressSeqStore_internal( | |
| 2887 2900 | 
             
                FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
         | 
| 2888 2901 | 
             
                FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
         | 
| 2889 2902 | 
             
                FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
         | 
| 2890 | 
            -
                const  | 
| 2903 | 
            +
                const SeqDef* const sequences = seqStorePtr->sequencesStart;
         | 
| 2891 2904 | 
             
                const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
         | 
| 2892 2905 | 
             
                const BYTE* const ofCodeTable = seqStorePtr->ofCode;
         | 
| 2893 2906 | 
             
                const BYTE* const llCodeTable = seqStorePtr->llCode;
         | 
| @@ -2906,12 +2919,9 @@ ZSTD_entropyCompressSeqStore_internal( | |
| 2906 2919 | 
             
                assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
         | 
| 2907 2920 |  | 
| 2908 2921 | 
             
                /* Compress literals */
         | 
| 2909 | 
            -
                {    | 
| 2910 | 
            -
                    size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
         | 
| 2911 | 
            -
                    size_t const numLiterals = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
         | 
| 2922 | 
            +
                {   size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
         | 
| 2912 2923 | 
             
                    /* Base suspicion of uncompressibility on ratio of literals to sequences */
         | 
| 2913 | 
            -
                     | 
| 2914 | 
            -
                    size_t const litSize = (size_t)(seqStorePtr->lit - literals);
         | 
| 2924 | 
            +
                    int const suspectUncompressible = (numSequences == 0) || (litSize / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
         | 
| 2915 2925 |  | 
| 2916 2926 | 
             
                    size_t const cSize = ZSTD_compressLiterals(
         | 
| 2917 2927 | 
             
                                                op, dstCapacity,
         | 
| @@ -2992,33 +3002,35 @@ ZSTD_entropyCompressSeqStore_internal( | |
| 2992 3002 | 
             
                return (size_t)(op - ostart);
         | 
| 2993 3003 | 
             
            }
         | 
| 2994 3004 |  | 
| 2995 | 
            -
             | 
| 2996 | 
            -
             | 
| 2997 | 
            -
             | 
| 3005 | 
            +
            static size_t
         | 
| 3006 | 
            +
            ZSTD_entropyCompressSeqStore_wExtLitBuffer(
         | 
| 3007 | 
            +
                                      void* dst, size_t dstCapacity,
         | 
| 3008 | 
            +
                                const void* literals, size_t litSize,
         | 
| 3009 | 
            +
                                      size_t blockSize,
         | 
| 3010 | 
            +
                                const SeqStore_t* seqStorePtr,
         | 
| 2998 3011 | 
             
                                const ZSTD_entropyCTables_t* prevEntropy,
         | 
| 2999 3012 | 
             
                                      ZSTD_entropyCTables_t* nextEntropy,
         | 
| 3000 3013 | 
             
                                const ZSTD_CCtx_params* cctxParams,
         | 
| 3001 | 
            -
                                      void* dst, size_t dstCapacity,
         | 
| 3002 | 
            -
                                      size_t srcSize,
         | 
| 3003 3014 | 
             
                                      void* entropyWorkspace, size_t entropyWkspSize,
         | 
| 3004 3015 | 
             
                                      int bmi2)
         | 
| 3005 3016 | 
             
            {
         | 
| 3006 3017 | 
             
                size_t const cSize = ZSTD_entropyCompressSeqStore_internal(
         | 
| 3007 | 
            -
                                        seqStorePtr, prevEntropy, nextEntropy, cctxParams,
         | 
| 3008 3018 | 
             
                                        dst, dstCapacity,
         | 
| 3019 | 
            +
                                        literals, litSize,
         | 
| 3020 | 
            +
                                        seqStorePtr, prevEntropy, nextEntropy, cctxParams,
         | 
| 3009 3021 | 
             
                                        entropyWorkspace, entropyWkspSize, bmi2);
         | 
| 3010 3022 | 
             
                if (cSize == 0) return 0;
         | 
| 3011 3023 | 
             
                /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
         | 
| 3012 3024 | 
             
                 * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
         | 
| 3013 3025 | 
             
                 */
         | 
| 3014 | 
            -
                if ((cSize == ERROR(dstSize_tooSmall)) & ( | 
| 3026 | 
            +
                if ((cSize == ERROR(dstSize_tooSmall)) & (blockSize <= dstCapacity)) {
         | 
| 3015 3027 | 
             
                    DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity);
         | 
| 3016 3028 | 
             
                    return 0;  /* block not compressed */
         | 
| 3017 3029 | 
             
                }
         | 
| 3018 3030 | 
             
                FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed");
         | 
| 3019 3031 |  | 
| 3020 3032 | 
             
                /* Check compressibility */
         | 
| 3021 | 
            -
                {   size_t const maxCSize =  | 
| 3033 | 
            +
                {   size_t const maxCSize = blockSize - ZSTD_minGain(blockSize, cctxParams->cParams.strategy);
         | 
| 3022 3034 | 
             
                    if (cSize >= maxCSize) return 0;  /* block not compressed */
         | 
| 3023 3035 | 
             
                }
         | 
| 3024 3036 | 
             
                DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize);
         | 
| @@ -3029,12 +3041,34 @@ ZSTD_entropyCompressSeqStore( | |
| 3029 3041 | 
             
                return cSize;
         | 
| 3030 3042 | 
             
            }
         | 
| 3031 3043 |  | 
| 3044 | 
            +
            static size_t
         | 
| 3045 | 
            +
            ZSTD_entropyCompressSeqStore(
         | 
| 3046 | 
            +
                                const SeqStore_t* seqStorePtr,
         | 
| 3047 | 
            +
                                const ZSTD_entropyCTables_t* prevEntropy,
         | 
| 3048 | 
            +
                                      ZSTD_entropyCTables_t* nextEntropy,
         | 
| 3049 | 
            +
                                const ZSTD_CCtx_params* cctxParams,
         | 
| 3050 | 
            +
                                      void* dst, size_t dstCapacity,
         | 
| 3051 | 
            +
                                      size_t srcSize,
         | 
| 3052 | 
            +
                                      void* entropyWorkspace, size_t entropyWkspSize,
         | 
| 3053 | 
            +
                                      int bmi2)
         | 
| 3054 | 
            +
            {
         | 
| 3055 | 
            +
                return ZSTD_entropyCompressSeqStore_wExtLitBuffer(
         | 
| 3056 | 
            +
                            dst, dstCapacity,
         | 
| 3057 | 
            +
                            seqStorePtr->litStart, (size_t)(seqStorePtr->lit - seqStorePtr->litStart),
         | 
| 3058 | 
            +
                            srcSize,
         | 
| 3059 | 
            +
                            seqStorePtr,
         | 
| 3060 | 
            +
                            prevEntropy, nextEntropy,
         | 
| 3061 | 
            +
                            cctxParams,
         | 
| 3062 | 
            +
                            entropyWorkspace, entropyWkspSize,
         | 
| 3063 | 
            +
                            bmi2);
         | 
| 3064 | 
            +
            }
         | 
| 3065 | 
            +
             | 
| 3032 3066 | 
             
            /* ZSTD_selectBlockCompressor() :
         | 
| 3033 3067 | 
             
             * Not static, but internal use only (used by long distance matcher)
         | 
| 3034 3068 | 
             
             * assumption : strat is a valid strategy */
         | 
| 3035 | 
            -
             | 
| 3069 | 
            +
            ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
         | 
| 3036 3070 | 
             
            {
         | 
| 3037 | 
            -
                static const  | 
| 3071 | 
            +
                static const ZSTD_BlockCompressor_f blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
         | 
| 3038 3072 | 
             
                    { ZSTD_compressBlock_fast  /* default for 0 */,
         | 
| 3039 3073 | 
             
                      ZSTD_compressBlock_fast,
         | 
| 3040 3074 | 
             
                      ZSTD_COMPRESSBLOCK_DOUBLEFAST,
         | 
| @@ -3079,13 +3113,13 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS | |
| 3079 3113 | 
             
                      NULL,
         | 
| 3080 3114 | 
             
                      NULL }
         | 
| 3081 3115 | 
             
                };
         | 
| 3082 | 
            -
                 | 
| 3116 | 
            +
                ZSTD_BlockCompressor_f selectedCompressor;
         | 
| 3083 3117 | 
             
                ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
         | 
| 3084 3118 |  | 
| 3085 | 
            -
                assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
         | 
| 3086 | 
            -
                DEBUGLOG( | 
| 3119 | 
            +
                assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat));
         | 
| 3120 | 
            +
                DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder);
         | 
| 3087 3121 | 
             
                if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) {
         | 
| 3088 | 
            -
                    static const  | 
| 3122 | 
            +
                    static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = {
         | 
| 3089 3123 | 
             
                        {
         | 
| 3090 3124 | 
             
                            ZSTD_COMPRESSBLOCK_GREEDY_ROW,
         | 
| 3091 3125 | 
             
                            ZSTD_COMPRESSBLOCK_LAZY_ROW,
         | 
| @@ -3107,7 +3141,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS | |
| 3107 3141 | 
             
                            ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW
         | 
| 3108 3142 | 
             
                        }
         | 
| 3109 3143 | 
             
                    };
         | 
| 3110 | 
            -
                    DEBUGLOG( | 
| 3144 | 
            +
                    DEBUGLOG(5, "Selecting a row-based matchfinder");
         | 
| 3111 3145 | 
             
                    assert(useRowMatchFinder != ZSTD_ps_auto);
         | 
| 3112 3146 | 
             
                    selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy];
         | 
| 3113 3147 | 
             
                } else {
         | 
| @@ -3117,14 +3151,14 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS | |
| 3117 3151 | 
             
                return selectedCompressor;
         | 
| 3118 3152 | 
             
            }
         | 
| 3119 3153 |  | 
| 3120 | 
            -
            static void ZSTD_storeLastLiterals( | 
| 3154 | 
            +
            static void ZSTD_storeLastLiterals(SeqStore_t* seqStorePtr,
         | 
| 3121 3155 | 
             
                                               const BYTE* anchor, size_t lastLLSize)
         | 
| 3122 3156 | 
             
            {
         | 
| 3123 3157 | 
             
                ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize);
         | 
| 3124 3158 | 
             
                seqStorePtr->lit += lastLLSize;
         | 
| 3125 3159 | 
             
            }
         | 
| 3126 3160 |  | 
| 3127 | 
            -
            void ZSTD_resetSeqStore( | 
| 3161 | 
            +
            void ZSTD_resetSeqStore(SeqStore_t* ssPtr)
         | 
| 3128 3162 | 
             
            {
         | 
| 3129 3163 | 
             
                ssPtr->lit = ssPtr->litStart;
         | 
| 3130 3164 | 
             
                ssPtr->sequences = ssPtr->sequencesStart;
         | 
| @@ -3197,11 +3231,39 @@ static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seq | |
| 3197 3231 | 
             
                return litLenSum + matchLenSum;
         | 
| 3198 3232 | 
             
            }
         | 
| 3199 3233 |  | 
| 3200 | 
            -
             | 
| 3234 | 
            +
            /**
         | 
| 3235 | 
            +
             * Function to validate sequences produced by a block compressor.
         | 
| 3236 | 
            +
             */
         | 
| 3237 | 
            +
            static void ZSTD_validateSeqStore(const SeqStore_t* seqStore, const ZSTD_compressionParameters* cParams)
         | 
| 3238 | 
            +
            {
         | 
| 3239 | 
            +
            #if DEBUGLEVEL >= 1
         | 
| 3240 | 
            +
                const SeqDef* seq = seqStore->sequencesStart;
         | 
| 3241 | 
            +
                const SeqDef* const seqEnd = seqStore->sequences;
         | 
| 3242 | 
            +
                size_t const matchLenLowerBound = cParams->minMatch == 3 ? 3 : 4;
         | 
| 3243 | 
            +
                for (; seq < seqEnd; ++seq) {
         | 
| 3244 | 
            +
                    const ZSTD_SequenceLength seqLength = ZSTD_getSequenceLength(seqStore, seq);
         | 
| 3245 | 
            +
                    assert(seqLength.matchLength >= matchLenLowerBound);
         | 
| 3246 | 
            +
                    (void)seqLength;
         | 
| 3247 | 
            +
                    (void)matchLenLowerBound;
         | 
| 3248 | 
            +
                }
         | 
| 3249 | 
            +
            #else
         | 
| 3250 | 
            +
                (void)seqStore;
         | 
| 3251 | 
            +
                (void)cParams;
         | 
| 3252 | 
            +
            #endif
         | 
| 3253 | 
            +
            }
         | 
| 3254 | 
            +
             | 
| 3255 | 
            +
            static size_t
         | 
| 3256 | 
            +
            ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx,
         | 
| 3257 | 
            +
                                               ZSTD_SequencePosition* seqPos,
         | 
| 3258 | 
            +
                                         const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         | 
| 3259 | 
            +
                                         const void* src, size_t blockSize,
         | 
| 3260 | 
            +
                                               ZSTD_ParamSwitch_e externalRepSearch);
         | 
| 3261 | 
            +
             | 
| 3262 | 
            +
            typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_BuildSeqStore_e;
         | 
| 3201 3263 |  | 
| 3202 3264 | 
             
            static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
         | 
| 3203 3265 | 
             
            {
         | 
| 3204 | 
            -
                 | 
| 3266 | 
            +
                ZSTD_MatchState_t* const ms = &zc->blockState.matchState;
         | 
| 3205 3267 | 
             
                DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize);
         | 
| 3206 3268 | 
             
                assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
         | 
| 3207 3269 | 
             
                /* Assert that we have correctly flushed the ctx params into the ms's copy */
         | 
| @@ -3262,7 +3324,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) | |
| 3262 3324 | 
             
                                                   src, srcSize);
         | 
| 3263 3325 | 
             
                        assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
         | 
| 3264 3326 | 
             
                    } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
         | 
| 3265 | 
            -
                         | 
| 3327 | 
            +
                        RawSeqStore_t ldmSeqStore = kNullRawSeqStore;
         | 
| 3266 3328 |  | 
| 3267 3329 | 
             
                        /* External matchfinder + LDM is technically possible, just not implemented yet.
         | 
| 3268 3330 | 
             
                         * We need to revisit soon and implement it. */
         | 
| @@ -3313,11 +3375,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) | |
| 3313 3375 |  | 
| 3314 3376 | 
             
                            /* Return early if there is no error, since we don't need to worry about last literals */
         | 
| 3315 3377 | 
             
                            if (!ZSTD_isError(nbPostProcessedSeqs)) {
         | 
| 3316 | 
            -
                                 | 
| 3378 | 
            +
                                ZSTD_SequencePosition seqPos = {0,0,0};
         | 
| 3317 3379 | 
             
                                size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs);
         | 
| 3318 3380 | 
             
                                RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!");
         | 
| 3319 3381 | 
             
                                FORWARD_IF_ERROR(
         | 
| 3320 | 
            -
                                     | 
| 3382 | 
            +
                                    ZSTD_transferSequences_wBlockDelim(
         | 
| 3321 3383 | 
             
                                        zc, &seqPos,
         | 
| 3322 3384 | 
             
                                        zc->extSeqBuf, nbPostProcessedSeqs,
         | 
| 3323 3385 | 
             
                                        src, srcSize,
         | 
| @@ -3336,7 +3398,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) | |
| 3336 3398 | 
             
                            }
         | 
| 3337 3399 |  | 
| 3338 3400 | 
             
                            /* Fallback to software matchfinder */
         | 
| 3339 | 
            -
                            {    | 
| 3401 | 
            +
                            {   ZSTD_BlockCompressor_f const blockCompressor =
         | 
| 3340 3402 | 
             
                                    ZSTD_selectBlockCompressor(
         | 
| 3341 3403 | 
             
                                        zc->appliedParams.cParams.strategy,
         | 
| 3342 3404 | 
             
                                        zc->appliedParams.useRowMatchFinder,
         | 
| @@ -3350,7 +3412,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) | |
| 3350 3412 | 
             
                                lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
         | 
| 3351 3413 | 
             
                        }   }
         | 
| 3352 3414 | 
             
                    } else {   /* not long range mode and no external matchfinder */
         | 
| 3353 | 
            -
                         | 
| 3415 | 
            +
                        ZSTD_BlockCompressor_f const blockCompressor = ZSTD_selectBlockCompressor(
         | 
| 3354 3416 | 
             
                                zc->appliedParams.cParams.strategy,
         | 
| 3355 3417 | 
             
                                zc->appliedParams.useRowMatchFinder,
         | 
| 3356 3418 | 
             
                                dictMode);
         | 
| @@ -3360,19 +3422,20 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) | |
| 3360 3422 | 
             
                    {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
         | 
| 3361 3423 | 
             
                        ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
         | 
| 3362 3424 | 
             
                }   }
         | 
| 3425 | 
            +
                ZSTD_validateSeqStore(&zc->seqStore, &zc->appliedParams.cParams);
         | 
| 3363 3426 | 
             
                return ZSTDbss_compress;
         | 
| 3364 3427 | 
             
            }
         | 
| 3365 3428 |  | 
| 3366 | 
            -
            static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const  | 
| 3429 | 
            +
            static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM])
         | 
| 3367 3430 | 
             
            {
         | 
| 3368 | 
            -
                const  | 
| 3369 | 
            -
                const size_t nbInSequences = seqStore->sequences - inSeqs;
         | 
| 3431 | 
            +
                const SeqDef* inSeqs = seqStore->sequencesStart;
         | 
| 3432 | 
            +
                const size_t nbInSequences = (size_t)(seqStore->sequences - inSeqs);
         | 
| 3370 3433 | 
             
                const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart);
         | 
| 3371 3434 |  | 
| 3372 3435 | 
             
                ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex;
         | 
| 3373 3436 | 
             
                const size_t nbOutSequences = nbInSequences + 1;
         | 
| 3374 3437 | 
             
                size_t nbOutLiterals = 0;
         | 
| 3375 | 
            -
                 | 
| 3438 | 
            +
                Repcodes_t repcodes;
         | 
| 3376 3439 | 
             
                size_t i;
         | 
| 3377 3440 |  | 
| 3378 3441 | 
             
                /* Bounds check that we have enough space for every input sequence
         | 
| @@ -3458,7 +3521,7 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, | |
| 3458 3521 | 
             
                                          size_t outSeqsSize, const void* src, size_t srcSize)
         | 
| 3459 3522 | 
             
            {
         | 
| 3460 3523 | 
             
                const size_t dstCapacity = ZSTD_compressBound(srcSize);
         | 
| 3461 | 
            -
                void* dst  | 
| 3524 | 
            +
                void* dst; /* Make C90 happy. */
         | 
| 3462 3525 | 
             
                SeqCollector seqCollector;
         | 
| 3463 3526 | 
             
                {
         | 
| 3464 3527 | 
             
                    int targetCBlockSize;
         | 
| @@ -3471,6 +3534,7 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, | |
| 3471 3534 | 
             
                    RETURN_ERROR_IF(nbWorkers != 0, parameter_unsupported, "nbWorkers != 0");
         | 
| 3472 3535 | 
             
                }
         | 
| 3473 3536 |  | 
| 3537 | 
            +
                dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
         | 
| 3474 3538 | 
             
                RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
         | 
| 3475 3539 |  | 
| 3476 3540 | 
             
                seqCollector.collectSequences = 1;
         | 
| @@ -3531,7 +3595,7 @@ static int ZSTD_isRLE(const BYTE* src, size_t length) { | |
| 3531 3595 | 
             
             * This is just a heuristic based on the compressibility.
         | 
| 3532 3596 | 
             
             * It may return both false positives and false negatives.
         | 
| 3533 3597 | 
             
             */
         | 
| 3534 | 
            -
            static int ZSTD_maybeRLE( | 
| 3598 | 
            +
            static int ZSTD_maybeRLE(SeqStore_t const* seqStore)
         | 
| 3535 3599 | 
             
            {
         | 
| 3536 3600 | 
             
                size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
         | 
| 3537 3601 | 
             
                size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart);
         | 
| @@ -3555,7 +3619,7 @@ writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock) | |
| 3555 3619 | 
             
                                    lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
         | 
| 3556 3620 | 
             
                                    lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
         | 
| 3557 3621 | 
             
                MEM_writeLE24(op, cBlockHeader);
         | 
| 3558 | 
            -
                DEBUGLOG( | 
| 3622 | 
            +
                DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
         | 
| 3559 3623 | 
             
            }
         | 
| 3560 3624 |  | 
| 3561 3625 | 
             
            /** ZSTD_buildBlockEntropyStats_literals() :
         | 
| @@ -3693,7 +3757,7 @@ ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) | |
| 3693 3757 | 
             
             * @return : size of fse tables or error code */
         | 
| 3694 3758 | 
             
            static size_t
         | 
| 3695 3759 | 
             
            ZSTD_buildBlockEntropyStats_sequences(
         | 
| 3696 | 
            -
                            const  | 
| 3760 | 
            +
                            const SeqStore_t* seqStorePtr,
         | 
| 3697 3761 | 
             
                            const ZSTD_fseCTables_t* prevEntropy,
         | 
| 3698 3762 | 
             
                                  ZSTD_fseCTables_t* nextEntropy,
         | 
| 3699 3763 | 
             
                            const ZSTD_CCtx_params* cctxParams,
         | 
| @@ -3717,9 +3781,9 @@ ZSTD_buildBlockEntropyStats_sequences( | |
| 3717 3781 | 
             
                                                      entropyWorkspace, entropyWorkspaceSize)
         | 
| 3718 3782 | 
             
                                   : ZSTD_buildDummySequencesStatistics(nextEntropy);
         | 
| 3719 3783 | 
             
                FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
         | 
| 3720 | 
            -
                fseMetadata->llType = ( | 
| 3721 | 
            -
                fseMetadata->ofType = ( | 
| 3722 | 
            -
                fseMetadata->mlType = ( | 
| 3784 | 
            +
                fseMetadata->llType = (SymbolEncodingType_e) stats.LLtype;
         | 
| 3785 | 
            +
                fseMetadata->ofType = (SymbolEncodingType_e) stats.Offtype;
         | 
| 3786 | 
            +
                fseMetadata->mlType = (SymbolEncodingType_e) stats.MLtype;
         | 
| 3723 3787 | 
             
                fseMetadata->lastCountSize = stats.lastCountSize;
         | 
| 3724 3788 | 
             
                return stats.size;
         | 
| 3725 3789 | 
             
            }
         | 
| @@ -3732,7 +3796,7 @@ ZSTD_buildBlockEntropyStats_sequences( | |
| 3732 3796 | 
             
             *  Note : also employed in superblock
         | 
| 3733 3797 | 
             
             */
         | 
| 3734 3798 | 
             
            size_t ZSTD_buildBlockEntropyStats(
         | 
| 3735 | 
            -
                        const  | 
| 3799 | 
            +
                        const SeqStore_t* seqStorePtr,
         | 
| 3736 3800 | 
             
                        const ZSTD_entropyCTables_t* prevEntropy,
         | 
| 3737 3801 | 
             
                              ZSTD_entropyCTables_t* nextEntropy,
         | 
| 3738 3802 | 
             
                        const ZSTD_CCtx_params* cctxParams,
         | 
| @@ -3790,7 +3854,7 @@ ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize, | |
| 3790 3854 |  | 
| 3791 3855 | 
             
            /* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */
         | 
| 3792 3856 | 
             
            static size_t
         | 
| 3793 | 
            -
            ZSTD_estimateBlockSize_symbolType( | 
| 3857 | 
            +
            ZSTD_estimateBlockSize_symbolType(SymbolEncodingType_e type,
         | 
| 3794 3858 | 
             
                                const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
         | 
| 3795 3859 | 
             
                                const FSE_CTable* fseCTable,
         | 
| 3796 3860 | 
             
                                const U8* additionalBits,
         | 
| @@ -3881,7 +3945,7 @@ ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, | |
| 3881 3945 | 
             
             * @return: estimated compressed size of the seqStore, or a zstd error.
         | 
| 3882 3946 | 
             
             */
         | 
| 3883 3947 | 
             
            static size_t
         | 
| 3884 | 
            -
            ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize( | 
| 3948 | 
            +
            ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(SeqStore_t* seqStore, ZSTD_CCtx* zc)
         | 
| 3885 3949 | 
             
            {
         | 
| 3886 3950 | 
             
                ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata;
         | 
| 3887 3951 | 
             
                DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()");
         | 
| @@ -3890,25 +3954,25 @@ ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CC | |
| 3890 3954 | 
             
                                &zc->blockState.nextCBlock->entropy,
         | 
| 3891 3955 | 
             
                                &zc->appliedParams,
         | 
| 3892 3956 | 
             
                                entropyMetadata,
         | 
| 3893 | 
            -
                                zc-> | 
| 3957 | 
            +
                                zc->tmpWorkspace, zc->tmpWkspSize), "");
         | 
| 3894 3958 | 
             
                return ZSTD_estimateBlockSize(
         | 
| 3895 3959 | 
             
                                seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
         | 
| 3896 3960 | 
             
                                seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
         | 
| 3897 3961 | 
             
                                (size_t)(seqStore->sequences - seqStore->sequencesStart),
         | 
| 3898 3962 | 
             
                                &zc->blockState.nextCBlock->entropy,
         | 
| 3899 3963 | 
             
                                entropyMetadata,
         | 
| 3900 | 
            -
                                zc-> | 
| 3964 | 
            +
                                zc->tmpWorkspace, zc->tmpWkspSize,
         | 
| 3901 3965 | 
             
                                (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1);
         | 
| 3902 3966 | 
             
            }
         | 
| 3903 3967 |  | 
| 3904 3968 | 
             
            /* Returns literals bytes represented in a seqStore */
         | 
| 3905 | 
            -
            static size_t ZSTD_countSeqStoreLiteralsBytes(const  | 
| 3969 | 
            +
            static size_t ZSTD_countSeqStoreLiteralsBytes(const SeqStore_t* const seqStore)
         | 
| 3906 3970 | 
             
            {
         | 
| 3907 3971 | 
             
                size_t literalsBytes = 0;
         | 
| 3908 3972 | 
             
                size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
         | 
| 3909 3973 | 
             
                size_t i;
         | 
| 3910 3974 | 
             
                for (i = 0; i < nbSeqs; ++i) {
         | 
| 3911 | 
            -
                     | 
| 3975 | 
            +
                    SeqDef const seq = seqStore->sequencesStart[i];
         | 
| 3912 3976 | 
             
                    literalsBytes += seq.litLength;
         | 
| 3913 3977 | 
             
                    if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) {
         | 
| 3914 3978 | 
             
                        literalsBytes += 0x10000;
         | 
| @@ -3917,13 +3981,13 @@ static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore) | |
| 3917 3981 | 
             
            }
         | 
| 3918 3982 |  | 
| 3919 3983 | 
             
            /* Returns match bytes represented in a seqStore */
         | 
| 3920 | 
            -
            static size_t ZSTD_countSeqStoreMatchBytes(const  | 
| 3984 | 
            +
            static size_t ZSTD_countSeqStoreMatchBytes(const SeqStore_t* const seqStore)
         | 
| 3921 3985 | 
             
            {
         | 
| 3922 3986 | 
             
                size_t matchBytes = 0;
         | 
| 3923 3987 | 
             
                size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
         | 
| 3924 3988 | 
             
                size_t i;
         | 
| 3925 3989 | 
             
                for (i = 0; i < nbSeqs; ++i) {
         | 
| 3926 | 
            -
                     | 
| 3990 | 
            +
                    SeqDef seq = seqStore->sequencesStart[i];
         | 
| 3927 3991 | 
             
                    matchBytes += seq.mlBase + MINMATCH;
         | 
| 3928 3992 | 
             
                    if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
         | 
| 3929 3993 | 
             
                        matchBytes += 0x10000;
         | 
| @@ -3934,8 +3998,8 @@ static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore) | |
| 3934 3998 | 
             
            /* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx).
         | 
| 3935 3999 | 
             
             * Stores the result in resultSeqStore.
         | 
| 3936 4000 | 
             
             */
         | 
| 3937 | 
            -
            static void ZSTD_deriveSeqStoreChunk( | 
| 3938 | 
            -
                                           const  | 
| 4001 | 
            +
            static void ZSTD_deriveSeqStoreChunk(SeqStore_t* resultSeqStore,
         | 
| 4002 | 
            +
                                           const SeqStore_t* originalSeqStore,
         | 
| 3939 4003 | 
             
                                                 size_t startIdx, size_t endIdx)
         | 
| 3940 4004 | 
             
            {
         | 
| 3941 4005 | 
             
                *resultSeqStore = *originalSeqStore;
         | 
| @@ -4003,13 +4067,13 @@ ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, c | |
| 4003 4067 | 
             
             *        4+ : real_offset+3
         | 
| 4004 4068 | 
             
             */
         | 
| 4005 4069 | 
             
            static void
         | 
| 4006 | 
            -
            ZSTD_seqStore_resolveOffCodes( | 
| 4007 | 
            -
                                    const  | 
| 4070 | 
            +
            ZSTD_seqStore_resolveOffCodes(Repcodes_t* const dRepcodes, Repcodes_t* const cRepcodes,
         | 
| 4071 | 
            +
                                    const SeqStore_t* const seqStore, U32 const nbSeq)
         | 
| 4008 4072 | 
             
            {
         | 
| 4009 4073 | 
             
                U32 idx = 0;
         | 
| 4010 4074 | 
             
                U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq;
         | 
| 4011 4075 | 
             
                for (; idx < nbSeq; ++idx) {
         | 
| 4012 | 
            -
                     | 
| 4076 | 
            +
                    SeqDef* const seq = seqStore->sequencesStart + idx;
         | 
| 4013 4077 | 
             
                    U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx);
         | 
| 4014 4078 | 
             
                    U32 const offBase = seq->offBase;
         | 
| 4015 4079 | 
             
                    assert(offBase > 0);
         | 
| @@ -4039,8 +4103,8 @@ ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRe | |
| 4039 4103 | 
             
             */
         | 
| 4040 4104 | 
             
            static size_t
         | 
| 4041 4105 | 
             
            ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
         | 
| 4042 | 
            -
                                        const  | 
| 4043 | 
            -
                                               | 
| 4106 | 
            +
                                        const SeqStore_t* const seqStore,
         | 
| 4107 | 
            +
                                              Repcodes_t* const dRep, Repcodes_t* const cRep,
         | 
| 4044 4108 | 
             
                                              void* dst, size_t dstCapacity,
         | 
| 4045 4109 | 
             
                                        const void* src, size_t srcSize,
         | 
| 4046 4110 | 
             
                                              U32 lastBlock, U32 isPartition)
         | 
| @@ -4052,7 +4116,7 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, | |
| 4052 4116 | 
             
                size_t cSeqsSize;
         | 
| 4053 4117 |  | 
| 4054 4118 | 
             
                /* In case of an RLE or raw block, the simulated decompression repcode history must be reset */
         | 
| 4055 | 
            -
                 | 
| 4119 | 
            +
                Repcodes_t const dRepOriginal = *dRep;
         | 
| 4056 4120 | 
             
                DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock");
         | 
| 4057 4121 | 
             
                if (isPartition)
         | 
| 4058 4122 | 
             
                    ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart));
         | 
| @@ -4063,7 +4127,7 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, | |
| 4063 4127 | 
             
                            &zc->appliedParams,
         | 
| 4064 4128 | 
             
                            op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize,
         | 
| 4065 4129 | 
             
                            srcSize,
         | 
| 4066 | 
            -
                            zc-> | 
| 4130 | 
            +
                            zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */,
         | 
| 4067 4131 | 
             
                            zc->bmi2);
         | 
| 4068 4132 | 
             
                FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!");
         | 
| 4069 4133 |  | 
| @@ -4087,18 +4151,18 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, | |
| 4087 4151 | 
             
                if (cSeqsSize == 0) {
         | 
| 4088 4152 | 
             
                    cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
         | 
| 4089 4153 | 
             
                    FORWARD_IF_ERROR(cSize, "Nocompress block failed");
         | 
| 4090 | 
            -
                    DEBUGLOG( | 
| 4154 | 
            +
                    DEBUGLOG(5, "Writing out nocompress block, size: %zu", cSize);
         | 
| 4091 4155 | 
             
                    *dRep = dRepOriginal; /* reset simulated decompression repcode history */
         | 
| 4092 4156 | 
             
                } else if (cSeqsSize == 1) {
         | 
| 4093 4157 | 
             
                    cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock);
         | 
| 4094 4158 | 
             
                    FORWARD_IF_ERROR(cSize, "RLE compress block failed");
         | 
| 4095 | 
            -
                    DEBUGLOG( | 
| 4159 | 
            +
                    DEBUGLOG(5, "Writing out RLE block, size: %zu", cSize);
         | 
| 4096 4160 | 
             
                    *dRep = dRepOriginal; /* reset simulated decompression repcode history */
         | 
| 4097 4161 | 
             
                } else {
         | 
| 4098 4162 | 
             
                    ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState);
         | 
| 4099 4163 | 
             
                    writeBlockHeader(op, cSeqsSize, srcSize, lastBlock);
         | 
| 4100 4164 | 
             
                    cSize = ZSTD_blockHeaderSize + cSeqsSize;
         | 
| 4101 | 
            -
                    DEBUGLOG( | 
| 4165 | 
            +
                    DEBUGLOG(5, "Writing out compressed block, size: %zu", cSize);
         | 
| 4102 4166 | 
             
                }
         | 
| 4103 4167 |  | 
| 4104 4168 | 
             
                if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
         | 
| @@ -4131,11 +4195,11 @@ typedef struct { | |
| 4131 4195 | 
             
             */
         | 
| 4132 4196 | 
             
            static void
         | 
| 4133 4197 | 
             
            ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
         | 
| 4134 | 
            -
                                         ZSTD_CCtx* zc, const  | 
| 4198 | 
            +
                                         ZSTD_CCtx* zc, const SeqStore_t* origSeqStore)
         | 
| 4135 4199 | 
             
            {
         | 
| 4136 | 
            -
                 | 
| 4137 | 
            -
                 | 
| 4138 | 
            -
                 | 
| 4200 | 
            +
                SeqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
         | 
| 4201 | 
            +
                SeqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
         | 
| 4202 | 
            +
                SeqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
         | 
| 4139 4203 | 
             
                size_t estimatedOriginalSize;
         | 
| 4140 4204 | 
             
                size_t estimatedFirstHalfSize;
         | 
| 4141 4205 | 
             
                size_t estimatedSecondHalfSize;
         | 
| @@ -4205,8 +4269,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, | |
| 4205 4269 | 
             
                size_t i = 0;
         | 
| 4206 4270 | 
             
                size_t srcBytesTotal = 0;
         | 
| 4207 4271 | 
             
                U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */
         | 
| 4208 | 
            -
                 | 
| 4209 | 
            -
                 | 
| 4272 | 
            +
                SeqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
         | 
| 4273 | 
            +
                SeqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore;
         | 
| 4210 4274 | 
             
                size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
         | 
| 4211 4275 |  | 
| 4212 4276 | 
             
                /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
         | 
| @@ -4223,11 +4287,11 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, | |
| 4223 4287 | 
             
                 *
         | 
| 4224 4288 | 
             
                 * See ZSTD_seqStore_resolveOffCodes() for more details.
         | 
| 4225 4289 | 
             
                 */
         | 
| 4226 | 
            -
                 | 
| 4227 | 
            -
                 | 
| 4228 | 
            -
                ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof( | 
| 4229 | 
            -
                ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof( | 
| 4230 | 
            -
                ZSTD_memset(nextSeqStore, 0, sizeof( | 
| 4290 | 
            +
                Repcodes_t dRep;
         | 
| 4291 | 
            +
                Repcodes_t cRep;
         | 
| 4292 | 
            +
                ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t));
         | 
| 4293 | 
            +
                ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t));
         | 
| 4294 | 
            +
                ZSTD_memset(nextSeqStore, 0, sizeof(SeqStore_t));
         | 
| 4231 4295 |  | 
| 4232 4296 | 
             
                DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
         | 
| 4233 4297 | 
             
                            (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
         | 
| @@ -4242,8 +4306,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, | |
| 4242 4306 | 
             
                                                        lastBlock, 0 /* isPartition */);
         | 
| 4243 4307 | 
             
                    FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!");
         | 
| 4244 4308 | 
             
                    DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits");
         | 
| 4245 | 
            -
                    assert(zc-> | 
| 4246 | 
            -
                    assert(cSizeSingleBlock <= zc-> | 
| 4309 | 
            +
                    assert(zc->blockSizeMax <= ZSTD_BLOCKSIZE_MAX);
         | 
| 4310 | 
            +
                    assert(cSizeSingleBlock <= zc->blockSizeMax + ZSTD_blockHeaderSize);
         | 
| 4247 4311 | 
             
                    return cSizeSingleBlock;
         | 
| 4248 4312 | 
             
                }
         | 
| 4249 4313 |  | 
| @@ -4277,12 +4341,12 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, | |
| 4277 4341 | 
             
                    dstCapacity -= cSizeChunk;
         | 
| 4278 4342 | 
             
                    cSize += cSizeChunk;
         | 
| 4279 4343 | 
             
                    *currSeqStore = *nextSeqStore;
         | 
| 4280 | 
            -
                    assert(cSizeChunk <= zc-> | 
| 4344 | 
            +
                    assert(cSizeChunk <= zc->blockSizeMax + ZSTD_blockHeaderSize);
         | 
| 4281 4345 | 
             
                }
         | 
| 4282 4346 | 
             
                /* cRep and dRep may have diverged during the compression.
         | 
| 4283 4347 | 
             
                 * If so, we use the dRep repcodes for the next block.
         | 
| 4284 4348 | 
             
                 */
         | 
| 4285 | 
            -
                ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof( | 
| 4349 | 
            +
                ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(Repcodes_t));
         | 
| 4286 4350 | 
             
                return cSize;
         | 
| 4287 4351 | 
             
            }
         | 
| 4288 4352 |  | 
| @@ -4293,8 +4357,8 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, | |
| 4293 4357 | 
             
            {
         | 
| 4294 4358 | 
             
                U32 nbSeq;
         | 
| 4295 4359 | 
             
                size_t cSize;
         | 
| 4296 | 
            -
                DEBUGLOG( | 
| 4297 | 
            -
                assert(zc->appliedParams. | 
| 4360 | 
            +
                DEBUGLOG(5, "ZSTD_compressBlock_splitBlock");
         | 
| 4361 | 
            +
                assert(zc->appliedParams.postBlockSplitter == ZSTD_ps_enable);
         | 
| 4298 4362 |  | 
| 4299 4363 | 
             
                {   const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
         | 
| 4300 4364 | 
             
                    FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
         | 
| @@ -4304,7 +4368,7 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, | |
| 4304 4368 | 
             
                        RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block");
         | 
| 4305 4369 | 
             
                        cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
         | 
| 4306 4370 | 
             
                        FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
         | 
| 4307 | 
            -
                        DEBUGLOG( | 
| 4371 | 
            +
                        DEBUGLOG(5, "ZSTD_compressBlock_splitBlock: Nocompress block");
         | 
| 4308 4372 | 
             
                        return cSize;
         | 
| 4309 4373 | 
             
                    }
         | 
| 4310 4374 | 
             
                    nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart);
         | 
| @@ -4353,7 +4417,7 @@ ZSTD_compressBlock_internal(ZSTD_CCtx* zc, | |
| 4353 4417 | 
             
                        &zc->appliedParams,
         | 
| 4354 4418 | 
             
                        dst, dstCapacity,
         | 
| 4355 4419 | 
             
                        srcSize,
         | 
| 4356 | 
            -
                        zc-> | 
| 4420 | 
            +
                        zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */,
         | 
| 4357 4421 | 
             
                        zc->bmi2);
         | 
| 4358 4422 |  | 
| 4359 4423 | 
             
                if (frame &&
         | 
| @@ -4459,7 +4523,7 @@ static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc, | |
| 4459 4523 | 
             
                return cSize;
         | 
| 4460 4524 | 
             
            }
         | 
| 4461 4525 |  | 
| 4462 | 
            -
            static void ZSTD_overflowCorrectIfNeeded( | 
| 4526 | 
            +
            static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms,
         | 
| 4463 4527 | 
             
                                                     ZSTD_cwksp* ws,
         | 
| 4464 4528 | 
             
                                                     ZSTD_CCtx_params const* params,
         | 
| 4465 4529 | 
             
                                                     void const* ip,
         | 
| @@ -4483,6 +4547,40 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, | |
| 4483 4547 | 
             
                }
         | 
| 4484 4548 | 
             
            }
         | 
| 4485 4549 |  | 
| 4550 | 
            +
            #include "zstd_preSplit.h"
         | 
| 4551 | 
            +
             | 
| 4552 | 
            +
            static size_t ZSTD_optimalBlockSize(ZSTD_CCtx* cctx, const void* src, size_t srcSize, size_t blockSizeMax, int splitLevel, ZSTD_strategy strat, S64 savings)
         | 
| 4553 | 
            +
            {
         | 
| 4554 | 
            +
                /* split level based on compression strategy, from `fast` to `btultra2` */
         | 
| 4555 | 
            +
                static const int splitLevels[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 };
         | 
| 4556 | 
            +
                /* note: conservatively only split full blocks (128 KB) currently.
         | 
| 4557 | 
            +
                 * While it's possible to go lower, let's keep it simple for a first implementation.
         | 
| 4558 | 
            +
                 * Besides, benefits of splitting are reduced when blocks are already small.
         | 
| 4559 | 
            +
                 */
         | 
| 4560 | 
            +
                if (srcSize < 128 KB || blockSizeMax < 128 KB)
         | 
| 4561 | 
            +
                    return MIN(srcSize, blockSizeMax);
         | 
| 4562 | 
            +
                /* do not split incompressible data though:
         | 
| 4563 | 
            +
                 * require verified savings to allow pre-splitting.
         | 
| 4564 | 
            +
                 * Note: as a consequence, the first full block is not split.
         | 
| 4565 | 
            +
                 */
         | 
| 4566 | 
            +
                if (savings < 3) {
         | 
| 4567 | 
            +
                    DEBUGLOG(6, "don't attempt splitting: savings (%i) too low", (int)savings);
         | 
| 4568 | 
            +
                    return 128 KB;
         | 
| 4569 | 
            +
                }
         | 
| 4570 | 
            +
                /* apply @splitLevel, or use default value (which depends on @strat).
         | 
| 4571 | 
            +
                 * note that splitting heuristic is still conditioned by @savings >= 3,
         | 
| 4572 | 
            +
                 * so the first block will not reach this code path */
         | 
| 4573 | 
            +
                if (splitLevel == 1) return 128 KB;
         | 
| 4574 | 
            +
                if (splitLevel == 0) {
         | 
| 4575 | 
            +
                    assert(ZSTD_fast <= strat && strat <= ZSTD_btultra2);
         | 
| 4576 | 
            +
                    splitLevel = splitLevels[strat];
         | 
| 4577 | 
            +
                } else {
         | 
| 4578 | 
            +
                    assert(2 <= splitLevel && splitLevel <= 6);
         | 
| 4579 | 
            +
                    splitLevel -= 2;
         | 
| 4580 | 
            +
                }
         | 
| 4581 | 
            +
                return ZSTD_splitBlock(src, blockSizeMax, splitLevel, cctx->tmpWorkspace, cctx->tmpWkspSize);
         | 
| 4582 | 
            +
            }
         | 
| 4583 | 
            +
             | 
| 4486 4584 | 
             
            /*! ZSTD_compress_frameChunk() :
         | 
| 4487 4585 | 
             
            *   Compress a chunk of data into one or multiple blocks.
         | 
| 4488 4586 | 
             
            *   All blocks will be terminated, all input will be consumed.
         | 
| @@ -4495,29 +4593,36 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, | |
| 4495 4593 | 
             
                                           const void* src, size_t srcSize,
         | 
| 4496 4594 | 
             
                                                 U32 lastFrameChunk)
         | 
| 4497 4595 | 
             
            {
         | 
| 4498 | 
            -
                size_t  | 
| 4596 | 
            +
                size_t blockSizeMax = cctx->blockSizeMax;
         | 
| 4499 4597 | 
             
                size_t remaining = srcSize;
         | 
| 4500 4598 | 
             
                const BYTE* ip = (const BYTE*)src;
         | 
| 4501 4599 | 
             
                BYTE* const ostart = (BYTE*)dst;
         | 
| 4502 4600 | 
             
                BYTE* op = ostart;
         | 
| 4503 4601 | 
             
                U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
         | 
| 4602 | 
            +
                S64 savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize;
         | 
| 4504 4603 |  | 
| 4505 4604 | 
             
                assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
         | 
| 4506 4605 |  | 
| 4507 | 
            -
                DEBUGLOG( | 
| 4606 | 
            +
                DEBUGLOG(5, "ZSTD_compress_frameChunk (srcSize=%u, blockSizeMax=%u)", (unsigned)srcSize, (unsigned)blockSizeMax);
         | 
| 4508 4607 | 
             
                if (cctx->appliedParams.fParams.checksumFlag && srcSize)
         | 
| 4509 4608 | 
             
                    XXH64_update(&cctx->xxhState, src, srcSize);
         | 
| 4510 4609 |  | 
| 4511 4610 | 
             
                while (remaining) {
         | 
| 4512 | 
            -
                     | 
| 4513 | 
            -
                     | 
| 4611 | 
            +
                    ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
         | 
| 4612 | 
            +
                    size_t const blockSize = ZSTD_optimalBlockSize(cctx,
         | 
| 4613 | 
            +
                                            ip, remaining,
         | 
| 4614 | 
            +
                                            blockSizeMax,
         | 
| 4615 | 
            +
                                            cctx->appliedParams.preBlockSplitter_level,
         | 
| 4616 | 
            +
                                            cctx->appliedParams.cParams.strategy,
         | 
| 4617 | 
            +
                                            savings);
         | 
| 4618 | 
            +
                    U32 const lastBlock = lastFrameChunk & (blockSize == remaining);
         | 
| 4619 | 
            +
                    assert(blockSize <= remaining);
         | 
| 4514 4620 |  | 
| 4515 4621 | 
             
                    /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
         | 
| 4516 4622 | 
             
                     * additional 1. We need to revisit and change this logic to be more consistent */
         | 
| 4517 4623 | 
             
                    RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE + 1,
         | 
| 4518 4624 | 
             
                                    dstSize_tooSmall,
         | 
| 4519 4625 | 
             
                                    "not enough space to store compressed block");
         | 
| 4520 | 
            -
                    if (remaining < blockSize) blockSize = remaining;
         | 
| 4521 4626 |  | 
| 4522 4627 | 
             
                    ZSTD_overflowCorrectIfNeeded(
         | 
| 4523 4628 | 
             
                        ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
         | 
| @@ -4555,6 +4660,21 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, | |
| 4555 4660 | 
             
                            }
         | 
| 4556 4661 | 
             
                        }  /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/
         | 
| 4557 4662 |  | 
| 4663 | 
            +
                        /* @savings is employed to ensure that splitting doesn't worsen expansion of incompressible data.
         | 
| 4664 | 
            +
                         * Without splitting, the maximum expansion is 3 bytes per full block.
         | 
| 4665 | 
            +
                         * An adversarial input could attempt to fudge the split detector,
         | 
| 4666 | 
            +
                         * and make it split incompressible data, resulting in more block headers.
         | 
| 4667 | 
            +
                         * Note that, since ZSTD_COMPRESSBOUND() assumes a worst case scenario of 1KB per block,
         | 
| 4668 | 
            +
                         * and the splitter never creates blocks that small (current lower limit is 8 KB),
         | 
| 4669 | 
            +
                         * there is already no risk to expand beyond ZSTD_COMPRESSBOUND() limit.
         | 
| 4670 | 
            +
                         * But if the goal is to not expand by more than 3-bytes per 128 KB full block,
         | 
| 4671 | 
            +
                         * then yes, it becomes possible to make the block splitter oversplit incompressible data.
         | 
| 4672 | 
            +
                         * Using @savings, we enforce an even more conservative condition,
         | 
| 4673 | 
            +
                         * requiring the presence of enough savings (at least 3 bytes) to authorize splitting,
         | 
| 4674 | 
            +
                         * otherwise only full blocks are used.
         | 
| 4675 | 
            +
                         * But being conservative is fine,
         | 
| 4676 | 
            +
                         * since splitting barely compressible blocks is not fruitful anyway */
         | 
| 4677 | 
            +
                        savings += (S64)blockSize - (S64)cSize;
         | 
| 4558 4678 |  | 
| 4559 4679 | 
             
                        ip += blockSize;
         | 
| 4560 4680 | 
             
                        assert(remaining >= blockSize);
         | 
| @@ -4573,8 +4693,10 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, | |
| 4573 4693 |  | 
| 4574 4694 |  | 
| 4575 4695 | 
             
            static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
         | 
| 4576 | 
            -
                                                const ZSTD_CCtx_params* params, | 
| 4577 | 
            -
             | 
| 4696 | 
            +
                                                const ZSTD_CCtx_params* params,
         | 
| 4697 | 
            +
                                                U64 pledgedSrcSize, U32 dictID)
         | 
| 4698 | 
            +
            {
         | 
| 4699 | 
            +
                BYTE* const op = (BYTE*)dst;
         | 
| 4578 4700 | 
             
                U32   const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536);   /* 0-3 */
         | 
| 4579 4701 | 
             
                U32   const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength;   /* 0-3 */
         | 
| 4580 4702 | 
             
                U32   const checksumFlag = params->fParams.checksumFlag>0;
         | 
| @@ -4672,7 +4794,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, | |
| 4672 4794 | 
             
                                    const void* src, size_t srcSize,
         | 
| 4673 4795 | 
             
                                           U32 frame, U32 lastFrameChunk)
         | 
| 4674 4796 | 
             
            {
         | 
| 4675 | 
            -
                 | 
| 4797 | 
            +
                ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
         | 
| 4676 4798 | 
             
                size_t fhSize = 0;
         | 
| 4677 4799 |  | 
| 4678 4800 | 
             
                DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
         | 
| @@ -4707,7 +4829,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, | |
| 4707 4829 | 
             
                        src, (BYTE const*)src + srcSize);
         | 
| 4708 4830 | 
             
                }
         | 
| 4709 4831 |  | 
| 4710 | 
            -
                DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx-> | 
| 4832 | 
            +
                DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSizeMax);
         | 
| 4711 4833 | 
             
                {   size_t const cSize = frame ?
         | 
| 4712 4834 | 
             
                                         ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
         | 
| 4713 4835 | 
             
                                         ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
         | 
| @@ -4776,13 +4898,14 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const | |
| 4776 4898 | 
             
            /*! ZSTD_loadDictionaryContent() :
         | 
| 4777 4899 | 
             
             *  @return : 0, or an error code
         | 
| 4778 4900 | 
             
             */
         | 
| 4779 | 
            -
            static size_t | 
| 4780 | 
            -
             | 
| 4781 | 
            -
             | 
| 4782 | 
            -
             | 
| 4783 | 
            -
             | 
| 4784 | 
            -
             | 
| 4785 | 
            -
             | 
| 4901 | 
            +
            static size_t
         | 
| 4902 | 
            +
            ZSTD_loadDictionaryContent(ZSTD_MatchState_t* ms,
         | 
| 4903 | 
            +
                                    ldmState_t* ls,
         | 
| 4904 | 
            +
                                    ZSTD_cwksp* ws,
         | 
| 4905 | 
            +
                                    ZSTD_CCtx_params const* params,
         | 
| 4906 | 
            +
                                    const void* src, size_t srcSize,
         | 
| 4907 | 
            +
                                    ZSTD_dictTableLoadMethod_e dtlm,
         | 
| 4908 | 
            +
                                    ZSTD_tableFillPurpose_e tfp)
         | 
| 4786 4909 | 
             
            {
         | 
| 4787 4910 | 
             
                const BYTE* ip = (const BYTE*) src;
         | 
| 4788 4911 | 
             
                const BYTE* const iend = ip + srcSize;
         | 
| @@ -4826,17 +4949,18 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, | |
| 4826 4949 | 
             
                }
         | 
| 4827 4950 | 
             
                ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0);
         | 
| 4828 4951 |  | 
| 4829 | 
            -
                DEBUGLOG(4, "ZSTD_loadDictionaryContent | 
| 4952 | 
            +
                DEBUGLOG(4, "ZSTD_loadDictionaryContent: useRowMatchFinder=%d", (int)params->useRowMatchFinder);
         | 
| 4830 4953 |  | 
| 4831 4954 | 
             
                if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */
         | 
| 4955 | 
            +
                    DEBUGLOG(4, "ZSTD_loadDictionaryContent: Trigger loadLdmDict");
         | 
| 4832 4956 | 
             
                    ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0);
         | 
| 4833 4957 | 
             
                    ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
         | 
| 4834 4958 | 
             
                    ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams);
         | 
| 4959 | 
            +
                    DEBUGLOG(4, "ZSTD_loadDictionaryContent: ZSTD_ldm_fillHashTable completes");
         | 
| 4835 4960 | 
             
                }
         | 
| 4836 4961 |  | 
| 4837 4962 | 
             
                /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */
         | 
| 4838 | 
            -
                 | 
| 4839 | 
            -
                    U32 maxDictSize = 8U << MIN(MAX(params->cParams.hashLog, params->cParams.chainLog), 28);
         | 
| 4963 | 
            +
                {   U32 maxDictSize = 1U << MIN(MAX(params->cParams.hashLog + 3, params->cParams.chainLog + 1), 31);
         | 
| 4840 4964 | 
             
                    if (srcSize > maxDictSize) {
         | 
| 4841 4965 | 
             
                        ip = iend - maxDictSize;
         | 
| 4842 4966 | 
             
                        src = ip;
         | 
| @@ -4900,6 +5024,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, | |
| 4900 5024 | 
             
             || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \
         | 
| 4901 5025 | 
             
             || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR)
         | 
| 4902 5026 | 
             
                    assert(srcSize >= HASH_READ_SIZE);
         | 
| 5027 | 
            +
                    DEBUGLOG(4, "Fill %u bytes into the Binary Tree", (unsigned)srcSize);
         | 
| 4903 5028 | 
             
                    ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
         | 
| 4904 5029 | 
             
            #else
         | 
| 4905 5030 | 
             
                    assert(0); /* shouldn't be called: cparams should've been adjusted. */
         | 
| @@ -4946,7 +5071,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, | |
| 4946 5071 | 
             
                {   unsigned maxSymbolValue = 255;
         | 
| 4947 5072 | 
             
                    unsigned hasZeroWeights = 1;
         | 
| 4948 5073 | 
             
                    size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr,
         | 
| 4949 | 
            -
                        dictEnd-dictPtr, &hasZeroWeights);
         | 
| 5074 | 
            +
                        (size_t)(dictEnd-dictPtr), &hasZeroWeights);
         | 
| 4950 5075 |  | 
| 4951 5076 | 
             
                    /* We only set the loaded table as valid if it contains all non-zero
         | 
| 4952 5077 | 
             
                     * weights. Otherwise, we set it to check */
         | 
| @@ -4958,7 +5083,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, | |
| 4958 5083 | 
             
                }
         | 
| 4959 5084 |  | 
| 4960 5085 | 
             
                {   unsigned offcodeLog;
         | 
| 4961 | 
            -
                    size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
         | 
| 5086 | 
            +
                    size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
         | 
| 4962 5087 | 
             
                    RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
         | 
| 4963 5088 | 
             
                    RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
         | 
| 4964 5089 | 
             
                    /* fill all offset symbols to avoid garbage at end of table */
         | 
| @@ -4973,7 +5098,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, | |
| 4973 5098 |  | 
| 4974 5099 | 
             
                {   short matchlengthNCount[MaxML+1];
         | 
| 4975 5100 | 
             
                    unsigned matchlengthMaxValue = MaxML, matchlengthLog;
         | 
| 4976 | 
            -
                    size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
         | 
| 5101 | 
            +
                    size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
         | 
| 4977 5102 | 
             
                    RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
         | 
| 4978 5103 | 
             
                    RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
         | 
| 4979 5104 | 
             
                    RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
         | 
| @@ -4987,7 +5112,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, | |
| 4987 5112 |  | 
| 4988 5113 | 
             
                {   short litlengthNCount[MaxLL+1];
         | 
| 4989 5114 | 
             
                    unsigned litlengthMaxValue = MaxLL, litlengthLog;
         | 
| 4990 | 
            -
                    size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
         | 
| 5115 | 
            +
                    size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
         | 
| 4991 5116 | 
             
                    RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
         | 
| 4992 5117 | 
             
                    RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
         | 
| 4993 5118 | 
             
                    RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
         | 
| @@ -5021,7 +5146,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, | |
| 5021 5146 | 
             
                            RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
         | 
| 5022 5147 | 
             
                }   }   }
         | 
| 5023 5148 |  | 
| 5024 | 
            -
                return dictPtr - (const BYTE*)dict;
         | 
| 5149 | 
            +
                return (size_t)(dictPtr - (const BYTE*)dict);
         | 
| 5025 5150 | 
             
            }
         | 
| 5026 5151 |  | 
| 5027 5152 | 
             
            /* Dictionary format :
         | 
| @@ -5034,7 +5159,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, | |
| 5034 5159 | 
             
             *                dictSize supposed >= 8
         | 
| 5035 5160 | 
             
             */
         | 
| 5036 5161 | 
             
            static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
         | 
| 5037 | 
            -
                                                   | 
| 5162 | 
            +
                                                  ZSTD_MatchState_t* ms,
         | 
| 5038 5163 | 
             
                                                  ZSTD_cwksp* ws,
         | 
| 5039 5164 | 
             
                                                  ZSTD_CCtx_params const* params,
         | 
| 5040 5165 | 
             
                                                  const void* dict, size_t dictSize,
         | 
| @@ -5067,7 +5192,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, | |
| 5067 5192 | 
             
            *   @return : dictID, or an error code */
         | 
| 5068 5193 | 
             
            static size_t
         | 
| 5069 5194 | 
             
            ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
         | 
| 5070 | 
            -
                                            | 
| 5195 | 
            +
                                           ZSTD_MatchState_t* ms,
         | 
| 5071 5196 | 
             
                                           ldmState_t* ls,
         | 
| 5072 5197 | 
             
                                           ZSTD_cwksp* ws,
         | 
| 5073 5198 | 
             
                                     const ZSTD_CCtx_params* params,
         | 
| @@ -5144,11 +5269,11 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, | |
| 5144 5269 | 
             
                                    cctx->blockState.prevCBlock, &cctx->blockState.matchState,
         | 
| 5145 5270 | 
             
                                    &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
         | 
| 5146 5271 | 
             
                                    cdict->dictContentSize, cdict->dictContentType, dtlm,
         | 
| 5147 | 
            -
                                    ZSTD_tfp_forCCtx, cctx-> | 
| 5272 | 
            +
                                    ZSTD_tfp_forCCtx, cctx->tmpWorkspace)
         | 
| 5148 5273 | 
             
                          : ZSTD_compress_insertDictionary(
         | 
| 5149 5274 | 
             
                                    cctx->blockState.prevCBlock, &cctx->blockState.matchState,
         | 
| 5150 5275 | 
             
                                    &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize,
         | 
| 5151 | 
            -
                                    dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx-> | 
| 5276 | 
            +
                                    dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->tmpWorkspace);
         | 
| 5152 5277 | 
             
                    FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
         | 
| 5153 5278 | 
             
                    assert(dictID <= UINT_MAX);
         | 
| 5154 5279 | 
             
                    cctx->dictID = (U32)dictID;
         | 
| @@ -5252,7 +5377,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) | |
| 5252 5377 | 
             
                }
         | 
| 5253 5378 |  | 
| 5254 5379 | 
             
                cctx->stage = ZSTDcs_created;  /* return to "created but no init" status */
         | 
| 5255 | 
            -
                return op-ostart;
         | 
| 5380 | 
            +
                return (size_t)(op-ostart);
         | 
| 5256 5381 | 
             
            }
         | 
| 5257 5382 |  | 
| 5258 5383 | 
             
            void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
         | 
| @@ -5476,14 +5601,16 @@ static size_t ZSTD_initCDict_internal( | |
| 5476 5601 | 
             
                return 0;
         | 
| 5477 5602 | 
             
            }
         | 
| 5478 5603 |  | 
| 5479 | 
            -
            static ZSTD_CDict* | 
| 5480 | 
            -
             | 
| 5481 | 
            -
             | 
| 5482 | 
            -
             | 
| 5483 | 
            -
             | 
| 5484 | 
            -
             | 
| 5604 | 
            +
            static ZSTD_CDict*
         | 
| 5605 | 
            +
            ZSTD_createCDict_advanced_internal(size_t dictSize,
         | 
| 5606 | 
            +
                                            ZSTD_dictLoadMethod_e dictLoadMethod,
         | 
| 5607 | 
            +
                                            ZSTD_compressionParameters cParams,
         | 
| 5608 | 
            +
                                            ZSTD_ParamSwitch_e useRowMatchFinder,
         | 
| 5609 | 
            +
                                            int enableDedicatedDictSearch,
         | 
| 5610 | 
            +
                                            ZSTD_customMem customMem)
         | 
| 5485 5611 | 
             
            {
         | 
| 5486 5612 | 
             
                if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
         | 
| 5613 | 
            +
                DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (dictSize=%u)", (unsigned)dictSize);
         | 
| 5487 5614 |  | 
| 5488 5615 | 
             
                {   size_t const workspaceSize =
         | 
| 5489 5616 | 
             
                        ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
         | 
| @@ -5520,6 +5647,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, | |
| 5520 5647 | 
             
            {
         | 
| 5521 5648 | 
             
                ZSTD_CCtx_params cctxParams;
         | 
| 5522 5649 | 
             
                ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
         | 
| 5650 | 
            +
                DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
         | 
| 5523 5651 | 
             
                ZSTD_CCtxParams_init(&cctxParams, 0);
         | 
| 5524 5652 | 
             
                cctxParams.cParams = cParams;
         | 
| 5525 5653 | 
             
                cctxParams.customMem = customMem;
         | 
| @@ -5540,7 +5668,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2( | |
| 5540 5668 | 
             
                ZSTD_compressionParameters cParams;
         | 
| 5541 5669 | 
             
                ZSTD_CDict* cdict;
         | 
| 5542 5670 |  | 
| 5543 | 
            -
                DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode | 
| 5671 | 
            +
                DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
         | 
| 5544 5672 | 
             
                if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
         | 
| 5545 5673 |  | 
| 5546 5674 | 
             
                if (cctxParams.enableDedicatedDictSearch) {
         | 
| @@ -5559,7 +5687,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2( | |
| 5559 5687 | 
             
                        &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
         | 
| 5560 5688 | 
             
                }
         | 
| 5561 5689 |  | 
| 5562 | 
            -
                DEBUGLOG(3, "ZSTD_createCDict_advanced2:  | 
| 5690 | 
            +
                DEBUGLOG(3, "ZSTD_createCDict_advanced2: DedicatedDictSearch=%u", cctxParams.enableDedicatedDictSearch);
         | 
| 5563 5691 | 
             
                cctxParams.cParams = cParams;
         | 
| 5564 5692 | 
             
                cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
         | 
| 5565 5693 |  | 
| @@ -5622,7 +5750,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict) | |
| 5622 5750 | 
             
             *  workspaceSize: Use ZSTD_estimateCDictSize()
         | 
| 5623 5751 | 
             
             *                 to determine how large workspace must be.
         | 
| 5624 5752 | 
             
             *  cParams : use ZSTD_getCParams() to transform a compression level
         | 
| 5625 | 
            -
             *            into its  | 
| 5753 | 
            +
             *            into its relevant cParams.
         | 
| 5626 5754 | 
             
             * @return : pointer to ZSTD_CDict*, or NULL if error (size too small)
         | 
| 5627 5755 | 
             
             *  Note : there is no corresponding "free" function.
         | 
| 5628 5756 | 
             
             *         Since workspace was allocated externally, it must be freed externally.
         | 
| @@ -5634,7 +5762,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict( | |
| 5634 5762 | 
             
                                             ZSTD_dictContentType_e dictContentType,
         | 
| 5635 5763 | 
             
                                             ZSTD_compressionParameters cParams)
         | 
| 5636 5764 | 
             
            {
         | 
| 5637 | 
            -
                 | 
| 5765 | 
            +
                ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams);
         | 
| 5638 5766 | 
             
                /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */
         | 
| 5639 5767 | 
             
                size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0);
         | 
| 5640 5768 | 
             
                size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
         | 
| @@ -5645,6 +5773,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict( | |
| 5645 5773 | 
             
                ZSTD_CDict* cdict;
         | 
| 5646 5774 | 
             
                ZSTD_CCtx_params params;
         | 
| 5647 5775 |  | 
| 5776 | 
            +
                DEBUGLOG(4, "ZSTD_initStaticCDict (dictSize==%u)", (unsigned)dictSize);
         | 
| 5648 5777 | 
             
                if ((size_t)workspace & 7) return NULL;  /* 8-aligned */
         | 
| 5649 5778 |  | 
| 5650 5779 | 
             
                {
         | 
| @@ -5655,8 +5784,6 @@ const ZSTD_CDict* ZSTD_initStaticCDict( | |
| 5655 5784 | 
             
                    ZSTD_cwksp_move(&cdict->workspace, &ws);
         | 
| 5656 5785 | 
             
                }
         | 
| 5657 5786 |  | 
| 5658 | 
            -
                DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
         | 
| 5659 | 
            -
                    (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
         | 
| 5660 5787 | 
             
                if (workspaceSize < neededSize) return NULL;
         | 
| 5661 5788 |  | 
| 5662 5789 | 
             
                ZSTD_CCtxParams_init(¶ms, 0);
         | 
| @@ -5829,7 +5956,7 @@ size_t ZSTD_CStreamOutSize(void) | |
| 5829 5956 | 
             
                return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
         | 
| 5830 5957 | 
             
            }
         | 
| 5831 5958 |  | 
| 5832 | 
            -
            static  | 
| 5959 | 
            +
            static ZSTD_CParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
         | 
| 5833 5960 | 
             
            {
         | 
| 5834 5961 | 
             
                if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize))
         | 
| 5835 5962 | 
             
                    return ZSTD_cpm_attachDict;
         | 
| @@ -5961,11 +6088,11 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) | |
| 5961 6088 | 
             
            static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
         | 
| 5962 6089 | 
             
            {
         | 
| 5963 6090 | 
             
                if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
         | 
| 5964 | 
            -
                    return cctx-> | 
| 6091 | 
            +
                    return cctx->blockSizeMax - cctx->stableIn_notConsumed;
         | 
| 5965 6092 | 
             
                }
         | 
| 5966 6093 | 
             
                assert(cctx->appliedParams.inBufferMode == ZSTD_bm_buffered);
         | 
| 5967 6094 | 
             
                {   size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos;
         | 
| 5968 | 
            -
                    if (hintInSize==0) hintInSize = cctx-> | 
| 6095 | 
            +
                    if (hintInSize==0) hintInSize = cctx->blockSizeMax;
         | 
| 5969 6096 | 
             
                    return hintInSize;
         | 
| 5970 6097 | 
             
                }
         | 
| 5971 6098 | 
             
            }
         | 
| @@ -6017,12 +6144,13 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 6017 6144 |  | 
| 6018 6145 | 
             
                    case zcss_load:
         | 
| 6019 6146 | 
             
                        if ( (flushMode == ZSTD_e_end)
         | 
| 6020 | 
            -
                          && ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip)     /* Enough output space */
         | 
| 6147 | 
            +
                          && ( (size_t)(oend-op) >= ZSTD_compressBound((size_t)(iend-ip))     /* Enough output space */
         | 
| 6021 6148 | 
             
                            || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)  /* OR we are allowed to return dstSizeTooSmall */
         | 
| 6022 6149 | 
             
                          && (zcs->inBuffPos == 0) ) {
         | 
| 6023 6150 | 
             
                            /* shortcut to compression pass directly into output buffer */
         | 
| 6024 6151 | 
             
                            size_t const cSize = ZSTD_compressEnd_public(zcs,
         | 
| 6025 | 
            -
                                                            op, oend-op, | 
| 6152 | 
            +
                                                            op, (size_t)(oend-op),
         | 
| 6153 | 
            +
                                                            ip, (size_t)(iend-ip));
         | 
| 6026 6154 | 
             
                            DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
         | 
| 6027 6155 | 
             
                            FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed");
         | 
| 6028 6156 | 
             
                            ip = iend;
         | 
| @@ -6036,7 +6164,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 6036 6164 | 
             
                            size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
         | 
| 6037 6165 | 
             
                            size_t const loaded = ZSTD_limitCopy(
         | 
| 6038 6166 | 
             
                                                    zcs->inBuff + zcs->inBuffPos, toLoad,
         | 
| 6039 | 
            -
                                                    ip, iend-ip);
         | 
| 6167 | 
            +
                                                    ip, (size_t)(iend-ip));
         | 
| 6040 6168 | 
             
                            zcs->inBuffPos += loaded;
         | 
| 6041 6169 | 
             
                            if (ip) ip += loaded;
         | 
| 6042 6170 | 
             
                            if ( (flushMode == ZSTD_e_continue)
         | 
| @@ -6052,7 +6180,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 6052 6180 | 
             
                        } else {
         | 
| 6053 6181 | 
             
                            assert(zcs->appliedParams.inBufferMode == ZSTD_bm_stable);
         | 
| 6054 6182 | 
             
                            if ( (flushMode == ZSTD_e_continue)
         | 
| 6055 | 
            -
                              && ( (size_t)(iend - ip) < zcs-> | 
| 6183 | 
            +
                              && ( (size_t)(iend - ip) < zcs->blockSizeMax) ) {
         | 
| 6056 6184 | 
             
                                /* can't compress a full block : stop here */
         | 
| 6057 6185 | 
             
                                zcs->stableIn_notConsumed = (size_t)(iend - ip);
         | 
| 6058 6186 | 
             
                                ip = iend;  /* pretend to have consumed input */
         | 
| @@ -6069,9 +6197,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 6069 6197 | 
             
                        {   int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered);
         | 
| 6070 6198 | 
             
                            void* cDst;
         | 
| 6071 6199 | 
             
                            size_t cSize;
         | 
| 6072 | 
            -
                            size_t oSize = oend-op;
         | 
| 6200 | 
            +
                            size_t oSize = (size_t)(oend-op);
         | 
| 6073 6201 | 
             
                            size_t const iSize = inputBuffered ? zcs->inBuffPos - zcs->inToCompress
         | 
| 6074 | 
            -
                                                               : MIN((size_t)(iend - ip), zcs-> | 
| 6202 | 
            +
                                                               : MIN((size_t)(iend - ip), zcs->blockSizeMax);
         | 
| 6075 6203 | 
             
                            if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)
         | 
| 6076 6204 | 
             
                                cDst = op;   /* compress into output buffer, to skip flush stage */
         | 
| 6077 6205 | 
             
                            else
         | 
| @@ -6086,9 +6214,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 6086 6214 | 
             
                                FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
         | 
| 6087 6215 | 
             
                                zcs->frameEnded = lastBlock;
         | 
| 6088 6216 | 
             
                                /* prepare next block */
         | 
| 6089 | 
            -
                                zcs->inBuffTarget = zcs->inBuffPos + zcs-> | 
| 6217 | 
            +
                                zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSizeMax;
         | 
| 6090 6218 | 
             
                                if (zcs->inBuffTarget > zcs->inBuffSize)
         | 
| 6091 | 
            -
                                    zcs->inBuffPos = 0, zcs->inBuffTarget = zcs-> | 
| 6219 | 
            +
                                    zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSizeMax;
         | 
| 6092 6220 | 
             
                                DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
         | 
| 6093 6221 | 
             
                                        (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
         | 
| 6094 6222 | 
             
                                if (!lastBlock)
         | 
| @@ -6152,8 +6280,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 6152 6280 | 
             
                    }
         | 
| 6153 6281 | 
             
                }
         | 
| 6154 6282 |  | 
| 6155 | 
            -
                input->pos = ip - istart;
         | 
| 6156 | 
            -
                output->pos = op - ostart;
         | 
| 6283 | 
            +
                input->pos = (size_t)(ip - istart);
         | 
| 6284 | 
            +
                output->pos = (size_t)(op - ostart);
         | 
| 6157 6285 | 
             
                if (zcs->frameEnded) return 0;
         | 
| 6158 6286 | 
             
                return ZSTD_nextInputSizeHint(zcs);
         | 
| 6159 6287 | 
             
            }
         | 
| @@ -6213,6 +6341,11 @@ static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx, | |
| 6213 6341 | 
             
                return 0;
         | 
| 6214 6342 | 
             
            }
         | 
| 6215 6343 |  | 
| 6344 | 
            +
            /*
         | 
| 6345 | 
            +
             * If @endOp == ZSTD_e_end, @inSize becomes pledgedSrcSize.
         | 
| 6346 | 
            +
             * Otherwise, it's ignored.
         | 
| 6347 | 
            +
             * @return: 0 on success, or a ZSTD_error code otherwise.
         | 
| 6348 | 
            +
             */
         | 
| 6216 6349 | 
             
            static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
         | 
| 6217 6350 | 
             
                                                         ZSTD_EndDirective endOp,
         | 
| 6218 6351 | 
             
                                                         size_t inSize)
         | 
| @@ -6229,19 +6362,19 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, | |
| 6229 6362 | 
             
                     */
         | 
| 6230 6363 | 
             
                    params.compressionLevel = cctx->cdict->compressionLevel;
         | 
| 6231 6364 | 
             
                }
         | 
| 6232 | 
            -
                DEBUGLOG(4, " | 
| 6365 | 
            +
                DEBUGLOG(4, "ZSTD_CCtx_init_compressStream2 : transparent init stage");
         | 
| 6233 6366 | 
             
                if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1;  /* auto-determine pledgedSrcSize */
         | 
| 6234 6367 |  | 
| 6235 6368 | 
             
                {   size_t const dictSize = prefixDict.dict
         | 
| 6236 6369 | 
             
                            ? prefixDict.dictSize
         | 
| 6237 6370 | 
             
                            : (cctx->cdict ? cctx->cdict->dictContentSize : 0);
         | 
| 6238 | 
            -
                     | 
| 6371 | 
            +
                    ZSTD_CParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, ¶ms, cctx->pledgedSrcSizePlusOne - 1);
         | 
| 6239 6372 | 
             
                    params.cParams = ZSTD_getCParamsFromCCtxParams(
         | 
| 6240 6373 | 
             
                            ¶ms, cctx->pledgedSrcSizePlusOne-1,
         | 
| 6241 6374 | 
             
                            dictSize, mode);
         | 
| 6242 6375 | 
             
                }
         | 
| 6243 6376 |  | 
| 6244 | 
            -
                params. | 
| 6377 | 
            +
                params.postBlockSplitter = ZSTD_resolveBlockSplitterMode(params.postBlockSplitter, ¶ms.cParams);
         | 
| 6245 6378 | 
             
                params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, ¶ms.cParams);
         | 
| 6246 6379 | 
             
                params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, ¶ms.cParams);
         | 
| 6247 6380 | 
             
                params.validateSequences = ZSTD_resolveExternalSequenceValidation(params.validateSequences);
         | 
| @@ -6260,9 +6393,9 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, | |
| 6260 6393 | 
             
                    params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
         | 
| 6261 6394 | 
             
                }
         | 
| 6262 6395 | 
             
                if (params.nbWorkers > 0) {
         | 
| 6263 | 
            -
            #if ZSTD_TRACE
         | 
| 6396 | 
            +
            # if ZSTD_TRACE
         | 
| 6264 6397 | 
             
                    cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0;
         | 
| 6265 | 
            -
            #endif
         | 
| 6398 | 
            +
            # endif
         | 
| 6266 6399 | 
             
                    /* mt context creation */
         | 
| 6267 6400 | 
             
                    if (cctx->mtctx == NULL) {
         | 
| 6268 6401 | 
             
                        DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
         | 
| @@ -6298,7 +6431,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, | |
| 6298 6431 | 
             
                        /* for small input: avoid automatic flush on reaching end of block, since
         | 
| 6299 6432 | 
             
                        * it would require to add a 3-bytes null block to end frame
         | 
| 6300 6433 | 
             
                        */
         | 
| 6301 | 
            -
                        cctx->inBuffTarget = cctx-> | 
| 6434 | 
            +
                        cctx->inBuffTarget = cctx->blockSizeMax + (cctx->blockSizeMax == pledgedSrcSize);
         | 
| 6302 6435 | 
             
                    } else {
         | 
| 6303 6436 | 
             
                        cctx->inBuffTarget = 0;
         | 
| 6304 6437 | 
             
                    }
         | 
| @@ -6464,11 +6597,11 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx, | |
| 6464 6597 | 
             
            }
         | 
| 6465 6598 |  | 
| 6466 6599 | 
             
            /* ZSTD_validateSequence() :
         | 
| 6467 | 
            -
             * @ | 
| 6600 | 
            +
             * @offBase : must use the format required by ZSTD_storeSeq()
         | 
| 6468 6601 | 
             
             * @returns a ZSTD error code if sequence is not valid
         | 
| 6469 6602 | 
             
             */
         | 
| 6470 6603 | 
             
            static size_t
         | 
| 6471 | 
            -
            ZSTD_validateSequence(U32  | 
| 6604 | 
            +
            ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch,
         | 
| 6472 6605 | 
             
                                  size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer)
         | 
| 6473 6606 | 
             
            {
         | 
| 6474 6607 | 
             
                U32 const windowSize = 1u << windowLog;
         | 
| @@ -6479,7 +6612,7 @@ ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch, | |
| 6479 6612 | 
             
                 */
         | 
| 6480 6613 | 
             
                size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
         | 
| 6481 6614 | 
             
                size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4;
         | 
| 6482 | 
            -
                RETURN_ERROR_IF( | 
| 6615 | 
            +
                RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!");
         | 
| 6483 6616 | 
             
                /* Validate maxNbSeq is large enough for the given matchLength and minMatch */
         | 
| 6484 6617 | 
             
                RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch");
         | 
| 6485 6618 | 
             
                return 0;
         | 
| @@ -6502,21 +6635,27 @@ static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 | |
| 6502 6635 | 
             
                return offBase;
         | 
| 6503 6636 | 
             
            }
         | 
| 6504 6637 |  | 
| 6505 | 
            -
             | 
| 6506 | 
            -
             | 
| 6507 | 
            -
             | 
| 6508 | 
            -
             | 
| 6509 | 
            -
             | 
| 6510 | 
            -
             | 
| 6638 | 
            +
            /* This function scans through an array of ZSTD_Sequence,
         | 
| 6639 | 
            +
             * storing the sequences it reads, until it reaches a block delimiter.
         | 
| 6640 | 
            +
             * Note that the block delimiter includes the last literals of the block.
         | 
| 6641 | 
            +
             * @blockSize must be == sum(sequence_lengths).
         | 
| 6642 | 
            +
             * @returns @blockSize on success, and a ZSTD_error otherwise.
         | 
| 6643 | 
            +
             */
         | 
| 6644 | 
            +
            static size_t
         | 
| 6645 | 
            +
            ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx,
         | 
| 6646 | 
            +
                                               ZSTD_SequencePosition* seqPos,
         | 
| 6647 | 
            +
                                         const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         | 
| 6648 | 
            +
                                         const void* src, size_t blockSize,
         | 
| 6649 | 
            +
                                               ZSTD_ParamSwitch_e externalRepSearch)
         | 
| 6511 6650 | 
             
            {
         | 
| 6512 6651 | 
             
                U32 idx = seqPos->idx;
         | 
| 6513 6652 | 
             
                U32 const startIdx = idx;
         | 
| 6514 6653 | 
             
                BYTE const* ip = (BYTE const*)(src);
         | 
| 6515 6654 | 
             
                const BYTE* const iend = ip + blockSize;
         | 
| 6516 | 
            -
                 | 
| 6655 | 
            +
                Repcodes_t updatedRepcodes;
         | 
| 6517 6656 | 
             
                U32 dictSize;
         | 
| 6518 6657 |  | 
| 6519 | 
            -
                DEBUGLOG(5, " | 
| 6658 | 
            +
                DEBUGLOG(5, "ZSTD_transferSequences_wBlockDelim (blockSize = %zu)", blockSize);
         | 
| 6520 6659 |  | 
| 6521 6660 | 
             
                if (cctx->cdict) {
         | 
| 6522 6661 | 
             
                    dictSize = (U32)cctx->cdict->dictContentSize;
         | 
| @@ -6525,7 +6664,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, | |
| 6525 6664 | 
             
                } else {
         | 
| 6526 6665 | 
             
                    dictSize = 0;
         | 
| 6527 6666 | 
             
                }
         | 
| 6528 | 
            -
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof( | 
| 6667 | 
            +
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
         | 
| 6529 6668 | 
             
                for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) {
         | 
| 6530 6669 | 
             
                    U32 const litLength = inSeqs[idx].litLength;
         | 
| 6531 6670 | 
             
                    U32 const matchLength = inSeqs[idx].matchLength;
         | 
| @@ -6542,8 +6681,10 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, | |
| 6542 6681 | 
             
                    DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
         | 
| 6543 6682 | 
             
                    if (cctx->appliedParams.validateSequences) {
         | 
| 6544 6683 | 
             
                        seqPos->posInSrc += litLength + matchLength;
         | 
| 6545 | 
            -
                        FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, | 
| 6546 | 
            -
                                                             | 
| 6684 | 
            +
                        FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch,
         | 
| 6685 | 
            +
                                                            seqPos->posInSrc,
         | 
| 6686 | 
            +
                                                            cctx->appliedParams.cParams.windowLog, dictSize,
         | 
| 6687 | 
            +
                                                            ZSTD_hasExtSeqProd(&cctx->appliedParams)),
         | 
| 6547 6688 | 
             
                                                            "Sequence validation failed");
         | 
| 6548 6689 | 
             
                    }
         | 
| 6549 6690 | 
             
                    RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
         | 
| @@ -6551,6 +6692,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, | |
| 6551 6692 | 
             
                    ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength);
         | 
| 6552 6693 | 
             
                    ip += matchLength + litLength;
         | 
| 6553 6694 | 
             
                }
         | 
| 6695 | 
            +
                RETURN_ERROR_IF(idx == inSeqsSize, externalSequences_invalid, "Block delimiter not found.");
         | 
| 6554 6696 |  | 
| 6555 6697 | 
             
                /* If we skipped repcode search while parsing, we need to update repcodes now */
         | 
| 6556 6698 | 
             
                assert(externalRepSearch != ZSTD_ps_auto);
         | 
| @@ -6575,7 +6717,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, | |
| 6575 6717 | 
             
                    }
         | 
| 6576 6718 | 
             
                }
         | 
| 6577 6719 |  | 
| 6578 | 
            -
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof( | 
| 6720 | 
            +
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
         | 
| 6579 6721 |  | 
| 6580 6722 | 
             
                if (inSeqs[idx].litLength) {
         | 
| 6581 6723 | 
             
                    DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength);
         | 
| @@ -6585,21 +6727,35 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, | |
| 6585 6727 | 
             
                }
         | 
| 6586 6728 | 
             
                RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!");
         | 
| 6587 6729 | 
             
                seqPos->idx = idx+1;
         | 
| 6588 | 
            -
                return  | 
| 6730 | 
            +
                return blockSize;
         | 
| 6589 6731 | 
             
            }
         | 
| 6590 6732 |  | 
| 6591 | 
            -
             | 
| 6592 | 
            -
             | 
| 6593 | 
            -
             | 
| 6594 | 
            -
             | 
| 6733 | 
            +
            /*
         | 
| 6734 | 
            +
             * This function attempts to scan through @blockSize bytes in @src
         | 
| 6735 | 
            +
             * represented by the sequences in @inSeqs,
         | 
| 6736 | 
            +
             * storing any (partial) sequences.
         | 
| 6737 | 
            +
             *
         | 
| 6738 | 
            +
             * Occasionally, we may want to reduce the actual number of bytes consumed from @src
         | 
| 6739 | 
            +
             * to avoid splitting a match, notably if it would produce a match smaller than MINMATCH.
         | 
| 6740 | 
            +
             *
         | 
| 6741 | 
            +
             * @returns the number of bytes consumed from @src, necessarily <= @blockSize.
         | 
| 6742 | 
            +
             * Otherwise, it may return a ZSTD error if something went wrong.
         | 
| 6743 | 
            +
             */
         | 
| 6744 | 
            +
            static size_t
         | 
| 6745 | 
            +
            ZSTD_transferSequences_noDelim(ZSTD_CCtx* cctx,
         | 
| 6746 | 
            +
                                           ZSTD_SequencePosition* seqPos,
         | 
| 6747 | 
            +
                                     const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         | 
| 6748 | 
            +
                                     const void* src, size_t blockSize,
         | 
| 6749 | 
            +
                                           ZSTD_ParamSwitch_e externalRepSearch)
         | 
| 6595 6750 | 
             
            {
         | 
| 6596 6751 | 
             
                U32 idx = seqPos->idx;
         | 
| 6597 6752 | 
             
                U32 startPosInSequence = seqPos->posInSequence;
         | 
| 6598 6753 | 
             
                U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
         | 
| 6599 6754 | 
             
                size_t dictSize;
         | 
| 6600 | 
            -
                BYTE const | 
| 6601 | 
            -
                BYTE | 
| 6602 | 
            -
                 | 
| 6755 | 
            +
                const BYTE* const istart = (const BYTE*)(src);
         | 
| 6756 | 
            +
                const BYTE* ip = istart;
         | 
| 6757 | 
            +
                const BYTE* iend = istart + blockSize;  /* May be adjusted if we decide to process fewer than blockSize bytes */
         | 
| 6758 | 
            +
                Repcodes_t updatedRepcodes;
         | 
| 6603 6759 | 
             
                U32 bytesAdjustment = 0;
         | 
| 6604 6760 | 
             
                U32 finalMatchSplit = 0;
         | 
| 6605 6761 |  | 
| @@ -6613,9 +6769,9 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* | |
| 6613 6769 | 
             
                } else {
         | 
| 6614 6770 | 
             
                    dictSize = 0;
         | 
| 6615 6771 | 
             
                }
         | 
| 6616 | 
            -
                DEBUGLOG(5, " | 
| 6772 | 
            +
                DEBUGLOG(5, "ZSTD_transferSequences_noDelim: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
         | 
| 6617 6773 | 
             
                DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
         | 
| 6618 | 
            -
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof( | 
| 6774 | 
            +
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
         | 
| 6619 6775 | 
             
                while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
         | 
| 6620 6776 | 
             
                    const ZSTD_Sequence currSeq = inSeqs[idx];
         | 
| 6621 6777 | 
             
                    U32 litLength = currSeq.litLength;
         | 
| @@ -6696,35 +6852,40 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* | |
| 6696 6852 | 
             
                assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength);
         | 
| 6697 6853 | 
             
                seqPos->idx = idx;
         | 
| 6698 6854 | 
             
                seqPos->posInSequence = endPosInSequence;
         | 
| 6699 | 
            -
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof( | 
| 6855 | 
            +
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
         | 
| 6700 6856 |  | 
| 6701 6857 | 
             
                iend -= bytesAdjustment;
         | 
| 6702 6858 | 
             
                if (ip != iend) {
         | 
| 6703 6859 | 
             
                    /* Store any last literals */
         | 
| 6704 | 
            -
                    U32 lastLLSize = (U32)(iend - ip);
         | 
| 6860 | 
            +
                    U32 const lastLLSize = (U32)(iend - ip);
         | 
| 6705 6861 | 
             
                    assert(ip <= iend);
         | 
| 6706 6862 | 
             
                    DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize);
         | 
| 6707 6863 | 
             
                    ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize);
         | 
| 6708 6864 | 
             
                    seqPos->posInSrc += lastLLSize;
         | 
| 6709 6865 | 
             
                }
         | 
| 6710 6866 |  | 
| 6711 | 
            -
                return  | 
| 6867 | 
            +
                return (size_t)(iend-istart);
         | 
| 6712 6868 | 
             
            }
         | 
| 6713 6869 |  | 
| 6714 | 
            -
             | 
| 6715 | 
            -
             | 
| 6716 | 
            -
             | 
| 6717 | 
            -
             | 
| 6870 | 
            +
            /* @seqPos represents a position within @inSeqs,
         | 
| 6871 | 
            +
             * it is read and updated by this function,
         | 
| 6872 | 
            +
             * once the goal to produce a block of size @blockSize is reached.
         | 
| 6873 | 
            +
             * @return: nb of bytes consumed from @src, necessarily <= @blockSize.
         | 
| 6874 | 
            +
             */
         | 
| 6875 | 
            +
            typedef size_t (*ZSTD_SequenceCopier_f)(ZSTD_CCtx* cctx,
         | 
| 6876 | 
            +
                                                    ZSTD_SequencePosition* seqPos,
         | 
| 6877 | 
            +
                                              const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
         | 
| 6878 | 
            +
                                              const void* src, size_t blockSize,
         | 
| 6879 | 
            +
                                                    ZSTD_ParamSwitch_e externalRepSearch);
         | 
| 6880 | 
            +
             | 
| 6881 | 
            +
            static ZSTD_SequenceCopier_f ZSTD_selectSequenceCopier(ZSTD_SequenceFormat_e mode)
         | 
| 6718 6882 | 
             
            {
         | 
| 6719 | 
            -
                 | 
| 6720 | 
            -
                assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
         | 
| 6883 | 
            +
                assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, (int)mode));
         | 
| 6721 6884 | 
             
                if (mode == ZSTD_sf_explicitBlockDelimiters) {
         | 
| 6722 | 
            -
                    return  | 
| 6723 | 
            -
                } else if (mode == ZSTD_sf_noBlockDelimiters) {
         | 
| 6724 | 
            -
                    return ZSTD_copySequencesToSeqStoreNoBlockDelim;
         | 
| 6885 | 
            +
                    return ZSTD_transferSequences_wBlockDelim;
         | 
| 6725 6886 | 
             
                }
         | 
| 6726 | 
            -
                assert( | 
| 6727 | 
            -
                return  | 
| 6887 | 
            +
                assert(mode == ZSTD_sf_noBlockDelimiters);
         | 
| 6888 | 
            +
                return ZSTD_transferSequences_noDelim;
         | 
| 6728 6889 | 
             
            }
         | 
| 6729 6890 |  | 
| 6730 6891 | 
             
            /* Discover the size of next block by searching for the delimiter.
         | 
| @@ -6732,7 +6893,7 @@ static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode) | |
| 6732 6893 | 
             
             * otherwise it's an input error.
         | 
| 6733 6894 | 
             
             * The block size retrieved will be later compared to ensure it remains within bounds */
         | 
| 6734 6895 | 
             
            static size_t
         | 
| 6735 | 
            -
            blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize,  | 
| 6896 | 
            +
            blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_SequencePosition seqPos)
         | 
| 6736 6897 | 
             
            {
         | 
| 6737 6898 | 
             
                int end = 0;
         | 
| 6738 6899 | 
             
                size_t blockSize = 0;
         | 
| @@ -6754,20 +6915,17 @@ blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD | |
| 6754 6915 | 
             
                return blockSize;
         | 
| 6755 6916 | 
             
            }
         | 
| 6756 6917 |  | 
| 6757 | 
            -
             | 
| 6758 | 
            -
            static size_t blockSize_noDelimiter(size_t blockSize, size_t remaining)
         | 
| 6759 | 
            -
            {
         | 
| 6760 | 
            -
                int const lastBlock = (remaining <= blockSize);
         | 
| 6761 | 
            -
                return lastBlock ? remaining : blockSize;
         | 
| 6762 | 
            -
            }
         | 
| 6763 | 
            -
             | 
| 6764 | 
            -
            static size_t determine_blockSize(ZSTD_sequenceFormat_e mode,
         | 
| 6918 | 
            +
            static size_t determine_blockSize(ZSTD_SequenceFormat_e mode,
         | 
| 6765 6919 | 
             
                                       size_t blockSize, size_t remaining,
         | 
| 6766 | 
            -
                                 const ZSTD_Sequence* inSeqs, size_t inSeqsSize, | 
| 6920 | 
            +
                                 const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
         | 
| 6921 | 
            +
                                       ZSTD_SequencePosition seqPos)
         | 
| 6767 6922 | 
             
            {
         | 
| 6768 6923 | 
             
                DEBUGLOG(6, "determine_blockSize : remainingSize = %zu", remaining);
         | 
| 6769 | 
            -
                if (mode == ZSTD_sf_noBlockDelimiters)
         | 
| 6770 | 
            -
                     | 
| 6924 | 
            +
                if (mode == ZSTD_sf_noBlockDelimiters) {
         | 
| 6925 | 
            +
                    /* Note: more a "target" block size */
         | 
| 6926 | 
            +
                    return MIN(remaining, blockSize);
         | 
| 6927 | 
            +
                }
         | 
| 6928 | 
            +
                assert(mode == ZSTD_sf_explicitBlockDelimiters);
         | 
| 6771 6929 | 
             
                {   size_t const explicitBlockSize = blockSize_explicitDelimiter(inSeqs, inSeqsSize, seqPos);
         | 
| 6772 6930 | 
             
                    FORWARD_IF_ERROR(explicitBlockSize, "Error while determining block size with explicit delimiters");
         | 
| 6773 6931 | 
             
                    if (explicitBlockSize > blockSize)
         | 
| @@ -6778,7 +6936,7 @@ static size_t determine_blockSize(ZSTD_sequenceFormat_e mode, | |
| 6778 6936 | 
             
                }
         | 
| 6779 6937 | 
             
            }
         | 
| 6780 6938 |  | 
| 6781 | 
            -
            /* Compress, block-by-block | 
| 6939 | 
            +
            /* Compress all provided sequences, block-by-block.
         | 
| 6782 6940 | 
             
             *
         | 
| 6783 6941 | 
             
             * Returns the cumulative size of all compressed blocks (including their headers),
         | 
| 6784 6942 | 
             
             * otherwise a ZSTD error.
         | 
| @@ -6791,11 +6949,11 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, | |
| 6791 6949 | 
             
            {
         | 
| 6792 6950 | 
             
                size_t cSize = 0;
         | 
| 6793 6951 | 
             
                size_t remaining = srcSize;
         | 
| 6794 | 
            -
                 | 
| 6952 | 
            +
                ZSTD_SequencePosition seqPos = {0, 0, 0};
         | 
| 6795 6953 |  | 
| 6796 | 
            -
                BYTE | 
| 6954 | 
            +
                const BYTE* ip = (BYTE const*)src;
         | 
| 6797 6955 | 
             
                BYTE* op = (BYTE*)dst;
         | 
| 6798 | 
            -
                 | 
| 6956 | 
            +
                ZSTD_SequenceCopier_f const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
         | 
| 6799 6957 |  | 
| 6800 6958 | 
             
                DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
         | 
| 6801 6959 | 
             
                /* Special case: empty frame */
         | 
| @@ -6811,19 +6969,19 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, | |
| 6811 6969 | 
             
                while (remaining) {
         | 
| 6812 6970 | 
             
                    size_t compressedSeqsSize;
         | 
| 6813 6971 | 
             
                    size_t cBlockSize;
         | 
| 6814 | 
            -
                    size_t additionalByteAdjustment;
         | 
| 6815 6972 | 
             
                    size_t blockSize = determine_blockSize(cctx->appliedParams.blockDelimiters,
         | 
| 6816 | 
            -
                                                    cctx-> | 
| 6973 | 
            +
                                                    cctx->blockSizeMax, remaining,
         | 
| 6817 6974 | 
             
                                                    inSeqs, inSeqsSize, seqPos);
         | 
| 6818 6975 | 
             
                    U32 const lastBlock = (blockSize == remaining);
         | 
| 6819 6976 | 
             
                    FORWARD_IF_ERROR(blockSize, "Error while trying to determine block size");
         | 
| 6820 6977 | 
             
                    assert(blockSize <= remaining);
         | 
| 6821 6978 | 
             
                    ZSTD_resetSeqStore(&cctx->seqStore);
         | 
| 6822 | 
            -
                    DEBUGLOG(5, "Working on new block. Blocksize: %zu (total:%zu)", blockSize, (ip - (const BYTE*)src) + blockSize);
         | 
| 6823 6979 |  | 
| 6824 | 
            -
                     | 
| 6825 | 
            -
             | 
| 6826 | 
            -
             | 
| 6980 | 
            +
                    blockSize = sequenceCopier(cctx,
         | 
| 6981 | 
            +
                                               &seqPos, inSeqs, inSeqsSize,
         | 
| 6982 | 
            +
                                               ip, blockSize,
         | 
| 6983 | 
            +
                                               cctx->appliedParams.searchForExternalRepcodes);
         | 
| 6984 | 
            +
                    FORWARD_IF_ERROR(blockSize, "Bad sequence copy");
         | 
| 6827 6985 |  | 
| 6828 6986 | 
             
                    /* If blocks are too small, emit as a nocompress block */
         | 
| 6829 6987 | 
             
                    /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
         | 
| @@ -6831,7 +6989,7 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, | |
| 6831 6989 | 
             
                    if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) {
         | 
| 6832 6990 | 
             
                        cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
         | 
| 6833 6991 | 
             
                        FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
         | 
| 6834 | 
            -
                        DEBUGLOG(5, "Block too small | 
| 6992 | 
            +
                        DEBUGLOG(5, "Block too small (%zu): data remains uncompressed: cSize=%zu", blockSize, cBlockSize);
         | 
| 6835 6993 | 
             
                        cSize += cBlockSize;
         | 
| 6836 6994 | 
             
                        ip += blockSize;
         | 
| 6837 6995 | 
             
                        op += cBlockSize;
         | 
| @@ -6846,7 +7004,7 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, | |
| 6846 7004 | 
             
                                            &cctx->appliedParams,
         | 
| 6847 7005 | 
             
                                            op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
         | 
| 6848 7006 | 
             
                                            blockSize,
         | 
| 6849 | 
            -
                                            cctx-> | 
| 7007 | 
            +
                                            cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */,
         | 
| 6850 7008 | 
             
                                            cctx->bmi2);
         | 
| 6851 7009 | 
             
                    FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
         | 
| 6852 7010 | 
             
                    DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
         | 
| @@ -6854,10 +7012,10 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx, | |
| 6854 7012 | 
             
                    if (!cctx->isFirstBlock &&
         | 
| 6855 7013 | 
             
                        ZSTD_maybeRLE(&cctx->seqStore) &&
         | 
| 6856 7014 | 
             
                        ZSTD_isRLE(ip, blockSize)) {
         | 
| 6857 | 
            -
                        /*  | 
| 6858 | 
            -
             | 
| 6859 | 
            -
             | 
| 6860 | 
            -
             | 
| 7015 | 
            +
                        /* Note: don't emit the first block as RLE even if it qualifies because
         | 
| 7016 | 
            +
                         * doing so will cause the decoder (cli <= v1.4.3 only) to throw an (invalid) error
         | 
| 7017 | 
            +
                         * "should consume all input error."
         | 
| 7018 | 
            +
                         */
         | 
| 6861 7019 | 
             
                        compressedSeqsSize = 1;
         | 
| 6862 7020 | 
             
                    }
         | 
| 6863 7021 |  | 
| @@ -6909,30 +7067,36 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx, | |
| 6909 7067 | 
             
            {
         | 
| 6910 7068 | 
             
                BYTE* op = (BYTE*)dst;
         | 
| 6911 7069 | 
             
                size_t cSize = 0;
         | 
| 6912 | 
            -
                size_t compressedBlocksSize = 0;
         | 
| 6913 | 
            -
                size_t frameHeaderSize = 0;
         | 
| 6914 7070 |  | 
| 6915 7071 | 
             
                /* Transparent initialization stage, same as compressStream2() */
         | 
| 6916 | 
            -
                DEBUGLOG(4, "ZSTD_compressSequences (dstCapacity=%zu)", dstCapacity);
         | 
| 7072 | 
            +
                DEBUGLOG(4, "ZSTD_compressSequences (nbSeqs=%zu,dstCapacity=%zu)", inSeqsSize, dstCapacity);
         | 
| 6917 7073 | 
             
                assert(cctx != NULL);
         | 
| 6918 7074 | 
             
                FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed");
         | 
| 7075 | 
            +
             | 
| 6919 7076 | 
             
                /* Begin writing output, starting with frame header */
         | 
| 6920 | 
            -
                frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, | 
| 6921 | 
            -
             | 
| 6922 | 
            -
             | 
| 6923 | 
            -
             | 
| 7077 | 
            +
                {   size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
         | 
| 7078 | 
            +
                                &cctx->appliedParams, srcSize, cctx->dictID);
         | 
| 7079 | 
            +
                    op += frameHeaderSize;
         | 
| 7080 | 
            +
                    assert(frameHeaderSize <= dstCapacity);
         | 
| 7081 | 
            +
                    dstCapacity -= frameHeaderSize;
         | 
| 7082 | 
            +
                    cSize += frameHeaderSize;
         | 
| 7083 | 
            +
                }
         | 
| 6924 7084 | 
             
                if (cctx->appliedParams.fParams.checksumFlag && srcSize) {
         | 
| 6925 7085 | 
             
                    XXH64_update(&cctx->xxhState, src, srcSize);
         | 
| 6926 7086 | 
             
                }
         | 
| 6927 | 
            -
             | 
| 6928 | 
            -
                 | 
| 7087 | 
            +
             | 
| 7088 | 
            +
                /* Now generate compressed blocks */
         | 
| 7089 | 
            +
                {   size_t const cBlocksSize = ZSTD_compressSequences_internal(cctx,
         | 
| 6929 7090 | 
             
                                                                       op, dstCapacity,
         | 
| 6930 7091 | 
             
                                                                       inSeqs, inSeqsSize,
         | 
| 6931 7092 | 
             
                                                                       src, srcSize);
         | 
| 6932 | 
            -
             | 
| 6933 | 
            -
             | 
| 6934 | 
            -
             | 
| 7093 | 
            +
                    FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!");
         | 
| 7094 | 
            +
                    cSize += cBlocksSize;
         | 
| 7095 | 
            +
                    assert(cBlocksSize <= dstCapacity);
         | 
| 7096 | 
            +
                    dstCapacity -= cBlocksSize;
         | 
| 7097 | 
            +
                }
         | 
| 6935 7098 |  | 
| 7099 | 
            +
                /* Complete with frame checksum, if needed */
         | 
| 6936 7100 | 
             
                if (cctx->appliedParams.fParams.checksumFlag) {
         | 
| 6937 7101 | 
             
                    U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
         | 
| 6938 7102 | 
             
                    RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
         | 
| @@ -6945,6 +7109,530 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx, | |
| 6945 7109 | 
             
                return cSize;
         | 
| 6946 7110 | 
             
            }
         | 
| 6947 7111 |  | 
| 7112 | 
            +
             | 
| 7113 | 
            +
            #if defined(__AVX2__)
         | 
| 7114 | 
            +
             | 
| 7115 | 
            +
            #include <immintrin.h>  /* AVX2 intrinsics */
         | 
| 7116 | 
            +
             | 
| 7117 | 
            +
            /*
         | 
| 7118 | 
            +
             * Convert 2 sequences per iteration, using AVX2 intrinsics:
         | 
| 7119 | 
            +
             *   - offset -> offBase = offset + 2
         | 
| 7120 | 
            +
             *   - litLength -> (U16) litLength
         | 
| 7121 | 
            +
             *   - matchLength -> (U16)(matchLength - 3)
         | 
| 7122 | 
            +
             *   - rep is ignored
         | 
| 7123 | 
            +
             * Store only 8 bytes per SeqDef (offBase[4], litLength[2], mlBase[2]).
         | 
| 7124 | 
            +
             *
         | 
| 7125 | 
            +
             * At the end, instead of extracting two __m128i,
         | 
| 7126 | 
            +
             * we use _mm256_permute4x64_epi64(..., 0xE8) to move lane2 into lane1,
         | 
| 7127 | 
            +
             * then store the lower 16 bytes in one go.
         | 
| 7128 | 
            +
             *
         | 
| 7129 | 
            +
             * @returns 0 on succes, with no long length detected
         | 
| 7130 | 
            +
             * @returns > 0 if there is one long length (> 65535),
         | 
| 7131 | 
            +
             * indicating the position, and type.
         | 
| 7132 | 
            +
             */
         | 
| 7133 | 
            +
            static size_t convertSequences_noRepcodes(
         | 
| 7134 | 
            +
                SeqDef* dstSeqs,
         | 
| 7135 | 
            +
                const ZSTD_Sequence* inSeqs,
         | 
| 7136 | 
            +
                size_t nbSequences)
         | 
| 7137 | 
            +
            {
         | 
| 7138 | 
            +
                /*
         | 
| 7139 | 
            +
                 * addition:
         | 
| 7140 | 
            +
                 *   For each 128-bit half: (offset+2, litLength+0, matchLength-3, rep+0)
         | 
| 7141 | 
            +
                 */
         | 
| 7142 | 
            +
                const __m256i addition = _mm256_setr_epi32(
         | 
| 7143 | 
            +
                    ZSTD_REP_NUM, 0, -MINMATCH, 0,    /* for sequence i */
         | 
| 7144 | 
            +
                    ZSTD_REP_NUM, 0, -MINMATCH, 0     /* for sequence i+1 */
         | 
| 7145 | 
            +
                );
         | 
| 7146 | 
            +
             | 
| 7147 | 
            +
                /* limit: check if there is a long length */
         | 
| 7148 | 
            +
                const __m256i limit = _mm256_set1_epi32(65535);
         | 
| 7149 | 
            +
             | 
| 7150 | 
            +
                /*
         | 
| 7151 | 
            +
                 * shuffle mask for byte-level rearrangement in each 128-bit half:
         | 
| 7152 | 
            +
                 *
         | 
| 7153 | 
            +
                 * Input layout (after addition) per 128-bit half:
         | 
| 7154 | 
            +
                 *   [ offset+2 (4 bytes) | litLength (4 bytes) | matchLength (4 bytes) | rep (4 bytes) ]
         | 
| 7155 | 
            +
                 * We only need:
         | 
| 7156 | 
            +
                 *   offBase (4 bytes) = offset+2
         | 
| 7157 | 
            +
                 *   litLength (2 bytes) = low 2 bytes of litLength
         | 
| 7158 | 
            +
                 *   mlBase (2 bytes) = low 2 bytes of (matchLength)
         | 
| 7159 | 
            +
                 * => Bytes [0..3, 4..5, 8..9], zero the rest.
         | 
| 7160 | 
            +
                 */
         | 
| 7161 | 
            +
                const __m256i mask = _mm256_setr_epi8(
         | 
| 7162 | 
            +
                    /* For the lower 128 bits => sequence i */
         | 
| 7163 | 
            +
                     0, 1, 2, 3,       /* offset+2 */
         | 
| 7164 | 
            +
                     4, 5,             /* litLength (16 bits) */
         | 
| 7165 | 
            +
                     8, 9,             /* matchLength (16 bits) */
         | 
| 7166 | 
            +
                     (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
         | 
| 7167 | 
            +
                     (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
         | 
| 7168 | 
            +
             | 
| 7169 | 
            +
                    /* For the upper 128 bits => sequence i+1 */
         | 
| 7170 | 
            +
                    16,17,18,19,       /* offset+2 */
         | 
| 7171 | 
            +
                    20,21,             /* litLength */
         | 
| 7172 | 
            +
                    24,25,             /* matchLength */
         | 
| 7173 | 
            +
                    (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
         | 
| 7174 | 
            +
                    (BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80
         | 
| 7175 | 
            +
                );
         | 
| 7176 | 
            +
             | 
| 7177 | 
            +
                /*
         | 
| 7178 | 
            +
                 * Next, we'll use _mm256_permute4x64_epi64(vshf, 0xE8).
         | 
| 7179 | 
            +
                 * Explanation of 0xE8 = 11101000b => [lane0, lane2, lane2, lane3].
         | 
| 7180 | 
            +
                 * So the lower 128 bits become [lane0, lane2] => combining seq0 and seq1.
         | 
| 7181 | 
            +
                 */
         | 
| 7182 | 
            +
            #define PERM_LANE_0X_E8 0xE8  /* [0,2,2,3] in lane indices */
         | 
| 7183 | 
            +
             | 
| 7184 | 
            +
                size_t longLen = 0, i = 0;
         | 
| 7185 | 
            +
             | 
| 7186 | 
            +
                /* AVX permutation depends on the specific definition of target structures */
         | 
| 7187 | 
            +
                ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
         | 
| 7188 | 
            +
                ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
         | 
| 7189 | 
            +
                ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4);
         | 
| 7190 | 
            +
                ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
         | 
| 7191 | 
            +
                ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8);
         | 
| 7192 | 
            +
                ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
         | 
| 7193 | 
            +
                ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
         | 
| 7194 | 
            +
                ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
         | 
| 7195 | 
            +
             | 
| 7196 | 
            +
                /* Process 2 sequences per loop iteration */
         | 
| 7197 | 
            +
                for (; i + 1 < nbSequences; i += 2) {
         | 
| 7198 | 
            +
                    /* Load 2 ZSTD_Sequence (32 bytes) */
         | 
| 7199 | 
            +
                    __m256i vin  = _mm256_loadu_si256((const __m256i*)(const void*)&inSeqs[i]);
         | 
| 7200 | 
            +
             | 
| 7201 | 
            +
                    /* Add {2, 0, -3, 0} in each 128-bit half */
         | 
| 7202 | 
            +
                    __m256i vadd = _mm256_add_epi32(vin, addition);
         | 
| 7203 | 
            +
             | 
| 7204 | 
            +
                    /* Check for long length */
         | 
| 7205 | 
            +
                    __m256i ll_cmp  = _mm256_cmpgt_epi32(vadd, limit);  /* 0xFFFFFFFF for element > 65535 */
         | 
| 7206 | 
            +
                    int ll_res  = _mm256_movemask_epi8(ll_cmp);
         | 
| 7207 | 
            +
             | 
| 7208 | 
            +
                    /* Shuffle bytes so each half gives us the 8 bytes we need */
         | 
| 7209 | 
            +
                    __m256i vshf = _mm256_shuffle_epi8(vadd, mask);
         | 
| 7210 | 
            +
                    /*
         | 
| 7211 | 
            +
                     * Now:
         | 
| 7212 | 
            +
                     *   Lane0 = seq0's 8 bytes
         | 
| 7213 | 
            +
                     *   Lane1 = 0
         | 
| 7214 | 
            +
                     *   Lane2 = seq1's 8 bytes
         | 
| 7215 | 
            +
                     *   Lane3 = 0
         | 
| 7216 | 
            +
                     */
         | 
| 7217 | 
            +
             | 
| 7218 | 
            +
                    /* Permute 64-bit lanes => move Lane2 down into Lane1. */
         | 
| 7219 | 
            +
                    __m256i vperm = _mm256_permute4x64_epi64(vshf, PERM_LANE_0X_E8);
         | 
| 7220 | 
            +
                    /*
         | 
| 7221 | 
            +
                     * Now the lower 16 bytes (Lane0+Lane1) = [seq0, seq1].
         | 
| 7222 | 
            +
                     * The upper 16 bytes are [Lane2, Lane3] = [seq1, 0], but we won't use them.
         | 
| 7223 | 
            +
                     */
         | 
| 7224 | 
            +
             | 
| 7225 | 
            +
                    /* Store only the lower 16 bytes => 2 SeqDef (8 bytes each) */
         | 
| 7226 | 
            +
                    _mm_storeu_si128((__m128i *)(void*)&dstSeqs[i], _mm256_castsi256_si128(vperm));
         | 
| 7227 | 
            +
                    /*
         | 
| 7228 | 
            +
                     * This writes out 16 bytes total:
         | 
| 7229 | 
            +
                     *   - offset 0..7  => seq0 (offBase, litLength, mlBase)
         | 
| 7230 | 
            +
                     *   - offset 8..15 => seq1 (offBase, litLength, mlBase)
         | 
| 7231 | 
            +
                     */
         | 
| 7232 | 
            +
             | 
| 7233 | 
            +
                    /* check (unlikely) long lengths > 65535
         | 
| 7234 | 
            +
                     * indices for lengths correspond to bits [4..7], [8..11], [20..23], [24..27]
         | 
| 7235 | 
            +
                     * => combined mask = 0x0FF00FF0
         | 
| 7236 | 
            +
                     */
         | 
| 7237 | 
            +
                    if (UNLIKELY((ll_res & 0x0FF00FF0) != 0)) {
         | 
| 7238 | 
            +
                        /* long length detected: let's figure out which one*/
         | 
| 7239 | 
            +
                        if (inSeqs[i].matchLength > 65535+MINMATCH) {
         | 
| 7240 | 
            +
                            assert(longLen == 0);
         | 
| 7241 | 
            +
                            longLen = i + 1;
         | 
| 7242 | 
            +
                        }
         | 
| 7243 | 
            +
                        if (inSeqs[i].litLength > 65535) {
         | 
| 7244 | 
            +
                            assert(longLen == 0);
         | 
| 7245 | 
            +
                            longLen = i + nbSequences + 1;
         | 
| 7246 | 
            +
                        }
         | 
| 7247 | 
            +
                        if (inSeqs[i+1].matchLength > 65535+MINMATCH) {
         | 
| 7248 | 
            +
                            assert(longLen == 0);
         | 
| 7249 | 
            +
                            longLen = i + 1 + 1;
         | 
| 7250 | 
            +
                        }
         | 
| 7251 | 
            +
                        if (inSeqs[i+1].litLength > 65535) {
         | 
| 7252 | 
            +
                            assert(longLen == 0);
         | 
| 7253 | 
            +
                            longLen = i + 1 + nbSequences + 1;
         | 
| 7254 | 
            +
                        }
         | 
| 7255 | 
            +
                    }
         | 
| 7256 | 
            +
                }
         | 
| 7257 | 
            +
             | 
| 7258 | 
            +
                /* Handle leftover if @nbSequences is odd */
         | 
| 7259 | 
            +
                if (i < nbSequences) {
         | 
| 7260 | 
            +
                    /* process last sequence */
         | 
| 7261 | 
            +
                    assert(i == nbSequences - 1);
         | 
| 7262 | 
            +
                    dstSeqs[i].offBase = OFFSET_TO_OFFBASE(inSeqs[i].offset);
         | 
| 7263 | 
            +
                    dstSeqs[i].litLength = (U16)inSeqs[i].litLength;
         | 
| 7264 | 
            +
                    dstSeqs[i].mlBase = (U16)(inSeqs[i].matchLength - MINMATCH);
         | 
| 7265 | 
            +
                    /* check (unlikely) long lengths > 65535 */
         | 
| 7266 | 
            +
                    if (UNLIKELY(inSeqs[i].matchLength > 65535+MINMATCH)) {
         | 
| 7267 | 
            +
                        assert(longLen == 0);
         | 
| 7268 | 
            +
                        longLen = i + 1;
         | 
| 7269 | 
            +
                    }
         | 
| 7270 | 
            +
                    if (UNLIKELY(inSeqs[i].litLength > 65535)) {
         | 
| 7271 | 
            +
                        assert(longLen == 0);
         | 
| 7272 | 
            +
                        longLen = i + nbSequences + 1;
         | 
| 7273 | 
            +
                    }
         | 
| 7274 | 
            +
                }
         | 
| 7275 | 
            +
             | 
| 7276 | 
            +
                return longLen;
         | 
| 7277 | 
            +
            }
         | 
| 7278 | 
            +
             | 
| 7279 | 
            +
            /* the vector implementation could also be ported to SSSE3,
         | 
| 7280 | 
            +
             * but since this implementation is targeting modern systems (>= Sapphire Rapid),
         | 
| 7281 | 
            +
             * it's not useful to develop and maintain code for older pre-AVX2 platforms */
         | 
| 7282 | 
            +
             | 
| 7283 | 
            +
            #else /* no AVX2 */
         | 
| 7284 | 
            +
             | 
| 7285 | 
            +
            static size_t convertSequences_noRepcodes(
         | 
| 7286 | 
            +
                SeqDef* dstSeqs,
         | 
| 7287 | 
            +
                const ZSTD_Sequence* inSeqs,
         | 
| 7288 | 
            +
                size_t nbSequences)
         | 
| 7289 | 
            +
            {
         | 
| 7290 | 
            +
                size_t longLen = 0;
         | 
| 7291 | 
            +
                size_t n;
         | 
| 7292 | 
            +
                for (n=0; n<nbSequences; n++) {
         | 
| 7293 | 
            +
                    dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
         | 
| 7294 | 
            +
                    dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
         | 
| 7295 | 
            +
                    dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
         | 
| 7296 | 
            +
                    /* check for long length > 65535 */
         | 
| 7297 | 
            +
                    if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
         | 
| 7298 | 
            +
                        assert(longLen == 0);
         | 
| 7299 | 
            +
                        longLen = n + 1;
         | 
| 7300 | 
            +
                    }
         | 
| 7301 | 
            +
                    if (UNLIKELY(inSeqs[n].litLength > 65535)) {
         | 
| 7302 | 
            +
                        assert(longLen == 0);
         | 
| 7303 | 
            +
                        longLen = n + nbSequences + 1;
         | 
| 7304 | 
            +
                    }
         | 
| 7305 | 
            +
                }
         | 
| 7306 | 
            +
                return longLen;
         | 
| 7307 | 
            +
            }
         | 
| 7308 | 
            +
             | 
| 7309 | 
            +
            #endif
         | 
| 7310 | 
            +
             | 
| 7311 | 
            +
            /*
         | 
| 7312 | 
            +
             * Precondition: Sequences must end on an explicit Block Delimiter
         | 
| 7313 | 
            +
             * @return: 0 on success, or an error code.
         | 
| 7314 | 
            +
             * Note: Sequence validation functionality has been disabled (removed).
         | 
| 7315 | 
            +
             * This is helpful to generate a lean main pipeline, improving performance.
         | 
| 7316 | 
            +
             * It may be re-inserted later.
         | 
| 7317 | 
            +
             */
         | 
| 7318 | 
            +
            size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
         | 
| 7319 | 
            +
                            const ZSTD_Sequence* const inSeqs, size_t nbSequences,
         | 
| 7320 | 
            +
                            int repcodeResolution)
         | 
| 7321 | 
            +
            {
         | 
| 7322 | 
            +
                Repcodes_t updatedRepcodes;
         | 
| 7323 | 
            +
                size_t seqNb = 0;
         | 
| 7324 | 
            +
             | 
| 7325 | 
            +
                DEBUGLOG(5, "ZSTD_convertBlockSequences (nbSequences = %zu)", nbSequences);
         | 
| 7326 | 
            +
             | 
| 7327 | 
            +
                RETURN_ERROR_IF(nbSequences >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
         | 
| 7328 | 
            +
                                "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
         | 
| 7329 | 
            +
             | 
| 7330 | 
            +
                ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
         | 
| 7331 | 
            +
             | 
| 7332 | 
            +
                /* check end condition */
         | 
| 7333 | 
            +
                assert(nbSequences >= 1);
         | 
| 7334 | 
            +
                assert(inSeqs[nbSequences-1].matchLength == 0);
         | 
| 7335 | 
            +
                assert(inSeqs[nbSequences-1].offset == 0);
         | 
| 7336 | 
            +
             | 
| 7337 | 
            +
                /* Convert Sequences from public format to internal format */
         | 
| 7338 | 
            +
                if (!repcodeResolution) {
         | 
| 7339 | 
            +
                    size_t const longl = convertSequences_noRepcodes(cctx->seqStore.sequencesStart, inSeqs, nbSequences-1);
         | 
| 7340 | 
            +
                    cctx->seqStore.sequences = cctx->seqStore.sequencesStart + nbSequences-1;
         | 
| 7341 | 
            +
                    if (longl) {
         | 
| 7342 | 
            +
                        DEBUGLOG(5, "long length");
         | 
| 7343 | 
            +
                        assert(cctx->seqStore.longLengthType == ZSTD_llt_none);
         | 
| 7344 | 
            +
                        if (longl <= nbSequences-1) {
         | 
| 7345 | 
            +
                            DEBUGLOG(5, "long match length detected at pos %zu", longl-1);
         | 
| 7346 | 
            +
                            cctx->seqStore.longLengthType = ZSTD_llt_matchLength;
         | 
| 7347 | 
            +
                            cctx->seqStore.longLengthPos = (U32)(longl-1);
         | 
| 7348 | 
            +
                        } else {
         | 
| 7349 | 
            +
                            DEBUGLOG(5, "long literals length detected at pos %zu", longl-nbSequences);
         | 
| 7350 | 
            +
                            assert(longl <= 2* (nbSequences-1));
         | 
| 7351 | 
            +
                            cctx->seqStore.longLengthType = ZSTD_llt_literalLength;
         | 
| 7352 | 
            +
                            cctx->seqStore.longLengthPos = (U32)(longl-(nbSequences-1)-1);
         | 
| 7353 | 
            +
                        }
         | 
| 7354 | 
            +
                    }
         | 
| 7355 | 
            +
                } else {
         | 
| 7356 | 
            +
                    for (seqNb = 0; seqNb < nbSequences - 1 ; seqNb++) {
         | 
| 7357 | 
            +
                        U32 const litLength = inSeqs[seqNb].litLength;
         | 
| 7358 | 
            +
                        U32 const matchLength = inSeqs[seqNb].matchLength;
         | 
| 7359 | 
            +
                        U32 const ll0 = (litLength == 0);
         | 
| 7360 | 
            +
                        U32 const offBase = ZSTD_finalizeOffBase(inSeqs[seqNb].offset, updatedRepcodes.rep, ll0);
         | 
| 7361 | 
            +
             | 
| 7362 | 
            +
                        DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
         | 
| 7363 | 
            +
                        ZSTD_storeSeqOnly(&cctx->seqStore, litLength, offBase, matchLength);
         | 
| 7364 | 
            +
                        ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0);
         | 
| 7365 | 
            +
                    }
         | 
| 7366 | 
            +
                }
         | 
| 7367 | 
            +
             | 
| 7368 | 
            +
                /* If we skipped repcode search while parsing, we need to update repcodes now */
         | 
| 7369 | 
            +
                if (!repcodeResolution && nbSequences > 1) {
         | 
| 7370 | 
            +
                    U32* const rep = updatedRepcodes.rep;
         | 
| 7371 | 
            +
             | 
| 7372 | 
            +
                    if (nbSequences >= 4) {
         | 
| 7373 | 
            +
                        U32 lastSeqIdx = (U32)nbSequences - 2; /* index of last full sequence */
         | 
| 7374 | 
            +
                        rep[2] = inSeqs[lastSeqIdx - 2].offset;
         | 
| 7375 | 
            +
                        rep[1] = inSeqs[lastSeqIdx - 1].offset;
         | 
| 7376 | 
            +
                        rep[0] = inSeqs[lastSeqIdx].offset;
         | 
| 7377 | 
            +
                    } else if (nbSequences == 3) {
         | 
| 7378 | 
            +
                        rep[2] = rep[0];
         | 
| 7379 | 
            +
                        rep[1] = inSeqs[0].offset;
         | 
| 7380 | 
            +
                        rep[0] = inSeqs[1].offset;
         | 
| 7381 | 
            +
                    } else {
         | 
| 7382 | 
            +
                        assert(nbSequences == 2);
         | 
| 7383 | 
            +
                        rep[2] = rep[1];
         | 
| 7384 | 
            +
                        rep[1] = rep[0];
         | 
| 7385 | 
            +
                        rep[0] = inSeqs[0].offset;
         | 
| 7386 | 
            +
                    }
         | 
| 7387 | 
            +
                }
         | 
| 7388 | 
            +
             | 
| 7389 | 
            +
                ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
         | 
| 7390 | 
            +
             | 
| 7391 | 
            +
                return 0;
         | 
| 7392 | 
            +
            }
         | 
| 7393 | 
            +
             | 
| 7394 | 
            +
            #if defined(ZSTD_ARCH_X86_AVX2)
         | 
| 7395 | 
            +
             | 
| 7396 | 
            +
            BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
         | 
| 7397 | 
            +
            {
         | 
| 7398 | 
            +
                size_t i;
         | 
| 7399 | 
            +
                __m256i const zeroVec = _mm256_setzero_si256();
         | 
| 7400 | 
            +
                __m256i sumVec = zeroVec;  /* accumulates match+lit in 32-bit lanes */
         | 
| 7401 | 
            +
                ZSTD_ALIGNED(32) U32 tmp[8];      /* temporary buffer for reduction */
         | 
| 7402 | 
            +
                size_t mSum = 0, lSum = 0;
         | 
| 7403 | 
            +
                ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
         | 
| 7404 | 
            +
             | 
| 7405 | 
            +
                /* Process 2 structs (32 bytes) at a time */
         | 
| 7406 | 
            +
                for (i = 0; i + 2 <= nbSeqs; i += 2) {
         | 
| 7407 | 
            +
                    /* Load two consecutive ZSTD_Sequence (8×4 = 32 bytes) */
         | 
| 7408 | 
            +
                    __m256i data     = _mm256_loadu_si256((const __m256i*)(const void*)&seqs[i]);
         | 
| 7409 | 
            +
                    /* check end of block signal */
         | 
| 7410 | 
            +
                    __m256i cmp      = _mm256_cmpeq_epi32(data, zeroVec);
         | 
| 7411 | 
            +
                    int cmp_res      = _mm256_movemask_epi8(cmp);
         | 
| 7412 | 
            +
                    /* indices for match lengths correspond to bits [8..11], [24..27]
         | 
| 7413 | 
            +
                     * => combined mask = 0x0F000F00 */
         | 
| 7414 | 
            +
                    ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
         | 
| 7415 | 
            +
                    if (cmp_res & 0x0F000F00) break;
         | 
| 7416 | 
            +
                    /* Accumulate in sumVec */
         | 
| 7417 | 
            +
                    sumVec           = _mm256_add_epi32(sumVec, data);
         | 
| 7418 | 
            +
                }
         | 
| 7419 | 
            +
             | 
| 7420 | 
            +
                /* Horizontal reduction */
         | 
| 7421 | 
            +
                _mm256_store_si256((__m256i*)tmp, sumVec);
         | 
| 7422 | 
            +
                lSum = tmp[1] + tmp[5];
         | 
| 7423 | 
            +
                mSum = tmp[2] + tmp[6];
         | 
| 7424 | 
            +
             | 
| 7425 | 
            +
                /* Handle the leftover */
         | 
| 7426 | 
            +
                for (; i < nbSeqs; i++) {
         | 
| 7427 | 
            +
                    lSum += seqs[i].litLength;
         | 
| 7428 | 
            +
                    mSum += seqs[i].matchLength;
         | 
| 7429 | 
            +
                    if (seqs[i].matchLength == 0) break; /* end of block */
         | 
| 7430 | 
            +
                }
         | 
| 7431 | 
            +
             | 
| 7432 | 
            +
                if (i==nbSeqs) {
         | 
| 7433 | 
            +
                    /* reaching end of sequences: end of block signal was not present */
         | 
| 7434 | 
            +
                    BlockSummary bs;
         | 
| 7435 | 
            +
                    bs.nbSequences = ERROR(externalSequences_invalid);
         | 
| 7436 | 
            +
                    return bs;
         | 
| 7437 | 
            +
                }
         | 
| 7438 | 
            +
                {   BlockSummary bs;
         | 
| 7439 | 
            +
                    bs.nbSequences = i+1;
         | 
| 7440 | 
            +
                    bs.blockSize = lSum + mSum;
         | 
| 7441 | 
            +
                    bs.litSize = lSum;
         | 
| 7442 | 
            +
                    return bs;
         | 
| 7443 | 
            +
                }
         | 
| 7444 | 
            +
            }
         | 
| 7445 | 
            +
             | 
| 7446 | 
            +
            #else
         | 
| 7447 | 
            +
             | 
| 7448 | 
            +
            BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
         | 
| 7449 | 
            +
            {
         | 
| 7450 | 
            +
                size_t totalMatchSize = 0;
         | 
| 7451 | 
            +
                size_t litSize = 0;
         | 
| 7452 | 
            +
                size_t n;
         | 
| 7453 | 
            +
                assert(seqs);
         | 
| 7454 | 
            +
                for (n=0; n<nbSeqs; n++) {
         | 
| 7455 | 
            +
                    totalMatchSize += seqs[n].matchLength;
         | 
| 7456 | 
            +
                    litSize += seqs[n].litLength;
         | 
| 7457 | 
            +
                    if (seqs[n].matchLength == 0) {
         | 
| 7458 | 
            +
                        assert(seqs[n].offset == 0);
         | 
| 7459 | 
            +
                        break;
         | 
| 7460 | 
            +
                    }
         | 
| 7461 | 
            +
                }
         | 
| 7462 | 
            +
                if (n==nbSeqs) {
         | 
| 7463 | 
            +
                    BlockSummary bs;
         | 
| 7464 | 
            +
                    bs.nbSequences = ERROR(externalSequences_invalid);
         | 
| 7465 | 
            +
                    return bs;
         | 
| 7466 | 
            +
                }
         | 
| 7467 | 
            +
                {   BlockSummary bs;
         | 
| 7468 | 
            +
                    bs.nbSequences = n+1;
         | 
| 7469 | 
            +
                    bs.blockSize = litSize + totalMatchSize;
         | 
| 7470 | 
            +
                    bs.litSize = litSize;
         | 
| 7471 | 
            +
                    return bs;
         | 
| 7472 | 
            +
                }
         | 
| 7473 | 
            +
            }
         | 
| 7474 | 
            +
            #endif
         | 
| 7475 | 
            +
             | 
| 7476 | 
            +
             | 
| 7477 | 
            +
            static size_t
         | 
| 7478 | 
            +
            ZSTD_compressSequencesAndLiterals_internal(ZSTD_CCtx* cctx,
         | 
| 7479 | 
            +
                                            void* dst, size_t dstCapacity,
         | 
| 7480 | 
            +
                                      const ZSTD_Sequence* inSeqs, size_t nbSequences,
         | 
| 7481 | 
            +
                                      const void* literals, size_t litSize, size_t srcSize)
         | 
| 7482 | 
            +
            {
         | 
| 7483 | 
            +
                size_t remaining = srcSize;
         | 
| 7484 | 
            +
                size_t cSize = 0;
         | 
| 7485 | 
            +
                BYTE* op = (BYTE*)dst;
         | 
| 7486 | 
            +
                int const repcodeResolution = (cctx->appliedParams.searchForExternalRepcodes == ZSTD_ps_enable);
         | 
| 7487 | 
            +
                assert(cctx->appliedParams.searchForExternalRepcodes != ZSTD_ps_auto);
         | 
| 7488 | 
            +
             | 
| 7489 | 
            +
                DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals_internal: nbSeqs=%zu, litSize=%zu", nbSequences, litSize);
         | 
| 7490 | 
            +
                RETURN_ERROR_IF(nbSequences == 0, externalSequences_invalid, "Requires at least 1 end-of-block");
         | 
| 7491 | 
            +
             | 
| 7492 | 
            +
                /* Special case: empty frame */
         | 
| 7493 | 
            +
                if ((nbSequences == 1) && (inSeqs[0].litLength == 0)) {
         | 
| 7494 | 
            +
                    U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1);
         | 
| 7495 | 
            +
                    RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "No room for empty frame block header");
         | 
| 7496 | 
            +
                    MEM_writeLE24(op, cBlockHeader24);
         | 
| 7497 | 
            +
                    op += ZSTD_blockHeaderSize;
         | 
| 7498 | 
            +
                    dstCapacity -= ZSTD_blockHeaderSize;
         | 
| 7499 | 
            +
                    cSize += ZSTD_blockHeaderSize;
         | 
| 7500 | 
            +
                }
         | 
| 7501 | 
            +
             | 
| 7502 | 
            +
                while (nbSequences) {
         | 
| 7503 | 
            +
                    size_t compressedSeqsSize, cBlockSize, conversionStatus;
         | 
| 7504 | 
            +
                    BlockSummary const block = ZSTD_get1BlockSummary(inSeqs, nbSequences);
         | 
| 7505 | 
            +
                    U32 const lastBlock = (block.nbSequences == nbSequences);
         | 
| 7506 | 
            +
                    FORWARD_IF_ERROR(block.nbSequences, "Error while trying to determine nb of sequences for a block");
         | 
| 7507 | 
            +
                    assert(block.nbSequences <= nbSequences);
         | 
| 7508 | 
            +
                    RETURN_ERROR_IF(block.litSize > litSize, externalSequences_invalid, "discrepancy: Sequences require more literals than present in buffer");
         | 
| 7509 | 
            +
                    ZSTD_resetSeqStore(&cctx->seqStore);
         | 
| 7510 | 
            +
             | 
| 7511 | 
            +
                    conversionStatus = ZSTD_convertBlockSequences(cctx,
         | 
| 7512 | 
            +
                                        inSeqs, block.nbSequences,
         | 
| 7513 | 
            +
                                        repcodeResolution);
         | 
| 7514 | 
            +
                    FORWARD_IF_ERROR(conversionStatus, "Bad sequence conversion");
         | 
| 7515 | 
            +
                    inSeqs += block.nbSequences;
         | 
| 7516 | 
            +
                    nbSequences -= block.nbSequences;
         | 
| 7517 | 
            +
                    remaining -= block.blockSize;
         | 
| 7518 | 
            +
             | 
| 7519 | 
            +
                    /* Note: when blockSize is very small, other variant send it uncompressed.
         | 
| 7520 | 
            +
                     * Here, we still send the sequences, because we don't have the original source to send it uncompressed.
         | 
| 7521 | 
            +
                     * One could imagine in theory reproducing the source from the sequences,
         | 
| 7522 | 
            +
                     * but that's complex and costly memory intensive, and goes against the objectives of this variant. */
         | 
| 7523 | 
            +
             | 
| 7524 | 
            +
                    RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "not enough dstCapacity to write a new compressed block");
         | 
| 7525 | 
            +
             | 
| 7526 | 
            +
                    compressedSeqsSize = ZSTD_entropyCompressSeqStore_internal(
         | 
| 7527 | 
            +
                                            op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
         | 
| 7528 | 
            +
                                            literals, block.litSize,
         | 
| 7529 | 
            +
                                            &cctx->seqStore,
         | 
| 7530 | 
            +
                                            &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy,
         | 
| 7531 | 
            +
                                            &cctx->appliedParams,
         | 
| 7532 | 
            +
                                            cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */,
         | 
| 7533 | 
            +
                                            cctx->bmi2);
         | 
| 7534 | 
            +
                    FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
         | 
| 7535 | 
            +
                    /* note: the spec forbids for any compressed block to be larger than maximum block size */
         | 
| 7536 | 
            +
                    if (compressedSeqsSize > cctx->blockSizeMax) compressedSeqsSize = 0;
         | 
| 7537 | 
            +
                    DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
         | 
| 7538 | 
            +
                    litSize -= block.litSize;
         | 
| 7539 | 
            +
                    literals = (const char*)literals + block.litSize;
         | 
| 7540 | 
            +
             | 
| 7541 | 
            +
                    /* Note: difficult to check source for RLE block when only Literals are provided,
         | 
| 7542 | 
            +
                     * but it could be considered from analyzing the sequence directly */
         | 
| 7543 | 
            +
             | 
| 7544 | 
            +
                    if (compressedSeqsSize == 0) {
         | 
| 7545 | 
            +
                        /* Sending uncompressed blocks is out of reach, because the source is not provided.
         | 
| 7546 | 
            +
                         * In theory, one could use the sequences to regenerate the source, like a decompressor,
         | 
| 7547 | 
            +
                         * but it's complex, and memory hungry, killing the purpose of this variant.
         | 
| 7548 | 
            +
                         * Current outcome: generate an error code.
         | 
| 7549 | 
            +
                         */
         | 
| 7550 | 
            +
                        RETURN_ERROR(cannotProduce_uncompressedBlock, "ZSTD_compressSequencesAndLiterals cannot generate an uncompressed block");
         | 
| 7551 | 
            +
                    } else {
         | 
| 7552 | 
            +
                        U32 cBlockHeader;
         | 
| 7553 | 
            +
                        assert(compressedSeqsSize > 1); /* no RLE */
         | 
| 7554 | 
            +
                        /* Error checking and repcodes update */
         | 
| 7555 | 
            +
                        ZSTD_blockState_confirmRepcodesAndEntropyTables(&cctx->blockState);
         | 
| 7556 | 
            +
                        if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
         | 
| 7557 | 
            +
                            cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
         | 
| 7558 | 
            +
             | 
| 7559 | 
            +
                        /* Write block header into beginning of block*/
         | 
| 7560 | 
            +
                        cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3);
         | 
| 7561 | 
            +
                        MEM_writeLE24(op, cBlockHeader);
         | 
| 7562 | 
            +
                        cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize;
         | 
| 7563 | 
            +
                        DEBUGLOG(5, "Writing out compressed block, size: %zu", cBlockSize);
         | 
| 7564 | 
            +
                    }
         | 
| 7565 | 
            +
             | 
| 7566 | 
            +
                    cSize += cBlockSize;
         | 
| 7567 | 
            +
                    op += cBlockSize;
         | 
| 7568 | 
            +
                    dstCapacity -= cBlockSize;
         | 
| 7569 | 
            +
                    cctx->isFirstBlock = 0;
         | 
| 7570 | 
            +
                    DEBUGLOG(5, "cSize running total: %zu (remaining dstCapacity=%zu)", cSize, dstCapacity);
         | 
| 7571 | 
            +
             | 
| 7572 | 
            +
                    if (lastBlock) {
         | 
| 7573 | 
            +
                        assert(nbSequences == 0);
         | 
| 7574 | 
            +
                        break;
         | 
| 7575 | 
            +
                    }
         | 
| 7576 | 
            +
                }
         | 
| 7577 | 
            +
             | 
| 7578 | 
            +
                RETURN_ERROR_IF(litSize != 0, externalSequences_invalid, "literals must be entirely and exactly consumed");
         | 
| 7579 | 
            +
                RETURN_ERROR_IF(remaining != 0, externalSequences_invalid, "Sequences must represent a total of exactly srcSize=%zu", srcSize);
         | 
| 7580 | 
            +
                DEBUGLOG(4, "cSize final total: %zu", cSize);
         | 
| 7581 | 
            +
                return cSize;
         | 
| 7582 | 
            +
            }
         | 
| 7583 | 
            +
             | 
| 7584 | 
            +
            size_t
         | 
| 7585 | 
            +
            ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
         | 
| 7586 | 
            +
                                void* dst, size_t dstCapacity,
         | 
| 7587 | 
            +
                                const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
         | 
| 7588 | 
            +
                                const void* literals, size_t litSize, size_t litCapacity,
         | 
| 7589 | 
            +
                                size_t decompressedSize)
         | 
| 7590 | 
            +
            {
         | 
| 7591 | 
            +
                BYTE* op = (BYTE*)dst;
         | 
| 7592 | 
            +
                size_t cSize = 0;
         | 
| 7593 | 
            +
             | 
| 7594 | 
            +
                /* Transparent initialization stage, same as compressStream2() */
         | 
| 7595 | 
            +
                DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals (dstCapacity=%zu)", dstCapacity);
         | 
| 7596 | 
            +
                assert(cctx != NULL);
         | 
| 7597 | 
            +
                if (litCapacity < litSize) {
         | 
| 7598 | 
            +
                    RETURN_ERROR(workSpace_tooSmall, "literals buffer is not large enough: must be at least 8 bytes larger than litSize (risk of read out-of-bound)");
         | 
| 7599 | 
            +
                }
         | 
| 7600 | 
            +
                FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, decompressedSize), "CCtx initialization failed");
         | 
| 7601 | 
            +
             | 
| 7602 | 
            +
                if (cctx->appliedParams.blockDelimiters == ZSTD_sf_noBlockDelimiters) {
         | 
| 7603 | 
            +
                    RETURN_ERROR(frameParameter_unsupported, "This mode is only compatible with explicit delimiters");
         | 
| 7604 | 
            +
                }
         | 
| 7605 | 
            +
                if (cctx->appliedParams.validateSequences) {
         | 
| 7606 | 
            +
                    RETURN_ERROR(parameter_unsupported, "This mode is not compatible with Sequence validation");
         | 
| 7607 | 
            +
                }
         | 
| 7608 | 
            +
                if (cctx->appliedParams.fParams.checksumFlag) {
         | 
| 7609 | 
            +
                    RETURN_ERROR(frameParameter_unsupported, "this mode is not compatible with frame checksum");
         | 
| 7610 | 
            +
                }
         | 
| 7611 | 
            +
             | 
| 7612 | 
            +
                /* Begin writing output, starting with frame header */
         | 
| 7613 | 
            +
                {   size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
         | 
| 7614 | 
            +
                                &cctx->appliedParams, decompressedSize, cctx->dictID);
         | 
| 7615 | 
            +
                    op += frameHeaderSize;
         | 
| 7616 | 
            +
                    assert(frameHeaderSize <= dstCapacity);
         | 
| 7617 | 
            +
                    dstCapacity -= frameHeaderSize;
         | 
| 7618 | 
            +
                    cSize += frameHeaderSize;
         | 
| 7619 | 
            +
                }
         | 
| 7620 | 
            +
             | 
| 7621 | 
            +
                /* Now generate compressed blocks */
         | 
| 7622 | 
            +
                {   size_t const cBlocksSize = ZSTD_compressSequencesAndLiterals_internal(cctx,
         | 
| 7623 | 
            +
                                                        op, dstCapacity,
         | 
| 7624 | 
            +
                                                        inSeqs, inSeqsSize,
         | 
| 7625 | 
            +
                                                        literals, litSize, decompressedSize);
         | 
| 7626 | 
            +
                    FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!");
         | 
| 7627 | 
            +
                    cSize += cBlocksSize;
         | 
| 7628 | 
            +
                    assert(cBlocksSize <= dstCapacity);
         | 
| 7629 | 
            +
                    dstCapacity -= cBlocksSize;
         | 
| 7630 | 
            +
                }
         | 
| 7631 | 
            +
             | 
| 7632 | 
            +
                DEBUGLOG(4, "Final compressed size: %zu", cSize);
         | 
| 7633 | 
            +
                return cSize;
         | 
| 7634 | 
            +
            }
         | 
| 7635 | 
            +
             | 
| 6948 7636 | 
             
            /*======   Finalize   ======*/
         | 
| 6949 7637 |  | 
| 6950 7638 | 
             
            static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream* zcs)
         | 
| @@ -6963,7 +7651,6 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) | |
| 6963 7651 | 
             
                return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);
         | 
| 6964 7652 | 
             
            }
         | 
| 6965 7653 |  | 
| 6966 | 
            -
             | 
| 6967 7654 | 
             
            size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
         | 
| 6968 7655 | 
             
            {
         | 
| 6969 7656 | 
             
                ZSTD_inBuffer input = inBuffer_forEndFlush(zcs);
         | 
| @@ -7044,7 +7731,7 @@ static void ZSTD_dedicatedDictSearch_revertCParams( | |
| 7044 7731 | 
             
                }
         | 
| 7045 7732 | 
             
            }
         | 
| 7046 7733 |  | 
| 7047 | 
            -
            static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize,  | 
| 7734 | 
            +
            static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
         | 
| 7048 7735 | 
             
            {
         | 
| 7049 7736 | 
             
                switch (mode) {
         | 
| 7050 7737 | 
             
                case ZSTD_cpm_unknown:
         | 
| @@ -7068,8 +7755,8 @@ static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMo | |
| 7068 7755 | 
             
             * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
         | 
| 7069 7756 | 
             
             *  Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
         | 
| 7070 7757 | 
             
             *        Use dictSize == 0 for unknown or unused.
         | 
| 7071 | 
            -
             *  Note: `mode` controls how we treat the `dictSize`. See docs for ` | 
| 7072 | 
            -
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize,  | 
| 7758 | 
            +
             *  Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */
         | 
| 7759 | 
            +
            static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
         | 
| 7073 7760 | 
             
            {
         | 
| 7074 7761 | 
             
                U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode);
         | 
| 7075 7762 | 
             
                U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
         | 
| @@ -7107,7 +7794,9 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l | |
| 7107 7794 | 
             
             *  same idea as ZSTD_getCParams()
         | 
| 7108 7795 | 
             
             * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
         | 
| 7109 7796 | 
             
             *  Fields of `ZSTD_frameParameters` are set to default values */
         | 
| 7110 | 
            -
            static ZSTD_parameters | 
| 7797 | 
            +
            static ZSTD_parameters
         | 
| 7798 | 
            +
            ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
         | 
| 7799 | 
            +
            {
         | 
| 7111 7800 | 
             
                ZSTD_parameters params;
         | 
| 7112 7801 | 
             
                ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
         | 
| 7113 7802 | 
             
                DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
         | 
| @@ -7121,7 +7810,8 @@ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned lo | |
| 7121 7810 | 
             
             *  same idea as ZSTD_getCParams()
         | 
| 7122 7811 | 
             
             * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
         | 
| 7123 7812 | 
             
             *  Fields of `ZSTD_frameParameters` are set to default values */
         | 
| 7124 | 
            -
            ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) | 
| 7813 | 
            +
            ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
         | 
| 7814 | 
            +
            {
         | 
| 7125 7815 | 
             
                if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
         | 
| 7126 7816 | 
             
                return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
         | 
| 7127 7817 | 
             
            }
         | 
| @@ -7129,8 +7819,8 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH | |
| 7129 7819 | 
             
            void ZSTD_registerSequenceProducer(
         | 
| 7130 7820 | 
             
                ZSTD_CCtx* zc,
         | 
| 7131 7821 | 
             
                void* extSeqProdState,
         | 
| 7132 | 
            -
                ZSTD_sequenceProducer_F extSeqProdFunc
         | 
| 7133 | 
            -
             | 
| 7822 | 
            +
                ZSTD_sequenceProducer_F extSeqProdFunc)
         | 
| 7823 | 
            +
            {
         | 
| 7134 7824 | 
             
                assert(zc != NULL);
         | 
| 7135 7825 | 
             
                ZSTD_CCtxParams_registerSequenceProducer(
         | 
| 7136 7826 | 
             
                    &zc->requestedParams, extSeqProdState, extSeqProdFunc
         | 
| @@ -7140,8 +7830,8 @@ void ZSTD_registerSequenceProducer( | |
| 7140 7830 | 
             
            void ZSTD_CCtxParams_registerSequenceProducer(
         | 
| 7141 7831 | 
             
              ZSTD_CCtx_params* params,
         | 
| 7142 7832 | 
             
              void* extSeqProdState,
         | 
| 7143 | 
            -
              ZSTD_sequenceProducer_F extSeqProdFunc
         | 
| 7144 | 
            -
             | 
| 7833 | 
            +
              ZSTD_sequenceProducer_F extSeqProdFunc)
         | 
| 7834 | 
            +
            {
         | 
| 7145 7835 | 
             
                assert(params != NULL);
         | 
| 7146 7836 | 
             
                if (extSeqProdFunc != NULL) {
         | 
| 7147 7837 | 
             
                    params->extSeqProdFunc = extSeqProdFunc;
         |