zstd-ruby 1.3.2.0 → 1.3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/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
|
***************************************/
|