Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) Yann Collet, Facebook, Inc.
0003  * All rights reserved.
0004  *
0005  * This source code is licensed under both the BSD-style license (found in the
0006  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
0007  * in the COPYING file in the root directory of this source tree).
0008  * You may select, at your option, one of the above-listed licenses.
0009  */
0010 
0011 /* This header contains definitions
0012  * that shall **only** be used by modules within lib/compress.
0013  */
0014 
0015 #ifndef ZSTD_COMPRESS_H
0016 #define ZSTD_COMPRESS_H
0017 
0018 /*-*************************************
0019 *  Dependencies
0020 ***************************************/
0021 #include "../common/zstd_internal.h"
0022 #include "zstd_cwksp.h"
0023 
0024 
0025 /*-*************************************
0026 *  Constants
0027 ***************************************/
0028 #define kSearchStrength      8
0029 #define HASH_READ_SIZE       8
0030 #define ZSTD_DUBT_UNSORTED_MARK 1   /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted".
0031                                        It could be confused for a real successor at index "1", if sorted as larger than its predecessor.
0032                                        It's not a big deal though : candidate will just be sorted again.
0033                                        Additionally, candidate position 1 will be lost.
0034                                        But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.
0035                                        The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy.
0036                                        This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
0037 
0038 
0039 /*-*************************************
0040 *  Context memory management
0041 ***************************************/
0042 typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
0043 typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage;
0044 
0045 typedef struct ZSTD_prefixDict_s {
0046     const void* dict;
0047     size_t dictSize;
0048     ZSTD_dictContentType_e dictContentType;
0049 } ZSTD_prefixDict;
0050 
0051 typedef struct {
0052     void* dictBuffer;
0053     void const* dict;
0054     size_t dictSize;
0055     ZSTD_dictContentType_e dictContentType;
0056     ZSTD_CDict* cdict;
0057 } ZSTD_localDict;
0058 
0059 typedef struct {
0060     HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)];
0061     HUF_repeat repeatMode;
0062 } ZSTD_hufCTables_t;
0063 
0064 typedef struct {
0065     FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
0066     FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
0067     FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
0068     FSE_repeat offcode_repeatMode;
0069     FSE_repeat matchlength_repeatMode;
0070     FSE_repeat litlength_repeatMode;
0071 } ZSTD_fseCTables_t;
0072 
0073 typedef struct {
0074     ZSTD_hufCTables_t huf;
0075     ZSTD_fseCTables_t fse;
0076 } ZSTD_entropyCTables_t;
0077 
0078 typedef struct {
0079     U32 off;            /* Offset code (offset + ZSTD_REP_MOVE) for the match */
0080     U32 len;            /* Raw length of match */
0081 } ZSTD_match_t;
0082 
0083 typedef struct {
0084     U32 offset;         /* Offset of sequence */
0085     U32 litLength;      /* Length of literals prior to match */
0086     U32 matchLength;    /* Raw length of match */
0087 } rawSeq;
0088 
0089 typedef struct {
0090   rawSeq* seq;          /* The start of the sequences */
0091   size_t pos;           /* The index in seq where reading stopped. pos <= size. */
0092   size_t posInSequence; /* The position within the sequence at seq[pos] where reading
0093                            stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
0094   size_t size;          /* The number of sequences. <= capacity. */
0095   size_t capacity;      /* The capacity starting from `seq` pointer */
0096 } rawSeqStore_t;
0097 
0098 UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
0099 
0100 typedef struct {
0101     int price;
0102     U32 off;
0103     U32 mlen;
0104     U32 litlen;
0105     U32 rep[ZSTD_REP_NUM];
0106 } ZSTD_optimal_t;
0107 
0108 typedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e;
0109 
0110 typedef struct {
0111     /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */
0112     unsigned* litFreq;           /* table of literals statistics, of size 256 */
0113     unsigned* litLengthFreq;     /* table of litLength statistics, of size (MaxLL+1) */
0114     unsigned* matchLengthFreq;   /* table of matchLength statistics, of size (MaxML+1) */
0115     unsigned* offCodeFreq;       /* table of offCode statistics, of size (MaxOff+1) */
0116     ZSTD_match_t* matchTable;    /* list of found matches, of size ZSTD_OPT_NUM+1 */
0117     ZSTD_optimal_t* priceTable;  /* All positions tracked by optimal parser, of size ZSTD_OPT_NUM+1 */
0118 
0119     U32  litSum;                 /* nb of literals */
0120     U32  litLengthSum;           /* nb of litLength codes */
0121     U32  matchLengthSum;         /* nb of matchLength codes */
0122     U32  offCodeSum;             /* nb of offset codes */
0123     U32  litSumBasePrice;        /* to compare to log2(litfreq) */
0124     U32  litLengthSumBasePrice;  /* to compare to log2(llfreq)  */
0125     U32  matchLengthSumBasePrice;/* to compare to log2(mlfreq)  */
0126     U32  offCodeSumBasePrice;    /* to compare to log2(offreq)  */
0127     ZSTD_OptPrice_e priceType;   /* prices can be determined dynamically, or follow a pre-defined cost structure */
0128     const ZSTD_entropyCTables_t* symbolCosts;  /* pre-calculated dictionary statistics */
0129     ZSTD_literalCompressionMode_e literalCompressionMode;
0130 } optState_t;
0131 
0132 typedef struct {
0133   ZSTD_entropyCTables_t entropy;
0134   U32 rep[ZSTD_REP_NUM];
0135 } ZSTD_compressedBlockState_t;
0136 
0137 typedef struct {
0138     BYTE const* nextSrc;    /* next block here to continue on current prefix */
0139     BYTE const* base;       /* All regular indexes relative to this position */
0140     BYTE const* dictBase;   /* extDict indexes relative to this position */
0141     U32 dictLimit;          /* below that point, need extDict */
0142     U32 lowLimit;           /* below that point, no more valid data */
0143 } ZSTD_window_t;
0144 
0145 typedef struct ZSTD_matchState_t ZSTD_matchState_t;
0146 struct ZSTD_matchState_t {
0147     ZSTD_window_t window;   /* State for window round buffer management */
0148     U32 loadedDictEnd;      /* index of end of dictionary, within context's referential.
0149                              * When loadedDictEnd != 0, a dictionary is in use, and still valid.
0150                              * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance.
0151                              * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity().
0152                              * When dict referential is copied into active context (i.e. not attached),
0153                              * loadedDictEnd == dictSize, since referential starts from zero.
0154                              */
0155     U32 nextToUpdate;       /* index from which to continue table update */
0156     U32 hashLog3;           /* dispatch table for matches of len==3 : larger == faster, more memory */
0157     U32* hashTable;
0158     U32* hashTable3;
0159     U32* chainTable;
0160     int dedicatedDictSearch;  /* Indicates whether this matchState is using the
0161                                * dedicated dictionary search structure.
0162                                */
0163     optState_t opt;         /* optimal parser state */
0164     const ZSTD_matchState_t* dictMatchState;
0165     ZSTD_compressionParameters cParams;
0166     const rawSeqStore_t* ldmSeqStore;
0167 };
0168 
0169 typedef struct {
0170     ZSTD_compressedBlockState_t* prevCBlock;
0171     ZSTD_compressedBlockState_t* nextCBlock;
0172     ZSTD_matchState_t matchState;
0173 } ZSTD_blockState_t;
0174 
0175 typedef struct {
0176     U32 offset;
0177     U32 checksum;
0178 } ldmEntry_t;
0179 
0180 typedef struct {
0181     BYTE const* split;
0182     U32 hash;
0183     U32 checksum;
0184     ldmEntry_t* bucket;
0185 } ldmMatchCandidate_t;
0186 
0187 #define LDM_BATCH_SIZE 64
0188 
0189 typedef struct {
0190     ZSTD_window_t window;   /* State for the window round buffer management */
0191     ldmEntry_t* hashTable;
0192     U32 loadedDictEnd;
0193     BYTE* bucketOffsets;    /* Next position in bucket to insert entry */
0194     size_t splitIndices[LDM_BATCH_SIZE];
0195     ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE];
0196 } ldmState_t;
0197 
0198 typedef struct {
0199     U32 enableLdm;          /* 1 if enable long distance matching */
0200     U32 hashLog;            /* Log size of hashTable */
0201     U32 bucketSizeLog;      /* Log bucket size for collision resolution, at most 8 */
0202     U32 minMatchLength;     /* Minimum match length */
0203     U32 hashRateLog;       /* Log number of entries to skip */
0204     U32 windowLog;          /* Window log for the LDM */
0205 } ldmParams_t;
0206 
0207 typedef struct {
0208     int collectSequences;
0209     ZSTD_Sequence* seqStart;
0210     size_t seqIndex;
0211     size_t maxSequences;
0212 } SeqCollector;
0213 
0214 struct ZSTD_CCtx_params_s {
0215     ZSTD_format_e format;
0216     ZSTD_compressionParameters cParams;
0217     ZSTD_frameParameters fParams;
0218 
0219     int compressionLevel;
0220     int forceWindow;           /* force back-references to respect limit of
0221                                 * 1<<wLog, even for dictionary */
0222     size_t targetCBlockSize;   /* Tries to fit compressed block size to be around targetCBlockSize.
0223                                 * No target when targetCBlockSize == 0.
0224                                 * There is no guarantee on compressed block size */
0225     int srcSizeHint;           /* User's best guess of source size.
0226                                 * Hint is not valid when srcSizeHint == 0.
0227                                 * There is no guarantee that hint is close to actual source size */
0228 
0229     ZSTD_dictAttachPref_e attachDictPref;
0230     ZSTD_literalCompressionMode_e literalCompressionMode;
0231 
0232     /* Multithreading: used to pass parameters to mtctx */
0233     int nbWorkers;
0234     size_t jobSize;
0235     int overlapLog;
0236     int rsyncable;
0237 
0238     /* Long distance matching parameters */
0239     ldmParams_t ldmParams;
0240 
0241     /* Dedicated dict search algorithm trigger */
0242     int enableDedicatedDictSearch;
0243 
0244     /* Input/output buffer modes */
0245     ZSTD_bufferMode_e inBufferMode;
0246     ZSTD_bufferMode_e outBufferMode;
0247 
0248     /* Sequence compression API */
0249     ZSTD_sequenceFormat_e blockDelimiters;
0250     int validateSequences;
0251 
0252     /* Internal use, for createCCtxParams() and freeCCtxParams() only */
0253     ZSTD_customMem customMem;
0254 };  /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
0255 
0256 #define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
0257 #define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
0258 
0259 /*
0260  * Indicates whether this compression proceeds directly from user-provided
0261  * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
0262  * whether the context needs to buffer the input/output (ZSTDb_buffered).
0263  */
0264 typedef enum {
0265     ZSTDb_not_buffered,
0266     ZSTDb_buffered
0267 } ZSTD_buffered_policy_e;
0268 
0269 struct ZSTD_CCtx_s {
0270     ZSTD_compressionStage_e stage;
0271     int cParamsChanged;                  /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
0272     int bmi2;                            /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
0273     ZSTD_CCtx_params requestedParams;
0274     ZSTD_CCtx_params appliedParams;
0275     U32   dictID;
0276     size_t dictContentSize;
0277 
0278     ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */
0279     size_t blockSize;
0280     unsigned long long pledgedSrcSizePlusOne;  /* this way, 0 (default) == unknown */
0281     unsigned long long consumedSrcSize;
0282     unsigned long long producedCSize;
0283     struct xxh64_state xxhState;
0284     ZSTD_customMem customMem;
0285     ZSTD_threadPool* pool;
0286     size_t staticSize;
0287     SeqCollector seqCollector;
0288     int isFirstBlock;
0289     int initialized;
0290 
0291     seqStore_t seqStore;      /* sequences storage ptrs */
0292     ldmState_t ldmState;      /* long distance matching state */
0293     rawSeq* ldmSequences;     /* Storage for the ldm output sequences */
0294     size_t maxNbLdmSequences;
0295     rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
0296     ZSTD_blockState_t blockState;
0297     U32* entropyWorkspace;  /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
0298 
0299     /* Wether we are streaming or not */
0300     ZSTD_buffered_policy_e bufferedPolicy;
0301 
0302     /* streaming */
0303     char*  inBuff;
0304     size_t inBuffSize;
0305     size_t inToCompress;
0306     size_t inBuffPos;
0307     size_t inBuffTarget;
0308     char*  outBuff;
0309     size_t outBuffSize;
0310     size_t outBuffContentSize;
0311     size_t outBuffFlushedSize;
0312     ZSTD_cStreamStage streamStage;
0313     U32    frameEnded;
0314 
0315     /* Stable in/out buffer verification */
0316     ZSTD_inBuffer expectedInBuffer;
0317     size_t expectedOutBufferSize;
0318 
0319     /* Dictionary */
0320     ZSTD_localDict localDict;
0321     const ZSTD_CDict* cdict;
0322     ZSTD_prefixDict prefixDict;   /* single-usage dictionary */
0323 
0324     /* Multi-threading */
0325 
0326     /* Tracing */
0327 };
0328 
0329 typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
0330 
0331 typedef enum {
0332     ZSTD_noDict = 0,
0333     ZSTD_extDict = 1,
0334     ZSTD_dictMatchState = 2,
0335     ZSTD_dedicatedDictSearch = 3
0336 } ZSTD_dictMode_e;
0337 
0338 typedef enum {
0339     ZSTD_cpm_noAttachDict = 0,  /* Compression with ZSTD_noDict or ZSTD_extDict.
0340                                  * In this mode we use both the srcSize and the dictSize
0341                                  * when selecting and adjusting parameters.
0342                                  */
0343     ZSTD_cpm_attachDict = 1,    /* Compression with ZSTD_dictMatchState or ZSTD_dedicatedDictSearch.
0344                                  * In this mode we only take the srcSize into account when selecting
0345                                  * and adjusting parameters.
0346                                  */
0347     ZSTD_cpm_createCDict = 2,   /* Creating a CDict.
0348                                  * In this mode we take both the source size and the dictionary size
0349                                  * into account when selecting and adjusting the parameters.
0350                                  */
0351     ZSTD_cpm_unknown = 3,       /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams.
0352                                  * We don't know what these parameters are for. We default to the legacy
0353                                  * behavior of taking both the source size and the dict size into account
0354                                  * when selecting and adjusting parameters.
0355                                  */
0356 } ZSTD_cParamMode_e;
0357 
0358 typedef size_t (*ZSTD_blockCompressor) (
0359         ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
0360         void const* src, size_t srcSize);
0361 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode);
0362 
0363 
0364 MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
0365 {
0366     static const BYTE LL_Code[64] = {  0,  1,  2,  3,  4,  5,  6,  7,
0367                                        8,  9, 10, 11, 12, 13, 14, 15,
0368                                       16, 16, 17, 17, 18, 18, 19, 19,
0369                                       20, 20, 20, 20, 21, 21, 21, 21,
0370                                       22, 22, 22, 22, 22, 22, 22, 22,
0371                                       23, 23, 23, 23, 23, 23, 23, 23,
0372                                       24, 24, 24, 24, 24, 24, 24, 24,
0373                                       24, 24, 24, 24, 24, 24, 24, 24 };
0374     static const U32 LL_deltaCode = 19;
0375     return (litLength > 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
0376 }
0377 
0378 /* ZSTD_MLcode() :
0379  * note : mlBase = matchLength - MINMATCH;
0380  *        because it's the format it's stored in seqStore->sequences */
0381 MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
0382 {
0383     static const BYTE ML_Code[128] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
0384                                       16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
0385                                       32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
0386                                       38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
0387                                       40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
0388                                       41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
0389                                       42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
0390                                       42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
0391     static const U32 ML_deltaCode = 36;
0392     return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
0393 }
0394 
0395 typedef struct repcodes_s {
0396     U32 rep[3];
0397 } repcodes_t;
0398 
0399 MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
0400 {
0401     repcodes_t newReps;
0402     if (offset >= ZSTD_REP_NUM) {  /* full offset */
0403         newReps.rep[2] = rep[1];
0404         newReps.rep[1] = rep[0];
0405         newReps.rep[0] = offset - ZSTD_REP_MOVE;
0406     } else {   /* repcode */
0407         U32 const repCode = offset + ll0;
0408         if (repCode > 0) {  /* note : if repCode==0, no change */
0409             U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
0410             newReps.rep[2] = (repCode >= 2) ? rep[1] : rep[2];
0411             newReps.rep[1] = rep[0];
0412             newReps.rep[0] = currentOffset;
0413         } else {   /* repCode == 0 */
0414             ZSTD_memcpy(&newReps, rep, sizeof(newReps));
0415         }
0416     }
0417     return newReps;
0418 }
0419 
0420 /* ZSTD_cParam_withinBounds:
0421  * @return 1 if value is within cParam bounds,
0422  * 0 otherwise */
0423 MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
0424 {
0425     ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
0426     if (ZSTD_isError(bounds.error)) return 0;
0427     if (value < bounds.lowerBound) return 0;
0428     if (value > bounds.upperBound) return 0;
0429     return 1;
0430 }
0431 
0432 /* ZSTD_noCompressBlock() :
0433  * Writes uncompressed block to dst buffer from given src.
0434  * Returns the size of the block */
0435 MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
0436 {
0437     U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
0438     RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
0439                     dstSize_tooSmall, "dst buf too small for uncompressed block");
0440     MEM_writeLE24(dst, cBlockHeader24);
0441     ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
0442     return ZSTD_blockHeaderSize + srcSize;
0443 }
0444 
0445 MEM_STATIC size_t ZSTD_rleCompressBlock (void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock)
0446 {
0447     BYTE* const op = (BYTE*)dst;
0448     U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3);
0449     RETURN_ERROR_IF(dstCapacity < 4, dstSize_tooSmall, "");
0450     MEM_writeLE24(op, cBlockHeader);
0451     op[3] = src;
0452     return 4;
0453 }
0454 
0455 
0456 /* ZSTD_minGain() :
0457  * minimum compression required
0458  * to generate a compress block or a compressed literals section.
0459  * note : use same formula for both situations */
0460 MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
0461 {
0462     U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
0463     ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);
0464     assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
0465     return (srcSize >> minlog) + 2;
0466 }
0467 
0468 MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)
0469 {
0470     switch (cctxParams->literalCompressionMode) {
0471     case ZSTD_lcm_huffman:
0472         return 0;
0473     case ZSTD_lcm_uncompressed:
0474         return 1;
0475     default:
0476         assert(0 /* impossible: pre-validated */);
0477         ZSTD_FALLTHROUGH;
0478     case ZSTD_lcm_auto:
0479         return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
0480     }
0481 }
0482 
0483 /*! ZSTD_safecopyLiterals() :
0484  *  memcpy() function that won't read beyond more than WILDCOPY_OVERLENGTH bytes past ilimit_w.
0485  *  Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single
0486  *  large copies.
0487  */
0488 static void ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w) {
0489     assert(iend > ilimit_w);
0490     if (ip <= ilimit_w) {
0491         ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap);
0492         op += ilimit_w - ip;
0493         ip = ilimit_w;
0494     }
0495     while (ip < iend) *op++ = *ip++;
0496 }
0497 
0498 /*! ZSTD_storeSeq() :
0499  *  Store a sequence (litlen, litPtr, offCode and mlBase) into seqStore_t.
0500  *  `offCode` : distance to match + ZSTD_REP_MOVE (values <= ZSTD_REP_MOVE are repCodes).
0501  *  `mlBase` : matchLength - MINMATCH
0502  *  Allowed to overread literals up to litLimit.
0503 */
0504 HINT_INLINE UNUSED_ATTR
0505 void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, const BYTE* litLimit, U32 offCode, size_t mlBase)
0506 {
0507     BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH;
0508     BYTE const* const litEnd = literals + litLength;
0509 #if defined(DEBUGLEVEL) && (DEBUGLEVEL >= 6)
0510     static const BYTE* g_start = NULL;
0511     if (g_start==NULL) g_start = (const BYTE*)literals;  /* note : index only works for compression within a single segment */
0512     {   U32 const pos = (U32)((const BYTE*)literals - g_start);
0513         DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offCode%7u",
0514                pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offCode);
0515     }
0516 #endif
0517     assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
0518     /* copy Literals */
0519     assert(seqStorePtr->maxNbLit <= 128 KB);
0520     assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
0521     assert(literals + litLength <= litLimit);
0522     if (litEnd <= litLimit_w) {
0523         /* Common case we can use wildcopy.
0524      * First copy 16 bytes, because literals are likely short.
0525      */
0526         assert(WILDCOPY_OVERLENGTH >= 16);
0527         ZSTD_copy16(seqStorePtr->lit, literals);
0528         if (litLength > 16) {
0529             ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap);
0530         }
0531     } else {
0532         ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);
0533     }
0534     seqStorePtr->lit += litLength;
0535 
0536     /* literal Length */
0537     if (litLength>0xFFFF) {
0538         assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
0539         seqStorePtr->longLengthID = 1;
0540         seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
0541     }
0542     seqStorePtr->sequences[0].litLength = (U16)litLength;
0543 
0544     /* match offset */
0545     seqStorePtr->sequences[0].offset = offCode + 1;
0546 
0547     /* match Length */
0548     if (mlBase>0xFFFF) {
0549         assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
0550         seqStorePtr->longLengthID = 2;
0551         seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
0552     }
0553     seqStorePtr->sequences[0].matchLength = (U16)mlBase;
0554 
0555     seqStorePtr->sequences++;
0556 }
0557 
0558 
0559 /*-*************************************
0560 *  Match length counter
0561 ***************************************/
0562 static unsigned ZSTD_NbCommonBytes (size_t val)
0563 {
0564     if (MEM_isLittleEndian()) {
0565         if (MEM_64bits()) {
0566 #       if (__GNUC__ >= 4)
0567             return (__builtin_ctzll((U64)val) >> 3);
0568 #       else
0569             static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
0570                                                      0, 3, 1, 3, 1, 4, 2, 7,
0571                                                      0, 2, 3, 6, 1, 5, 3, 5,
0572                                                      1, 3, 4, 4, 2, 5, 6, 7,
0573                                                      7, 0, 1, 2, 3, 3, 4, 6,
0574                                                      2, 6, 5, 5, 3, 4, 5, 6,
0575                                                      7, 1, 2, 4, 6, 4, 4, 5,
0576                                                      7, 2, 6, 5, 7, 6, 7, 7 };
0577             return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
0578 #       endif
0579         } else { /* 32 bits */
0580 #       if (__GNUC__ >= 3)
0581             return (__builtin_ctz((U32)val) >> 3);
0582 #       else
0583             static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
0584                                                      3, 2, 2, 1, 3, 2, 0, 1,
0585                                                      3, 3, 1, 2, 2, 2, 2, 0,
0586                                                      3, 1, 2, 0, 1, 0, 1, 1 };
0587             return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
0588 #       endif
0589         }
0590     } else {  /* Big Endian CPU */
0591         if (MEM_64bits()) {
0592 #       if (__GNUC__ >= 4)
0593             return (__builtin_clzll(val) >> 3);
0594 #       else
0595             unsigned r;
0596             const unsigned n32 = sizeof(size_t)*4;   /* calculate this way due to compiler complaining in 32-bits mode */
0597             if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
0598             if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
0599             r += (!val);
0600             return r;
0601 #       endif
0602         } else { /* 32 bits */
0603 #       if (__GNUC__ >= 3)
0604             return (__builtin_clz((U32)val) >> 3);
0605 #       else
0606             unsigned r;
0607             if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
0608             r += (!val);
0609             return r;
0610 #       endif
0611     }   }
0612 }
0613 
0614 
0615 MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
0616 {
0617     const BYTE* const pStart = pIn;
0618     const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
0619 
0620     if (pIn < pInLoopLimit) {
0621         { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
0622           if (diff) return ZSTD_NbCommonBytes(diff); }
0623         pIn+=sizeof(size_t); pMatch+=sizeof(size_t);
0624         while (pIn < pInLoopLimit) {
0625             size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
0626             if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
0627             pIn += ZSTD_NbCommonBytes(diff);
0628             return (size_t)(pIn - pStart);
0629     }   }
0630     if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
0631     if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
0632     if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
0633     return (size_t)(pIn - pStart);
0634 }
0635 
0636 /* ZSTD_count_2segments() :
0637  *  can count match length with `ip` & `match` in 2 different segments.
0638  *  convention : on reaching mEnd, match count continue starting from iStart
0639  */
0640 MEM_STATIC size_t
0641 ZSTD_count_2segments(const BYTE* ip, const BYTE* match,
0642                      const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
0643 {
0644     const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
0645     size_t const matchLength = ZSTD_count(ip, match, vEnd);
0646     if (match + matchLength != mEnd) return matchLength;
0647     DEBUGLOG(7, "ZSTD_count_2segments: found a 2-parts match (current length==%zu)", matchLength);
0648     DEBUGLOG(7, "distance from match beginning to end dictionary = %zi", mEnd - match);
0649     DEBUGLOG(7, "distance from current pos to end buffer = %zi", iEnd - ip);
0650     DEBUGLOG(7, "next byte : ip==%02X, istart==%02X", ip[matchLength], *iStart);
0651     DEBUGLOG(7, "final match length = %zu", matchLength + ZSTD_count(ip+matchLength, iStart, iEnd));
0652     return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
0653 }
0654 
0655 
0656 /*-*************************************
0657  *  Hashes
0658  ***************************************/
0659 static const U32 prime3bytes = 506832829U;
0660 static U32    ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes)  >> (32-h) ; }
0661 MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
0662 
0663 static const U32 prime4bytes = 2654435761U;
0664 static U32    ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
0665 static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
0666 
0667 static const U64 prime5bytes = 889523592379ULL;
0668 static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u  << (64-40)) * prime5bytes) >> (64-h)) ; }
0669 static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
0670 
0671 static const U64 prime6bytes = 227718039650203ULL;
0672 static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u  << (64-48)) * prime6bytes) >> (64-h)) ; }
0673 static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
0674 
0675 static const U64 prime7bytes = 58295818150454627ULL;
0676 static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u  << (64-56)) * prime7bytes) >> (64-h)) ; }
0677 static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
0678 
0679 static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
0680 static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
0681 static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
0682 
0683 MEM_STATIC FORCE_INLINE_ATTR
0684 size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
0685 {
0686     switch(mls)
0687     {
0688     default:
0689     case 4: return ZSTD_hash4Ptr(p, hBits);
0690     case 5: return ZSTD_hash5Ptr(p, hBits);
0691     case 6: return ZSTD_hash6Ptr(p, hBits);
0692     case 7: return ZSTD_hash7Ptr(p, hBits);
0693     case 8: return ZSTD_hash8Ptr(p, hBits);
0694     }
0695 }
0696 
0697 /* ZSTD_ipow() :
0698  * Return base^exponent.
0699  */
0700 static U64 ZSTD_ipow(U64 base, U64 exponent)
0701 {
0702     U64 power = 1;
0703     while (exponent) {
0704       if (exponent & 1) power *= base;
0705       exponent >>= 1;
0706       base *= base;
0707     }
0708     return power;
0709 }
0710 
0711 #define ZSTD_ROLL_HASH_CHAR_OFFSET 10
0712 
0713 /* ZSTD_rollingHash_append() :
0714  * Add the buffer to the hash value.
0715  */
0716 static U64 ZSTD_rollingHash_append(U64 hash, void const* buf, size_t size)
0717 {
0718     BYTE const* istart = (BYTE const*)buf;
0719     size_t pos;
0720     for (pos = 0; pos < size; ++pos) {
0721         hash *= prime8bytes;
0722         hash += istart[pos] + ZSTD_ROLL_HASH_CHAR_OFFSET;
0723     }
0724     return hash;
0725 }
0726 
0727 /* ZSTD_rollingHash_compute() :
0728  * Compute the rolling hash value of the buffer.
0729  */
0730 MEM_STATIC U64 ZSTD_rollingHash_compute(void const* buf, size_t size)
0731 {
0732     return ZSTD_rollingHash_append(0, buf, size);
0733 }
0734 
0735 /* ZSTD_rollingHash_primePower() :
0736  * Compute the primePower to be passed to ZSTD_rollingHash_rotate() for a hash
0737  * over a window of length bytes.
0738  */
0739 MEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length)
0740 {
0741     return ZSTD_ipow(prime8bytes, length - 1);
0742 }
0743 
0744 /* ZSTD_rollingHash_rotate() :
0745  * Rotate the rolling hash by one byte.
0746  */
0747 MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower)
0748 {
0749     hash -= (toRemove + ZSTD_ROLL_HASH_CHAR_OFFSET) * primePower;
0750     hash *= prime8bytes;
0751     hash += toAdd + ZSTD_ROLL_HASH_CHAR_OFFSET;
0752     return hash;
0753 }
0754 
0755 /*-*************************************
0756 *  Round buffer management
0757 ***************************************/
0758 #if (ZSTD_WINDOWLOG_MAX_64 > 31)
0759 # error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
0760 #endif
0761 /* Max current allowed */
0762 #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
0763 /* Maximum chunk size before overflow correction needs to be called again */
0764 #define ZSTD_CHUNKSIZE_MAX                                                     \
0765     ( ((U32)-1)                  /* Maximum ending current index */            \
0766     - ZSTD_CURRENT_MAX)          /* Maximum beginning lowLimit */
0767 
0768 /*
0769  * ZSTD_window_clear():
0770  * Clears the window containing the history by simply setting it to empty.
0771  */
0772 MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)
0773 {
0774     size_t const endT = (size_t)(window->nextSrc - window->base);
0775     U32 const end = (U32)endT;
0776 
0777     window->lowLimit = end;
0778     window->dictLimit = end;
0779 }
0780 
0781 /*
0782  * ZSTD_window_hasExtDict():
0783  * Returns non-zero if the window has a non-empty extDict.
0784  */
0785 MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window)
0786 {
0787     return window.lowLimit < window.dictLimit;
0788 }
0789 
0790 /*
0791  * ZSTD_matchState_dictMode():
0792  * Inspects the provided matchState and figures out what dictMode should be
0793  * passed to the compressor.
0794  */
0795 MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
0796 {
0797     return ZSTD_window_hasExtDict(ms->window) ?
0798         ZSTD_extDict :
0799         ms->dictMatchState != NULL ?
0800             (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) :
0801             ZSTD_noDict;
0802 }
0803 
0804 /*
0805  * ZSTD_window_needOverflowCorrection():
0806  * Returns non-zero if the indices are getting too large and need overflow
0807  * protection.
0808  */
0809 MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
0810                                                   void const* srcEnd)
0811 {
0812     U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
0813     return curr > ZSTD_CURRENT_MAX;
0814 }
0815 
0816 /*
0817  * ZSTD_window_correctOverflow():
0818  * Reduces the indices to protect from index overflow.
0819  * Returns the correction made to the indices, which must be applied to every
0820  * stored index.
0821  *
0822  * The least significant cycleLog bits of the indices must remain the same,
0823  * which may be 0. Every index up to maxDist in the past must be valid.
0824  * NOTE: (maxDist & cycleMask) must be zero.
0825  */
0826 MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
0827                                            U32 maxDist, void const* src)
0828 {
0829     /* preemptive overflow correction:
0830      * 1. correction is large enough:
0831      *    lowLimit > (3<<29) ==> current > 3<<29 + 1<<windowLog
0832      *    1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog
0833      *
0834      *    current - newCurrent
0835      *    > (3<<29 + 1<<windowLog) - (1<<windowLog + 1<<chainLog)
0836      *    > (3<<29) - (1<<chainLog)
0837      *    > (3<<29) - (1<<30)             (NOTE: chainLog <= 30)
0838      *    > 1<<29
0839      *
0840      * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow:
0841      *    After correction, current is less than (1<<chainLog + 1<<windowLog).
0842      *    In 64-bit mode we are safe, because we have 64-bit ptrdiff_t.
0843      *    In 32-bit mode we are safe, because (chainLog <= 29), so
0844      *    ip+ZSTD_CHUNKSIZE_MAX - cctx->base < 1<<32.
0845      * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:
0846      *    windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
0847      */
0848     U32 const cycleMask = (1U << cycleLog) - 1;
0849     U32 const curr = (U32)((BYTE const*)src - window->base);
0850     U32 const currentCycle0 = curr & cycleMask;
0851     /* Exclude zero so that newCurrent - maxDist >= 1. */
0852     U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
0853     U32 const newCurrent = currentCycle1 + maxDist;
0854     U32 const correction = curr - newCurrent;
0855     assert((maxDist & cycleMask) == 0);
0856     assert(curr > newCurrent);
0857     /* Loose bound, should be around 1<<29 (see above) */
0858     assert(correction > 1<<28);
0859 
0860     window->base += correction;
0861     window->dictBase += correction;
0862     if (window->lowLimit <= correction) window->lowLimit = 1;
0863     else window->lowLimit -= correction;
0864     if (window->dictLimit <= correction) window->dictLimit = 1;
0865     else window->dictLimit -= correction;
0866 
0867     /* Ensure we can still reference the full window. */
0868     assert(newCurrent >= maxDist);
0869     assert(newCurrent - maxDist >= 1);
0870     /* Ensure that lowLimit and dictLimit didn't underflow. */
0871     assert(window->lowLimit <= newCurrent);
0872     assert(window->dictLimit <= newCurrent);
0873 
0874     DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
0875              window->lowLimit);
0876     return correction;
0877 }
0878 
0879 /*
0880  * ZSTD_window_enforceMaxDist():
0881  * Updates lowLimit so that:
0882  *    (srcEnd - base) - lowLimit == maxDist + loadedDictEnd
0883  *
0884  * It ensures index is valid as long as index >= lowLimit.
0885  * This must be called before a block compression call.
0886  *
0887  * loadedDictEnd is only defined if a dictionary is in use for current compression.
0888  * As the name implies, loadedDictEnd represents the index at end of dictionary.
0889  * The value lies within context's referential, it can be directly compared to blockEndIdx.
0890  *
0891  * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0.
0892  * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit.
0893  * This is because dictionaries are allowed to be referenced fully
0894  * as long as the last byte of the dictionary is in the window.
0895  * Once input has progressed beyond window size, dictionary cannot be referenced anymore.
0896  *
0897  * In normal dict mode, the dictionary lies between lowLimit and dictLimit.
0898  * In dictMatchState mode, lowLimit and dictLimit are the same,
0899  * and the dictionary is below them.
0900  * forceWindow and dictMatchState are therefore incompatible.
0901  */
0902 MEM_STATIC void
0903 ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
0904                      const void* blockEnd,
0905                            U32   maxDist,
0906                            U32*  loadedDictEndPtr,
0907                      const ZSTD_matchState_t** dictMatchStatePtr)
0908 {
0909     U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
0910     U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
0911     DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
0912                 (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
0913 
0914     /* - When there is no dictionary : loadedDictEnd == 0.
0915          In which case, the test (blockEndIdx > maxDist) is merely to avoid
0916          overflowing next operation `newLowLimit = blockEndIdx - maxDist`.
0917        - When there is a standard dictionary :
0918          Index referential is copied from the dictionary,
0919          which means it starts from 0.
0920          In which case, loadedDictEnd == dictSize,
0921          and it makes sense to compare `blockEndIdx > maxDist + dictSize`
0922          since `blockEndIdx` also starts from zero.
0923        - When there is an attached dictionary :
0924          loadedDictEnd is expressed within the referential of the context,
0925          so it can be directly compared against blockEndIdx.
0926     */
0927     if (blockEndIdx > maxDist + loadedDictEnd) {
0928         U32 const newLowLimit = blockEndIdx - maxDist;
0929         if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;
0930         if (window->dictLimit < window->lowLimit) {
0931             DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u",
0932                         (unsigned)window->dictLimit, (unsigned)window->lowLimit);
0933             window->dictLimit = window->lowLimit;
0934         }
0935         /* On reaching window size, dictionaries are invalidated */
0936         if (loadedDictEndPtr) *loadedDictEndPtr = 0;
0937         if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
0938     }
0939 }
0940 
0941 /* Similar to ZSTD_window_enforceMaxDist(),
0942  * but only invalidates dictionary
0943  * when input progresses beyond window size.
0944  * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL)
0945  *              loadedDictEnd uses same referential as window->base
0946  *              maxDist is the window size */
0947 MEM_STATIC void
0948 ZSTD_checkDictValidity(const ZSTD_window_t* window,
0949                        const void* blockEnd,
0950                              U32   maxDist,
0951                              U32*  loadedDictEndPtr,
0952                        const ZSTD_matchState_t** dictMatchStatePtr)
0953 {
0954     assert(loadedDictEndPtr != NULL);
0955     assert(dictMatchStatePtr != NULL);
0956     {   U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
0957         U32 const loadedDictEnd = *loadedDictEndPtr;
0958         DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
0959                     (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
0960         assert(blockEndIdx >= loadedDictEnd);
0961 
0962         if (blockEndIdx > loadedDictEnd + maxDist) {
0963             /* On reaching window size, dictionaries are invalidated.
0964              * For simplification, if window size is reached anywhere within next block,
0965              * the dictionary is invalidated for the full block.
0966              */
0967             DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)");
0968             *loadedDictEndPtr = 0;
0969             *dictMatchStatePtr = NULL;
0970         } else {
0971             if (*loadedDictEndPtr != 0) {
0972                 DEBUGLOG(6, "dictionary considered valid for current block");
0973     }   }   }
0974 }
0975 
0976 MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
0977     ZSTD_memset(window, 0, sizeof(*window));
0978     window->base = (BYTE const*)"";
0979     window->dictBase = (BYTE const*)"";
0980     window->dictLimit = 1;    /* start from 1, so that 1st position is valid */
0981     window->lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */
0982     window->nextSrc = window->base + 1;   /* see issue #1241 */
0983 }
0984 
0985 /*
0986  * ZSTD_window_update():
0987  * Updates the window by appending [src, src + srcSize) to the window.
0988  * If it is not contiguous, the current prefix becomes the extDict, and we
0989  * forget about the extDict. Handles overlap of the prefix and extDict.
0990  * Returns non-zero if the segment is contiguous.
0991  */
0992 MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
0993                                   void const* src, size_t srcSize)
0994 {
0995     BYTE const* const ip = (BYTE const*)src;
0996     U32 contiguous = 1;
0997     DEBUGLOG(5, "ZSTD_window_update");
0998     if (srcSize == 0)
0999         return contiguous;
1000     assert(window->base != NULL);
1001     assert(window->dictBase != NULL);
1002     /* Check if blocks follow each other */
1003     if (src != window->nextSrc) {
1004         /* not contiguous */
1005         size_t const distanceFromBase = (size_t)(window->nextSrc - window->base);
1006         DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit);
1007         window->lowLimit = window->dictLimit;
1008         assert(distanceFromBase == (size_t)(U32)distanceFromBase);  /* should never overflow */
1009         window->dictLimit = (U32)distanceFromBase;
1010         window->dictBase = window->base;
1011         window->base = ip - distanceFromBase;
1012         /* ms->nextToUpdate = window->dictLimit; */
1013         if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit;   /* too small extDict */
1014         contiguous = 0;
1015     }
1016     window->nextSrc = ip + srcSize;
1017     /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
1018     if ( (ip+srcSize > window->dictBase + window->lowLimit)
1019        & (ip < window->dictBase + window->dictLimit)) {
1020         ptrdiff_t const highInputIdx = (ip + srcSize) - window->dictBase;
1021         U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx;
1022         window->lowLimit = lowLimitMax;
1023         DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit);
1024     }
1025     return contiguous;
1026 }
1027 
1028 /*
1029  * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
1030  */
1031 MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
1032 {
1033     U32    const maxDistance = 1U << windowLog;
1034     U32    const lowestValid = ms->window.lowLimit;
1035     U32    const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
1036     U32    const isDictionary = (ms->loadedDictEnd != 0);
1037     /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary
1038      * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't
1039      * valid for the entire block. So this check is sufficient to find the lowest valid match index.
1040      */
1041     U32    const matchLowest = isDictionary ? lowestValid : withinWindow;
1042     return matchLowest;
1043 }
1044 
1045 /*
1046  * Returns the lowest allowed match index in the prefix.
1047  */
1048 MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
1049 {
1050     U32    const maxDistance = 1U << windowLog;
1051     U32    const lowestValid = ms->window.dictLimit;
1052     U32    const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
1053     U32    const isDictionary = (ms->loadedDictEnd != 0);
1054     /* When computing the lowest prefix index we need to take the dictionary into account to handle
1055      * the edge case where the dictionary and the source are contiguous in memory.
1056      */
1057     U32    const matchLowest = isDictionary ? lowestValid : withinWindow;
1058     return matchLowest;
1059 }
1060 
1061 
1062 
1063 /* debug functions */
1064 #if (DEBUGLEVEL>=2)
1065 
1066 MEM_STATIC double ZSTD_fWeight(U32 rawStat)
1067 {
1068     U32 const fp_accuracy = 8;
1069     U32 const fp_multiplier = (1 << fp_accuracy);
1070     U32 const newStat = rawStat + 1;
1071     U32 const hb = ZSTD_highbit32(newStat);
1072     U32 const BWeight = hb * fp_multiplier;
1073     U32 const FWeight = (newStat << fp_accuracy) >> hb;
1074     U32 const weight = BWeight + FWeight;
1075     assert(hb + fp_accuracy < 31);
1076     return (double)weight / fp_multiplier;
1077 }
1078 
1079 /* display a table content,
1080  * listing each element, its frequency, and its predicted bit cost */
1081 MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
1082 {
1083     unsigned u, sum;
1084     for (u=0, sum=0; u<=max; u++) sum += table[u];
1085     DEBUGLOG(2, "total nb elts: %u", sum);
1086     for (u=0; u<=max; u++) {
1087         DEBUGLOG(2, "%2u: %5u  (%.2f)",
1088                 u, table[u], ZSTD_fWeight(sum) - ZSTD_fWeight(table[u]) );
1089     }
1090 }
1091 
1092 #endif
1093 
1094 
1095 
1096 /* ===============================================================
1097  * Shared internal declarations
1098  * These prototypes may be called from sources not in lib/compress
1099  * =============================================================== */
1100 
1101 /* ZSTD_loadCEntropy() :
1102  * dict : must point at beginning of a valid zstd dictionary.
1103  * return : size of dictionary header (size of magic number + dict ID + entropy tables)
1104  * assumptions : magic number supposed already checked
1105  *               and dictSize >= 8 */
1106 size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
1107                          const void* const dict, size_t dictSize);
1108 
1109 void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
1110 
1111 /* ==============================================================
1112  * Private declarations
1113  * These prototypes shall only be called from within lib/compress
1114  * ============================================================== */
1115 
1116 /* ZSTD_getCParamsFromCCtxParams() :
1117  * cParams are built depending on compressionLevel, src size hints,
1118  * LDM and manually set compression parameters.
1119  * Note: srcSizeHint == 0 means 0!
1120  */
1121 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1122         const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
1123 
1124 /*! ZSTD_initCStream_internal() :
1125  *  Private use only. Init streaming operation.
1126  *  expects params to be valid.
1127  *  must receive dict, or cdict, or none, but not both.
1128  *  @return : 0, or an error code */
1129 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
1130                      const void* dict, size_t dictSize,
1131                      const ZSTD_CDict* cdict,
1132                      const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize);
1133 
1134 void ZSTD_resetSeqStore(seqStore_t* ssPtr);
1135 
1136 /*! ZSTD_getCParamsFromCDict() :
1137  *  as the name implies */
1138 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);
1139 
1140 /* ZSTD_compressBegin_advanced_internal() :
1141  * Private use only. To be called from zstdmt_compress.c. */
1142 size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
1143                                     const void* dict, size_t dictSize,
1144                                     ZSTD_dictContentType_e dictContentType,
1145                                     ZSTD_dictTableLoadMethod_e dtlm,
1146                                     const ZSTD_CDict* cdict,
1147                                     const ZSTD_CCtx_params* params,
1148                                     unsigned long long pledgedSrcSize);
1149 
1150 /* ZSTD_compress_advanced_internal() :
1151  * Private use only. To be called from zstdmt_compress.c. */
1152 size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx,
1153                                        void* dst, size_t dstCapacity,
1154                                  const void* src, size_t srcSize,
1155                                  const void* dict,size_t dictSize,
1156                                  const ZSTD_CCtx_params* params);
1157 
1158 
1159 /* ZSTD_writeLastEmptyBlock() :
1160  * output an empty Block with end-of-frame mark to complete a frame
1161  * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
1162  *           or an error code if `dstCapacity` is too small (<ZSTD_blockHeaderSize)
1163  */
1164 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity);
1165 
1166 
1167 /* ZSTD_referenceExternalSequences() :
1168  * Must be called before starting a compression operation.
1169  * seqs must parse a prefix of the source.
1170  * This cannot be used when long range matching is enabled.
1171  * Zstd will use these sequences, and pass the literals to a secondary block
1172  * compressor.
1173  * @return : An error code on failure.
1174  * NOTE: seqs are not verified! Invalid sequences can cause out-of-bounds memory
1175  * access and data corruption.
1176  */
1177 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq);
1178 
1179 /* ZSTD_cycleLog() :
1180  *  condition for correct operation : hashLog > 1 */
1181 U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
1182 
1183 /* ZSTD_CCtx_trace() :
1184  *  Trace the end of a compression call.
1185  */
1186 void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize);
1187 
1188 #endif /* ZSTD_COMPRESS_H */