zstd-ruby 1.3.4.0 → 1.3.5.0
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/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +56 -10
- data/ext/zstdruby/libzstd/README.md +4 -0
- data/ext/zstdruby/libzstd/common/bitstream.h +6 -19
- data/ext/zstdruby/libzstd/common/compiler.h +3 -3
- data/ext/zstdruby/libzstd/common/cpu.h +1 -2
- data/ext/zstdruby/libzstd/common/debug.c +44 -0
- data/ext/zstdruby/libzstd/common/debug.h +123 -0
- data/ext/zstdruby/libzstd/common/entropy_common.c +16 -1
- data/ext/zstdruby/libzstd/common/fse.h +45 -41
- data/ext/zstdruby/libzstd/common/fse_decompress.c +1 -1
- data/ext/zstdruby/libzstd/common/huf.h +34 -27
- data/ext/zstdruby/libzstd/common/pool.c +89 -32
- data/ext/zstdruby/libzstd/common/pool.h +29 -19
- data/ext/zstdruby/libzstd/common/zstd_common.c +0 -5
- data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -37
- data/ext/zstdruby/libzstd/compress/fse_compress.c +28 -163
- data/ext/zstdruby/libzstd/compress/hist.c +195 -0
- data/ext/zstdruby/libzstd/compress/hist.h +92 -0
- data/ext/zstdruby/libzstd/compress/huf_compress.c +14 -6
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +798 -350
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +120 -34
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +247 -87
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +4 -1
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +177 -56
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +4 -1
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +331 -65
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +13 -0
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +15 -20
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +1 -2
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +503 -300
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +7 -0
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +122 -47
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -5
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +325 -325
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +80 -43
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +9 -2
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +5 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +12 -61
- data/ext/zstdruby/libzstd/zstd.h +137 -69
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +7 -3
| @@ -0,0 +1,92 @@ | |
| 1 | 
            +
            /* ******************************************************************
         | 
| 2 | 
            +
               hist : Histogram functions
         | 
| 3 | 
            +
               part of Finite State Entropy project
         | 
| 4 | 
            +
               Copyright (C) 2013-present, Yann Collet.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
               BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
               Redistribution and use in source and binary forms, with or without
         | 
| 9 | 
            +
               modification, are permitted provided that the following conditions are
         | 
| 10 | 
            +
               met:
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                   * Redistributions of source code must retain the above copyright
         | 
| 13 | 
            +
               notice, this list of conditions and the following disclaimer.
         | 
| 14 | 
            +
                   * Redistributions in binary form must reproduce the above
         | 
| 15 | 
            +
               copyright notice, this list of conditions and the following disclaimer
         | 
| 16 | 
            +
               in the documentation and/or other materials provided with the
         | 
| 17 | 
            +
               distribution.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
               THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
         | 
| 20 | 
            +
               "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
         | 
| 21 | 
            +
               LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
         | 
| 22 | 
            +
               A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
         | 
| 23 | 
            +
               OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
         | 
| 24 | 
            +
               SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
         | 
| 25 | 
            +
               LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
         | 
| 26 | 
            +
               DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
         | 
| 27 | 
            +
               THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
         | 
| 28 | 
            +
               (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
         | 
| 29 | 
            +
               OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                You can contact the author at :
         | 
| 32 | 
            +
                - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
         | 
| 33 | 
            +
                - Public forum : https://groups.google.com/forum/#!forum/lz4c
         | 
| 34 | 
            +
            ****************************************************************** */
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            /* --- dependencies --- */
         | 
| 37 | 
            +
            #include <stddef.h>   /* size_t */
         | 
| 38 | 
            +
             | 
| 39 | 
            +
             | 
| 40 | 
            +
            /* --- simple histogram functions --- */
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            /*! HIST_count():
         | 
| 43 | 
            +
             *  Provides the precise count of each byte within a table 'count'.
         | 
| 44 | 
            +
             *  'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
         | 
| 45 | 
            +
             *  Updates *maxSymbolValuePtr with actual largest symbol value detected.
         | 
| 46 | 
            +
             *  @return : count of the most frequent symbol (which isn't identified).
         | 
| 47 | 
            +
             *            or an error code, which can be tested using HIST_isError().
         | 
| 48 | 
            +
             *            note : if return == srcSize, there is only one symbol.
         | 
| 49 | 
            +
             */
         | 
| 50 | 
            +
            size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
         | 
| 51 | 
            +
                              const void* src, size_t srcSize);
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            unsigned HIST_isError(size_t code);  /*< tells if a return value is an error code */
         | 
| 54 | 
            +
             | 
| 55 | 
            +
             | 
| 56 | 
            +
            /* --- advanced histogram functions --- */
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            #define HIST_WKSP_SIZE_U32 1024
         | 
| 59 | 
            +
            /** HIST_count_wksp() :
         | 
| 60 | 
            +
             *  Same as HIST_count(), but using an externally provided scratch buffer.
         | 
| 61 | 
            +
             *  Benefit is this function will use very little stack space.
         | 
| 62 | 
            +
             * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32
         | 
| 63 | 
            +
             */
         | 
| 64 | 
            +
            size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
         | 
| 65 | 
            +
                                   const void* src, size_t srcSize,
         | 
| 66 | 
            +
                                   unsigned* workSpace);
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            /** HIST_countFast() :
         | 
| 69 | 
            +
             *  same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr.
         | 
| 70 | 
            +
             *  This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr`
         | 
| 71 | 
            +
             */
         | 
| 72 | 
            +
            size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
         | 
| 73 | 
            +
                                  const void* src, size_t srcSize);
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            /** HIST_countFast_wksp() :
         | 
| 76 | 
            +
             *  Same as HIST_countFast(), but using an externally provided scratch buffer.
         | 
| 77 | 
            +
             * `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32
         | 
| 78 | 
            +
             */
         | 
| 79 | 
            +
            size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
         | 
| 80 | 
            +
                                       const void* src, size_t srcSize,
         | 
| 81 | 
            +
                                       unsigned* workSpace);
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            /*! HIST_count_simple() :
         | 
| 84 | 
            +
             *  Same as HIST_countFast(), this function is unsafe,
         | 
| 85 | 
            +
             *  and will segfault if any value within `src` is `> *maxSymbolValuePtr`.
         | 
| 86 | 
            +
             *  It is also a bit slower for large inputs.
         | 
| 87 | 
            +
             *  However, it does not need any additional memory (not even on stack).
         | 
| 88 | 
            +
             * @return : count of the most frequent symbol.
         | 
| 89 | 
            +
             *  Note this function doesn't produce any error (i.e. it must succeed).
         | 
| 90 | 
            +
             */
         | 
| 91 | 
            +
            unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
         | 
| 92 | 
            +
                                       const void* src, size_t srcSize);
         | 
| @@ -45,8 +45,9 @@ | |
| 45 45 | 
             
            ****************************************************************/
         | 
| 46 46 | 
             
            #include <string.h>     /* memcpy, memset */
         | 
| 47 47 | 
             
            #include <stdio.h>      /* printf (debug) */
         | 
| 48 | 
            -
            #include "bitstream.h"
         | 
| 49 48 | 
             
            #include "compiler.h"
         | 
| 49 | 
            +
            #include "bitstream.h"
         | 
| 50 | 
            +
            #include "hist.h"
         | 
| 50 51 | 
             
            #define FSE_STATIC_LINKING_ONLY   /* FSE_optimalTableLog_internal */
         | 
| 51 52 | 
             
            #include "fse.h"        /* header compression */
         | 
| 52 53 | 
             
            #define HUF_STATIC_LINKING_ONLY
         | 
| @@ -58,7 +59,7 @@ | |
| 58 59 | 
             
            *  Error Management
         | 
| 59 60 | 
             
            ****************************************************************/
         | 
| 60 61 | 
             
            #define HUF_isError ERR_isError
         | 
| 61 | 
            -
            #define HUF_STATIC_ASSERT(c)  | 
| 62 | 
            +
            #define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)   /* use only *after* variable declarations */
         | 
| 62 63 | 
             
            #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
         | 
| 63 64 | 
             
            #define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
         | 
| 64 65 |  | 
| @@ -100,9 +101,9 @@ size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, | |
| 100 101 | 
             
                if (wtSize <= 1) return 0;  /* Not compressible */
         | 
| 101 102 |  | 
| 102 103 | 
             
                /* Scan input and build symbol stats */
         | 
| 103 | 
            -
                {    | 
| 104 | 
            +
                {   unsigned const maxCount = HIST_count_simple(count, &maxSymbolValue, weightTable, wtSize);   /* never fails */
         | 
| 104 105 | 
             
                    if (maxCount == wtSize) return 1;   /* only a single symbol in src : rle */
         | 
| 105 | 
            -
                    if (maxCount == 1) return 0; | 
| 106 | 
            +
                    if (maxCount == 1) return 0;        /* each symbol present maximum once => not compressible */
         | 
| 106 107 | 
             
                }
         | 
| 107 108 |  | 
| 108 109 | 
             
                tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
         | 
| @@ -216,6 +217,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32* maxSymbolValuePtr, const void* src | |
| 216 217 | 
             
                return readSize;
         | 
| 217 218 | 
             
            }
         | 
| 218 219 |  | 
| 220 | 
            +
            U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue)
         | 
| 221 | 
            +
            {
         | 
| 222 | 
            +
                const HUF_CElt* table = (const HUF_CElt*)symbolTable;
         | 
| 223 | 
            +
                assert(symbolValue <= HUF_SYMBOLVALUE_MAX);
         | 
| 224 | 
            +
                return table[symbolValue].nbBits;
         | 
| 225 | 
            +
            }
         | 
| 226 | 
            +
             | 
| 219 227 |  | 
| 220 228 | 
             
            typedef struct nodeElt_s {
         | 
| 221 229 | 
             
                U32 count;
         | 
| @@ -660,9 +668,9 @@ static size_t HUF_compress_internal ( | |
| 660 668 | 
             
                }
         | 
| 661 669 |  | 
| 662 670 | 
             
                /* Scan input and build symbol stats */
         | 
| 663 | 
            -
                {   CHECK_V_F(largest,  | 
| 671 | 
            +
                {   CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->count) );
         | 
| 664 672 | 
             
                    if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }   /* single symbol, rle */
         | 
| 665 | 
            -
                    if (largest <= (srcSize >> 7)+ | 
| 673 | 
            +
                    if (largest <= (srcSize >> 7)+4) return 0;   /* heuristic : probably not compressible enough */
         | 
| 666 674 | 
             
                }
         | 
| 667 675 |  | 
| 668 676 | 
             
                /* Check validity of previous table */
         | 
| @@ -8,21 +8,13 @@ | |
| 8 8 | 
             
             * You may select, at your option, one of the above-listed licenses.
         | 
| 9 9 | 
             
             */
         | 
| 10 10 |  | 
| 11 | 
            -
             | 
| 12 | 
            -
            /*-*************************************
         | 
| 13 | 
            -
            *  Tuning parameters
         | 
| 14 | 
            -
            ***************************************/
         | 
| 15 | 
            -
            #ifndef ZSTD_CLEVEL_DEFAULT
         | 
| 16 | 
            -
            #  define ZSTD_CLEVEL_DEFAULT 3
         | 
| 17 | 
            -
            #endif
         | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 11 | 
             
            /*-*************************************
         | 
| 21 12 | 
             
            *  Dependencies
         | 
| 22 13 | 
             
            ***************************************/
         | 
| 23 14 | 
             
            #include <string.h>         /* memset */
         | 
| 24 15 | 
             
            #include "cpu.h"
         | 
| 25 16 | 
             
            #include "mem.h"
         | 
| 17 | 
            +
            #include "hist.h"           /* HIST_countFast_wksp */
         | 
| 26 18 | 
             
            #define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */
         | 
| 27 19 | 
             
            #include "fse.h"
         | 
| 28 20 | 
             
            #define HUF_STATIC_LINKING_ONLY
         | 
| @@ -64,17 +56,26 @@ ZSTD_CCtx* ZSTD_createCCtx(void) | |
| 64 56 | 
             
                return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
         | 
| 65 57 | 
             
            }
         | 
| 66 58 |  | 
| 59 | 
            +
            static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
         | 
| 60 | 
            +
            {
         | 
| 61 | 
            +
                assert(cctx != NULL);
         | 
| 62 | 
            +
                memset(cctx, 0, sizeof(*cctx));
         | 
| 63 | 
            +
                cctx->customMem = memManager;
         | 
| 64 | 
            +
                cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
         | 
| 65 | 
            +
                {   size_t const err = ZSTD_CCtx_resetParameters(cctx);
         | 
| 66 | 
            +
                    assert(!ZSTD_isError(err));
         | 
| 67 | 
            +
                    (void)err;
         | 
| 68 | 
            +
                }
         | 
| 69 | 
            +
            }
         | 
| 70 | 
            +
             | 
| 67 71 | 
             
            ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
         | 
| 68 72 | 
             
            {
         | 
| 69 73 | 
             
                ZSTD_STATIC_ASSERT(zcss_init==0);
         | 
| 70 74 | 
             
                ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
         | 
| 71 75 | 
             
                if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
         | 
| 72 | 
            -
                {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*) | 
| 76 | 
            +
                {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
         | 
| 73 77 | 
             
                    if (!cctx) return NULL;
         | 
| 74 | 
            -
                    cctx | 
| 75 | 
            -
                    cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
         | 
| 76 | 
            -
                    cctx->requestedParams.fParams.contentSizeFlag = 1;
         | 
| 77 | 
            -
                    cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
         | 
| 78 | 
            +
                    ZSTD_initCCtx(cctx, customMem);
         | 
| 78 79 | 
             
                    return cctx;
         | 
| 79 80 | 
             
                }
         | 
| 80 81 | 
             
            }
         | 
| @@ -102,17 +103,24 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize) | |
| 102 103 | 
             
                return cctx;
         | 
| 103 104 | 
             
            }
         | 
| 104 105 |  | 
| 105 | 
            -
             | 
| 106 | 
            +
            static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
         | 
| 106 107 | 
             
            {
         | 
| 107 | 
            -
                 | 
| 108 | 
            -
                 | 
| 108 | 
            +
                assert(cctx != NULL);
         | 
| 109 | 
            +
                assert(cctx->staticSize == 0);
         | 
| 109 110 | 
             
                ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
         | 
| 110 111 | 
             
                ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL;
         | 
| 111 112 | 
             
            #ifdef ZSTD_MULTITHREAD
         | 
| 112 113 | 
             
                ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
         | 
| 113 114 | 
             
            #endif
         | 
| 115 | 
            +
            }
         | 
| 116 | 
            +
             | 
| 117 | 
            +
            size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
         | 
| 118 | 
            +
            {
         | 
| 119 | 
            +
                if (cctx==NULL) return 0;   /* support free on NULL */
         | 
| 120 | 
            +
                if (cctx->staticSize) return ERROR(memory_allocation);   /* not compatible with static CCtx */
         | 
| 121 | 
            +
                ZSTD_freeCCtxContent(cctx);
         | 
| 114 122 | 
             
                ZSTD_free(cctx, cctx->customMem);
         | 
| 115 | 
            -
                return 0; | 
| 123 | 
            +
                return 0;
         | 
| 116 124 | 
             
            }
         | 
| 117 125 |  | 
| 118 126 |  | 
| @@ -143,21 +151,6 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) | |
| 143 151 | 
             
            /* private API call, for dictBuilder only */
         | 
| 144 152 | 
             
            const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
         | 
| 145 153 |  | 
| 146 | 
            -
            ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
         | 
| 147 | 
            -
                    const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
         | 
| 148 | 
            -
            {
         | 
| 149 | 
            -
                ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
         | 
| 150 | 
            -
                if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
         | 
| 151 | 
            -
                if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
         | 
| 152 | 
            -
                if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
         | 
| 153 | 
            -
                if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
         | 
| 154 | 
            -
                if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
         | 
| 155 | 
            -
                if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
         | 
| 156 | 
            -
                if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
         | 
| 157 | 
            -
                if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
         | 
| 158 | 
            -
                return cParams;
         | 
| 159 | 
            -
            }
         | 
| 160 | 
            -
             | 
| 161 154 | 
             
            static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
         | 
| 162 155 | 
             
                    ZSTD_compressionParameters cParams)
         | 
| 163 156 | 
             
            {
         | 
| @@ -251,7 +244,6 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) | |
| 251 244 | 
             
                case ZSTD_p_minMatch:
         | 
| 252 245 | 
             
                case ZSTD_p_targetLength:
         | 
| 253 246 | 
             
                case ZSTD_p_compressionStrategy:
         | 
| 254 | 
            -
                case ZSTD_p_compressLiterals:
         | 
| 255 247 | 
             
                    return 1;
         | 
| 256 248 |  | 
| 257 249 | 
             
                case ZSTD_p_format:
         | 
| @@ -268,6 +260,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) | |
| 268 260 | 
             
                case ZSTD_p_ldmMinMatch:
         | 
| 269 261 | 
             
                case ZSTD_p_ldmBucketSizeLog:
         | 
| 270 262 | 
             
                case ZSTD_p_ldmHashEveryLog:
         | 
| 263 | 
            +
                case ZSTD_p_forceAttachDict:
         | 
| 271 264 | 
             
                default:
         | 
| 272 265 | 
             
                    return 0;
         | 
| 273 266 | 
             
                }
         | 
| @@ -302,7 +295,6 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v | |
| 302 295 | 
             
                    if (cctx->cdict) return ERROR(stage_wrong);
         | 
| 303 296 | 
             
                    return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
         | 
| 304 297 |  | 
| 305 | 
            -
                case ZSTD_p_compressLiterals:
         | 
| 306 298 | 
             
                case ZSTD_p_contentSizeFlag:
         | 
| 307 299 | 
             
                case ZSTD_p_checksumFlag:
         | 
| 308 300 | 
             
                case ZSTD_p_dictIDFlag:
         | 
| @@ -313,6 +305,9 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v | |
| 313 305 | 
             
                                               * default : 0 when using a CDict, 1 when using a Prefix */
         | 
| 314 306 | 
             
                    return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
         | 
| 315 307 |  | 
| 308 | 
            +
                case ZSTD_p_forceAttachDict:
         | 
| 309 | 
            +
                    return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
         | 
| 310 | 
            +
             | 
| 316 311 | 
             
                case ZSTD_p_nbWorkers:
         | 
| 317 312 | 
             
                    if ((value>0) && cctx->staticSize) {
         | 
| 318 313 | 
             
                        return ERROR(parameter_unsupported);  /* MT not compatible with static alloc */
         | 
| @@ -351,7 +346,6 @@ size_t ZSTD_CCtxParam_setParameter( | |
| 351 346 | 
             
                    int cLevel = (int)value;  /* cast expected to restore negative sign */
         | 
| 352 347 | 
             
                    if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
         | 
| 353 348 | 
             
                    if (cLevel) {  /* 0 : does not change current level */
         | 
| 354 | 
            -
                        CCtxParams->disableLiteralCompression = (cLevel<0);  /* negative levels disable huffman */
         | 
| 355 349 | 
             
                        CCtxParams->compressionLevel = cLevel;
         | 
| 356 350 | 
             
                    }
         | 
| 357 351 | 
             
                    if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
         | 
| @@ -399,10 +393,6 @@ size_t ZSTD_CCtxParam_setParameter( | |
| 399 393 | 
             
                    CCtxParams->cParams.strategy = (ZSTD_strategy)value;
         | 
| 400 394 | 
             
                    return (size_t)CCtxParams->cParams.strategy;
         | 
| 401 395 |  | 
| 402 | 
            -
                case ZSTD_p_compressLiterals:
         | 
| 403 | 
            -
                    CCtxParams->disableLiteralCompression = !value;
         | 
| 404 | 
            -
                    return !CCtxParams->disableLiteralCompression;
         | 
| 405 | 
            -
             | 
| 406 396 | 
             
                case ZSTD_p_contentSizeFlag :
         | 
| 407 397 | 
             
                    /* Content size written in frame header _when known_ (default:1) */
         | 
| 408 398 | 
             
                    DEBUGLOG(4, "set content size flag = %u", (value>0));
         | 
| @@ -423,6 +413,12 @@ size_t ZSTD_CCtxParam_setParameter( | |
| 423 413 | 
             
                    CCtxParams->forceWindow = (value > 0);
         | 
| 424 414 | 
             
                    return CCtxParams->forceWindow;
         | 
| 425 415 |  | 
| 416 | 
            +
                case ZSTD_p_forceAttachDict :
         | 
| 417 | 
            +
                    CCtxParams->attachDictPref = value ?
         | 
| 418 | 
            +
                                                (value > 0 ? ZSTD_dictForceAttach : ZSTD_dictForceCopy) :
         | 
| 419 | 
            +
                                                 ZSTD_dictDefaultAttach;
         | 
| 420 | 
            +
                    return CCtxParams->attachDictPref;
         | 
| 421 | 
            +
             | 
| 426 422 | 
             
                case ZSTD_p_nbWorkers :
         | 
| 427 423 | 
             
            #ifndef ZSTD_MULTITHREAD
         | 
| 428 424 | 
             
                    if (value>0) return ERROR(parameter_unsupported);
         | 
| @@ -477,6 +473,98 @@ size_t ZSTD_CCtxParam_setParameter( | |
| 477 473 | 
             
                }
         | 
| 478 474 | 
             
            }
         | 
| 479 475 |  | 
| 476 | 
            +
            size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value)
         | 
| 477 | 
            +
            {
         | 
| 478 | 
            +
                return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value);
         | 
| 479 | 
            +
            }
         | 
| 480 | 
            +
             | 
| 481 | 
            +
            size_t ZSTD_CCtxParam_getParameter(
         | 
| 482 | 
            +
                    ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned* value)
         | 
| 483 | 
            +
            {
         | 
| 484 | 
            +
                switch(param)
         | 
| 485 | 
            +
                {
         | 
| 486 | 
            +
                case ZSTD_p_format :
         | 
| 487 | 
            +
                    *value = CCtxParams->format;
         | 
| 488 | 
            +
                    break;
         | 
| 489 | 
            +
                case ZSTD_p_compressionLevel :
         | 
| 490 | 
            +
                    *value = CCtxParams->compressionLevel;
         | 
| 491 | 
            +
                    break;
         | 
| 492 | 
            +
                case ZSTD_p_windowLog :
         | 
| 493 | 
            +
                    *value = CCtxParams->cParams.windowLog;
         | 
| 494 | 
            +
                    break;
         | 
| 495 | 
            +
                case ZSTD_p_hashLog :
         | 
| 496 | 
            +
                    *value = CCtxParams->cParams.hashLog;
         | 
| 497 | 
            +
                    break;
         | 
| 498 | 
            +
                case ZSTD_p_chainLog :
         | 
| 499 | 
            +
                    *value = CCtxParams->cParams.chainLog;
         | 
| 500 | 
            +
                    break;
         | 
| 501 | 
            +
                case ZSTD_p_searchLog :
         | 
| 502 | 
            +
                    *value = CCtxParams->cParams.searchLog;
         | 
| 503 | 
            +
                    break;
         | 
| 504 | 
            +
                case ZSTD_p_minMatch :
         | 
| 505 | 
            +
                    *value = CCtxParams->cParams.searchLength;
         | 
| 506 | 
            +
                    break;
         | 
| 507 | 
            +
                case ZSTD_p_targetLength :
         | 
| 508 | 
            +
                    *value = CCtxParams->cParams.targetLength;
         | 
| 509 | 
            +
                    break;
         | 
| 510 | 
            +
                case ZSTD_p_compressionStrategy :
         | 
| 511 | 
            +
                    *value = (unsigned)CCtxParams->cParams.strategy;
         | 
| 512 | 
            +
                    break;
         | 
| 513 | 
            +
                case ZSTD_p_contentSizeFlag :
         | 
| 514 | 
            +
                    *value = CCtxParams->fParams.contentSizeFlag;
         | 
| 515 | 
            +
                    break;
         | 
| 516 | 
            +
                case ZSTD_p_checksumFlag :
         | 
| 517 | 
            +
                    *value = CCtxParams->fParams.checksumFlag;
         | 
| 518 | 
            +
                    break;
         | 
| 519 | 
            +
                case ZSTD_p_dictIDFlag :
         | 
| 520 | 
            +
                    *value = !CCtxParams->fParams.noDictIDFlag;
         | 
| 521 | 
            +
                    break;
         | 
| 522 | 
            +
                case ZSTD_p_forceMaxWindow :
         | 
| 523 | 
            +
                    *value = CCtxParams->forceWindow;
         | 
| 524 | 
            +
                    break;
         | 
| 525 | 
            +
                case ZSTD_p_forceAttachDict :
         | 
| 526 | 
            +
                    *value = CCtxParams->attachDictPref;
         | 
| 527 | 
            +
                    break;
         | 
| 528 | 
            +
                case ZSTD_p_nbWorkers :
         | 
| 529 | 
            +
            #ifndef ZSTD_MULTITHREAD
         | 
| 530 | 
            +
                    assert(CCtxParams->nbWorkers == 0);
         | 
| 531 | 
            +
            #endif
         | 
| 532 | 
            +
                    *value = CCtxParams->nbWorkers;
         | 
| 533 | 
            +
                    break;
         | 
| 534 | 
            +
                case ZSTD_p_jobSize :
         | 
| 535 | 
            +
            #ifndef ZSTD_MULTITHREAD
         | 
| 536 | 
            +
                    return ERROR(parameter_unsupported);
         | 
| 537 | 
            +
            #else
         | 
| 538 | 
            +
                    *value = CCtxParams->jobSize;
         | 
| 539 | 
            +
                    break;
         | 
| 540 | 
            +
            #endif
         | 
| 541 | 
            +
                case ZSTD_p_overlapSizeLog :
         | 
| 542 | 
            +
            #ifndef ZSTD_MULTITHREAD
         | 
| 543 | 
            +
                    return ERROR(parameter_unsupported);
         | 
| 544 | 
            +
            #else
         | 
| 545 | 
            +
                    *value = CCtxParams->overlapSizeLog;
         | 
| 546 | 
            +
                    break;
         | 
| 547 | 
            +
            #endif
         | 
| 548 | 
            +
                case ZSTD_p_enableLongDistanceMatching :
         | 
| 549 | 
            +
                    *value = CCtxParams->ldmParams.enableLdm;
         | 
| 550 | 
            +
                    break;
         | 
| 551 | 
            +
                case ZSTD_p_ldmHashLog :
         | 
| 552 | 
            +
                    *value = CCtxParams->ldmParams.hashLog;
         | 
| 553 | 
            +
                    break;
         | 
| 554 | 
            +
                case ZSTD_p_ldmMinMatch :
         | 
| 555 | 
            +
                    *value = CCtxParams->ldmParams.minMatchLength;
         | 
| 556 | 
            +
                    break;
         | 
| 557 | 
            +
                case ZSTD_p_ldmBucketSizeLog :
         | 
| 558 | 
            +
                    *value = CCtxParams->ldmParams.bucketSizeLog;
         | 
| 559 | 
            +
                    break;
         | 
| 560 | 
            +
                case ZSTD_p_ldmHashEveryLog :
         | 
| 561 | 
            +
                    *value = CCtxParams->ldmParams.hashEveryLog;
         | 
| 562 | 
            +
                    break;
         | 
| 563 | 
            +
                default: return ERROR(parameter_unsupported);
         | 
| 564 | 
            +
                }
         | 
| 565 | 
            +
                return 0;
         | 
| 566 | 
            +
            }
         | 
| 567 | 
            +
             | 
| 480 568 | 
             
            /** ZSTD_CCtx_setParametersUsingCCtxParams() :
         | 
| 481 569 | 
             
             *  just applies `params` into `cctx`
         | 
| 482 570 | 
             
             *  no action is performed, parameters are merely stored.
         | 
| @@ -487,6 +575,7 @@ size_t ZSTD_CCtxParam_setParameter( | |
| 487 575 | 
             
            size_t ZSTD_CCtx_setParametersUsingCCtxParams(
         | 
| 488 576 | 
             
                    ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
         | 
| 489 577 | 
             
            {
         | 
| 578 | 
            +
                DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
         | 
| 490 579 | 
             
                if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
         | 
| 491 580 | 
             
                if (cctx->cdict) return ERROR(stage_wrong);
         | 
| 492 581 |  | 
| @@ -565,18 +654,19 @@ size_t ZSTD_CCtx_refPrefix_advanced( | |
| 565 654 | 
             
                return 0;
         | 
| 566 655 | 
             
            }
         | 
| 567 656 |  | 
| 568 | 
            -
             | 
| 657 | 
            +
            /*! ZSTD_CCtx_reset() :
         | 
| 658 | 
            +
             *  Also dumps dictionary */
         | 
| 659 | 
            +
            void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
         | 
| 569 660 | 
             
            {
         | 
| 570 661 | 
             
                cctx->streamStage = zcss_init;
         | 
| 571 662 | 
             
                cctx->pledgedSrcSizePlusOne = 0;
         | 
| 572 663 | 
             
            }
         | 
| 573 664 |  | 
| 574 | 
            -
             | 
| 575 | 
            -
             *  Also dumps dictionary */
         | 
| 576 | 
            -
            void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
         | 
| 665 | 
            +
            size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx)
         | 
| 577 666 | 
             
            {
         | 
| 578 | 
            -
                 | 
| 667 | 
            +
                if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
         | 
| 579 668 | 
             
                cctx->cdict = NULL;
         | 
| 669 | 
            +
                return ZSTD_CCtxParams_reset(&cctx->requestedParams);
         | 
| 580 670 | 
             
            }
         | 
| 581 671 |  | 
| 582 672 | 
             
            /** ZSTD_checkCParams() :
         | 
| @@ -589,8 +679,6 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) | |
| 589 679 | 
             
                CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
         | 
| 590 680 | 
             
                CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
         | 
| 591 681 | 
             
                CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
         | 
| 592 | 
            -
                if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN)
         | 
| 593 | 
            -
                    return ERROR(parameter_unsupported);
         | 
| 594 682 | 
             
                if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
         | 
| 595 683 | 
             
                    return ERROR(parameter_unsupported);
         | 
| 596 684 | 
             
                return 0;
         | 
| @@ -599,7 +687,8 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) | |
| 599 687 | 
             
            /** ZSTD_clampCParams() :
         | 
| 600 688 | 
             
             *  make CParam values within valid range.
         | 
| 601 689 | 
             
             *  @return : valid CParams */
         | 
| 602 | 
            -
            static ZSTD_compressionParameters | 
| 690 | 
            +
            static ZSTD_compressionParameters
         | 
| 691 | 
            +
            ZSTD_clampCParams(ZSTD_compressionParameters cParams)
         | 
| 603 692 | 
             
            {
         | 
| 604 693 | 
             
            #   define CLAMP(val,min,max) {      \
         | 
| 605 694 | 
             
                    if (val<min) val=min;        \
         | 
| @@ -610,8 +699,7 @@ static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters c | |
| 610 699 | 
             
                CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
         | 
| 611 700 | 
             
                CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
         | 
| 612 701 | 
             
                CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
         | 
| 613 | 
            -
                 | 
| 614 | 
            -
                if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) cParams.strategy = ZSTD_btultra;
         | 
| 702 | 
            +
                CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra);
         | 
| 615 703 | 
             
                return cParams;
         | 
| 616 704 | 
             
            }
         | 
| 617 705 |  | 
| @@ -627,8 +715,11 @@ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) | |
| 627 715 | 
             
                optimize `cPar` for a given input (`srcSize` and `dictSize`).
         | 
| 628 716 | 
             
                mostly downsizing to reduce memory consumption and initialization latency.
         | 
| 629 717 | 
             
                Both `srcSize` and `dictSize` are optional (use 0 if unknown).
         | 
| 630 | 
            -
                Note : cPar is  | 
| 631 | 
            -
             | 
| 718 | 
            +
                Note : cPar is assumed validated. Use ZSTD_checkCParams() to ensure this condition. */
         | 
| 719 | 
            +
            static ZSTD_compressionParameters
         | 
| 720 | 
            +
            ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
         | 
| 721 | 
            +
                                        unsigned long long srcSize,
         | 
| 722 | 
            +
                                        size_t dictSize)
         | 
| 632 723 | 
             
            {
         | 
| 633 724 | 
             
                static const U64 minSrcSize = 513; /* (1<<9) + 1 */
         | 
| 634 725 | 
             
                static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
         | 
| @@ -648,7 +739,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameter | |
| 648 739 | 
             
                                        ZSTD_highbit32(tSize-1) + 1;
         | 
| 649 740 | 
             
                    if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
         | 
| 650 741 | 
             
                }
         | 
| 651 | 
            -
                if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
         | 
| 742 | 
            +
                if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1;
         | 
| 652 743 | 
             
                {   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
         | 
| 653 744 | 
             
                    if (cycleLog > cPar.windowLog)
         | 
| 654 745 | 
             
                        cPar.chainLog -= (cycleLog - cPar.windowLog);
         | 
| @@ -660,13 +751,34 @@ ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameter | |
| 660 751 | 
             
                return cPar;
         | 
| 661 752 | 
             
            }
         | 
| 662 753 |  | 
| 663 | 
            -
            ZSTD_compressionParameters | 
| 754 | 
            +
            ZSTD_compressionParameters
         | 
| 755 | 
            +
            ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
         | 
| 756 | 
            +
                               unsigned long long srcSize,
         | 
| 757 | 
            +
                               size_t dictSize)
         | 
| 664 758 | 
             
            {
         | 
| 665 759 | 
             
                cPar = ZSTD_clampCParams(cPar);
         | 
| 666 760 | 
             
                return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
         | 
| 667 761 | 
             
            }
         | 
| 668 762 |  | 
| 669 | 
            -
             | 
| 763 | 
            +
            ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
         | 
| 764 | 
            +
                    const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
         | 
| 765 | 
            +
            {
         | 
| 766 | 
            +
                ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
         | 
| 767 | 
            +
                if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
         | 
| 768 | 
            +
                if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
         | 
| 769 | 
            +
                if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
         | 
| 770 | 
            +
                if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
         | 
| 771 | 
            +
                if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
         | 
| 772 | 
            +
                if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
         | 
| 773 | 
            +
                if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
         | 
| 774 | 
            +
                if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
         | 
| 775 | 
            +
                assert(!ZSTD_checkCParams(cParams));
         | 
| 776 | 
            +
                return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
         | 
| 777 | 
            +
            }
         | 
| 778 | 
            +
             | 
| 779 | 
            +
            static size_t
         | 
| 780 | 
            +
            ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
         | 
| 781 | 
            +
                                   const U32 forCCtx)
         | 
| 670 782 | 
             
            {
         | 
| 671 783 | 
             
                size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
         | 
| 672 784 | 
             
                size_t const hSize = ((size_t)1) << cParams->hashLog;
         | 
| @@ -752,12 +864,14 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams) | |
| 752 864 | 
             
                return ZSTD_estimateCStreamSize_usingCCtxParams(¶ms);
         | 
| 753 865 | 
             
            }
         | 
| 754 866 |  | 
| 755 | 
            -
            static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) | 
| 867 | 
            +
            static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
         | 
| 868 | 
            +
            {
         | 
| 756 869 | 
             
                ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
         | 
| 757 870 | 
             
                return ZSTD_estimateCStreamSize_usingCParams(cParams);
         | 
| 758 871 | 
             
            }
         | 
| 759 872 |  | 
| 760 | 
            -
            size_t ZSTD_estimateCStreamSize(int compressionLevel) | 
| 873 | 
            +
            size_t ZSTD_estimateCStreamSize(int compressionLevel)
         | 
| 874 | 
            +
            {
         | 
| 761 875 | 
             
                int level;
         | 
| 762 876 | 
             
                size_t memBudget = 0;
         | 
| 763 877 | 
             
                for (level=1; level<=compressionLevel; level++) {
         | 
| @@ -851,10 +965,10 @@ static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) | |
| 851 965 | 
             
                int i;
         | 
| 852 966 | 
             
                for (i = 0; i < ZSTD_REP_NUM; ++i)
         | 
| 853 967 | 
             
                    bs->rep[i] = repStartValue[i];
         | 
| 854 | 
            -
                bs->entropy. | 
| 855 | 
            -
                bs->entropy.offcode_repeatMode = FSE_repeat_none;
         | 
| 856 | 
            -
                bs->entropy.matchlength_repeatMode = FSE_repeat_none;
         | 
| 857 | 
            -
                bs->entropy.litlength_repeatMode = FSE_repeat_none;
         | 
| 968 | 
            +
                bs->entropy.huf.repeatMode = HUF_repeat_none;
         | 
| 969 | 
            +
                bs->entropy.fse.offcode_repeatMode = FSE_repeat_none;
         | 
| 970 | 
            +
                bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none;
         | 
| 971 | 
            +
                bs->entropy.fse.litlength_repeatMode = FSE_repeat_none;
         | 
| 858 972 | 
             
            }
         | 
| 859 973 |  | 
| 860 974 | 
             
            /*! ZSTD_invalidateMatchState()
         | 
| @@ -866,8 +980,10 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) | |
| 866 980 | 
             
                ZSTD_window_clear(&ms->window);
         | 
| 867 981 |  | 
| 868 982 | 
             
                ms->nextToUpdate = ms->window.dictLimit + 1;
         | 
| 983 | 
            +
                ms->nextToUpdate3 = ms->window.dictLimit + 1;
         | 
| 869 984 | 
             
                ms->loadedDictEnd = 0;
         | 
| 870 985 | 
             
                ms->opt.litLengthSum = 0;  /* force reset of btopt stats */
         | 
| 986 | 
            +
                ms->dictMatchState = NULL;
         | 
| 871 987 | 
             
            }
         | 
| 872 988 |  | 
| 873 989 | 
             
            /*! ZSTD_continueCCtx() :
         | 
| @@ -900,7 +1016,11 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pl | |
| 900 1016 |  | 
| 901 1017 | 
             
            typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
         | 
| 902 1018 |  | 
| 903 | 
            -
            static void* | 
| 1019 | 
            +
            static void*
         | 
| 1020 | 
            +
            ZSTD_reset_matchState(ZSTD_matchState_t* ms,
         | 
| 1021 | 
            +
                                  void* ptr,
         | 
| 1022 | 
            +
                            const ZSTD_compressionParameters* cParams,
         | 
| 1023 | 
            +
                                  ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
         | 
| 904 1024 | 
             
            {
         | 
| 905 1025 | 
             
                size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
         | 
| 906 1026 | 
             
                size_t const hSize = ((size_t)1) << cParams->hashLog;
         | 
| @@ -941,10 +1061,18 @@ static void* ZSTD_reset_matchState(ZSTD_matchState_t* ms, void* ptr, ZSTD_compre | |
| 941 1061 | 
             
                return ptr;
         | 
| 942 1062 | 
             
            }
         | 
| 943 1063 |  | 
| 1064 | 
            +
            #define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
         | 
| 1065 | 
            +
            #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128  /* when workspace is continuously too large
         | 
| 1066 | 
            +
                                                     * during at least this number of times,
         | 
| 1067 | 
            +
                                                     * context's memory usage is considered wasteful,
         | 
| 1068 | 
            +
                                                     * because it's sized to handle a worst case scenario which rarely happens.
         | 
| 1069 | 
            +
                                                     * In which case, resize it down to free some memory */
         | 
| 1070 | 
            +
             | 
| 944 1071 | 
             
            /*! ZSTD_resetCCtx_internal() :
         | 
| 945 1072 | 
             
                note : `params` are assumed fully validated at this stage */
         | 
| 946 1073 | 
             
            static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
         | 
| 947 | 
            -
                                                  ZSTD_CCtx_params params, | 
| 1074 | 
            +
                                                  ZSTD_CCtx_params params,
         | 
| 1075 | 
            +
                                                  U64 pledgedSrcSize,
         | 
| 948 1076 | 
             
                                                  ZSTD_compResetPolicy_e const crp,
         | 
| 949 1077 | 
             
                                                  ZSTD_buffered_policy_e const zbuff)
         | 
| 950 1078 | 
             
            {
         | 
| @@ -956,20 +1084,20 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 956 1084 | 
             
                    if (ZSTD_equivalentParams(zc->appliedParams, params,
         | 
| 957 1085 | 
             
                                            zc->inBuffSize, zc->blockSize,
         | 
| 958 1086 | 
             
                                            zbuff, pledgedSrcSize)) {
         | 
| 959 | 
            -
                        DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=% | 
| 960 | 
            -
                                    zc->appliedParams.cParams.windowLog,  | 
| 961 | 
            -
                         | 
| 1087 | 
            +
                        DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
         | 
| 1088 | 
            +
                                    zc->appliedParams.cParams.windowLog, zc->blockSize);
         | 
| 1089 | 
            +
                        zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0);   /* if it was too large, it still is */
         | 
| 1090 | 
            +
                        if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION)
         | 
| 1091 | 
            +
                            return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
         | 
| 962 1092 | 
             
                }   }
         | 
| 963 1093 | 
             
                DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
         | 
| 964 1094 |  | 
| 965 1095 | 
             
                if (params.ldmParams.enableLdm) {
         | 
| 966 1096 | 
             
                    /* Adjust long distance matching parameters */
         | 
| 967 | 
            -
                    params.ldmParams.windowLog = params.cParams.windowLog;
         | 
| 968 1097 | 
             
                    ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams);
         | 
| 969 1098 | 
             
                    assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
         | 
| 970 1099 | 
             
                    assert(params.ldmParams.hashEveryLog < 32);
         | 
| 971 | 
            -
                    zc->ldmState.hashPower =
         | 
| 972 | 
            -
                            ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
         | 
| 1100 | 
            +
                    zc->ldmState.hashPower = ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
         | 
| 973 1101 | 
             
                }
         | 
| 974 1102 |  | 
| 975 1103 | 
             
                {   size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
         | 
| @@ -981,7 +1109,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 981 1109 | 
             
                    size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
         | 
| 982 1110 | 
             
                    size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
         | 
| 983 1111 | 
             
                    size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
         | 
| 984 | 
            -
                    void* ptr;
         | 
| 1112 | 
            +
                    void* ptr;   /* used to partition workSpace */
         | 
| 985 1113 |  | 
| 986 1114 | 
             
                    /* Check if workSpace is large enough, alloc a new one if needed */
         | 
| 987 1115 | 
             
                    {   size_t const entropySpace = HUF_WORKSPACE_SIZE;
         | 
| @@ -993,14 +1121,20 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 993 1121 | 
             
                        size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace +
         | 
| 994 1122 | 
             
                                                   ldmSeqSpace + matchStateSize + tokenSpace +
         | 
| 995 1123 | 
             
                                                   bufferSpace;
         | 
| 996 | 
            -
             | 
| 997 | 
            -
             | 
| 998 | 
            -
                         | 
| 999 | 
            -
             | 
| 1000 | 
            -
                         | 
| 1001 | 
            -
             | 
| 1002 | 
            -
             | 
| 1003 | 
            -
             | 
| 1124 | 
            +
             | 
| 1125 | 
            +
                        int const workSpaceTooSmall = zc->workSpaceSize < neededSpace;
         | 
| 1126 | 
            +
                        int const workSpaceTooLarge = zc->workSpaceSize > ZSTD_WORKSPACETOOLARGE_FACTOR * neededSpace;
         | 
| 1127 | 
            +
                        int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION);
         | 
| 1128 | 
            +
                        zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0;
         | 
| 1129 | 
            +
             | 
| 1130 | 
            +
                        DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
         | 
| 1131 | 
            +
                                    neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
         | 
| 1132 | 
            +
                        DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
         | 
| 1133 | 
            +
             | 
| 1134 | 
            +
                        if (workSpaceTooSmall || workSpaceWasteful) {
         | 
| 1135 | 
            +
                            DEBUGLOG(4, "Need to resize workSpaceSize from %zuKB to %zuKB",
         | 
| 1136 | 
            +
                                        zc->workSpaceSize >> 10,
         | 
| 1137 | 
            +
                                        neededSpace >> 10);
         | 
| 1004 1138 | 
             
                            /* static cctx : no resize, error out */
         | 
| 1005 1139 | 
             
                            if (zc->staticSize) return ERROR(memory_allocation);
         | 
| 1006 1140 |  | 
| @@ -1009,9 +1143,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, | |
| 1009 1143 | 
             
                            zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
         | 
| 1010 1144 | 
             
                            if (zc->workSpace == NULL) return ERROR(memory_allocation);
         | 
| 1011 1145 | 
             
                            zc->workSpaceSize = neededSpace;
         | 
| 1146 | 
            +
                            zc->workSpaceOversizedDuration = 0;
         | 
| 1012 1147 | 
             
                            ptr = zc->workSpace;
         | 
| 1013 1148 |  | 
| 1014 | 
            -
                            /* Statically sized space. | 
| 1149 | 
            +
                            /* Statically sized space.
         | 
| 1150 | 
            +
                             * entropyWorkspace never moves,
         | 
| 1151 | 
            +
                             * though prev/next block swap places */
         | 
| 1015 1152 | 
             
                            assert(((size_t)zc->workSpace & 3) == 0);   /* ensure correct alignment */
         | 
| 1016 1153 | 
             
                            assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t));
         | 
| 1017 1154 | 
             
                            zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace;
         | 
| @@ -1100,48 +1237,98 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) { | |
| 1100 1237 |  | 
| 1101 1238 | 
             
            static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
         | 
| 1102 1239 | 
             
                                        const ZSTD_CDict* cdict,
         | 
| 1103 | 
            -
                                         | 
| 1104 | 
            -
                                        ZSTD_frameParameters fParams,
         | 
| 1240 | 
            +
                                        ZSTD_CCtx_params params,
         | 
| 1105 1241 | 
             
                                        U64 pledgedSrcSize,
         | 
| 1106 1242 | 
             
                                        ZSTD_buffered_policy_e zbuff)
         | 
| 1107 1243 | 
             
            {
         | 
| 1108 | 
            -
                 | 
| 1244 | 
            +
                /* We have a choice between copying the dictionary context into the working
         | 
| 1245 | 
            +
                 * context, or referencing the dictionary context from the working context
         | 
| 1246 | 
            +
                 * in-place. We decide here which strategy to use. */
         | 
| 1247 | 
            +
                const U64 attachDictSizeCutoffs[(unsigned)ZSTD_btultra+1] = {
         | 
| 1248 | 
            +
                    8 KB, /* unused */
         | 
| 1249 | 
            +
                    8 KB, /* ZSTD_fast */
         | 
| 1250 | 
            +
                    16 KB, /* ZSTD_dfast */
         | 
| 1251 | 
            +
                    32 KB, /* ZSTD_greedy */
         | 
| 1252 | 
            +
                    32 KB, /* ZSTD_lazy */
         | 
| 1253 | 
            +
                    32 KB, /* ZSTD_lazy2 */
         | 
| 1254 | 
            +
                    32 KB, /* ZSTD_btlazy2 */
         | 
| 1255 | 
            +
                    32 KB, /* ZSTD_btopt */
         | 
| 1256 | 
            +
                    8 KB /* ZSTD_btultra */
         | 
| 1257 | 
            +
                };
         | 
| 1258 | 
            +
                const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy]
         | 
| 1259 | 
            +
                                      || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
         | 
| 1260 | 
            +
                                      || params.attachDictPref == ZSTD_dictForceAttach )
         | 
| 1261 | 
            +
                                    && params.attachDictPref != ZSTD_dictForceCopy
         | 
| 1262 | 
            +
                                    && !params.forceWindow /* dictMatchState isn't correctly
         | 
| 1263 | 
            +
                                                            * handled in _enforceMaxDist */
         | 
| 1264 | 
            +
                                    && ZSTD_equivalentCParams(cctx->appliedParams.cParams,
         | 
| 1265 | 
            +
                                                              cdict->cParams);
         | 
| 1266 | 
            +
             | 
| 1267 | 
            +
                DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
         | 
| 1268 | 
            +
             | 
| 1269 | 
            +
             | 
| 1270 | 
            +
                {   unsigned const windowLog = params.cParams.windowLog;
         | 
| 1271 | 
            +
                    assert(windowLog != 0);
         | 
| 1109 1272 | 
             
                    /* Copy only compression parameters related to tables. */
         | 
| 1110 1273 | 
             
                    params.cParams = cdict->cParams;
         | 
| 1111 | 
            -
                     | 
| 1112 | 
            -
                    params.fParams = fParams;
         | 
| 1274 | 
            +
                    params.cParams.windowLog = windowLog;
         | 
| 1113 1275 | 
             
                    ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
         | 
| 1114 | 
            -
                                            ZSTDcrp_noMemset, | 
| 1276 | 
            +
                                            attachDict ? ZSTDcrp_continue : ZSTDcrp_noMemset,
         | 
| 1277 | 
            +
                                            zbuff);
         | 
| 1115 1278 | 
             
                    assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
         | 
| 1116 1279 | 
             
                    assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
         | 
| 1117 1280 | 
             
                    assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
         | 
| 1118 1281 | 
             
                }
         | 
| 1119 1282 |  | 
| 1120 | 
            -
                 | 
| 1121 | 
            -
             | 
| 1122 | 
            -
             | 
| 1123 | 
            -
                     | 
| 1124 | 
            -
             | 
| 1125 | 
            -
             | 
| 1126 | 
            -
                     | 
| 1127 | 
            -
             | 
| 1128 | 
            -
             | 
| 1129 | 
            -
             | 
| 1130 | 
            -
             | 
| 1131 | 
            -
             | 
| 1132 | 
            -
             | 
| 1133 | 
            -
             | 
| 1134 | 
            -
             | 
| 1283 | 
            +
                if (attachDict) {
         | 
| 1284 | 
            +
                    const U32 cdictLen = (U32)( cdict->matchState.window.nextSrc
         | 
| 1285 | 
            +
                                              - cdict->matchState.window.base);
         | 
| 1286 | 
            +
                    if (cdictLen == 0) {
         | 
| 1287 | 
            +
                        /* don't even attach dictionaries with no contents */
         | 
| 1288 | 
            +
                        DEBUGLOG(4, "skipping attaching empty dictionary");
         | 
| 1289 | 
            +
                    } else {
         | 
| 1290 | 
            +
                        DEBUGLOG(4, "attaching dictionary into context");
         | 
| 1291 | 
            +
                        cctx->blockState.matchState.dictMatchState = &cdict->matchState;
         | 
| 1292 | 
            +
             | 
| 1293 | 
            +
                        /* prep working match state so dict matches never have negative indices
         | 
| 1294 | 
            +
                         * when they are translated to the working context's index space. */
         | 
| 1295 | 
            +
                        if (cctx->blockState.matchState.window.dictLimit < cdictLen) {
         | 
| 1296 | 
            +
                            cctx->blockState.matchState.window.nextSrc =
         | 
| 1297 | 
            +
                                cctx->blockState.matchState.window.base + cdictLen;
         | 
| 1298 | 
            +
                            ZSTD_window_clear(&cctx->blockState.matchState.window);
         | 
| 1299 | 
            +
                        }
         | 
| 1300 | 
            +
                        cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
         | 
| 1301 | 
            +
                    }
         | 
| 1302 | 
            +
                } else {
         | 
| 1303 | 
            +
                    DEBUGLOG(4, "copying dictionary into context");
         | 
| 1304 | 
            +
                    /* copy tables */
         | 
| 1305 | 
            +
                    {   size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
         | 
| 1306 | 
            +
                        size_t const hSize =  (size_t)1 << cdict->cParams.hashLog;
         | 
| 1307 | 
            +
                        size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
         | 
| 1308 | 
            +
                        assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize);  /* chainTable must follow hashTable */
         | 
| 1309 | 
            +
                        assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
         | 
| 1310 | 
            +
                        assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize);  /* chainTable must follow hashTable */
         | 
| 1311 | 
            +
                        assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
         | 
| 1312 | 
            +
                        memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace);   /* presumes all tables follow each other */
         | 
| 1313 | 
            +
                    }
         | 
| 1135 1314 |  | 
| 1136 | 
            -
             | 
| 1137 | 
            -
             | 
| 1138 | 
            -
             | 
| 1139 | 
            -
             | 
| 1140 | 
            -
                     | 
| 1141 | 
            -
             | 
| 1142 | 
            -
                     | 
| 1143 | 
            -
                     | 
| 1315 | 
            +
                    /* Zero the hashTable3, since the cdict never fills it */
         | 
| 1316 | 
            +
                    {   size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
         | 
| 1317 | 
            +
                        assert(cdict->matchState.hashLog3 == 0);
         | 
| 1318 | 
            +
                        memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
         | 
| 1319 | 
            +
                    }
         | 
| 1320 | 
            +
             | 
| 1321 | 
            +
                    /* copy dictionary offsets */
         | 
| 1322 | 
            +
                    {
         | 
| 1323 | 
            +
                        ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
         | 
| 1324 | 
            +
                        ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
         | 
| 1325 | 
            +
                        dstMatchState->window       = srcMatchState->window;
         | 
| 1326 | 
            +
                        dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
         | 
| 1327 | 
            +
                        dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
         | 
| 1328 | 
            +
                        dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
         | 
| 1329 | 
            +
                    }
         | 
| 1144 1330 | 
             
                }
         | 
| 1331 | 
            +
             | 
| 1145 1332 | 
             
                cctx->dictID = cdict->dictID;
         | 
| 1146 1333 |  | 
| 1147 1334 | 
             
                /* copy block state */
         | 
| @@ -1192,7 +1379,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, | |
| 1192 1379 |  | 
| 1193 1380 | 
             
                /* copy dictionary offsets */
         | 
| 1194 1381 | 
             
                {
         | 
| 1195 | 
            -
                    ZSTD_matchState_t | 
| 1382 | 
            +
                    const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
         | 
| 1196 1383 | 
             
                    ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
         | 
| 1197 1384 | 
             
                    dstMatchState->window       = srcMatchState->window;
         | 
| 1198 1385 | 
             
                    dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
         | 
| @@ -1356,16 +1543,24 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, cons | |
| 1356 1543 | 
             
            }
         | 
| 1357 1544 |  | 
| 1358 1545 |  | 
| 1359 | 
            -
             | 
| 1546 | 
            +
            /* ZSTD_minGain() :
         | 
| 1547 | 
            +
             * minimum compression required
         | 
| 1548 | 
            +
             * to generate a compress block or a compressed literals section.
         | 
| 1549 | 
            +
             * note : use same formula for both situations */
         | 
| 1550 | 
            +
            static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
         | 
| 1551 | 
            +
            {
         | 
| 1552 | 
            +
                U32 const minlog = (strat==ZSTD_btultra) ? 7 : 6;
         | 
| 1553 | 
            +
                return (srcSize >> minlog) + 2;
         | 
| 1554 | 
            +
            }
         | 
| 1360 1555 |  | 
| 1361 | 
            -
            static size_t ZSTD_compressLiterals ( | 
| 1362 | 
            -
                                                  | 
| 1556 | 
            +
            static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
         | 
| 1557 | 
            +
                                                 ZSTD_hufCTables_t* nextHuf,
         | 
| 1363 1558 | 
             
                                                 ZSTD_strategy strategy, int disableLiteralCompression,
         | 
| 1364 1559 | 
             
                                                 void* dst, size_t dstCapacity,
         | 
| 1365 1560 | 
             
                                           const void* src, size_t srcSize,
         | 
| 1366 1561 | 
             
                                                 U32* workspace, const int bmi2)
         | 
| 1367 1562 | 
             
            {
         | 
| 1368 | 
            -
                size_t const minGain = ZSTD_minGain(srcSize);
         | 
| 1563 | 
            +
                size_t const minGain = ZSTD_minGain(srcSize, strategy);
         | 
| 1369 1564 | 
             
                size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
         | 
| 1370 1565 | 
             
                BYTE*  const ostart = (BYTE*)dst;
         | 
| 1371 1566 | 
             
                U32 singleStream = srcSize < 256;
         | 
| @@ -1376,27 +1571,25 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy, | |
| 1376 1571 | 
             
                            disableLiteralCompression);
         | 
| 1377 1572 |  | 
| 1378 1573 | 
             
                /* Prepare nextEntropy assuming reusing the existing table */
         | 
| 1379 | 
            -
                 | 
| 1380 | 
            -
                memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable,
         | 
| 1381 | 
            -
                       sizeof(prevEntropy->hufCTable));
         | 
| 1574 | 
            +
                memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
         | 
| 1382 1575 |  | 
| 1383 1576 | 
             
                if (disableLiteralCompression)
         | 
| 1384 1577 | 
             
                    return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
         | 
| 1385 1578 |  | 
| 1386 1579 | 
             
                /* small ? don't even attempt compression (speed opt) */
         | 
| 1387 1580 | 
             
            #   define COMPRESS_LITERALS_SIZE_MIN 63
         | 
| 1388 | 
            -
                {   size_t const minLitSize = ( | 
| 1581 | 
            +
                {   size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
         | 
| 1389 1582 | 
             
                    if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
         | 
| 1390 1583 | 
             
                }
         | 
| 1391 1584 |  | 
| 1392 1585 | 
             
                if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
         | 
| 1393 | 
            -
                {   HUF_repeat repeat =  | 
| 1586 | 
            +
                {   HUF_repeat repeat = prevHuf->repeatMode;
         | 
| 1394 1587 | 
             
                    int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
         | 
| 1395 1588 | 
             
                    if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
         | 
| 1396 1589 | 
             
                    cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
         | 
| 1397 | 
            -
                                                  workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*) | 
| 1590 | 
            +
                                                  workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
         | 
| 1398 1591 | 
             
                                            : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
         | 
| 1399 | 
            -
                                                  workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*) | 
| 1592 | 
            +
                                                  workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
         | 
| 1400 1593 | 
             
                    if (repeat != HUF_repeat_none) {
         | 
| 1401 1594 | 
             
                        /* reused the existing table */
         | 
| 1402 1595 | 
             
                        hType = set_repeat;
         | 
| @@ -1404,17 +1597,17 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy, | |
| 1404 1597 | 
             
                }
         | 
| 1405 1598 |  | 
| 1406 1599 | 
             
                if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
         | 
| 1407 | 
            -
                    memcpy( | 
| 1600 | 
            +
                    memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
         | 
| 1408 1601 | 
             
                    return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
         | 
| 1409 1602 | 
             
                }
         | 
| 1410 1603 | 
             
                if (cLitSize==1) {
         | 
| 1411 | 
            -
                    memcpy( | 
| 1604 | 
            +
                    memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
         | 
| 1412 1605 | 
             
                    return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
         | 
| 1413 1606 | 
             
                }
         | 
| 1414 1607 |  | 
| 1415 1608 | 
             
                if (hType == set_compressed) {
         | 
| 1416 1609 | 
             
                    /* using a newly constructed table */
         | 
| 1417 | 
            -
                     | 
| 1610 | 
            +
                    nextHuf->repeatMode = HUF_repeat_check;
         | 
| 1418 1611 | 
             
                }
         | 
| 1419 1612 |  | 
| 1420 1613 | 
             
                /* Build header */
         | 
| @@ -1464,61 +1657,234 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr) | |
| 1464 1657 | 
             
                    mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
         | 
| 1465 1658 | 
             
            }
         | 
| 1466 1659 |  | 
| 1660 | 
            +
             | 
| 1661 | 
            +
            /**
         | 
| 1662 | 
            +
             * -log2(x / 256) lookup table for x in [0, 256).
         | 
| 1663 | 
            +
             * If x == 0: Return 0
         | 
| 1664 | 
            +
             * Else: Return floor(-log2(x / 256) * 256)
         | 
| 1665 | 
            +
             */
         | 
| 1666 | 
            +
            static unsigned const kInverseProbabiltyLog256[256] = {
         | 
| 1667 | 
            +
                0,    2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
         | 
| 1668 | 
            +
                1130, 1100, 1073, 1047, 1024, 1001, 980,  960,  941,  923,  906,  889,
         | 
| 1669 | 
            +
                874,  859,  844,  830,  817,  804,  791,  779,  768,  756,  745,  734,
         | 
| 1670 | 
            +
                724,  714,  704,  694,  685,  676,  667,  658,  650,  642,  633,  626,
         | 
| 1671 | 
            +
                618,  610,  603,  595,  588,  581,  574,  567,  561,  554,  548,  542,
         | 
| 1672 | 
            +
                535,  529,  523,  517,  512,  506,  500,  495,  489,  484,  478,  473,
         | 
| 1673 | 
            +
                468,  463,  458,  453,  448,  443,  438,  434,  429,  424,  420,  415,
         | 
| 1674 | 
            +
                411,  407,  402,  398,  394,  390,  386,  382,  377,  373,  370,  366,
         | 
| 1675 | 
            +
                362,  358,  354,  350,  347,  343,  339,  336,  332,  329,  325,  322,
         | 
| 1676 | 
            +
                318,  315,  311,  308,  305,  302,  298,  295,  292,  289,  286,  282,
         | 
| 1677 | 
            +
                279,  276,  273,  270,  267,  264,  261,  258,  256,  253,  250,  247,
         | 
| 1678 | 
            +
                244,  241,  239,  236,  233,  230,  228,  225,  222,  220,  217,  215,
         | 
| 1679 | 
            +
                212,  209,  207,  204,  202,  199,  197,  194,  192,  190,  187,  185,
         | 
| 1680 | 
            +
                182,  180,  178,  175,  173,  171,  168,  166,  164,  162,  159,  157,
         | 
| 1681 | 
            +
                155,  153,  151,  149,  146,  144,  142,  140,  138,  136,  134,  132,
         | 
| 1682 | 
            +
                130,  128,  126,  123,  121,  119,  117,  115,  114,  112,  110,  108,
         | 
| 1683 | 
            +
                106,  104,  102,  100,  98,   96,   94,   93,   91,   89,   87,   85,
         | 
| 1684 | 
            +
                83,   82,   80,   78,   76,   74,   73,   71,   69,   67,   66,   64,
         | 
| 1685 | 
            +
                62,   61,   59,   57,   55,   54,   52,   50,   49,   47,   46,   44,
         | 
| 1686 | 
            +
                42,   41,   39,   37,   36,   34,   33,   31,   30,   28,   26,   25,
         | 
| 1687 | 
            +
                23,   22,   20,   19,   17,   16,   14,   13,   11,   10,   8,    7,
         | 
| 1688 | 
            +
                5,    4,    2,    1,
         | 
| 1689 | 
            +
            };
         | 
| 1690 | 
            +
             | 
| 1691 | 
            +
             | 
| 1692 | 
            +
            /**
         | 
| 1693 | 
            +
             * Returns the cost in bits of encoding the distribution described by count
         | 
| 1694 | 
            +
             * using the entropy bound.
         | 
| 1695 | 
            +
             */
         | 
| 1696 | 
            +
            static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
         | 
| 1697 | 
            +
            {
         | 
| 1698 | 
            +
                unsigned cost = 0;
         | 
| 1699 | 
            +
                unsigned s;
         | 
| 1700 | 
            +
                for (s = 0; s <= max; ++s) {
         | 
| 1701 | 
            +
                    unsigned norm = (unsigned)((256 * count[s]) / total);
         | 
| 1702 | 
            +
                    if (count[s] != 0 && norm == 0)
         | 
| 1703 | 
            +
                        norm = 1;
         | 
| 1704 | 
            +
                    assert(count[s] < total);
         | 
| 1705 | 
            +
                    cost += count[s] * kInverseProbabiltyLog256[norm];
         | 
| 1706 | 
            +
                }
         | 
| 1707 | 
            +
                return cost >> 8;
         | 
| 1708 | 
            +
            }
         | 
| 1709 | 
            +
             | 
| 1710 | 
            +
             | 
| 1711 | 
            +
            /**
         | 
| 1712 | 
            +
             * Returns the cost in bits of encoding the distribution in count using the
         | 
| 1713 | 
            +
             * table described by norm. The max symbol support by norm is assumed >= max.
         | 
| 1714 | 
            +
             * norm must be valid for every symbol with non-zero probability in count.
         | 
| 1715 | 
            +
             */
         | 
| 1716 | 
            +
            static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
         | 
| 1717 | 
            +
                                                unsigned const* count, unsigned const max)
         | 
| 1718 | 
            +
            {
         | 
| 1719 | 
            +
                unsigned const shift = 8 - accuracyLog;
         | 
| 1720 | 
            +
                size_t cost = 0;
         | 
| 1721 | 
            +
                unsigned s;
         | 
| 1722 | 
            +
                assert(accuracyLog <= 8);
         | 
| 1723 | 
            +
                for (s = 0; s <= max; ++s) {
         | 
| 1724 | 
            +
                    unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
         | 
| 1725 | 
            +
                    unsigned const norm256 = normAcc << shift;
         | 
| 1726 | 
            +
                    assert(norm256 > 0);
         | 
| 1727 | 
            +
                    assert(norm256 < 256);
         | 
| 1728 | 
            +
                    cost += count[s] * kInverseProbabiltyLog256[norm256];
         | 
| 1729 | 
            +
                }
         | 
| 1730 | 
            +
                return cost >> 8;
         | 
| 1731 | 
            +
            }
         | 
| 1732 | 
            +
             | 
| 1733 | 
            +
             | 
| 1734 | 
            +
            static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
         | 
| 1735 | 
            +
              void const* ptr = ctable;
         | 
| 1736 | 
            +
              U16 const* u16ptr = (U16 const*)ptr;
         | 
| 1737 | 
            +
              U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
         | 
| 1738 | 
            +
              return maxSymbolValue;
         | 
| 1739 | 
            +
            }
         | 
| 1740 | 
            +
             | 
| 1741 | 
            +
             | 
| 1742 | 
            +
            /**
         | 
| 1743 | 
            +
             * Returns the cost in bits of encoding the distribution in count using ctable.
         | 
| 1744 | 
            +
             * Returns an error if ctable cannot represent all the symbols in count.
         | 
| 1745 | 
            +
             */
         | 
| 1746 | 
            +
            static size_t ZSTD_fseBitCost(
         | 
| 1747 | 
            +
                FSE_CTable const* ctable,
         | 
| 1748 | 
            +
                unsigned const* count,
         | 
| 1749 | 
            +
                unsigned const max)
         | 
| 1750 | 
            +
            {
         | 
| 1751 | 
            +
                unsigned const kAccuracyLog = 8;
         | 
| 1752 | 
            +
                size_t cost = 0;
         | 
| 1753 | 
            +
                unsigned s;
         | 
| 1754 | 
            +
                FSE_CState_t cstate;
         | 
| 1755 | 
            +
                FSE_initCState(&cstate, ctable);
         | 
| 1756 | 
            +
                if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
         | 
| 1757 | 
            +
                    DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
         | 
| 1758 | 
            +
                                ZSTD_getFSEMaxSymbolValue(ctable), max);
         | 
| 1759 | 
            +
                    return ERROR(GENERIC);
         | 
| 1760 | 
            +
                }
         | 
| 1761 | 
            +
                for (s = 0; s <= max; ++s) {
         | 
| 1762 | 
            +
                    unsigned const tableLog = cstate.stateLog;
         | 
| 1763 | 
            +
                    unsigned const badCost = (tableLog + 1) << kAccuracyLog;
         | 
| 1764 | 
            +
                    unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
         | 
| 1765 | 
            +
                    if (count[s] == 0)
         | 
| 1766 | 
            +
                        continue;
         | 
| 1767 | 
            +
                    if (bitCost >= badCost) {
         | 
| 1768 | 
            +
                        DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
         | 
| 1769 | 
            +
                        return ERROR(GENERIC);
         | 
| 1770 | 
            +
                    }
         | 
| 1771 | 
            +
                    cost += count[s] * bitCost;
         | 
| 1772 | 
            +
                }
         | 
| 1773 | 
            +
                return cost >> kAccuracyLog;
         | 
| 1774 | 
            +
            }
         | 
| 1775 | 
            +
             | 
| 1776 | 
            +
            /**
         | 
| 1777 | 
            +
             * Returns the cost in bytes of encoding the normalized count header.
         | 
| 1778 | 
            +
             * Returns an error if any of the helper functions return an error.
         | 
| 1779 | 
            +
             */
         | 
| 1780 | 
            +
            static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
         | 
| 1781 | 
            +
                                          size_t const nbSeq, unsigned const FSELog)
         | 
| 1782 | 
            +
            {
         | 
| 1783 | 
            +
                BYTE wksp[FSE_NCOUNTBOUND];
         | 
| 1784 | 
            +
                S16 norm[MaxSeq + 1];
         | 
| 1785 | 
            +
                const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
         | 
| 1786 | 
            +
                CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
         | 
| 1787 | 
            +
                return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
         | 
| 1788 | 
            +
            }
         | 
| 1789 | 
            +
             | 
| 1790 | 
            +
             | 
| 1467 1791 | 
             
            typedef enum {
         | 
| 1468 1792 | 
             
                ZSTD_defaultDisallowed = 0,
         | 
| 1469 1793 | 
             
                ZSTD_defaultAllowed = 1
         | 
| 1470 1794 | 
             
            } ZSTD_defaultPolicy_e;
         | 
| 1471 1795 |  | 
| 1472 | 
            -
            MEM_STATIC
         | 
| 1473 | 
            -
             | 
| 1474 | 
            -
                    FSE_repeat* repeatMode,  | 
| 1475 | 
            -
                     | 
| 1796 | 
            +
            MEM_STATIC symbolEncodingType_e
         | 
| 1797 | 
            +
            ZSTD_selectEncodingType(
         | 
| 1798 | 
            +
                    FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
         | 
| 1799 | 
            +
                    size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
         | 
| 1800 | 
            +
                    FSE_CTable const* prevCTable,
         | 
| 1801 | 
            +
                    short const* defaultNorm, U32 defaultNormLog,
         | 
| 1802 | 
            +
                    ZSTD_defaultPolicy_e const isDefaultAllowed,
         | 
| 1803 | 
            +
                    ZSTD_strategy const strategy)
         | 
| 1476 1804 | 
             
            {
         | 
| 1477 | 
            -
            #define MIN_SEQ_FOR_DYNAMIC_FSE   64
         | 
| 1478 | 
            -
            #define MAX_SEQ_FOR_STATIC_FSE  1000
         | 
| 1479 1805 | 
             
                ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
         | 
| 1480 | 
            -
                if ( | 
| 1806 | 
            +
                if (mostFrequent == nbSeq) {
         | 
| 1807 | 
            +
                    *repeatMode = FSE_repeat_none;
         | 
| 1808 | 
            +
                    if (isDefaultAllowed && nbSeq <= 2) {
         | 
| 1809 | 
            +
                        /* Prefer set_basic over set_rle when there are 2 or less symbols,
         | 
| 1810 | 
            +
                         * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
         | 
| 1811 | 
            +
                         * If basic encoding isn't possible, always choose RLE.
         | 
| 1812 | 
            +
                         */
         | 
| 1813 | 
            +
                        DEBUGLOG(5, "Selected set_basic");
         | 
| 1814 | 
            +
                        return set_basic;
         | 
| 1815 | 
            +
                    }
         | 
| 1481 1816 | 
             
                    DEBUGLOG(5, "Selected set_rle");
         | 
| 1482 | 
            -
                    /* Prefer set_basic over set_rle when there are 2 or less symbols,
         | 
| 1483 | 
            -
                     * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
         | 
| 1484 | 
            -
                     * If basic encoding isn't possible, always choose RLE.
         | 
| 1485 | 
            -
                     */
         | 
| 1486 | 
            -
                    *repeatMode = FSE_repeat_check;
         | 
| 1487 1817 | 
             
                    return set_rle;
         | 
| 1488 1818 | 
             
                }
         | 
| 1489 | 
            -
                if (  | 
| 1490 | 
            -
             | 
| 1491 | 
            -
             | 
| 1492 | 
            -
             | 
| 1493 | 
            -
             | 
| 1494 | 
            -
             | 
| 1495 | 
            -
             | 
| 1496 | 
            -
             | 
| 1497 | 
            -
             | 
| 1498 | 
            -
             | 
| 1499 | 
            -
             | 
| 1500 | 
            -
             | 
| 1501 | 
            -
             | 
| 1502 | 
            -
             | 
| 1503 | 
            -
             | 
| 1504 | 
            -
             | 
| 1819 | 
            +
                if (strategy < ZSTD_lazy) {
         | 
| 1820 | 
            +
                    if (isDefaultAllowed) {
         | 
| 1821 | 
            +
                        size_t const staticFse_nbSeq_max = 1000;
         | 
| 1822 | 
            +
                        size_t const mult = 10 - strategy;
         | 
| 1823 | 
            +
                        size_t const baseLog = 3;
         | 
| 1824 | 
            +
                        size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog;  /* 28-36 for offset, 56-72 for lengths */
         | 
| 1825 | 
            +
                        assert(defaultNormLog >= 5 && defaultNormLog <= 6);  /* xx_DEFAULTNORMLOG */
         | 
| 1826 | 
            +
                        assert(mult <= 9 && mult >= 7);
         | 
| 1827 | 
            +
                        if ( (*repeatMode == FSE_repeat_valid)
         | 
| 1828 | 
            +
                          && (nbSeq < staticFse_nbSeq_max) ) {
         | 
| 1829 | 
            +
                            DEBUGLOG(5, "Selected set_repeat");
         | 
| 1830 | 
            +
                            return set_repeat;
         | 
| 1831 | 
            +
                        }
         | 
| 1832 | 
            +
                        if ( (nbSeq < dynamicFse_nbSeq_min)
         | 
| 1833 | 
            +
                          || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
         | 
| 1834 | 
            +
                            DEBUGLOG(5, "Selected set_basic");
         | 
| 1835 | 
            +
                            /* The format allows default tables to be repeated, but it isn't useful.
         | 
| 1836 | 
            +
                             * When using simple heuristics to select encoding type, we don't want
         | 
| 1837 | 
            +
                             * to confuse these tables with dictionaries. When running more careful
         | 
| 1838 | 
            +
                             * analysis, we don't need to waste time checking both repeating tables
         | 
| 1839 | 
            +
                             * and default tables.
         | 
| 1840 | 
            +
                             */
         | 
| 1841 | 
            +
                            *repeatMode = FSE_repeat_none;
         | 
| 1842 | 
            +
                            return set_basic;
         | 
| 1843 | 
            +
                        }
         | 
| 1844 | 
            +
                    }
         | 
| 1845 | 
            +
                } else {
         | 
| 1846 | 
            +
                    size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
         | 
| 1847 | 
            +
                    size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
         | 
| 1848 | 
            +
                    size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
         | 
| 1849 | 
            +
                    size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
         | 
| 1850 | 
            +
             | 
| 1851 | 
            +
                    if (isDefaultAllowed) {
         | 
| 1852 | 
            +
                        assert(!ZSTD_isError(basicCost));
         | 
| 1853 | 
            +
                        assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
         | 
| 1854 | 
            +
                    }
         | 
| 1855 | 
            +
                    assert(!ZSTD_isError(NCountCost));
         | 
| 1856 | 
            +
                    assert(compressedCost < ERROR(maxCode));
         | 
| 1857 | 
            +
                    DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
         | 
| 1858 | 
            +
                                (U32)basicCost, (U32)repeatCost, (U32)compressedCost);
         | 
| 1859 | 
            +
                    if (basicCost <= repeatCost && basicCost <= compressedCost) {
         | 
| 1860 | 
            +
                        DEBUGLOG(5, "Selected set_basic");
         | 
| 1861 | 
            +
                        assert(isDefaultAllowed);
         | 
| 1862 | 
            +
                        *repeatMode = FSE_repeat_none;
         | 
| 1863 | 
            +
                        return set_basic;
         | 
| 1864 | 
            +
                    }
         | 
| 1865 | 
            +
                    if (repeatCost <= compressedCost) {
         | 
| 1866 | 
            +
                        DEBUGLOG(5, "Selected set_repeat");
         | 
| 1867 | 
            +
                        assert(!ZSTD_isError(repeatCost));
         | 
| 1868 | 
            +
                        return set_repeat;
         | 
| 1869 | 
            +
                    }
         | 
| 1870 | 
            +
                    assert(compressedCost < basicCost && compressedCost < repeatCost);
         | 
| 1505 1871 | 
             
                }
         | 
| 1506 1872 | 
             
                DEBUGLOG(5, "Selected set_compressed");
         | 
| 1507 1873 | 
             
                *repeatMode = FSE_repeat_check;
         | 
| 1508 1874 | 
             
                return set_compressed;
         | 
| 1509 1875 | 
             
            }
         | 
| 1510 1876 |  | 
| 1511 | 
            -
            MEM_STATIC
         | 
| 1512 | 
            -
             | 
| 1513 | 
            -
             | 
| 1514 | 
            -
             | 
| 1515 | 
            -
             | 
| 1516 | 
            -
             | 
| 1517 | 
            -
             | 
| 1518 | 
            -
             | 
| 1877 | 
            +
            MEM_STATIC size_t
         | 
| 1878 | 
            +
            ZSTD_buildCTable(void* dst, size_t dstCapacity,
         | 
| 1879 | 
            +
                            FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
         | 
| 1880 | 
            +
                            U32* count, U32 max,
         | 
| 1881 | 
            +
                            const BYTE* codeTable, size_t nbSeq,
         | 
| 1882 | 
            +
                            const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
         | 
| 1883 | 
            +
                            const FSE_CTable* prevCTable, size_t prevCTableSize,
         | 
| 1884 | 
            +
                            void* workspace, size_t workspaceSize)
         | 
| 1519 1885 | 
             
            {
         | 
| 1520 1886 | 
             
                BYTE* op = (BYTE*)dst;
         | 
| 1521 | 
            -
                BYTE | 
| 1887 | 
            +
                const BYTE* const oend = op + dstCapacity;
         | 
| 1522 1888 |  | 
| 1523 1889 | 
             
                switch (type) {
         | 
| 1524 1890 | 
             
                case set_rle:
         | 
| @@ -1706,10 +2072,11 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, | |
| 1706 2072 | 
             
                                          const int bmi2)
         | 
| 1707 2073 | 
             
            {
         | 
| 1708 2074 | 
             
                const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
         | 
| 2075 | 
            +
                ZSTD_strategy const strategy = cctxParams->cParams.strategy;
         | 
| 1709 2076 | 
             
                U32 count[MaxSeq+1];
         | 
| 1710 | 
            -
                FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
         | 
| 1711 | 
            -
                FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
         | 
| 1712 | 
            -
                FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
         | 
| 2077 | 
            +
                FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
         | 
| 2078 | 
            +
                FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
         | 
| 2079 | 
            +
                FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
         | 
| 1713 2080 | 
             
                U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
         | 
| 1714 2081 | 
             
                const seqDef* const sequences = seqStorePtr->sequencesStart;
         | 
| 1715 2082 | 
             
                const BYTE* const ofCodeTable = seqStorePtr->ofCode;
         | 
| @@ -1720,15 +2087,17 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, | |
| 1720 2087 | 
             
                BYTE* op = ostart;
         | 
| 1721 2088 | 
             
                size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
         | 
| 1722 2089 | 
             
                BYTE* seqHead;
         | 
| 2090 | 
            +
                BYTE* lastNCount = NULL;
         | 
| 1723 2091 |  | 
| 1724 2092 | 
             
                ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
         | 
| 1725 2093 |  | 
| 1726 2094 | 
             
                /* Compress literals */
         | 
| 1727 2095 | 
             
                {   const BYTE* const literals = seqStorePtr->litStart;
         | 
| 1728 2096 | 
             
                    size_t const litSize = seqStorePtr->lit - literals;
         | 
| 2097 | 
            +
                    int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
         | 
| 1729 2098 | 
             
                    size_t const cSize = ZSTD_compressLiterals(
         | 
| 1730 | 
            -
                                                prevEntropy, nextEntropy,
         | 
| 1731 | 
            -
                                                cctxParams->cParams.strategy,  | 
| 2099 | 
            +
                                                &prevEntropy->huf, &nextEntropy->huf,
         | 
| 2100 | 
            +
                                                cctxParams->cParams.strategy, disableLiteralCompression,
         | 
| 1732 2101 | 
             
                                                op, dstCapacity,
         | 
| 1733 2102 | 
             
                                                literals, litSize,
         | 
| 1734 2103 | 
             
                                                workspace, bmi2);
         | 
| @@ -1747,13 +2116,9 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, | |
| 1747 2116 | 
             
                else
         | 
| 1748 2117 | 
             
                    op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
         | 
| 1749 2118 | 
             
                if (nbSeq==0) {
         | 
| 1750 | 
            -
             | 
| 1751 | 
            -
             | 
| 1752 | 
            -
             | 
| 1753 | 
            -
                  nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
         | 
| 1754 | 
            -
                  memcpy(nextEntropy->matchlengthCTable, prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable));
         | 
| 1755 | 
            -
                  nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
         | 
| 1756 | 
            -
                  return op - ostart;
         | 
| 2119 | 
            +
                    /* Copy the old tables over as if we repeated them */
         | 
| 2120 | 
            +
                    memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
         | 
| 2121 | 
            +
                    return op - ostart;
         | 
| 1757 2122 | 
             
                }
         | 
| 1758 2123 |  | 
| 1759 2124 | 
             
                /* seqHead : flags for FSE encoding type */
         | 
| @@ -1763,43 +2128,53 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, | |
| 1763 2128 | 
             
                ZSTD_seqToCodes(seqStorePtr);
         | 
| 1764 2129 | 
             
                /* build CTable for Literal Lengths */
         | 
| 1765 2130 | 
             
                {   U32 max = MaxLL;
         | 
| 1766 | 
            -
                    size_t const mostFrequent =  | 
| 2131 | 
            +
                    size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace);   /* can't fail */
         | 
| 1767 2132 | 
             
                    DEBUGLOG(5, "Building LL table");
         | 
| 1768 | 
            -
                    nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
         | 
| 1769 | 
            -
                    LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, mostFrequent, nbSeq, LL_defaultNormLog, ZSTD_defaultAllowed);
         | 
| 2133 | 
            +
                    nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
         | 
| 2134 | 
            +
                    LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy);
         | 
| 2135 | 
            +
                    assert(set_basic < set_compressed && set_rle < set_compressed);
         | 
| 2136 | 
            +
                    assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
         | 
| 1770 2137 | 
             
                    {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
         | 
| 1771 | 
            -
             | 
| 1772 | 
            -
             | 
| 1773 | 
            -
             | 
| 2138 | 
            +
                                                                count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
         | 
| 2139 | 
            +
                                                                prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
         | 
| 2140 | 
            +
                                                                workspace, HUF_WORKSPACE_SIZE);
         | 
| 1774 2141 | 
             
                        if (ZSTD_isError(countSize)) return countSize;
         | 
| 2142 | 
            +
                        if (LLtype == set_compressed)
         | 
| 2143 | 
            +
                            lastNCount = op;
         | 
| 1775 2144 | 
             
                        op += countSize;
         | 
| 1776 2145 | 
             
                }   }
         | 
| 1777 2146 | 
             
                /* build CTable for Offsets */
         | 
| 1778 2147 | 
             
                {   U32 max = MaxOff;
         | 
| 1779 | 
            -
                    size_t const mostFrequent =  | 
| 2148 | 
            +
                    size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace);  /* can't fail */
         | 
| 1780 2149 | 
             
                    /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
         | 
| 1781 2150 | 
             
                    ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
         | 
| 1782 2151 | 
             
                    DEBUGLOG(5, "Building OF table");
         | 
| 1783 | 
            -
                    nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
         | 
| 1784 | 
            -
                    Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, mostFrequent, nbSeq, OF_defaultNormLog, defaultPolicy);
         | 
| 2152 | 
            +
                    nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;
         | 
| 2153 | 
            +
                    Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode, count, max, mostFrequent, nbSeq, OffFSELog, prevEntropy->fse.offcodeCTable, OF_defaultNorm, OF_defaultNormLog, defaultPolicy, strategy);
         | 
| 2154 | 
            +
                    assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
         | 
| 1785 2155 | 
             
                    {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
         | 
| 1786 | 
            -
             | 
| 1787 | 
            -
             | 
| 1788 | 
            -
             | 
| 2156 | 
            +
                                                                count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
         | 
| 2157 | 
            +
                                                                prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
         | 
| 2158 | 
            +
                                                                workspace, HUF_WORKSPACE_SIZE);
         | 
| 1789 2159 | 
             
                        if (ZSTD_isError(countSize)) return countSize;
         | 
| 2160 | 
            +
                        if (Offtype == set_compressed)
         | 
| 2161 | 
            +
                            lastNCount = op;
         | 
| 1790 2162 | 
             
                        op += countSize;
         | 
| 1791 2163 | 
             
                }   }
         | 
| 1792 2164 | 
             
                /* build CTable for MatchLengths */
         | 
| 1793 2165 | 
             
                {   U32 max = MaxML;
         | 
| 1794 | 
            -
                    size_t const mostFrequent =  | 
| 2166 | 
            +
                    size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace);   /* can't fail */
         | 
| 1795 2167 | 
             
                    DEBUGLOG(5, "Building ML table");
         | 
| 1796 | 
            -
                    nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
         | 
| 1797 | 
            -
                    MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, mostFrequent, nbSeq, ML_defaultNormLog, ZSTD_defaultAllowed);
         | 
| 2168 | 
            +
                    nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
         | 
| 2169 | 
            +
                    MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy);
         | 
| 2170 | 
            +
                    assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
         | 
| 1798 2171 | 
             
                    {   size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
         | 
| 1799 | 
            -
             | 
| 1800 | 
            -
             | 
| 1801 | 
            -
             | 
| 2172 | 
            +
                                                                count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
         | 
| 2173 | 
            +
                                                                prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
         | 
| 2174 | 
            +
                                                                workspace, HUF_WORKSPACE_SIZE);
         | 
| 1802 2175 | 
             
                        if (ZSTD_isError(countSize)) return countSize;
         | 
| 2176 | 
            +
                        if (MLtype == set_compressed)
         | 
| 2177 | 
            +
                            lastNCount = op;
         | 
| 1803 2178 | 
             
                        op += countSize;
         | 
| 1804 2179 | 
             
                }   }
         | 
| 1805 2180 |  | 
| @@ -1814,21 +2189,37 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, | |
| 1814 2189 | 
             
                                                    longOffsets, bmi2);
         | 
| 1815 2190 | 
             
                    if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
         | 
| 1816 2191 | 
             
                    op += bitstreamSize;
         | 
| 2192 | 
            +
                    /* zstd versions <= 1.3.4 mistakenly report corruption when
         | 
| 2193 | 
            +
                     * FSE_readNCount() recieves a buffer < 4 bytes.
         | 
| 2194 | 
            +
                     * Fixed by https://github.com/facebook/zstd/pull/1146.
         | 
| 2195 | 
            +
                     * This can happen when the last set_compressed table present is 2
         | 
| 2196 | 
            +
                     * bytes and the bitstream is only one byte.
         | 
| 2197 | 
            +
                     * In this exceedingly rare case, we will simply emit an uncompressed
         | 
| 2198 | 
            +
                     * block, since it isn't worth optimizing.
         | 
| 2199 | 
            +
                     */
         | 
| 2200 | 
            +
                    if (lastNCount && (op - lastNCount) < 4) {
         | 
| 2201 | 
            +
                        /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
         | 
| 2202 | 
            +
                        assert(op - lastNCount == 3);
         | 
| 2203 | 
            +
                        DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
         | 
| 2204 | 
            +
                                    "emitting an uncompressed block.");
         | 
| 2205 | 
            +
                        return 0;
         | 
| 2206 | 
            +
                    }
         | 
| 1817 2207 | 
             
                }
         | 
| 1818 2208 |  | 
| 1819 2209 | 
             
                return op - ostart;
         | 
| 1820 2210 | 
             
            }
         | 
| 1821 2211 |  | 
| 1822 2212 | 
             
            MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
         | 
| 1823 | 
            -
             | 
| 2213 | 
            +
                                    const ZSTD_entropyCTables_t* prevEntropy,
         | 
| 1824 2214 | 
             
                                          ZSTD_entropyCTables_t* nextEntropy,
         | 
| 1825 | 
            -
             | 
| 2215 | 
            +
                                    const ZSTD_CCtx_params* cctxParams,
         | 
| 1826 2216 | 
             
                                          void* dst, size_t dstCapacity,
         | 
| 1827 2217 | 
             
                                          size_t srcSize, U32* workspace, int bmi2)
         | 
| 1828 2218 | 
             
            {
         | 
| 1829 2219 | 
             
                size_t const cSize = ZSTD_compressSequences_internal(
         | 
| 1830 2220 | 
             
                        seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity,
         | 
| 1831 2221 | 
             
                        workspace, bmi2);
         | 
| 2222 | 
            +
                if (cSize == 0) return 0;
         | 
| 1832 2223 | 
             
                /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
         | 
| 1833 2224 | 
             
                 * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
         | 
| 1834 2225 | 
             
                 */
         | 
| @@ -1837,7 +2228,7 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr, | |
| 1837 2228 | 
             
                if (ZSTD_isError(cSize)) return cSize;
         | 
| 1838 2229 |  | 
| 1839 2230 | 
             
                /* Check compressibility */
         | 
| 1840 | 
            -
                {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize | 
| 2231 | 
            +
                {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
         | 
| 1841 2232 | 
             
                    if (cSize >= maxCSize) return 0;  /* block not compressed */
         | 
| 1842 2233 | 
             
                }
         | 
| 1843 2234 |  | 
| @@ -1845,8 +2236,8 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr, | |
| 1845 2236 | 
             
                 * block. After the first block, the offcode table might not have large
         | 
| 1846 2237 | 
             
                 * enough codes to represent the offsets in the data.
         | 
| 1847 2238 | 
             
                 */
         | 
| 1848 | 
            -
                if (nextEntropy->offcode_repeatMode == FSE_repeat_valid)
         | 
| 1849 | 
            -
                    nextEntropy->offcode_repeatMode = FSE_repeat_check;
         | 
| 2239 | 
            +
                if (nextEntropy->fse.offcode_repeatMode == FSE_repeat_valid)
         | 
| 2240 | 
            +
                    nextEntropy->fse.offcode_repeatMode = FSE_repeat_check;
         | 
| 1850 2241 |  | 
| 1851 2242 | 
             
                return cSize;
         | 
| 1852 2243 | 
             
            }
         | 
| @@ -1854,23 +2245,45 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr, | |
| 1854 2245 | 
             
            /* ZSTD_selectBlockCompressor() :
         | 
| 1855 2246 | 
             
             * Not static, but internal use only (used by long distance matcher)
         | 
| 1856 2247 | 
             
             * assumption : strat is a valid strategy */
         | 
| 1857 | 
            -
            ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat,  | 
| 2248 | 
            +
            ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
         | 
| 1858 2249 | 
             
            {
         | 
| 1859 | 
            -
                static const ZSTD_blockCompressor blockCompressor[ | 
| 2250 | 
            +
                static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = {
         | 
| 1860 2251 | 
             
                    { ZSTD_compressBlock_fast  /* default for 0 */,
         | 
| 1861 | 
            -
                      ZSTD_compressBlock_fast, | 
| 1862 | 
            -
                       | 
| 1863 | 
            -
                       | 
| 2252 | 
            +
                      ZSTD_compressBlock_fast,
         | 
| 2253 | 
            +
                      ZSTD_compressBlock_doubleFast,
         | 
| 2254 | 
            +
                      ZSTD_compressBlock_greedy,
         | 
| 2255 | 
            +
                      ZSTD_compressBlock_lazy,
         | 
| 2256 | 
            +
                      ZSTD_compressBlock_lazy2,
         | 
| 2257 | 
            +
                      ZSTD_compressBlock_btlazy2,
         | 
| 2258 | 
            +
                      ZSTD_compressBlock_btopt,
         | 
| 2259 | 
            +
                      ZSTD_compressBlock_btultra },
         | 
| 1864 2260 | 
             
                    { ZSTD_compressBlock_fast_extDict  /* default for 0 */,
         | 
| 1865 | 
            -
                      ZSTD_compressBlock_fast_extDict, | 
| 1866 | 
            -
                       | 
| 1867 | 
            -
                       | 
| 2261 | 
            +
                      ZSTD_compressBlock_fast_extDict,
         | 
| 2262 | 
            +
                      ZSTD_compressBlock_doubleFast_extDict,
         | 
| 2263 | 
            +
                      ZSTD_compressBlock_greedy_extDict,
         | 
| 2264 | 
            +
                      ZSTD_compressBlock_lazy_extDict,
         | 
| 2265 | 
            +
                      ZSTD_compressBlock_lazy2_extDict,
         | 
| 2266 | 
            +
                      ZSTD_compressBlock_btlazy2_extDict,
         | 
| 2267 | 
            +
                      ZSTD_compressBlock_btopt_extDict,
         | 
| 2268 | 
            +
                      ZSTD_compressBlock_btultra_extDict },
         | 
| 2269 | 
            +
                    { ZSTD_compressBlock_fast_dictMatchState  /* default for 0 */,
         | 
| 2270 | 
            +
                      ZSTD_compressBlock_fast_dictMatchState,
         | 
| 2271 | 
            +
                      ZSTD_compressBlock_doubleFast_dictMatchState,
         | 
| 2272 | 
            +
                      ZSTD_compressBlock_greedy_dictMatchState,
         | 
| 2273 | 
            +
                      ZSTD_compressBlock_lazy_dictMatchState,
         | 
| 2274 | 
            +
                      ZSTD_compressBlock_lazy2_dictMatchState,
         | 
| 2275 | 
            +
                      ZSTD_compressBlock_btlazy2_dictMatchState,
         | 
| 2276 | 
            +
                      ZSTD_compressBlock_btopt_dictMatchState,
         | 
| 2277 | 
            +
                      ZSTD_compressBlock_btultra_dictMatchState }
         | 
| 1868 2278 | 
             
                };
         | 
| 2279 | 
            +
                ZSTD_blockCompressor selectedCompressor;
         | 
| 1869 2280 | 
             
                ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
         | 
| 1870 2281 |  | 
| 1871 2282 | 
             
                assert((U32)strat >= (U32)ZSTD_fast);
         | 
| 1872 2283 | 
             
                assert((U32)strat <= (U32)ZSTD_btultra);
         | 
| 1873 | 
            -
                 | 
| 2284 | 
            +
                selectedCompressor = blockCompressor[(int)dictMode][(U32)strat];
         | 
| 2285 | 
            +
                assert(selectedCompressor != NULL);
         | 
| 2286 | 
            +
                return selectedCompressor;
         | 
| 1874 2287 | 
             
            }
         | 
| 1875 2288 |  | 
| 1876 2289 | 
             
            static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
         | 
| @@ -1880,7 +2293,7 @@ static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr, | |
| 1880 2293 | 
             
                seqStorePtr->lit += lastLLSize;
         | 
| 1881 2294 | 
             
            }
         | 
| 1882 2295 |  | 
| 1883 | 
            -
             | 
| 2296 | 
            +
            void ZSTD_resetSeqStore(seqStore_t* ssPtr)
         | 
| 1884 2297 | 
             
            {
         | 
| 1885 2298 | 
             
                ssPtr->lit = ssPtr->litStart;
         | 
| 1886 2299 | 
             
                ssPtr->sequences = ssPtr->sequencesStart;
         | 
| @@ -1892,24 +2305,32 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, | |
| 1892 2305 | 
             
                                                    const void* src, size_t srcSize)
         | 
| 1893 2306 | 
             
            {
         | 
| 1894 2307 | 
             
                ZSTD_matchState_t* const ms = &zc->blockState.matchState;
         | 
| 1895 | 
            -
                DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=% | 
| 1896 | 
            -
                             | 
| 2308 | 
            +
                DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)",
         | 
| 2309 | 
            +
                            dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
         | 
| 2310 | 
            +
             | 
| 1897 2311 | 
             
                if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
         | 
| 1898 2312 | 
             
                    ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
         | 
| 1899 2313 | 
             
                    return 0;   /* don't even attempt compression below a certain srcSize */
         | 
| 1900 2314 | 
             
                }
         | 
| 1901 2315 | 
             
                ZSTD_resetSeqStore(&(zc->seqStore));
         | 
| 2316 | 
            +
                ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;   /* required for optimal parser to read stats from dictionary */
         | 
| 2317 | 
            +
             | 
| 2318 | 
            +
                /* a gap between an attached dict and the current window is not safe,
         | 
| 2319 | 
            +
                 * they must remain adjacent, and when that stops being the case, the dict
         | 
| 2320 | 
            +
                 * must be unset */
         | 
| 2321 | 
            +
                assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
         | 
| 1902 2322 |  | 
| 1903 2323 | 
             
                /* limited update after a very long match */
         | 
| 1904 2324 | 
             
                {   const BYTE* const base = ms->window.base;
         | 
| 1905 2325 | 
             
                    const BYTE* const istart = (const BYTE*)src;
         | 
| 1906 2326 | 
             
                    const U32 current = (U32)(istart-base);
         | 
| 2327 | 
            +
                    if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1));   /* ensure no overflow */
         | 
| 1907 2328 | 
             
                    if (current > ms->nextToUpdate + 384)
         | 
| 1908 2329 | 
             
                        ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));
         | 
| 1909 2330 | 
             
                }
         | 
| 1910 2331 |  | 
| 1911 2332 | 
             
                /* select and store sequences */
         | 
| 1912 | 
            -
                {    | 
| 2333 | 
            +
                {   ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms);
         | 
| 1913 2334 | 
             
                    size_t lastLLSize;
         | 
| 1914 2335 | 
             
                    {   int i;
         | 
| 1915 2336 | 
             
                        for (i = 0; i < ZSTD_REP_NUM; ++i)
         | 
| @@ -1923,7 +2344,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, | |
| 1923 2344 | 
             
                                                   ms, &zc->seqStore,
         | 
| 1924 2345 | 
             
                                                   zc->blockState.nextCBlock->rep,
         | 
| 1925 2346 | 
             
                                                   &zc->appliedParams.cParams,
         | 
| 1926 | 
            -
                                                   src, srcSize | 
| 2347 | 
            +
                                                   src, srcSize);
         | 
| 1927 2348 | 
             
                        assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
         | 
| 1928 2349 | 
             
                    } else if (zc->appliedParams.ldmParams.enableLdm) {
         | 
| 1929 2350 | 
             
                        rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
         | 
| @@ -1940,10 +2361,10 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, | |
| 1940 2361 | 
             
                                                   ms, &zc->seqStore,
         | 
| 1941 2362 | 
             
                                                   zc->blockState.nextCBlock->rep,
         | 
| 1942 2363 | 
             
                                                   &zc->appliedParams.cParams,
         | 
| 1943 | 
            -
                                                   src, srcSize | 
| 2364 | 
            +
                                                   src, srcSize);
         | 
| 1944 2365 | 
             
                        assert(ldmSeqStore.pos == ldmSeqStore.size);
         | 
| 1945 2366 | 
             
                    } else {   /* not long range mode */
         | 
| 1946 | 
            -
                        ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,  | 
| 2367 | 
            +
                        ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
         | 
| 1947 2368 | 
             
                        lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, &zc->appliedParams.cParams, src, srcSize);
         | 
| 1948 2369 | 
             
                    }
         | 
| 1949 2370 | 
             
                    {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
         | 
| @@ -2010,8 +2431,9 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx, | |
| 2010 2431 | 
             
                        if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
         | 
| 2011 2432 | 
             
                        else ms->nextToUpdate -= correction;
         | 
| 2012 2433 | 
             
                        ms->loadedDictEnd = 0;
         | 
| 2434 | 
            +
                        ms->dictMatchState = NULL;
         | 
| 2013 2435 | 
             
                    }
         | 
| 2014 | 
            -
                    ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd);
         | 
| 2436 | 
            +
                    ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
         | 
| 2015 2437 | 
             
                    if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
         | 
| 2016 2438 |  | 
| 2017 2439 | 
             
                    {   size_t cSize = ZSTD_compressBlock_internal(cctx,
         | 
| @@ -2060,6 +2482,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, | |
| 2060 2482 | 
             
                BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
         | 
| 2061 2483 | 
             
                size_t pos=0;
         | 
| 2062 2484 |  | 
| 2485 | 
            +
                assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
         | 
| 2063 2486 | 
             
                if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
         | 
| 2064 2487 | 
             
                DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
         | 
| 2065 2488 | 
             
                            !params.fParams.noDictIDFlag, dictID,  dictIDSizeCode);
         | 
| @@ -2153,7 +2576,9 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, | |
| 2153 2576 | 
             
                    if (ZSTD_isError(cSize)) return cSize;
         | 
| 2154 2577 | 
             
                    cctx->consumedSrcSize += srcSize;
         | 
| 2155 2578 | 
             
                    cctx->producedCSize += (cSize + fhSize);
         | 
| 2156 | 
            -
                     | 
| 2579 | 
            +
                    assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
         | 
| 2580 | 
            +
                    if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
         | 
| 2581 | 
            +
                        ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
         | 
| 2157 2582 | 
             
                        if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
         | 
| 2158 2583 | 
             
                            DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
         | 
| 2159 2584 | 
             
                                (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
         | 
| @@ -2190,7 +2615,10 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const | |
| 2190 2615 | 
             
            /*! ZSTD_loadDictionaryContent() :
         | 
| 2191 2616 | 
             
             *  @return : 0, or an error code
         | 
| 2192 2617 | 
             
             */
         | 
| 2193 | 
            -
            static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, | 
| 2618 | 
            +
            static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
         | 
| 2619 | 
            +
                                                     ZSTD_CCtx_params const* params,
         | 
| 2620 | 
            +
                                                     const void* src, size_t srcSize,
         | 
| 2621 | 
            +
                                                     ZSTD_dictTableLoadMethod_e dtlm)
         | 
| 2194 2622 | 
             
            {
         | 
| 2195 2623 | 
             
                const BYTE* const ip = (const BYTE*) src;
         | 
| 2196 2624 | 
             
                const BYTE* const iend = ip + srcSize;
         | 
| @@ -2204,10 +2632,10 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params | |
| 2204 2632 | 
             
                switch(params->cParams.strategy)
         | 
| 2205 2633 | 
             
                {
         | 
| 2206 2634 | 
             
                case ZSTD_fast:
         | 
| 2207 | 
            -
                    ZSTD_fillHashTable(ms, cParams, iend);
         | 
| 2635 | 
            +
                    ZSTD_fillHashTable(ms, cParams, iend, dtlm);
         | 
| 2208 2636 | 
             
                    break;
         | 
| 2209 2637 | 
             
                case ZSTD_dfast:
         | 
| 2210 | 
            -
                    ZSTD_fillDoubleHashTable(ms, cParams, iend);
         | 
| 2638 | 
            +
                    ZSTD_fillDoubleHashTable(ms, cParams, iend, dtlm);
         | 
| 2211 2639 | 
             
                    break;
         | 
| 2212 2640 |  | 
| 2213 2641 | 
             
                case ZSTD_greedy:
         | 
| @@ -2256,7 +2684,12 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym | |
| 2256 2684 | 
             
             *  assumptions : magic number supposed already checked
         | 
| 2257 2685 | 
             
             *                dictSize supposed > 8
         | 
| 2258 2686 | 
             
             */
         | 
| 2259 | 
            -
            static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, | 
| 2687 | 
            +
            static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
         | 
| 2688 | 
            +
                                                  ZSTD_matchState_t* ms,
         | 
| 2689 | 
            +
                                                  ZSTD_CCtx_params const* params,
         | 
| 2690 | 
            +
                                                  const void* dict, size_t dictSize,
         | 
| 2691 | 
            +
                                                  ZSTD_dictTableLoadMethod_e dtlm,
         | 
| 2692 | 
            +
                                                  void* workspace)
         | 
| 2260 2693 | 
             
            {
         | 
| 2261 2694 | 
             
                const BYTE* dictPtr = (const BYTE*)dict;
         | 
| 2262 2695 | 
             
                const BYTE* const dictEnd = dictPtr + dictSize;
         | 
| @@ -2265,13 +2698,15 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc | |
| 2265 2698 | 
             
                size_t dictID;
         | 
| 2266 2699 |  | 
| 2267 2700 | 
             
                ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
         | 
| 2701 | 
            +
                assert(dictSize > 8);
         | 
| 2702 | 
            +
                assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
         | 
| 2268 2703 |  | 
| 2269 2704 | 
             
                dictPtr += 4;   /* skip magic number */
         | 
| 2270 2705 | 
             
                dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
         | 
| 2271 2706 | 
             
                dictPtr += 4;
         | 
| 2272 2707 |  | 
| 2273 2708 | 
             
                {   unsigned maxSymbolValue = 255;
         | 
| 2274 | 
            -
                    size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy. | 
| 2709 | 
            +
                    size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
         | 
| 2275 2710 | 
             
                    if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
         | 
| 2276 2711 | 
             
                    if (maxSymbolValue < 255) return ERROR(dictionary_corrupted);
         | 
| 2277 2712 | 
             
                    dictPtr += hufHeaderSize;
         | 
| @@ -2282,7 +2717,8 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc | |
| 2282 2717 | 
             
                    if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
         | 
| 2283 2718 | 
             
                    if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
         | 
| 2284 2719 | 
             
                    /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
         | 
| 2285 | 
            -
                     | 
| 2720 | 
            +
                    /* fill all offset symbols to avoid garbage at end of table */
         | 
| 2721 | 
            +
                    CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable, offcodeNCount, MaxOff, offcodeLog, workspace, HUF_WORKSPACE_SIZE),
         | 
| 2286 2722 | 
             
                             dictionary_corrupted);
         | 
| 2287 2723 | 
             
                    dictPtr += offcodeHeaderSize;
         | 
| 2288 2724 | 
             
                }
         | 
| @@ -2294,7 +2730,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc | |
| 2294 2730 | 
             
                    if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
         | 
| 2295 2731 | 
             
                    /* Every match length code must have non-zero probability */
         | 
| 2296 2732 | 
             
                    CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
         | 
| 2297 | 
            -
                    CHECK_E( FSE_buildCTable_wksp(bs->entropy.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
         | 
| 2733 | 
            +
                    CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
         | 
| 2298 2734 | 
             
                             dictionary_corrupted);
         | 
| 2299 2735 | 
             
                    dictPtr += matchlengthHeaderSize;
         | 
| 2300 2736 | 
             
                }
         | 
| @@ -2306,7 +2742,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc | |
| 2306 2742 | 
             
                    if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
         | 
| 2307 2743 | 
             
                    /* Every literal length code must have non-zero probability */
         | 
| 2308 2744 | 
             
                    CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
         | 
| 2309 | 
            -
                    CHECK_E( FSE_buildCTable_wksp(bs->entropy.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
         | 
| 2745 | 
            +
                    CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
         | 
| 2310 2746 | 
             
                             dictionary_corrupted);
         | 
| 2311 2747 | 
             
                    dictPtr += litlengthHeaderSize;
         | 
| 2312 2748 | 
             
                }
         | 
| @@ -2332,22 +2768,25 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc | |
| 2332 2768 | 
             
                            if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
         | 
| 2333 2769 | 
             
                    }   }
         | 
| 2334 2770 |  | 
| 2335 | 
            -
                    bs->entropy. | 
| 2336 | 
            -
                    bs->entropy.offcode_repeatMode = FSE_repeat_valid;
         | 
| 2337 | 
            -
                    bs->entropy.matchlength_repeatMode = FSE_repeat_valid;
         | 
| 2338 | 
            -
                    bs->entropy.litlength_repeatMode = FSE_repeat_valid;
         | 
| 2339 | 
            -
                    CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize));
         | 
| 2771 | 
            +
                    bs->entropy.huf.repeatMode = HUF_repeat_valid;
         | 
| 2772 | 
            +
                    bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
         | 
| 2773 | 
            +
                    bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
         | 
| 2774 | 
            +
                    bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
         | 
| 2775 | 
            +
                    CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm));
         | 
| 2340 2776 | 
             
                    return dictID;
         | 
| 2341 2777 | 
             
                }
         | 
| 2342 2778 | 
             
            }
         | 
| 2343 2779 |  | 
| 2344 2780 | 
             
            /** ZSTD_compress_insertDictionary() :
         | 
| 2345 2781 | 
             
            *   @return : dictID, or an error code */
         | 
| 2346 | 
            -
            static size_t | 
| 2347 | 
            -
             | 
| 2348 | 
            -
             | 
| 2349 | 
            -
             | 
| 2350 | 
            -
             | 
| 2782 | 
            +
            static size_t
         | 
| 2783 | 
            +
            ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
         | 
| 2784 | 
            +
                                           ZSTD_matchState_t* ms,
         | 
| 2785 | 
            +
                                     const ZSTD_CCtx_params* params,
         | 
| 2786 | 
            +
                                     const void* dict, size_t dictSize,
         | 
| 2787 | 
            +
                                           ZSTD_dictContentType_e dictContentType,
         | 
| 2788 | 
            +
                                           ZSTD_dictTableLoadMethod_e dtlm,
         | 
| 2789 | 
            +
                                           void* workspace)
         | 
| 2351 2790 | 
             
            {
         | 
| 2352 2791 | 
             
                DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
         | 
| 2353 2792 | 
             
                if ((dict==NULL) || (dictSize<=8)) return 0;
         | 
| @@ -2356,12 +2795,12 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZS | |
| 2356 2795 |  | 
| 2357 2796 | 
             
                /* dict restricted modes */
         | 
| 2358 2797 | 
             
                if (dictContentType == ZSTD_dct_rawContent)
         | 
| 2359 | 
            -
                    return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
         | 
| 2798 | 
            +
                    return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
         | 
| 2360 2799 |  | 
| 2361 2800 | 
             
                if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
         | 
| 2362 2801 | 
             
                    if (dictContentType == ZSTD_dct_auto) {
         | 
| 2363 2802 | 
             
                        DEBUGLOG(4, "raw content dictionary detected");
         | 
| 2364 | 
            -
                        return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
         | 
| 2803 | 
            +
                        return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
         | 
| 2365 2804 | 
             
                    }
         | 
| 2366 2805 | 
             
                    if (dictContentType == ZSTD_dct_fullDict)
         | 
| 2367 2806 | 
             
                        return ERROR(dictionary_wrong);
         | 
| @@ -2369,7 +2808,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZS | |
| 2369 2808 | 
             
                }
         | 
| 2370 2809 |  | 
| 2371 2810 | 
             
                /* dict as full zstd dictionary */
         | 
| 2372 | 
            -
                return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, workspace);
         | 
| 2811 | 
            +
                return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace);
         | 
| 2373 2812 | 
             
            }
         | 
| 2374 2813 |  | 
| 2375 2814 | 
             
            /*! ZSTD_compressBegin_internal() :
         | 
| @@ -2377,6 +2816,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZS | |
| 2377 2816 | 
             
            size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
         | 
| 2378 2817 | 
             
                                         const void* dict, size_t dictSize,
         | 
| 2379 2818 | 
             
                                         ZSTD_dictContentType_e dictContentType,
         | 
| 2819 | 
            +
                                         ZSTD_dictTableLoadMethod_e dtlm,
         | 
| 2380 2820 | 
             
                                         const ZSTD_CDict* cdict,
         | 
| 2381 2821 | 
             
                                         ZSTD_CCtx_params params, U64 pledgedSrcSize,
         | 
| 2382 2822 | 
             
                                         ZSTD_buffered_policy_e zbuff)
         | 
| @@ -2387,9 +2827,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, | |
| 2387 2827 | 
             
                assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
         | 
| 2388 2828 |  | 
| 2389 2829 | 
             
                if (cdict && cdict->dictContentSize>0) {
         | 
| 2390 | 
            -
                    cctx | 
| 2391 | 
            -
                    return ZSTD_resetCCtx_usingCDict(cctx, cdict, params.cParams.windowLog,
         | 
| 2392 | 
            -
                                                     params.fParams, pledgedSrcSize, zbuff);
         | 
| 2830 | 
            +
                    return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
         | 
| 2393 2831 | 
             
                }
         | 
| 2394 2832 |  | 
| 2395 2833 | 
             
                CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
         | 
| @@ -2397,7 +2835,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, | |
| 2397 2835 | 
             
                {
         | 
| 2398 2836 | 
             
                    size_t const dictID = ZSTD_compress_insertDictionary(
         | 
| 2399 2837 | 
             
                            cctx->blockState.prevCBlock, &cctx->blockState.matchState,
         | 
| 2400 | 
            -
                            ¶ms, dict, dictSize, dictContentType, cctx->entropyWorkspace);
         | 
| 2838 | 
            +
                            ¶ms, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
         | 
| 2401 2839 | 
             
                    if (ZSTD_isError(dictID)) return dictID;
         | 
| 2402 2840 | 
             
                    assert(dictID <= (size_t)(U32)-1);
         | 
| 2403 2841 | 
             
                    cctx->dictID = (U32)dictID;
         | 
| @@ -2408,6 +2846,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, | |
| 2408 2846 | 
             
            size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
         | 
| 2409 2847 | 
             
                                                const void* dict, size_t dictSize,
         | 
| 2410 2848 | 
             
                                                ZSTD_dictContentType_e dictContentType,
         | 
| 2849 | 
            +
                                                ZSTD_dictTableLoadMethod_e dtlm,
         | 
| 2411 2850 | 
             
                                                const ZSTD_CDict* cdict,
         | 
| 2412 2851 | 
             
                                                ZSTD_CCtx_params params,
         | 
| 2413 2852 | 
             
                                                unsigned long long pledgedSrcSize)
         | 
| @@ -2416,7 +2855,7 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, | |
| 2416 2855 | 
             
                /* compression parameters verification and optimization */
         | 
| 2417 2856 | 
             
                CHECK_F( ZSTD_checkCParams(params.cParams) );
         | 
| 2418 2857 | 
             
                return ZSTD_compressBegin_internal(cctx,
         | 
| 2419 | 
            -
                                                   dict, dictSize, dictContentType,
         | 
| 2858 | 
            +
                                                   dict, dictSize, dictContentType, dtlm,
         | 
| 2420 2859 | 
             
                                                   cdict,
         | 
| 2421 2860 | 
             
                                                   params, pledgedSrcSize,
         | 
| 2422 2861 | 
             
                                                   ZSTDb_not_buffered);
         | 
| @@ -2431,7 +2870,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, | |
| 2431 2870 | 
             
                ZSTD_CCtx_params const cctxParams =
         | 
| 2432 2871 | 
             
                        ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
         | 
| 2433 2872 | 
             
                return ZSTD_compressBegin_advanced_internal(cctx,
         | 
| 2434 | 
            -
                                                        dict, dictSize, ZSTD_dct_auto,
         | 
| 2873 | 
            +
                                                        dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
         | 
| 2435 2874 | 
             
                                                        NULL /*cdict*/,
         | 
| 2436 2875 | 
             
                                                        cctxParams, pledgedSrcSize);
         | 
| 2437 2876 | 
             
            }
         | 
| @@ -2442,7 +2881,7 @@ size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t di | |
| 2442 2881 | 
             
                ZSTD_CCtx_params const cctxParams =
         | 
| 2443 2882 | 
             
                        ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
         | 
| 2444 2883 | 
             
                DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize);
         | 
| 2445 | 
            -
                return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL,
         | 
| 2884 | 
            +
                return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
         | 
| 2446 2885 | 
             
                                                   cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
         | 
| 2447 2886 | 
             
            }
         | 
| 2448 2887 |  | 
| @@ -2505,7 +2944,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, | |
| 2505 2944 | 
             
                if (ZSTD_isError(cSize)) return cSize;
         | 
| 2506 2945 | 
             
                endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
         | 
| 2507 2946 | 
             
                if (ZSTD_isError(endResult)) return endResult;
         | 
| 2508 | 
            -
                 | 
| 2947 | 
            +
                assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
         | 
| 2948 | 
            +
                if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */
         | 
| 2949 | 
            +
                    ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
         | 
| 2509 2950 | 
             
                    DEBUGLOG(4, "end of frame : controlling src size");
         | 
| 2510 2951 | 
             
                    if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
         | 
| 2511 2952 | 
             
                        DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
         | 
| @@ -2517,22 +2958,22 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, | |
| 2517 2958 |  | 
| 2518 2959 |  | 
| 2519 2960 | 
             
            static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
         | 
| 2520 | 
            -
             | 
| 2521 | 
            -
             | 
| 2522 | 
            -
             | 
| 2523 | 
            -
             | 
| 2961 | 
            +
                                                  void* dst, size_t dstCapacity,
         | 
| 2962 | 
            +
                                            const void* src, size_t srcSize,
         | 
| 2963 | 
            +
                                            const void* dict,size_t dictSize,
         | 
| 2964 | 
            +
                                                  ZSTD_parameters params)
         | 
| 2524 2965 | 
             
            {
         | 
| 2525 2966 | 
             
                ZSTD_CCtx_params const cctxParams =
         | 
| 2526 2967 | 
             
                        ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
         | 
| 2527 2968 | 
             
                DEBUGLOG(4, "ZSTD_compress_internal");
         | 
| 2528 2969 | 
             
                return ZSTD_compress_advanced_internal(cctx,
         | 
| 2529 | 
            -
             | 
| 2530 | 
            -
             | 
| 2531 | 
            -
             | 
| 2532 | 
            -
             | 
| 2970 | 
            +
                                                       dst, dstCapacity,
         | 
| 2971 | 
            +
                                                       src, srcSize,
         | 
| 2972 | 
            +
                                                       dict, dictSize,
         | 
| 2973 | 
            +
                                                       cctxParams);
         | 
| 2533 2974 | 
             
            }
         | 
| 2534 2975 |  | 
| 2535 | 
            -
            size_t ZSTD_compress_advanced (ZSTD_CCtx*  | 
| 2976 | 
            +
            size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
         | 
| 2536 2977 | 
             
                                           void* dst, size_t dstCapacity,
         | 
| 2537 2978 | 
             
                                     const void* src, size_t srcSize,
         | 
| 2538 2979 | 
             
                                     const void* dict,size_t dictSize,
         | 
| @@ -2540,7 +2981,11 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, | |
| 2540 2981 | 
             
            {
         | 
| 2541 2982 | 
             
                DEBUGLOG(4, "ZSTD_compress_advanced");
         | 
| 2542 2983 | 
             
                CHECK_F(ZSTD_checkCParams(params.cParams));
         | 
| 2543 | 
            -
                return ZSTD_compress_internal( | 
| 2984 | 
            +
                return ZSTD_compress_internal(cctx,
         | 
| 2985 | 
            +
                                              dst, dstCapacity,
         | 
| 2986 | 
            +
                                              src, srcSize,
         | 
| 2987 | 
            +
                                              dict, dictSize,
         | 
| 2988 | 
            +
                                              params);
         | 
| 2544 2989 | 
             
            }
         | 
| 2545 2990 |  | 
| 2546 2991 | 
             
            /* Internal */
         | 
| @@ -2551,37 +2996,44 @@ size_t ZSTD_compress_advanced_internal( | |
| 2551 2996 | 
             
                    const void* dict,size_t dictSize,
         | 
| 2552 2997 | 
             
                    ZSTD_CCtx_params params)
         | 
| 2553 2998 | 
             
            {
         | 
| 2554 | 
            -
                DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)",
         | 
| 2555 | 
            -
             | 
| 2556 | 
            -
             | 
| 2557 | 
            -
             | 
| 2999 | 
            +
                DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (U32)srcSize);
         | 
| 3000 | 
            +
                CHECK_F( ZSTD_compressBegin_internal(cctx,
         | 
| 3001 | 
            +
                                     dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
         | 
| 3002 | 
            +
                                     params, srcSize, ZSTDb_not_buffered) );
         | 
| 2558 3003 | 
             
                return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
         | 
| 2559 3004 | 
             
            }
         | 
| 2560 3005 |  | 
| 2561 | 
            -
            size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, | 
| 2562 | 
            -
                                            | 
| 3006 | 
            +
            size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
         | 
| 3007 | 
            +
                                           void* dst, size_t dstCapacity,
         | 
| 3008 | 
            +
                                     const void* src, size_t srcSize,
         | 
| 3009 | 
            +
                                     const void* dict, size_t dictSize,
         | 
| 3010 | 
            +
                                           int compressionLevel)
         | 
| 2563 3011 | 
             
            {
         | 
| 2564 | 
            -
                ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize  | 
| 3012 | 
            +
                ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
         | 
| 2565 3013 | 
             
                ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
         | 
| 2566 3014 | 
             
                assert(params.fParams.contentSizeFlag == 1);
         | 
| 2567 | 
            -
                ZSTD_CCtxParam_setParameter(&cctxParams, ZSTD_p_compressLiterals, compressionLevel>=0);
         | 
| 2568 3015 | 
             
                return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
         | 
| 2569 3016 | 
             
            }
         | 
| 2570 3017 |  | 
| 2571 | 
            -
            size_t ZSTD_compressCCtx | 
| 3018 | 
            +
            size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
         | 
| 3019 | 
            +
                                     void* dst, size_t dstCapacity,
         | 
| 3020 | 
            +
                               const void* src, size_t srcSize,
         | 
| 3021 | 
            +
                                     int compressionLevel)
         | 
| 2572 3022 | 
             
            {
         | 
| 2573 3023 | 
             
                DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize);
         | 
| 3024 | 
            +
                assert(cctx != NULL);
         | 
| 2574 3025 | 
             
                return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
         | 
| 2575 3026 | 
             
            }
         | 
| 2576 3027 |  | 
| 2577 | 
            -
            size_t ZSTD_compress(void* dst, size_t dstCapacity, | 
| 3028 | 
            +
            size_t ZSTD_compress(void* dst, size_t dstCapacity,
         | 
| 3029 | 
            +
                           const void* src, size_t srcSize,
         | 
| 3030 | 
            +
                                 int compressionLevel)
         | 
| 2578 3031 | 
             
            {
         | 
| 2579 3032 | 
             
                size_t result;
         | 
| 2580 3033 | 
             
                ZSTD_CCtx ctxBody;
         | 
| 2581 | 
            -
                 | 
| 2582 | 
            -
                ctxBody.customMem = ZSTD_defaultCMem;
         | 
| 3034 | 
            +
                ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);
         | 
| 2583 3035 | 
             
                result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
         | 
| 2584 | 
            -
                 | 
| 3036 | 
            +
                ZSTD_freeCCtxContent(&ctxBody);   /* can't free ctxBody itself, as it's on stack; free only heap content */
         | 
| 2585 3037 | 
             
                return result;
         | 
| 2586 3038 | 
             
            }
         | 
| 2587 3039 |  | 
| @@ -2619,7 +3071,7 @@ static size_t ZSTD_initCDict_internal( | |
| 2619 3071 | 
             
                                ZSTD_dictContentType_e dictContentType,
         | 
| 2620 3072 | 
             
                                ZSTD_compressionParameters cParams)
         | 
| 2621 3073 | 
             
            {
         | 
| 2622 | 
            -
                DEBUGLOG(3, "ZSTD_initCDict_internal | 
| 3074 | 
            +
                DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (U32)dictContentType);
         | 
| 2623 3075 | 
             
                assert(!ZSTD_checkCParams(cParams));
         | 
| 2624 3076 | 
             
                cdict->cParams = cParams;
         | 
| 2625 3077 | 
             
                if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
         | 
| @@ -2654,7 +3106,7 @@ static size_t ZSTD_initCDict_internal( | |
| 2654 3106 | 
             
                    {   size_t const dictID = ZSTD_compress_insertDictionary(
         | 
| 2655 3107 | 
             
                                &cdict->cBlockState, &cdict->matchState, ¶ms,
         | 
| 2656 3108 | 
             
                                cdict->dictContent, cdict->dictContentSize,
         | 
| 2657 | 
            -
                                dictContentType, cdict->workspace);
         | 
| 3109 | 
            +
                                dictContentType, ZSTD_dtlm_full, cdict->workspace);
         | 
| 2658 3110 | 
             
                        if (ZSTD_isError(dictID)) return dictID;
         | 
| 2659 3111 | 
             
                        assert(dictID <= (size_t)(U32)-1);
         | 
| 2660 3112 | 
             
                        cdict->dictID = (U32)dictID;
         | 
| @@ -2799,7 +3251,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced( | |
| 2799 3251 | 
             
                    }
         | 
| 2800 3252 | 
             
                    params.fParams = fParams;
         | 
| 2801 3253 | 
             
                    return ZSTD_compressBegin_internal(cctx,
         | 
| 2802 | 
            -
                                                       NULL, 0, ZSTD_dct_auto,
         | 
| 3254 | 
            +
                                                       NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
         | 
| 2803 3255 | 
             
                                                       cdict,
         | 
| 2804 3256 | 
             
                                                       params, pledgedSrcSize,
         | 
| 2805 3257 | 
             
                                                       ZSTDb_not_buffered);
         | 
| @@ -2813,7 +3265,7 @@ size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) | |
| 2813 3265 | 
             
            {
         | 
| 2814 3266 | 
             
                ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
         | 
| 2815 3267 | 
             
                DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
         | 
| 2816 | 
            -
                return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams,  | 
| 3268 | 
            +
                return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN);
         | 
| 2817 3269 | 
             
            }
         | 
| 2818 3270 |  | 
| 2819 3271 | 
             
            size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
         | 
| @@ -2882,14 +3334,13 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx, | |
| 2882 3334 | 
             
                                const ZSTD_CDict* const cdict,
         | 
| 2883 3335 | 
             
                                ZSTD_CCtx_params const params, unsigned long long const pledgedSrcSize)
         | 
| 2884 3336 | 
             
            {
         | 
| 2885 | 
            -
                DEBUGLOG(4, "ZSTD_resetCStream_internal | 
| 2886 | 
            -
                            params.disableLiteralCompression);
         | 
| 3337 | 
            +
                DEBUGLOG(4, "ZSTD_resetCStream_internal");
         | 
| 2887 3338 | 
             
                /* params are supposed to be fully validated at this point */
         | 
| 2888 3339 | 
             
                assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         | 
| 2889 3340 | 
             
                assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
         | 
| 2890 3341 |  | 
| 2891 3342 | 
             
                CHECK_F( ZSTD_compressBegin_internal(cctx,
         | 
| 2892 | 
            -
                                                     dict, dictSize, dictContentType,
         | 
| 3343 | 
            +
                                                     dict, dictSize, dictContentType, ZSTD_dtlm_fast,
         | 
| 2893 3344 | 
             
                                                     cdict,
         | 
| 2894 3345 | 
             
                                                     params, pledgedSrcSize,
         | 
| 2895 3346 | 
             
                                                     ZSTDb_buffered) );
         | 
| @@ -3073,7 +3524,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 3073 3524 | 
             
                            ip = iend;
         | 
| 3074 3525 | 
             
                            op += cSize;
         | 
| 3075 3526 | 
             
                            zcs->frameEnded = 1;
         | 
| 3076 | 
            -
                             | 
| 3527 | 
            +
                            ZSTD_CCtx_reset(zcs);
         | 
| 3077 3528 | 
             
                            someMoreWork = 0; break;
         | 
| 3078 3529 | 
             
                        }
         | 
| 3079 3530 | 
             
                        /* complete loading into inBuffer */
         | 
| @@ -3126,7 +3577,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 3126 3577 | 
             
                                if (zcs->frameEnded) {
         | 
| 3127 3578 | 
             
                                    DEBUGLOG(5, "Frame completed directly in outBuffer");
         | 
| 3128 3579 | 
             
                                    someMoreWork = 0;
         | 
| 3129 | 
            -
                                     | 
| 3580 | 
            +
                                    ZSTD_CCtx_reset(zcs);
         | 
| 3130 3581 | 
             
                                }
         | 
| 3131 3582 | 
             
                                break;
         | 
| 3132 3583 | 
             
                            }
         | 
| @@ -3154,7 +3605,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, | |
| 3154 3605 | 
             
                            if (zcs->frameEnded) {
         | 
| 3155 3606 | 
             
                                DEBUGLOG(5, "Frame completed on flush");
         | 
| 3156 3607 | 
             
                                someMoreWork = 0;
         | 
| 3157 | 
            -
                                 | 
| 3608 | 
            +
                                ZSTD_CCtx_reset(zcs);
         | 
| 3158 3609 | 
             
                                break;
         | 
| 3159 3610 | 
             
                            }
         | 
| 3160 3611 | 
             
                            zcs->streamStage = zcss_load;
         | 
| @@ -3207,19 +3658,16 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, | |
| 3207 3658 | 
             
                    params.cParams = ZSTD_getCParamsFromCCtxParams(
         | 
| 3208 3659 | 
             
                            &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
         | 
| 3209 3660 |  | 
| 3661 | 
            +
             | 
| 3210 3662 | 
             
            #ifdef ZSTD_MULTITHREAD
         | 
| 3211 3663 | 
             
                    if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
         | 
| 3212 3664 | 
             
                        params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
         | 
| 3213 3665 | 
             
                    }
         | 
| 3214 3666 | 
             
                    if (params.nbWorkers > 0) {
         | 
| 3215 3667 | 
             
                        /* mt context creation */
         | 
| 3216 | 
            -
                        if (cctx->mtctx == NULL | 
| 3668 | 
            +
                        if (cctx->mtctx == NULL) {
         | 
| 3217 3669 | 
             
                            DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u",
         | 
| 3218 3670 | 
             
                                        params.nbWorkers);
         | 
| 3219 | 
            -
                            if (cctx->mtctx != NULL)
         | 
| 3220 | 
            -
                                DEBUGLOG(4, "ZSTD_compress_generic: previous nbWorkers was %u",
         | 
| 3221 | 
            -
                                            ZSTDMT_getNbWorkers(cctx->mtctx));
         | 
| 3222 | 
            -
                            ZSTDMT_freeCCtx(cctx->mtctx);
         | 
| 3223 3671 | 
             
                            cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
         | 
| 3224 3672 | 
             
                            if (cctx->mtctx == NULL) return ERROR(memory_allocation);
         | 
| 3225 3673 | 
             
                        }
         | 
| @@ -3251,7 +3699,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, | |
| 3251 3699 | 
             
                    {   size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
         | 
| 3252 3700 | 
             
                        if ( ZSTD_isError(flushMin)
         | 
| 3253 3701 | 
             
                          || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
         | 
| 3254 | 
            -
                             | 
| 3702 | 
            +
                            ZSTD_CCtx_reset(cctx);
         | 
| 3255 3703 | 
             
                        }
         | 
| 3256 3704 | 
             
                        return flushMin;
         | 
| 3257 3705 | 
             
                }   }
         | 
| @@ -3313,77 +3761,77 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV | |
| 3313 3761 | 
             
            {   /* "default" - guarantees a monotonically increasing memory budget */
         | 
| 3314 3762 | 
             
                /* W,  C,  H,  S,  L, TL, strat */
         | 
| 3315 3763 | 
             
                { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */
         | 
| 3316 | 
            -
                { 19, 13, 14,  1,  7,   | 
| 3317 | 
            -
                { 19, 15, 16,  1,  6,   | 
| 3318 | 
            -
                { 20, 16, 17,  1,  5,   | 
| 3319 | 
            -
                { 20,  | 
| 3320 | 
            -
                { 20,  | 
| 3321 | 
            -
                { 21,  | 
| 3322 | 
            -
                { 21, 18, 19,  3,  5, | 
| 3323 | 
            -
                { 21,  | 
| 3324 | 
            -
                { 21, 19, 20,   | 
| 3325 | 
            -
                { 21,  | 
| 3326 | 
            -
                {  | 
| 3764 | 
            +
                { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */
         | 
| 3765 | 
            +
                { 19, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */
         | 
| 3766 | 
            +
                { 20, 16, 17,  1,  5,  1, ZSTD_dfast   },  /* level  3 */
         | 
| 3767 | 
            +
                { 20, 18, 18,  1,  5,  1, ZSTD_dfast   },  /* level  4 */
         | 
| 3768 | 
            +
                { 20, 18, 18,  2,  5,  2, ZSTD_greedy  },  /* level  5 */
         | 
| 3769 | 
            +
                { 21, 18, 19,  2,  5,  4, ZSTD_lazy    },  /* level  6 */
         | 
| 3770 | 
            +
                { 21, 18, 19,  3,  5,  8, ZSTD_lazy2   },  /* level  7 */
         | 
| 3771 | 
            +
                { 21, 19, 19,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
         | 
| 3772 | 
            +
                { 21, 19, 20,  4,  5, 16, ZSTD_lazy2   },  /* level  9 */
         | 
| 3773 | 
            +
                { 21, 20, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
         | 
| 3774 | 
            +
                { 21, 21, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
         | 
| 3327 3775 | 
             
                { 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
         | 
| 3328 3776 | 
             
                { 22, 21, 22,  4,  5, 32, ZSTD_btlazy2 },  /* level 13 */
         | 
| 3329 3777 | 
             
                { 22, 21, 22,  5,  5, 32, ZSTD_btlazy2 },  /* level 14 */
         | 
| 3330 3778 | 
             
                { 22, 22, 22,  6,  5, 32, ZSTD_btlazy2 },  /* level 15 */
         | 
| 3331 3779 | 
             
                { 22, 21, 22,  4,  5, 48, ZSTD_btopt   },  /* level 16 */
         | 
| 3332 | 
            -
                { 23, 22, 22,  4,  4,  | 
| 3333 | 
            -
                { 23,  | 
| 3334 | 
            -
                { 23,  | 
| 3335 | 
            -
                { 25, 25, 23,  7,  3, | 
| 3336 | 
            -
                { 26, 26, 24,  7,  3, | 
| 3337 | 
            -
                { 27, 27, 25,  9,  3, | 
| 3780 | 
            +
                { 23, 22, 22,  4,  4, 64, ZSTD_btopt   },  /* level 17 */
         | 
| 3781 | 
            +
                { 23, 23, 22,  6,  3,256, ZSTD_btopt   },  /* level 18 */
         | 
| 3782 | 
            +
                { 23, 24, 22,  7,  3,256, ZSTD_btultra },  /* level 19 */
         | 
| 3783 | 
            +
                { 25, 25, 23,  7,  3,256, ZSTD_btultra },  /* level 20 */
         | 
| 3784 | 
            +
                { 26, 26, 24,  7,  3,512, ZSTD_btultra },  /* level 21 */
         | 
| 3785 | 
            +
                { 27, 27, 25,  9,  3,999, ZSTD_btultra },  /* level 22 */
         | 
| 3338 3786 | 
             
            },
         | 
| 3339 3787 | 
             
            {   /* for srcSize <= 256 KB */
         | 
| 3340 3788 | 
             
                /* W,  C,  H,  S,  L,  T, strat */
         | 
| 3341 3789 | 
             
                { 18, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
         | 
| 3342 | 
            -
                { 18, 13, 14,  1,  6,   | 
| 3343 | 
            -
                { 18, 14,  | 
| 3344 | 
            -
                { 18, 16,  | 
| 3345 | 
            -
                { 18,  | 
| 3346 | 
            -
                { 18,  | 
| 3347 | 
            -
                { 18,  | 
| 3348 | 
            -
                { 18,  | 
| 3349 | 
            -
                { 18,  | 
| 3350 | 
            -
                { 18,  | 
| 3351 | 
            -
                { 18,  | 
| 3352 | 
            -
                { 18, 18,  | 
| 3353 | 
            -
                { 18,  | 
| 3354 | 
            -
                { 18, 19,  | 
| 3355 | 
            -
                { 18, 18,  | 
| 3356 | 
            -
                { 18, 18,  | 
| 3357 | 
            -
                { 18, 19,  | 
| 3358 | 
            -
                { 18, 19,  | 
| 3359 | 
            -
                { 18, 19,  | 
| 3360 | 
            -
                { 18, 19,  | 
| 3361 | 
            -
                { 18, 19,  | 
| 3362 | 
            -
                { 18, 19,  | 
| 3363 | 
            -
                { 18, 19,  | 
| 3790 | 
            +
                { 18, 13, 14,  1,  6,  0, ZSTD_fast    },  /* level  1 */
         | 
| 3791 | 
            +
                { 18, 14, 14,  1,  5,  1, ZSTD_dfast   },  /* level  2 */
         | 
| 3792 | 
            +
                { 18, 16, 16,  1,  4,  1, ZSTD_dfast   },  /* level  3 */
         | 
| 3793 | 
            +
                { 18, 16, 17,  2,  5,  2, ZSTD_greedy  },  /* level  4.*/
         | 
| 3794 | 
            +
                { 18, 18, 18,  3,  5,  2, ZSTD_greedy  },  /* level  5.*/
         | 
| 3795 | 
            +
                { 18, 18, 19,  3,  5,  4, ZSTD_lazy    },  /* level  6.*/
         | 
| 3796 | 
            +
                { 18, 18, 19,  4,  4,  4, ZSTD_lazy    },  /* level  7 */
         | 
| 3797 | 
            +
                { 18, 18, 19,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
         | 
| 3798 | 
            +
                { 18, 18, 19,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
         | 
| 3799 | 
            +
                { 18, 18, 19,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
         | 
| 3800 | 
            +
                { 18, 18, 19,  5,  4, 16, ZSTD_btlazy2 },  /* level 11.*/
         | 
| 3801 | 
            +
                { 18, 19, 19,  6,  4, 16, ZSTD_btlazy2 },  /* level 12.*/
         | 
| 3802 | 
            +
                { 18, 19, 19,  8,  4, 16, ZSTD_btlazy2 },  /* level 13 */
         | 
| 3803 | 
            +
                { 18, 18, 19,  4,  4, 24, ZSTD_btopt   },  /* level 14.*/
         | 
| 3804 | 
            +
                { 18, 18, 19,  4,  3, 24, ZSTD_btopt   },  /* level 15.*/
         | 
| 3805 | 
            +
                { 18, 19, 19,  6,  3, 64, ZSTD_btopt   },  /* level 16.*/
         | 
| 3806 | 
            +
                { 18, 19, 19,  8,  3,128, ZSTD_btopt   },  /* level 17.*/
         | 
| 3807 | 
            +
                { 18, 19, 19, 10,  3,256, ZSTD_btopt   },  /* level 18.*/
         | 
| 3808 | 
            +
                { 18, 19, 19, 10,  3,256, ZSTD_btultra },  /* level 19.*/
         | 
| 3809 | 
            +
                { 18, 19, 19, 11,  3,512, ZSTD_btultra },  /* level 20.*/
         | 
| 3810 | 
            +
                { 18, 19, 19, 12,  3,512, ZSTD_btultra },  /* level 21.*/
         | 
| 3811 | 
            +
                { 18, 19, 19, 13,  3,999, ZSTD_btultra },  /* level 22.*/
         | 
| 3364 3812 | 
             
            },
         | 
| 3365 3813 | 
             
            {   /* for srcSize <= 128 KB */
         | 
| 3366 3814 | 
             
                /* W,  C,  H,  S,  L,  T, strat */
         | 
| 3367 | 
            -
                { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /*  | 
| 3368 | 
            -
                { 17, 12, 13,  1,  6,   | 
| 3369 | 
            -
                { 17, 13,  | 
| 3370 | 
            -
                { 17,  | 
| 3371 | 
            -
                { 17,  | 
| 3372 | 
            -
                { 17,  | 
| 3373 | 
            -
                { 17,  | 
| 3374 | 
            -
                { 17,  | 
| 3815 | 
            +
                { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
         | 
| 3816 | 
            +
                { 17, 12, 13,  1,  6,  0, ZSTD_fast    },  /* level  1 */
         | 
| 3817 | 
            +
                { 17, 13, 15,  1,  5,  0, ZSTD_fast    },  /* level  2 */
         | 
| 3818 | 
            +
                { 17, 15, 16,  2,  5,  1, ZSTD_dfast   },  /* level  3 */
         | 
| 3819 | 
            +
                { 17, 17, 17,  2,  4,  1, ZSTD_dfast   },  /* level  4 */
         | 
| 3820 | 
            +
                { 17, 16, 17,  3,  4,  2, ZSTD_greedy  },  /* level  5 */
         | 
| 3821 | 
            +
                { 17, 17, 17,  3,  4,  4, ZSTD_lazy    },  /* level  6 */
         | 
| 3822 | 
            +
                { 17, 17, 17,  3,  4,  8, ZSTD_lazy2   },  /* level  7 */
         | 
| 3375 3823 | 
             
                { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
         | 
| 3376 3824 | 
             
                { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
         | 
| 3377 3825 | 
             
                { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
         | 
| 3378 3826 | 
             
                { 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
         | 
| 3379 | 
            -
                { 17,  | 
| 3380 | 
            -
                { 17, 18, 17,   | 
| 3381 | 
            -
                { 17,  | 
| 3382 | 
            -
                { 17,  | 
| 3383 | 
            -
                { 17, 18, 17,  7,  3, | 
| 3384 | 
            -
                { 17, 18, 17,  7,  3, | 
| 3385 | 
            -
                { 17, 18, 17,   | 
| 3386 | 
            -
                { 17, 18, 17,  8,  3,256,  | 
| 3827 | 
            +
                { 17, 18, 17,  6,  4, 16, ZSTD_btlazy2 },  /* level 12 */
         | 
| 3828 | 
            +
                { 17, 18, 17,  8,  4, 16, ZSTD_btlazy2 },  /* level 13.*/
         | 
| 3829 | 
            +
                { 17, 18, 17,  4,  4, 32, ZSTD_btopt   },  /* level 14.*/
         | 
| 3830 | 
            +
                { 17, 18, 17,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
         | 
| 3831 | 
            +
                { 17, 18, 17,  7,  3,128, ZSTD_btopt   },  /* level 16.*/
         | 
| 3832 | 
            +
                { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 17.*/
         | 
| 3833 | 
            +
                { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 18.*/
         | 
| 3834 | 
            +
                { 17, 18, 17,  8,  3,256, ZSTD_btultra },  /* level 19.*/
         | 
| 3387 3835 | 
             
                { 17, 18, 17,  9,  3,256, ZSTD_btultra },  /* level 20.*/
         | 
| 3388 3836 | 
             
                { 17, 18, 17, 10,  3,256, ZSTD_btultra },  /* level 21.*/
         | 
| 3389 3837 | 
             
                { 17, 18, 17, 11,  3,512, ZSTD_btultra },  /* level 22.*/
         | 
| @@ -3391,28 +3839,28 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV | |
| 3391 3839 | 
             
            {   /* for srcSize <= 16 KB */
         | 
| 3392 3840 | 
             
                /* W,  C,  H,  S,  L,  T, strat */
         | 
| 3393 3841 | 
             
                { 14, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */
         | 
| 3394 | 
            -
                { 14, 14,  | 
| 3395 | 
            -
                { 14, 14,  | 
| 3396 | 
            -
                { 14, 14, 14,   | 
| 3397 | 
            -
                { 14, 14, 14,  4,  4,   | 
| 3398 | 
            -
                { 14, 14, 14,  3,  4,   | 
| 3399 | 
            -
                { 14, 14, 14,  4,  4,   | 
| 3400 | 
            -
                { 14, 14, 14,   | 
| 3401 | 
            -
                { 14, 14, 14,   | 
| 3402 | 
            -
                { 14, 15, 14,   | 
| 3403 | 
            -
                { 14, 15, 14,   | 
| 3404 | 
            -
                { 14, 15, 14,   | 
| 3842 | 
            +
                { 14, 14, 15,  1,  5,  0, ZSTD_fast    },  /* level  1 */
         | 
| 3843 | 
            +
                { 14, 14, 15,  1,  4,  0, ZSTD_fast    },  /* level  2 */
         | 
| 3844 | 
            +
                { 14, 14, 14,  2,  4,  1, ZSTD_dfast   },  /* level  3.*/
         | 
| 3845 | 
            +
                { 14, 14, 14,  4,  4,  2, ZSTD_greedy  },  /* level  4.*/
         | 
| 3846 | 
            +
                { 14, 14, 14,  3,  4,  4, ZSTD_lazy    },  /* level  5.*/
         | 
| 3847 | 
            +
                { 14, 14, 14,  4,  4,  8, ZSTD_lazy2   },  /* level  6 */
         | 
| 3848 | 
            +
                { 14, 14, 14,  6,  4,  8, ZSTD_lazy2   },  /* level  7 */
         | 
| 3849 | 
            +
                { 14, 14, 14,  8,  4,  8, ZSTD_lazy2   },  /* level  8.*/
         | 
| 3850 | 
            +
                { 14, 15, 14,  5,  4,  8, ZSTD_btlazy2 },  /* level  9.*/
         | 
| 3851 | 
            +
                { 14, 15, 14,  9,  4,  8, ZSTD_btlazy2 },  /* level 10.*/
         | 
| 3852 | 
            +
                { 14, 15, 14,  3,  4, 12, ZSTD_btopt   },  /* level 11.*/
         | 
| 3405 3853 | 
             
                { 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
         | 
| 3406 3854 | 
             
                { 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
         | 
| 3407 3855 | 
             
                { 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
         | 
| 3408 3856 | 
             
                { 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
         | 
| 3409 3857 | 
             
                { 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
         | 
| 3410 3858 | 
             
                { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
         | 
| 3411 | 
            -
                { 14, 15, 15,   | 
| 3412 | 
            -
                { 14, 15, 15,   | 
| 3859 | 
            +
                { 14, 15, 15,  8,  3,256, ZSTD_btopt   },  /* level 18.*/
         | 
| 3860 | 
            +
                { 14, 15, 15,  6,  3,256, ZSTD_btultra },  /* level 19.*/
         | 
| 3413 3861 | 
             
                { 14, 15, 15,  8,  3,256, ZSTD_btultra },  /* level 20.*/
         | 
| 3414 3862 | 
             
                { 14, 15, 15,  9,  3,256, ZSTD_btultra },  /* level 21.*/
         | 
| 3415 | 
            -
                { 14, 15, 15, 10,  3, | 
| 3863 | 
            +
                { 14, 15, 15, 10,  3,512, ZSTD_btultra },  /* level 22.*/
         | 
| 3416 3864 | 
             
            },
         | 
| 3417 3865 | 
             
            };
         | 
| 3418 3866 |  |