extzstd 0.3.1 → 0.3.2
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 +28 -14
- data/contrib/zstd/CHANGELOG +114 -56
- data/contrib/zstd/CONTRIBUTING.md +14 -0
- data/contrib/zstd/Makefile +37 -31
- data/contrib/zstd/README.md +6 -0
- data/contrib/zstd/appveyor.yml +4 -1
- data/contrib/zstd/lib/Makefile +231 -134
- data/contrib/zstd/lib/README.md +28 -0
- data/contrib/zstd/lib/common/bitstream.h +24 -15
- data/contrib/zstd/lib/common/compiler.h +116 -3
- data/contrib/zstd/lib/common/cpu.h +0 -2
- data/contrib/zstd/lib/common/debug.h +11 -18
- data/contrib/zstd/lib/common/entropy_common.c +188 -42
- data/contrib/zstd/lib/common/error_private.c +1 -0
- data/contrib/zstd/lib/common/error_private.h +1 -1
- data/contrib/zstd/lib/common/fse.h +38 -11
- data/contrib/zstd/lib/common/fse_decompress.c +123 -16
- data/contrib/zstd/lib/common/huf.h +26 -5
- data/contrib/zstd/lib/common/mem.h +66 -93
- data/contrib/zstd/lib/common/pool.c +22 -16
- data/contrib/zstd/lib/common/pool.h +1 -1
- data/contrib/zstd/lib/common/threading.c +6 -5
- data/contrib/zstd/lib/common/xxhash.c +18 -56
- data/contrib/zstd/lib/common/xxhash.h +1 -1
- data/contrib/zstd/lib/common/zstd_common.c +9 -9
- data/contrib/zstd/lib/common/zstd_deps.h +111 -0
- data/contrib/zstd/lib/common/zstd_errors.h +1 -0
- data/contrib/zstd/lib/common/zstd_internal.h +89 -58
- data/contrib/zstd/lib/compress/fse_compress.c +30 -23
- data/contrib/zstd/lib/compress/hist.c +26 -28
- data/contrib/zstd/lib/compress/hist.h +1 -1
- data/contrib/zstd/lib/compress/huf_compress.c +210 -95
- data/contrib/zstd/lib/compress/zstd_compress.c +1339 -409
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +119 -41
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +4 -4
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +17 -3
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +23 -19
- data/contrib/zstd/lib/compress/zstd_cwksp.h +60 -24
- data/contrib/zstd/lib/compress/zstd_double_fast.c +22 -22
- data/contrib/zstd/lib/compress/zstd_fast.c +19 -19
- data/contrib/zstd/lib/compress/zstd_lazy.c +351 -77
- data/contrib/zstd/lib/compress/zstd_lazy.h +20 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +59 -18
- data/contrib/zstd/lib/compress/zstd_ldm.h +6 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +190 -45
- data/contrib/zstd/lib/compress/zstdmt_compress.c +74 -406
- data/contrib/zstd/lib/compress/zstdmt_compress.h +26 -108
- data/contrib/zstd/lib/decompress/huf_decompress.c +302 -200
- data/contrib/zstd/lib/decompress/zstd_ddict.c +8 -8
- data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/contrib/zstd/lib/decompress/zstd_decompress.c +125 -80
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +145 -37
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +5 -2
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +11 -10
- data/contrib/zstd/lib/dictBuilder/cover.c +29 -20
- data/contrib/zstd/lib/dictBuilder/cover.h +1 -1
- data/contrib/zstd/lib/dictBuilder/fastcover.c +20 -19
- data/contrib/zstd/lib/dictBuilder/zdict.c +15 -16
- data/contrib/zstd/lib/dictBuilder/zdict.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v01.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v02.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v03.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v04.c +6 -2
- data/contrib/zstd/lib/legacy/zstd_v05.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v06.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v07.c +5 -1
- data/contrib/zstd/lib/libzstd.pc.in +3 -3
- data/contrib/zstd/lib/zstd.h +348 -47
- data/ext/extzstd.c +6 -0
- data/ext/extzstd.h +6 -0
- data/gemstub.rb +3 -21
- data/lib/extzstd.rb +0 -2
- data/lib/extzstd/version.rb +6 -1
- data/test/test_basic.rb +0 -5
- metadata +5 -4
@@ -44,6 +44,16 @@ typedef enum {
|
|
44
44
|
ZSTD_cwksp_alloc_aligned
|
45
45
|
} ZSTD_cwksp_alloc_phase_e;
|
46
46
|
|
47
|
+
/**
|
48
|
+
* Used to describe whether the workspace is statically allocated (and will not
|
49
|
+
* necessarily ever be freed), or if it's dynamically allocated and we can
|
50
|
+
* expect a well-formed caller to free this.
|
51
|
+
*/
|
52
|
+
typedef enum {
|
53
|
+
ZSTD_cwksp_dynamic_alloc,
|
54
|
+
ZSTD_cwksp_static_alloc
|
55
|
+
} ZSTD_cwksp_static_alloc_e;
|
56
|
+
|
47
57
|
/**
|
48
58
|
* Zstd fits all its internal datastructures into a single continuous buffer,
|
49
59
|
* so that it only needs to perform a single OS allocation (or so that a buffer
|
@@ -92,7 +102,7 @@ typedef enum {
|
|
92
102
|
*
|
93
103
|
* - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict,
|
94
104
|
* so that literally everything fits in a single buffer. Note: if present,
|
95
|
-
* this must be the first object in the workspace, since
|
105
|
+
* this must be the first object in the workspace, since ZSTD_customFree{CCtx,
|
96
106
|
* CDict}() rely on a pointer comparison to see whether one or two frees are
|
97
107
|
* required.
|
98
108
|
*
|
@@ -137,9 +147,10 @@ typedef struct {
|
|
137
147
|
void* tableValidEnd;
|
138
148
|
void* allocStart;
|
139
149
|
|
140
|
-
|
150
|
+
BYTE allocFailed;
|
141
151
|
int workspaceOversizedDuration;
|
142
152
|
ZSTD_cwksp_alloc_phase_e phase;
|
153
|
+
ZSTD_cwksp_static_alloc_e isStatic;
|
143
154
|
} ZSTD_cwksp;
|
144
155
|
|
145
156
|
/*-*************************************
|
@@ -178,7 +189,9 @@ MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) {
|
|
178
189
|
* else is though.
|
179
190
|
*/
|
180
191
|
MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) {
|
181
|
-
|
192
|
+
if (size == 0)
|
193
|
+
return 0;
|
194
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
182
195
|
return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
|
183
196
|
#else
|
184
197
|
return size;
|
@@ -228,7 +241,10 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal(
|
|
228
241
|
ZSTD_cwksp_internal_advance_phase(ws, phase);
|
229
242
|
alloc = (BYTE *)ws->allocStart - bytes;
|
230
243
|
|
231
|
-
|
244
|
+
if (bytes == 0)
|
245
|
+
return NULL;
|
246
|
+
|
247
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
232
248
|
/* over-reserve space */
|
233
249
|
alloc = (BYTE *)alloc - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
|
234
250
|
#endif
|
@@ -247,11 +263,13 @@ MEM_STATIC void* ZSTD_cwksp_reserve_internal(
|
|
247
263
|
}
|
248
264
|
ws->allocStart = alloc;
|
249
265
|
|
250
|
-
#if
|
266
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
251
267
|
/* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
|
252
268
|
* either size. */
|
253
269
|
alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
|
254
|
-
|
270
|
+
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
|
271
|
+
__asan_unpoison_memory_region(alloc, bytes);
|
272
|
+
}
|
255
273
|
#endif
|
256
274
|
|
257
275
|
return alloc;
|
@@ -296,8 +314,10 @@ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {
|
|
296
314
|
}
|
297
315
|
ws->tableEnd = end;
|
298
316
|
|
299
|
-
#if
|
300
|
-
|
317
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
318
|
+
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
|
319
|
+
__asan_unpoison_memory_region(alloc, bytes);
|
320
|
+
}
|
301
321
|
#endif
|
302
322
|
|
303
323
|
return alloc;
|
@@ -311,7 +331,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
|
|
311
331
|
void* alloc = ws->objectEnd;
|
312
332
|
void* end = (BYTE*)alloc + roundedBytes;
|
313
333
|
|
314
|
-
#if
|
334
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
315
335
|
/* over-reserve space */
|
316
336
|
end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
|
317
337
|
#endif
|
@@ -332,11 +352,13 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
|
|
332
352
|
ws->tableEnd = end;
|
333
353
|
ws->tableValidEnd = end;
|
334
354
|
|
335
|
-
#if
|
355
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
336
356
|
/* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
|
337
357
|
* either size. */
|
338
358
|
alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
|
339
|
-
|
359
|
+
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
|
360
|
+
__asan_unpoison_memory_region(alloc, bytes);
|
361
|
+
}
|
340
362
|
#endif
|
341
363
|
|
342
364
|
return alloc;
|
@@ -345,7 +367,7 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {
|
|
345
367
|
MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) {
|
346
368
|
DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty");
|
347
369
|
|
348
|
-
#if
|
370
|
+
#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
349
371
|
/* To validate that the table re-use logic is sound, and that we don't
|
350
372
|
* access table space that we haven't cleaned, we re-"poison" the table
|
351
373
|
* space every time we mark it dirty. */
|
@@ -380,7 +402,7 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) {
|
|
380
402
|
assert(ws->tableValidEnd >= ws->objectEnd);
|
381
403
|
assert(ws->tableValidEnd <= ws->allocStart);
|
382
404
|
if (ws->tableValidEnd < ws->tableEnd) {
|
383
|
-
|
405
|
+
ZSTD_memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd);
|
384
406
|
}
|
385
407
|
ZSTD_cwksp_mark_tables_clean(ws);
|
386
408
|
}
|
@@ -392,8 +414,12 @@ MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) {
|
|
392
414
|
MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) {
|
393
415
|
DEBUGLOG(4, "cwksp: clearing tables!");
|
394
416
|
|
395
|
-
#if
|
396
|
-
|
417
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
418
|
+
/* We don't do this when the workspace is statically allocated, because
|
419
|
+
* when that is the case, we have no capability to hook into the end of the
|
420
|
+
* workspace's lifecycle to unpoison the memory.
|
421
|
+
*/
|
422
|
+
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
|
397
423
|
size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;
|
398
424
|
__asan_poison_memory_region(ws->objectEnd, size);
|
399
425
|
}
|
@@ -410,7 +436,7 @@ MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) {
|
|
410
436
|
MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
|
411
437
|
DEBUGLOG(4, "cwksp: clearing!");
|
412
438
|
|
413
|
-
#if
|
439
|
+
#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
414
440
|
/* To validate that the context re-use logic is sound, and that we don't
|
415
441
|
* access stuff that this compression hasn't initialized, we re-"poison"
|
416
442
|
* the workspace (or at least the non-static, non-table parts of it)
|
@@ -421,8 +447,12 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
|
|
421
447
|
}
|
422
448
|
#endif
|
423
449
|
|
424
|
-
#if
|
425
|
-
|
450
|
+
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
|
451
|
+
/* We don't do this when the workspace is statically allocated, because
|
452
|
+
* when that is the case, we have no capability to hook into the end of the
|
453
|
+
* workspace's lifecycle to unpoison the memory.
|
454
|
+
*/
|
455
|
+
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
|
426
456
|
size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd;
|
427
457
|
__asan_poison_memory_region(ws->objectEnd, size);
|
428
458
|
}
|
@@ -442,7 +472,7 @@ MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {
|
|
442
472
|
* Any existing values in the workspace are ignored (the previously managed
|
443
473
|
* buffer, if present, must be separately freed).
|
444
474
|
*/
|
445
|
-
MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {
|
475
|
+
MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) {
|
446
476
|
DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size);
|
447
477
|
assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */
|
448
478
|
ws->workspace = start;
|
@@ -450,24 +480,25 @@ MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {
|
|
450
480
|
ws->objectEnd = ws->workspace;
|
451
481
|
ws->tableValidEnd = ws->objectEnd;
|
452
482
|
ws->phase = ZSTD_cwksp_alloc_objects;
|
483
|
+
ws->isStatic = isStatic;
|
453
484
|
ZSTD_cwksp_clear(ws);
|
454
485
|
ws->workspaceOversizedDuration = 0;
|
455
486
|
ZSTD_cwksp_assert_internal_consistency(ws);
|
456
487
|
}
|
457
488
|
|
458
489
|
MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) {
|
459
|
-
void* workspace =
|
490
|
+
void* workspace = ZSTD_customMalloc(size, customMem);
|
460
491
|
DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size);
|
461
492
|
RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!");
|
462
|
-
ZSTD_cwksp_init(ws, workspace, size);
|
493
|
+
ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc);
|
463
494
|
return 0;
|
464
495
|
}
|
465
496
|
|
466
497
|
MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
|
467
498
|
void *ptr = ws->workspace;
|
468
499
|
DEBUGLOG(4, "cwksp: freeing workspace");
|
469
|
-
|
470
|
-
|
500
|
+
ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp));
|
501
|
+
ZSTD_customFree(ptr, customMem);
|
471
502
|
}
|
472
503
|
|
473
504
|
/**
|
@@ -476,13 +507,18 @@ MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
|
|
476
507
|
*/
|
477
508
|
MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) {
|
478
509
|
*dst = *src;
|
479
|
-
|
510
|
+
ZSTD_memset(src, 0, sizeof(ZSTD_cwksp));
|
480
511
|
}
|
481
512
|
|
482
513
|
MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) {
|
483
514
|
return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace);
|
484
515
|
}
|
485
516
|
|
517
|
+
MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) {
|
518
|
+
return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace)
|
519
|
+
+ (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart);
|
520
|
+
}
|
521
|
+
|
486
522
|
MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) {
|
487
523
|
return ws->allocFailed;
|
488
524
|
}
|
@@ -31,15 +31,15 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
|
|
31
31
|
* is empty.
|
32
32
|
*/
|
33
33
|
for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {
|
34
|
-
U32 const
|
34
|
+
U32 const curr = (U32)(ip - base);
|
35
35
|
U32 i;
|
36
36
|
for (i = 0; i < fastHashFillStep; ++i) {
|
37
37
|
size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls);
|
38
38
|
size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8);
|
39
39
|
if (i == 0)
|
40
|
-
hashSmall[smHash] =
|
40
|
+
hashSmall[smHash] = curr + i;
|
41
41
|
if (i == 0 || hashLarge[lgHash] == 0)
|
42
|
-
hashLarge[lgHash] =
|
42
|
+
hashLarge[lgHash] = curr + i;
|
43
43
|
/* Only load extra positions for ZSTD_dtlm_full */
|
44
44
|
if (dtlm == ZSTD_dtlm_fast)
|
45
45
|
break;
|
@@ -108,9 +108,9 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
108
108
|
/* init */
|
109
109
|
ip += (dictAndPrefixLength == 0);
|
110
110
|
if (dictMode == ZSTD_noDict) {
|
111
|
-
U32 const
|
112
|
-
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms,
|
113
|
-
U32 const maxRep =
|
111
|
+
U32 const curr = (U32)(ip - base);
|
112
|
+
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
|
113
|
+
U32 const maxRep = curr - windowLow;
|
114
114
|
if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
|
115
115
|
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
|
116
116
|
}
|
@@ -129,17 +129,17 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
129
129
|
size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
|
130
130
|
size_t const dictHL = ZSTD_hashPtr(ip, dictHBitsL, 8);
|
131
131
|
size_t const dictHS = ZSTD_hashPtr(ip, dictHBitsS, mls);
|
132
|
-
U32 const
|
132
|
+
U32 const curr = (U32)(ip-base);
|
133
133
|
U32 const matchIndexL = hashLong[h2];
|
134
134
|
U32 matchIndexS = hashSmall[h];
|
135
135
|
const BYTE* matchLong = base + matchIndexL;
|
136
136
|
const BYTE* match = base + matchIndexS;
|
137
|
-
const U32 repIndex =
|
137
|
+
const U32 repIndex = curr + 1 - offset_1;
|
138
138
|
const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
|
139
139
|
&& repIndex < prefixLowestIndex) ?
|
140
140
|
dictBase + (repIndex - dictIndexDelta) :
|
141
141
|
base + repIndex;
|
142
|
-
hashLong[h2] = hashSmall[h] =
|
142
|
+
hashLong[h2] = hashSmall[h] = curr; /* update hash tables */
|
143
143
|
|
144
144
|
/* check dictMatchState repcode */
|
145
145
|
if (dictMode == ZSTD_dictMatchState
|
@@ -177,7 +177,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
177
177
|
|
178
178
|
if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) {
|
179
179
|
mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8;
|
180
|
-
offset = (U32)(
|
180
|
+
offset = (U32)(curr - dictMatchIndexL - dictIndexDelta);
|
181
181
|
while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */
|
182
182
|
goto _match_found;
|
183
183
|
} }
|
@@ -209,7 +209,7 @@ _search_next_long:
|
|
209
209
|
size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
|
210
210
|
U32 const matchIndexL3 = hashLong[hl3];
|
211
211
|
const BYTE* matchL3 = base + matchIndexL3;
|
212
|
-
hashLong[hl3] =
|
212
|
+
hashLong[hl3] = curr + 1;
|
213
213
|
|
214
214
|
/* check prefix long +1 match */
|
215
215
|
if (matchIndexL3 > prefixLowestIndex) {
|
@@ -228,7 +228,7 @@ _search_next_long:
|
|
228
228
|
if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) {
|
229
229
|
mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8;
|
230
230
|
ip++;
|
231
|
-
offset = (U32)(
|
231
|
+
offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta);
|
232
232
|
while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */
|
233
233
|
goto _match_found;
|
234
234
|
} } }
|
@@ -236,7 +236,7 @@ _search_next_long:
|
|
236
236
|
/* if no long +1 match, explore the short match we found */
|
237
237
|
if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {
|
238
238
|
mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;
|
239
|
-
offset = (U32)(
|
239
|
+
offset = (U32)(curr - matchIndexS);
|
240
240
|
while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
241
241
|
} else {
|
242
242
|
mLength = ZSTD_count(ip+4, match+4, iend) + 4;
|
@@ -260,7 +260,7 @@ _match_stored:
|
|
260
260
|
if (ip <= ilimit) {
|
261
261
|
/* Complementary insertion */
|
262
262
|
/* done after iLimit test, as candidates could be > iend-8 */
|
263
|
-
{ U32 const indexToInsert =
|
263
|
+
{ U32 const indexToInsert = curr+2;
|
264
264
|
hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
|
265
265
|
hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
|
266
266
|
hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
|
@@ -401,12 +401,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
401
401
|
const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base;
|
402
402
|
const BYTE* matchLong = matchLongBase + matchLongIndex;
|
403
403
|
|
404
|
-
const U32
|
405
|
-
const U32 repIndex =
|
404
|
+
const U32 curr = (U32)(ip-base);
|
405
|
+
const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */
|
406
406
|
const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
|
407
407
|
const BYTE* const repMatch = repBase + repIndex;
|
408
408
|
size_t mLength;
|
409
|
-
hashSmall[hSmall] = hashLong[hLong] =
|
409
|
+
hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
|
410
410
|
|
411
411
|
if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
|
412
412
|
& (repIndex > dictStartIndex))
|
@@ -421,7 +421,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
421
421
|
const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart;
|
422
422
|
U32 offset;
|
423
423
|
mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8;
|
424
|
-
offset =
|
424
|
+
offset = curr - matchLongIndex;
|
425
425
|
while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
|
426
426
|
offset_2 = offset_1;
|
427
427
|
offset_1 = offset;
|
@@ -433,19 +433,19 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
433
433
|
const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base;
|
434
434
|
const BYTE* match3 = match3Base + matchIndex3;
|
435
435
|
U32 offset;
|
436
|
-
hashLong[h3] =
|
436
|
+
hashLong[h3] = curr + 1;
|
437
437
|
if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
|
438
438
|
const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend;
|
439
439
|
const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart;
|
440
440
|
mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8;
|
441
441
|
ip++;
|
442
|
-
offset =
|
442
|
+
offset = curr+1 - matchIndex3;
|
443
443
|
while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
|
444
444
|
} else {
|
445
445
|
const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
|
446
446
|
const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
|
447
447
|
mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
|
448
|
-
offset =
|
448
|
+
offset = curr - matchIndex;
|
449
449
|
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
450
450
|
}
|
451
451
|
offset_2 = offset_1;
|
@@ -464,7 +464,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
464
464
|
if (ip <= ilimit) {
|
465
465
|
/* Complementary insertion */
|
466
466
|
/* done after iLimit test, as candidates could be > iend-8 */
|
467
|
-
{ U32 const indexToInsert =
|
467
|
+
{ U32 const indexToInsert = curr+2;
|
468
468
|
hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
|
469
469
|
hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
|
470
470
|
hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
|
@@ -29,16 +29,16 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
|
|
29
29
|
* Insert the other positions if their hash entry is empty.
|
30
30
|
*/
|
31
31
|
for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) {
|
32
|
-
U32 const
|
32
|
+
U32 const curr = (U32)(ip - base);
|
33
33
|
size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls);
|
34
|
-
hashTable[hash0] =
|
34
|
+
hashTable[hash0] = curr;
|
35
35
|
if (dtlm == ZSTD_dtlm_fast) continue;
|
36
36
|
/* Only load extra positions for ZSTD_dtlm_full */
|
37
37
|
{ U32 p;
|
38
38
|
for (p = 1; p < fastHashFillStep; ++p) {
|
39
39
|
size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls);
|
40
40
|
if (hashTable[hash] == 0) { /* not yet filled */
|
41
|
-
hashTable[hash] =
|
41
|
+
hashTable[hash] = curr + p;
|
42
42
|
} } } }
|
43
43
|
}
|
44
44
|
|
@@ -72,9 +72,9 @@ ZSTD_compressBlock_fast_generic(
|
|
72
72
|
DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
|
73
73
|
ip0 += (ip0 == prefixStart);
|
74
74
|
ip1 = ip0 + 1;
|
75
|
-
{ U32 const
|
76
|
-
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms,
|
77
|
-
U32 const maxRep =
|
75
|
+
{ U32 const curr = (U32)(ip0 - base);
|
76
|
+
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
|
77
|
+
U32 const maxRep = curr - windowLow;
|
78
78
|
if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
|
79
79
|
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
|
80
80
|
}
|
@@ -258,14 +258,14 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
|
|
258
258
|
while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
|
259
259
|
size_t mLength;
|
260
260
|
size_t const h = ZSTD_hashPtr(ip, hlog, mls);
|
261
|
-
U32 const
|
261
|
+
U32 const curr = (U32)(ip-base);
|
262
262
|
U32 const matchIndex = hashTable[h];
|
263
263
|
const BYTE* match = base + matchIndex;
|
264
|
-
const U32 repIndex =
|
264
|
+
const U32 repIndex = curr + 1 - offset_1;
|
265
265
|
const BYTE* repMatch = (repIndex < prefixStartIndex) ?
|
266
266
|
dictBase + (repIndex - dictIndexDelta) :
|
267
267
|
base + repIndex;
|
268
|
-
hashTable[h] =
|
268
|
+
hashTable[h] = curr; /* update hash table */
|
269
269
|
|
270
270
|
if ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex isn't overlapping dict + prefix */
|
271
271
|
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
@@ -284,7 +284,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
|
|
284
284
|
continue;
|
285
285
|
} else {
|
286
286
|
/* found a dict match */
|
287
|
-
U32 const offset = (U32)(
|
287
|
+
U32 const offset = (U32)(curr-dictMatchIndex-dictIndexDelta);
|
288
288
|
mLength = ZSTD_count_2segments(ip+4, dictMatch+4, iend, dictEnd, prefixStart) + 4;
|
289
289
|
while (((ip>anchor) & (dictMatch>dictStart))
|
290
290
|
&& (ip[-1] == dictMatch[-1])) {
|
@@ -316,8 +316,8 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
|
|
316
316
|
|
317
317
|
if (ip <= ilimit) {
|
318
318
|
/* Fill Table */
|
319
|
-
assert(base+
|
320
|
-
hashTable[ZSTD_hashPtr(base+
|
319
|
+
assert(base+curr+2 > istart); /* check base overflow */
|
320
|
+
hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */
|
321
321
|
hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);
|
322
322
|
|
323
323
|
/* check immediate repcode */
|
@@ -410,13 +410,13 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
|
|
410
410
|
const U32 matchIndex = hashTable[h];
|
411
411
|
const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;
|
412
412
|
const BYTE* match = matchBase + matchIndex;
|
413
|
-
const U32
|
414
|
-
const U32 repIndex =
|
413
|
+
const U32 curr = (U32)(ip-base);
|
414
|
+
const U32 repIndex = curr + 1 - offset_1;
|
415
415
|
const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
|
416
416
|
const BYTE* const repMatch = repBase + repIndex;
|
417
|
-
hashTable[h] =
|
418
|
-
DEBUGLOG(7, "offset_1 = %u ,
|
419
|
-
assert(offset_1 <=
|
417
|
+
hashTable[h] = curr; /* update hash table */
|
418
|
+
DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr);
|
419
|
+
assert(offset_1 <= curr +1); /* check repIndex */
|
420
420
|
|
421
421
|
if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))
|
422
422
|
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
@@ -435,7 +435,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
|
|
435
435
|
}
|
436
436
|
{ const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
|
437
437
|
const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
|
438
|
-
U32 const offset =
|
438
|
+
U32 const offset = curr - matchIndex;
|
439
439
|
size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
|
440
440
|
while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
441
441
|
offset_2 = offset_1; offset_1 = offset; /* update offset history */
|
@@ -446,7 +446,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
|
|
446
446
|
|
447
447
|
if (ip <= ilimit) {
|
448
448
|
/* Fill Table */
|
449
|
-
hashTable[ZSTD_hashPtr(base+
|
449
|
+
hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2;
|
450
450
|
hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);
|
451
451
|
/* check immediate repcode */
|
452
452
|
while (ip <= ilimit) {
|