zstd-ruby 1.3.2.0 → 1.3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/BUCK +31 -10
- data/ext/zstdruby/libzstd/common/bitstream.h +1 -1
- data/ext/zstdruby/libzstd/common/mem.h +15 -13
- data/ext/zstdruby/libzstd/common/pool.c +1 -2
- data/ext/zstdruby/libzstd/common/zstd_common.c +10 -4
- data/ext/zstdruby/libzstd/common/zstd_internal.h +52 -170
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +434 -337
- data/ext/zstdruby/libzstd/compress/{zstd_compress.h → zstd_compress_internal.h} +191 -36
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +1 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +1 -0
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +66 -50
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +504 -676
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +130 -80
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +15 -7
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +41 -31
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -0
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -74
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -74
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -72
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -73
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -77
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -77
- data/ext/zstdruby/libzstd/zstd.h +43 -30
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +4 -4
@@ -8,6 +8,9 @@
|
|
8
8
|
* You may select, at your option, one of the above-listed licenses.
|
9
9
|
*/
|
10
10
|
|
11
|
+
/* This header contains definitions
|
12
|
+
* that shall **only** be used by modules within lib/compress.
|
13
|
+
*/
|
11
14
|
|
12
15
|
#ifndef ZSTD_COMPRESS_H
|
13
16
|
#define ZSTD_COMPRESS_H
|
@@ -43,6 +46,95 @@ typedef struct ZSTD_prefixDict_s {
|
|
43
46
|
ZSTD_dictMode_e dictMode;
|
44
47
|
} ZSTD_prefixDict;
|
45
48
|
|
49
|
+
typedef struct {
|
50
|
+
U32 hufCTable[HUF_CTABLE_SIZE_U32(255)];
|
51
|
+
FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
|
52
|
+
FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
|
53
|
+
FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
|
54
|
+
U32 workspace[HUF_WORKSPACE_SIZE_U32];
|
55
|
+
HUF_repeat hufCTable_repeatMode;
|
56
|
+
FSE_repeat offcode_repeatMode;
|
57
|
+
FSE_repeat matchlength_repeatMode;
|
58
|
+
FSE_repeat litlength_repeatMode;
|
59
|
+
} ZSTD_entropyCTables_t;
|
60
|
+
|
61
|
+
typedef struct {
|
62
|
+
U32 off;
|
63
|
+
U32 len;
|
64
|
+
} ZSTD_match_t;
|
65
|
+
|
66
|
+
typedef struct {
|
67
|
+
int price;
|
68
|
+
U32 off;
|
69
|
+
U32 mlen;
|
70
|
+
U32 litlen;
|
71
|
+
U32 rep[ZSTD_REP_NUM];
|
72
|
+
} ZSTD_optimal_t;
|
73
|
+
|
74
|
+
typedef struct {
|
75
|
+
/* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */
|
76
|
+
U32* litFreq; /* table of literals statistics, of size 256 */
|
77
|
+
U32* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */
|
78
|
+
U32* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */
|
79
|
+
U32* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */
|
80
|
+
ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_NUM+1 */
|
81
|
+
ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_NUM+1 */
|
82
|
+
|
83
|
+
U32 litSum; /* nb of literals */
|
84
|
+
U32 litLengthSum; /* nb of litLength codes */
|
85
|
+
U32 matchLengthSum; /* nb of matchLength codes */
|
86
|
+
U32 offCodeSum; /* nb of offset codes */
|
87
|
+
/* begin updated by ZSTD_setLog2Prices */
|
88
|
+
U32 log2litSum; /* pow2 to compare log2(litfreq) to */
|
89
|
+
U32 log2litLengthSum; /* pow2 to compare log2(llfreq) to */
|
90
|
+
U32 log2matchLengthSum; /* pow2 to compare log2(mlfreq) to */
|
91
|
+
U32 log2offCodeSum; /* pow2 to compare log2(offreq) to */
|
92
|
+
/* end : updated by ZSTD_setLog2Prices */
|
93
|
+
U32 staticPrices; /* prices follow a pre-defined cost structure, statistics are irrelevant */
|
94
|
+
} optState_t;
|
95
|
+
|
96
|
+
typedef struct {
|
97
|
+
U32 offset;
|
98
|
+
U32 checksum;
|
99
|
+
} ldmEntry_t;
|
100
|
+
|
101
|
+
typedef struct {
|
102
|
+
ldmEntry_t* hashTable;
|
103
|
+
BYTE* bucketOffsets; /* Next position in bucket to insert entry */
|
104
|
+
U64 hashPower; /* Used to compute the rolling hash.
|
105
|
+
* Depends on ldmParams.minMatchLength */
|
106
|
+
} ldmState_t;
|
107
|
+
|
108
|
+
typedef struct {
|
109
|
+
U32 enableLdm; /* 1 if enable long distance matching */
|
110
|
+
U32 hashLog; /* Log size of hashTable */
|
111
|
+
U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */
|
112
|
+
U32 minMatchLength; /* Minimum match length */
|
113
|
+
U32 hashEveryLog; /* Log number of entries to skip */
|
114
|
+
} ldmParams_t;
|
115
|
+
|
116
|
+
struct ZSTD_CCtx_params_s {
|
117
|
+
ZSTD_format_e format;
|
118
|
+
ZSTD_compressionParameters cParams;
|
119
|
+
ZSTD_frameParameters fParams;
|
120
|
+
|
121
|
+
int compressionLevel;
|
122
|
+
U32 forceWindow; /* force back-references to respect limit of
|
123
|
+
* 1<<wLog, even for dictionary */
|
124
|
+
|
125
|
+
/* Multithreading: used to pass parameters to mtctx */
|
126
|
+
U32 nbThreads;
|
127
|
+
unsigned jobSize;
|
128
|
+
unsigned overlapSizeLog;
|
129
|
+
|
130
|
+
/* Long distance matching parameters */
|
131
|
+
ldmParams_t ldmParams;
|
132
|
+
|
133
|
+
/* For use with createCCtxParams() and freeCCtxParams() only */
|
134
|
+
ZSTD_customMem customMem;
|
135
|
+
|
136
|
+
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
|
137
|
+
|
46
138
|
struct ZSTD_CCtx_s {
|
47
139
|
const BYTE* nextSrc; /* next block here to continue on current prefix */
|
48
140
|
const BYTE* base; /* All regular indexes relative to this position */
|
@@ -99,38 +191,51 @@ struct ZSTD_CCtx_s {
|
|
99
191
|
};
|
100
192
|
|
101
193
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
194
|
+
MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
|
195
|
+
{
|
196
|
+
static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
|
197
|
+
8, 9, 10, 11, 12, 13, 14, 15,
|
198
|
+
16, 16, 17, 17, 18, 18, 19, 19,
|
199
|
+
20, 20, 20, 20, 21, 21, 21, 21,
|
200
|
+
22, 22, 22, 22, 22, 22, 22, 22,
|
201
|
+
23, 23, 23, 23, 23, 23, 23, 23,
|
202
|
+
24, 24, 24, 24, 24, 24, 24, 24,
|
203
|
+
24, 24, 24, 24, 24, 24, 24, 24 };
|
204
|
+
static const U32 LL_deltaCode = 19;
|
205
|
+
return (litLength > 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
|
206
|
+
}
|
207
|
+
|
208
|
+
/* ZSTD_MLcode() :
|
209
|
+
* note : mlBase = matchLength - MINMATCH;
|
210
|
+
* because it's the format it's stored in seqStore->sequences */
|
211
|
+
MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
|
212
|
+
{
|
213
|
+
static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
214
|
+
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
215
|
+
32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
|
216
|
+
38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
|
217
|
+
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
218
|
+
41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
219
|
+
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
220
|
+
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
|
221
|
+
static const U32 ML_deltaCode = 36;
|
222
|
+
return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
|
223
|
+
}
|
119
224
|
|
120
225
|
/*! ZSTD_storeSeq() :
|
121
|
-
|
122
|
-
|
123
|
-
|
226
|
+
* Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
|
227
|
+
* `offsetCode` : distance to match + 3 (values 1-3 are repCodes).
|
228
|
+
* `mlBase` : matchLength - MINMATCH
|
124
229
|
*/
|
125
|
-
MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t
|
230
|
+
MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t mlBase)
|
126
231
|
{
|
127
232
|
#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG >= 6)
|
128
233
|
static const BYTE* g_start = NULL;
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
234
|
+
if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */
|
235
|
+
{ U32 const pos = (U32)((const BYTE*)literals - g_start);
|
236
|
+
DEBUGLOG(6, "Cpos%7u :%3u literals, match%3u bytes at dist.code%7u",
|
237
|
+
pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offsetCode);
|
238
|
+
}
|
134
239
|
#endif
|
135
240
|
/* copy Literals */
|
136
241
|
assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + 128 KB);
|
@@ -139,6 +244,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|
139
244
|
|
140
245
|
/* literal Length */
|
141
246
|
if (litLength>0xFFFF) {
|
247
|
+
assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
|
142
248
|
seqStorePtr->longLengthID = 1;
|
143
249
|
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
144
250
|
}
|
@@ -148,11 +254,12 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|
148
254
|
seqStorePtr->sequences[0].offset = offsetCode + 1;
|
149
255
|
|
150
256
|
/* match Length */
|
151
|
-
if (
|
257
|
+
if (mlBase>0xFFFF) {
|
258
|
+
assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
|
152
259
|
seqStorePtr->longLengthID = 2;
|
153
260
|
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
154
261
|
}
|
155
|
-
seqStorePtr->sequences[0].matchLength = (U16)
|
262
|
+
seqStorePtr->sequences[0].matchLength = (U16)mlBase;
|
156
263
|
|
157
264
|
seqStorePtr->sequences++;
|
158
265
|
}
|
@@ -161,7 +268,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
|
|
161
268
|
/*-*************************************
|
162
269
|
* Match length counter
|
163
270
|
***************************************/
|
164
|
-
static unsigned ZSTD_NbCommonBytes (
|
271
|
+
static unsigned ZSTD_NbCommonBytes (size_t val)
|
165
272
|
{
|
166
273
|
if (MEM_isLittleEndian()) {
|
167
274
|
if (MEM_64bits()) {
|
@@ -235,13 +342,17 @@ MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* co
|
|
235
342
|
const BYTE* const pStart = pIn;
|
236
343
|
const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
|
237
344
|
|
238
|
-
|
239
|
-
size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
240
|
-
|
241
|
-
pIn +=
|
242
|
-
|
243
|
-
|
244
|
-
|
345
|
+
if (pIn < pInLoopLimit) {
|
346
|
+
{ size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
347
|
+
if (diff) return ZSTD_NbCommonBytes(diff); }
|
348
|
+
pIn+=sizeof(size_t); pMatch+=sizeof(size_t);
|
349
|
+
while (pIn < pInLoopLimit) {
|
350
|
+
size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
|
351
|
+
if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
|
352
|
+
pIn += ZSTD_NbCommonBytes(diff);
|
353
|
+
return (size_t)(pIn - pStart);
|
354
|
+
} }
|
355
|
+
if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
|
245
356
|
if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
|
246
357
|
if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
|
247
358
|
return (size_t)(pIn - pStart);
|
@@ -304,4 +415,48 @@ MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
|
|
304
415
|
}
|
305
416
|
#endif
|
306
417
|
|
418
|
+
|
419
|
+
/* ==============================================================
|
420
|
+
* Private declarations
|
421
|
+
* These prototypes shall only be called from within lib/compress
|
422
|
+
* ============================================================== */
|
423
|
+
|
424
|
+
/*! ZSTD_initCStream_internal() :
|
425
|
+
* Private use only. Init streaming operation.
|
426
|
+
* expects params to be valid.
|
427
|
+
* must receive dict, or cdict, or none, but not both.
|
428
|
+
* @return : 0, or an error code */
|
429
|
+
size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
430
|
+
const void* dict, size_t dictSize,
|
431
|
+
const ZSTD_CDict* cdict,
|
432
|
+
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
|
433
|
+
|
434
|
+
/*! ZSTD_compressStream_generic() :
|
435
|
+
* Private use only. To be called from zstdmt_compress.c in single-thread mode. */
|
436
|
+
size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
437
|
+
ZSTD_outBuffer* output,
|
438
|
+
ZSTD_inBuffer* input,
|
439
|
+
ZSTD_EndDirective const flushMode);
|
440
|
+
|
441
|
+
/*! ZSTD_getCParamsFromCDict() :
|
442
|
+
* as the name implies */
|
443
|
+
ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);
|
444
|
+
|
445
|
+
/* ZSTD_compressBegin_advanced_internal() :
|
446
|
+
* Private use only. To be called from zstdmt_compress.c. */
|
447
|
+
size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
448
|
+
const void* dict, size_t dictSize,
|
449
|
+
ZSTD_dictMode_e dictMode,
|
450
|
+
const ZSTD_CDict* cdict,
|
451
|
+
ZSTD_CCtx_params params,
|
452
|
+
unsigned long long pledgedSrcSize);
|
453
|
+
|
454
|
+
/* ZSTD_compress_advanced_internal() :
|
455
|
+
* Private use only. To be called from zstdmt_compress.c. */
|
456
|
+
size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx,
|
457
|
+
void* dst, size_t dstCapacity,
|
458
|
+
const void* src, size_t srcSize,
|
459
|
+
const void* dict,size_t dictSize,
|
460
|
+
ZSTD_CCtx_params params);
|
461
|
+
|
307
462
|
#endif /* ZSTD_COMPRESS_H */
|
@@ -11,12 +11,13 @@
|
|
11
11
|
#ifndef ZSTD_DOUBLE_FAST_H
|
12
12
|
#define ZSTD_DOUBLE_FAST_H
|
13
13
|
|
14
|
-
#include "zstd_compress.h"
|
15
|
-
|
16
14
|
#if defined (__cplusplus)
|
17
15
|
extern "C" {
|
18
16
|
#endif
|
19
17
|
|
18
|
+
#include "mem.h" /* U32 */
|
19
|
+
#include "zstd.h" /* ZSTD_CCtx, size_t */
|
20
|
+
|
20
21
|
void ZSTD_fillDoubleHashTable(ZSTD_CCtx* cctx, const void* end, const U32 mls);
|
21
22
|
size_t ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
|
22
23
|
size_t ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
|
@@ -11,12 +11,13 @@
|
|
11
11
|
#ifndef ZSTD_FAST_H
|
12
12
|
#define ZSTD_FAST_H
|
13
13
|
|
14
|
-
#include "zstd_compress.h"
|
15
|
-
|
16
14
|
#if defined (__cplusplus)
|
17
15
|
extern "C" {
|
18
16
|
#endif
|
19
17
|
|
18
|
+
#include "mem.h" /* U32 */
|
19
|
+
#include "zstd.h" /* ZSTD_CCtx, size_t */
|
20
|
+
|
20
21
|
void ZSTD_fillHashTable(ZSTD_CCtx* zc, const void* end, const U32 mls);
|
21
22
|
size_t ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
|
22
23
|
const void* src, size_t srcSize);
|
@@ -8,6 +8,7 @@
|
|
8
8
|
* You may select, at your option, one of the above-listed licenses.
|
9
9
|
*/
|
10
10
|
|
11
|
+
#include "zstd_compress_internal.h"
|
11
12
|
#include "zstd_lazy.h"
|
12
13
|
|
13
14
|
|
@@ -15,10 +16,11 @@
|
|
15
16
|
* Binary Tree search
|
16
17
|
***************************************/
|
17
18
|
/** ZSTD_insertBt1() : add one or multiple positions to tree.
|
18
|
-
*
|
19
|
-
*
|
20
|
-
static U32 ZSTD_insertBt1(ZSTD_CCtx* zc,
|
21
|
-
|
19
|
+
* ip : assumed <= iend-8 .
|
20
|
+
* @return : nb of positions added */
|
21
|
+
static U32 ZSTD_insertBt1(ZSTD_CCtx* zc,
|
22
|
+
const BYTE* const ip, const BYTE* const iend,
|
23
|
+
U32 nbCompares, U32 const mls, U32 const extDict)
|
22
24
|
{
|
23
25
|
U32* const hashTable = zc->hashTable;
|
24
26
|
U32 const hashLog = zc->appliedParams.cParams.hashLog;
|
@@ -40,7 +42,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
40
42
|
U32* largerPtr = smallerPtr + 1;
|
41
43
|
U32 dummy32; /* to be nullified at the end */
|
42
44
|
U32 const windowLow = zc->lowLimit;
|
43
|
-
U32 matchEndIdx = current+8;
|
45
|
+
U32 matchEndIdx = current+8+1;
|
44
46
|
size_t bestLength = 8;
|
45
47
|
#ifdef ZSTD_C_PREDICT
|
46
48
|
U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
|
@@ -49,12 +51,15 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
49
51
|
predictedLarge += (predictedLarge>0);
|
50
52
|
#endif /* ZSTD_C_PREDICT */
|
51
53
|
|
54
|
+
DEBUGLOG(8, "ZSTD_insertBt1 (%u)", current);
|
55
|
+
|
52
56
|
assert(ip <= iend-8); /* required for h calculation */
|
53
57
|
hashTable[h] = current; /* Update Hash Table */
|
54
58
|
|
55
59
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
56
60
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
57
61
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
62
|
+
assert(matchIndex < current);
|
58
63
|
|
59
64
|
#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
|
60
65
|
const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
|
@@ -76,10 +81,11 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
76
81
|
continue;
|
77
82
|
}
|
78
83
|
#endif
|
84
|
+
|
79
85
|
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
86
|
+
assert(matchIndex+matchLength >= dictLimit); /* might be wrong if extDict is incorrectly set to 0 */
|
80
87
|
match = base + matchIndex;
|
81
|
-
|
82
|
-
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
|
88
|
+
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
|
83
89
|
} else {
|
84
90
|
match = dictBase + matchIndex;
|
85
91
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
@@ -93,16 +99,17 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
93
99
|
matchEndIdx = matchIndex + (U32)matchLength;
|
94
100
|
}
|
95
101
|
|
96
|
-
if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
|
102
|
+
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
|
97
103
|
break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
|
104
|
+
}
|
98
105
|
|
99
106
|
if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */
|
100
|
-
/* match
|
107
|
+
/* match is smaller than current */
|
101
108
|
*smallerPtr = matchIndex; /* update smaller idx */
|
102
109
|
commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
|
103
110
|
if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */
|
104
|
-
smallerPtr = nextPtr+1; /* new "
|
105
|
-
matchIndex = nextPtr[1]; /* new matchIndex larger than previous
|
111
|
+
smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */
|
112
|
+
matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */
|
106
113
|
} else {
|
107
114
|
/* match is larger than current */
|
108
115
|
*largerPtr = matchIndex;
|
@@ -114,8 +121,38 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
114
121
|
|
115
122
|
*smallerPtr = *largerPtr = 0;
|
116
123
|
if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
|
117
|
-
|
118
|
-
return
|
124
|
+
assert(matchEndIdx > current + 8);
|
125
|
+
return matchEndIdx - (current + 8);
|
126
|
+
}
|
127
|
+
|
128
|
+
FORCE_INLINE_TEMPLATE
|
129
|
+
void ZSTD_updateTree_internal(ZSTD_CCtx* zc,
|
130
|
+
const BYTE* const ip, const BYTE* const iend,
|
131
|
+
const U32 nbCompares, const U32 mls, const U32 extDict)
|
132
|
+
{
|
133
|
+
const BYTE* const base = zc->base;
|
134
|
+
U32 const target = (U32)(ip - base);
|
135
|
+
U32 idx = zc->nextToUpdate;
|
136
|
+
DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (extDict:%u)",
|
137
|
+
idx, target, extDict);
|
138
|
+
|
139
|
+
while(idx < target)
|
140
|
+
idx += ZSTD_insertBt1(zc, base+idx, iend, nbCompares, mls, extDict);
|
141
|
+
zc->nextToUpdate = target;
|
142
|
+
}
|
143
|
+
|
144
|
+
void ZSTD_updateTree(ZSTD_CCtx* zc,
|
145
|
+
const BYTE* const ip, const BYTE* const iend,
|
146
|
+
const U32 nbCompares, const U32 mls)
|
147
|
+
{
|
148
|
+
ZSTD_updateTree_internal(zc, ip, iend, nbCompares, mls, 0 /*extDict*/);
|
149
|
+
}
|
150
|
+
|
151
|
+
void ZSTD_updateTree_extDict(ZSTD_CCtx* zc,
|
152
|
+
const BYTE* const ip, const BYTE* const iend,
|
153
|
+
const U32 nbCompares, const U32 mls)
|
154
|
+
{
|
155
|
+
ZSTD_updateTree_internal(zc, ip, iend, nbCompares, mls, 1 /*extDict*/);
|
119
156
|
}
|
120
157
|
|
121
158
|
|
@@ -144,7 +181,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|
144
181
|
const U32 windowLow = zc->lowLimit;
|
145
182
|
U32* smallerPtr = bt + 2*(current&btMask);
|
146
183
|
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
147
|
-
U32 matchEndIdx = current+8;
|
184
|
+
U32 matchEndIdx = current+8+1;
|
148
185
|
U32 dummy32; /* to be nullified at the end */
|
149
186
|
size_t bestLength = 0;
|
150
187
|
|
@@ -158,8 +195,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|
158
195
|
|
159
196
|
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
160
197
|
match = base + matchIndex;
|
161
|
-
|
162
|
-
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
|
198
|
+
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
|
163
199
|
} else {
|
164
200
|
match = dictBase + matchIndex;
|
165
201
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
@@ -172,8 +208,9 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|
172
208
|
matchEndIdx = matchIndex + (U32)matchLength;
|
173
209
|
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
|
174
210
|
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
|
175
|
-
if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
|
211
|
+
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
|
176
212
|
break; /* drop, to guarantee consistency (miss a little bit of compression) */
|
213
|
+
}
|
177
214
|
}
|
178
215
|
|
179
216
|
if (match[matchLength] < ip[matchLength]) {
|
@@ -194,21 +231,12 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|
194
231
|
|
195
232
|
*smallerPtr = *largerPtr = 0;
|
196
233
|
|
197
|
-
|
234
|
+
assert(matchEndIdx > current+8);
|
235
|
+
zc->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
|
198
236
|
return bestLength;
|
199
237
|
}
|
200
238
|
|
201
239
|
|
202
|
-
void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
|
203
|
-
{
|
204
|
-
const BYTE* const base = zc->base;
|
205
|
-
const U32 target = (U32)(ip - base);
|
206
|
-
U32 idx = zc->nextToUpdate;
|
207
|
-
|
208
|
-
while(idx < target)
|
209
|
-
idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
|
210
|
-
}
|
211
|
-
|
212
240
|
/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
|
213
241
|
static size_t ZSTD_BtFindBestMatch (
|
214
242
|
ZSTD_CCtx* zc,
|
@@ -239,16 +267,6 @@ static size_t ZSTD_BtFindBestMatch_selectMLS (
|
|
239
267
|
}
|
240
268
|
|
241
269
|
|
242
|
-
void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
|
243
|
-
{
|
244
|
-
const BYTE* const base = zc->base;
|
245
|
-
const U32 target = (U32)(ip - base);
|
246
|
-
U32 idx = zc->nextToUpdate;
|
247
|
-
|
248
|
-
while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
|
249
|
-
}
|
250
|
-
|
251
|
-
|
252
270
|
/** Tree updater, providing best match */
|
253
271
|
static size_t ZSTD_BtFindBestMatch_extDict (
|
254
272
|
ZSTD_CCtx* zc,
|
@@ -335,14 +353,14 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
335
353
|
U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
|
336
354
|
|
337
355
|
for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
|
338
|
-
const BYTE* match;
|
339
356
|
size_t currentMl=0;
|
340
357
|
if ((!extDict) || matchIndex >= dictLimit) {
|
341
|
-
match = base + matchIndex;
|
358
|
+
const BYTE* const match = base + matchIndex;
|
342
359
|
if (match[ml] == ip[ml]) /* potentially better */
|
343
360
|
currentMl = ZSTD_count(ip, match, iLimit);
|
344
361
|
} else {
|
345
|
-
match = dictBase + matchIndex;
|
362
|
+
const BYTE* const match = dictBase + matchIndex;
|
363
|
+
assert(match+4 <= dictEnd);
|
346
364
|
if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
|
347
365
|
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
|
348
366
|
}
|
@@ -380,10 +398,10 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
|
|
380
398
|
|
381
399
|
|
382
400
|
FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
|
383
|
-
ZSTD_CCtx* zc,
|
401
|
+
ZSTD_CCtx* const zc,
|
384
402
|
const BYTE* ip, const BYTE* const iLimit,
|
385
|
-
size_t* offsetPtr,
|
386
|
-
const
|
403
|
+
size_t* const offsetPtr,
|
404
|
+
U32 const maxNbAttempts, U32 const matchLengthSearch)
|
387
405
|
{
|
388
406
|
switch(matchLengthSearch)
|
389
407
|
{
|
@@ -502,9 +520,8 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|
502
520
|
*/
|
503
521
|
/* catch up */
|
504
522
|
if (offset) {
|
505
|
-
while ( (start > anchor)
|
506
|
-
&& (start
|
507
|
-
&& (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1]) ) /* only search for offset within prefix */
|
523
|
+
while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > base))
|
524
|
+
&& (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
|
508
525
|
{ start--; matchLength++; }
|
509
526
|
offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
|
510
527
|
}
|
@@ -516,9 +533,8 @@ _storeSequence:
|
|
516
533
|
}
|
517
534
|
|
518
535
|
/* check immediate repcode */
|
519
|
-
while ( (ip <= ilimit)
|
520
|
-
&& ((offset_2
|
521
|
-
& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
|
536
|
+
while ( ((ip <= ilimit) & (offset_2>0))
|
537
|
+
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
|
522
538
|
/* store sequence */
|
523
539
|
matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
|
524
540
|
offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
|
@@ -11,12 +11,13 @@
|
|
11
11
|
#ifndef ZSTD_LAZY_H
|
12
12
|
#define ZSTD_LAZY_H
|
13
13
|
|
14
|
-
#include "zstd_compress.h"
|
15
|
-
|
16
14
|
#if defined (__cplusplus)
|
17
15
|
extern "C" {
|
18
16
|
#endif
|
19
17
|
|
18
|
+
#include "mem.h" /* U32 */
|
19
|
+
#include "zstd.h" /* ZSTD_CCtx, size_t */
|
20
|
+
|
20
21
|
U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls);
|
21
22
|
void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls);
|
22
23
|
void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls);
|
@@ -10,12 +10,13 @@
|
|
10
10
|
#ifndef ZSTD_LDM_H
|
11
11
|
#define ZSTD_LDM_H
|
12
12
|
|
13
|
-
#include "zstd_compress.h"
|
14
|
-
|
15
13
|
#if defined (__cplusplus)
|
16
14
|
extern "C" {
|
17
15
|
#endif
|
18
16
|
|
17
|
+
#include "zstd_compress_internal.h" /* ldmParams_t, U32 */
|
18
|
+
#include "zstd.h" /* ZSTD_CCtx, size_t */
|
19
|
+
|
19
20
|
/*-*************************************
|
20
21
|
* Long distance matching
|
21
22
|
***************************************/
|