0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ZSTD_COMPRESS_H
0016 #define ZSTD_COMPRESS_H
0017
0018
0019
0020
0021 #include "../common/zstd_internal.h"
0022 #include "zstd_cwksp.h"
0023
0024
0025
0026
0027
0028 #define kSearchStrength 8
0029 #define HASH_READ_SIZE 8
0030 #define ZSTD_DUBT_UNSORTED_MARK 1
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
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;
0080 U32 len;
0081 } ZSTD_match_t;
0082
0083 typedef struct {
0084 U32 offset;
0085 U32 litLength;
0086 U32 matchLength;
0087 } rawSeq;
0088
0089 typedef struct {
0090 rawSeq* seq;
0091 size_t pos;
0092 size_t posInSequence;
0093
0094 size_t size;
0095 size_t capacity;
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
0112 unsigned* litFreq;
0113 unsigned* litLengthFreq;
0114 unsigned* matchLengthFreq;
0115 unsigned* offCodeFreq;
0116 ZSTD_match_t* matchTable;
0117 ZSTD_optimal_t* priceTable;
0118
0119 U32 litSum;
0120 U32 litLengthSum;
0121 U32 matchLengthSum;
0122 U32 offCodeSum;
0123 U32 litSumBasePrice;
0124 U32 litLengthSumBasePrice;
0125 U32 matchLengthSumBasePrice;
0126 U32 offCodeSumBasePrice;
0127 ZSTD_OptPrice_e priceType;
0128 const ZSTD_entropyCTables_t* symbolCosts;
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;
0139 BYTE const* base;
0140 BYTE const* dictBase;
0141 U32 dictLimit;
0142 U32 lowLimit;
0143 } ZSTD_window_t;
0144
0145 typedef struct ZSTD_matchState_t ZSTD_matchState_t;
0146 struct ZSTD_matchState_t {
0147 ZSTD_window_t window;
0148 U32 loadedDictEnd;
0149
0150
0151
0152
0153
0154
0155 U32 nextToUpdate;
0156 U32 hashLog3;
0157 U32* hashTable;
0158 U32* hashTable3;
0159 U32* chainTable;
0160 int dedicatedDictSearch;
0161
0162
0163 optState_t opt;
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;
0191 ldmEntry_t* hashTable;
0192 U32 loadedDictEnd;
0193 BYTE* bucketOffsets;
0194 size_t splitIndices[LDM_BATCH_SIZE];
0195 ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE];
0196 } ldmState_t;
0197
0198 typedef struct {
0199 U32 enableLdm;
0200 U32 hashLog;
0201 U32 bucketSizeLog;
0202 U32 minMatchLength;
0203 U32 hashRateLog;
0204 U32 windowLog;
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;
0221
0222 size_t targetCBlockSize;
0223
0224
0225 int srcSizeHint;
0226
0227
0228
0229 ZSTD_dictAttachPref_e attachDictPref;
0230 ZSTD_literalCompressionMode_e literalCompressionMode;
0231
0232
0233 int nbWorkers;
0234 size_t jobSize;
0235 int overlapLog;
0236 int rsyncable;
0237
0238
0239 ldmParams_t ldmParams;
0240
0241
0242 int enableDedicatedDictSearch;
0243
0244
0245 ZSTD_bufferMode_e inBufferMode;
0246 ZSTD_bufferMode_e outBufferMode;
0247
0248
0249 ZSTD_sequenceFormat_e blockDelimiters;
0250 int validateSequences;
0251
0252
0253 ZSTD_customMem customMem;
0254 };
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
0261
0262
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;
0272 int bmi2;
0273 ZSTD_CCtx_params requestedParams;
0274 ZSTD_CCtx_params appliedParams;
0275 U32 dictID;
0276 size_t dictContentSize;
0277
0278 ZSTD_cwksp workspace;
0279 size_t blockSize;
0280 unsigned long long pledgedSrcSizePlusOne;
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;
0292 ldmState_t ldmState;
0293 rawSeq* ldmSequences;
0294 size_t maxNbLdmSequences;
0295 rawSeqStore_t externSeqStore;
0296 ZSTD_blockState_t blockState;
0297 U32* entropyWorkspace;
0298
0299
0300 ZSTD_buffered_policy_e bufferedPolicy;
0301
0302
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
0316 ZSTD_inBuffer expectedInBuffer;
0317 size_t expectedOutBufferSize;
0318
0319
0320 ZSTD_localDict localDict;
0321 const ZSTD_CDict* cdict;
0322 ZSTD_prefixDict prefixDict;
0323
0324
0325
0326
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,
0340
0341
0342
0343 ZSTD_cpm_attachDict = 1,
0344
0345
0346
0347 ZSTD_cpm_createCDict = 2,
0348
0349
0350
0351 ZSTD_cpm_unknown = 3,
0352
0353
0354
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
0379
0380
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) {
0403 newReps.rep[2] = rep[1];
0404 newReps.rep[1] = rep[0];
0405 newReps.rep[0] = offset - ZSTD_REP_MOVE;
0406 } else {
0407 U32 const repCode = offset + ll0;
0408 if (repCode > 0) {
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 {
0414 ZSTD_memcpy(&newReps, rep, sizeof(newReps));
0415 }
0416 }
0417 return newReps;
0418 }
0419
0420
0421
0422
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
0433
0434
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
0457
0458
0459
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 );
0477 ZSTD_FALLTHROUGH;
0478 case ZSTD_lcm_auto:
0479 return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
0480 }
0481 }
0482
0483
0484
0485
0486
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
0499
0500
0501
0502
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;
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
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
0524
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
0537 if (litLength>0xFFFF) {
0538 assert(seqStorePtr->longLengthID == 0);
0539 seqStorePtr->longLengthID = 1;
0540 seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
0541 }
0542 seqStorePtr->sequences[0].litLength = (U16)litLength;
0543
0544
0545 seqStorePtr->sequences[0].offset = offCode + 1;
0546
0547
0548 if (mlBase>0xFFFF) {
0549 assert(seqStorePtr->longLengthID == 0);
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
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 {
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 {
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;
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 {
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
0637
0638
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
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); }
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
0698
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
0714
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
0728
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
0736
0737
0738
0739 MEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length)
0740 {
0741 return ZSTD_ipow(prime8bytes, length - 1);
0742 }
0743
0744
0745
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
0757
0758 #if (ZSTD_WINDOWLOG_MAX_64 > 31)
0759 # error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
0760 #endif
0761
0762 #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
0763
0764 #define ZSTD_CHUNKSIZE_MAX \
0765 ( ((U32)-1) \
0766 - ZSTD_CURRENT_MAX)
0767
0768
0769
0770
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
0783
0784
0785 MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window)
0786 {
0787 return window.lowLimit < window.dictLimit;
0788 }
0789
0790
0791
0792
0793
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
0806
0807
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
0818
0819
0820
0821
0822
0823
0824
0825
0826 MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
0827 U32 maxDist, void const* src)
0828 {
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
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
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
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
0868 assert(newCurrent >= maxDist);
0869 assert(newCurrent - maxDist >= 1);
0870
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
0881
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
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
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
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
0936 if (loadedDictEndPtr) *loadedDictEndPtr = 0;
0937 if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
0938 }
0939 }
0940
0941
0942
0943
0944
0945
0946
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
0964
0965
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;
0981 window->lowLimit = 1;
0982 window->nextSrc = window->base + 1;
0983 }
0984
0985
0986
0987
0988
0989
0990
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
1003 if (src != window->nextSrc) {
1004
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);
1009 window->dictLimit = (U32)distanceFromBase;
1010 window->dictBase = window->base;
1011 window->base = ip - distanceFromBase;
1012
1013 if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit;
1014 contiguous = 0;
1015 }
1016 window->nextSrc = ip + srcSize;
1017
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
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
1038
1039
1040
1041 U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
1042 return matchLowest;
1043 }
1044
1045
1046
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
1055
1056
1057 U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
1058 return matchLowest;
1059 }
1060
1061
1062
1063
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
1080
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
1098
1099
1100
1101
1102
1103
1104
1105
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
1113
1114
1115
1116
1117
1118
1119
1120
1121 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
1122 const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
1123
1124
1125
1126
1127
1128
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
1137
1138 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);
1139
1140
1141
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
1151
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
1160
1161
1162
1163
1164 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity);
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq);
1178
1179
1180
1181 U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
1182
1183
1184
1185
1186 void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize);
1187
1188 #endif