zstd-ruby 1.5.2.2 → 1.5.4.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 +15 -3
- data/ext/zstdruby/common.h +7 -0
- data/ext/zstdruby/libzstd/common/bits.h +175 -0
- data/ext/zstdruby/libzstd/common/bitstream.h +18 -59
- data/ext/zstdruby/libzstd/common/compiler.h +22 -3
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/debug.c +1 -1
- data/ext/zstdruby/libzstd/common/debug.h +1 -1
- data/ext/zstdruby/libzstd/common/entropy_common.c +12 -40
- data/ext/zstdruby/libzstd/common/error_private.c +9 -2
- data/ext/zstdruby/libzstd/common/error_private.h +1 -1
- data/ext/zstdruby/libzstd/common/fse.h +5 -83
- data/ext/zstdruby/libzstd/common/fse_decompress.c +7 -99
- data/ext/zstdruby/libzstd/common/huf.h +65 -156
- data/ext/zstdruby/libzstd/common/mem.h +39 -46
- data/ext/zstdruby/libzstd/common/pool.c +26 -10
- data/ext/zstdruby/libzstd/common/pool.h +7 -1
- data/ext/zstdruby/libzstd/common/portability_macros.h +22 -3
- data/ext/zstdruby/libzstd/common/threading.c +68 -14
- data/ext/zstdruby/libzstd/common/threading.h +5 -10
- data/ext/zstdruby/libzstd/common/xxhash.c +2 -2
- data/ext/zstdruby/libzstd/common/xxhash.h +8 -8
- data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
- data/ext/zstdruby/libzstd/common/zstd_deps.h +1 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +17 -113
- data/ext/zstdruby/libzstd/common/zstd_trace.h +3 -3
- data/ext/zstdruby/libzstd/compress/clevels.h +1 -1
- data/ext/zstdruby/libzstd/compress/fse_compress.c +7 -124
- data/ext/zstdruby/libzstd/compress/hist.c +1 -1
- data/ext/zstdruby/libzstd/compress/hist.h +1 -1
- data/ext/zstdruby/libzstd/compress/huf_compress.c +234 -169
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +1055 -455
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +165 -145
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +115 -39
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +16 -8
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +3 -3
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +25 -21
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +5 -3
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +95 -33
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +433 -148
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +306 -283
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +4 -2
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +5 -5
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +104 -80
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +12 -5
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +1 -1
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +434 -441
- data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +30 -39
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +3 -4
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +164 -42
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +186 -65
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +4 -2
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +19 -15
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +2 -2
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +9 -87
- data/ext/zstdruby/libzstd/zdict.h +53 -31
- data/ext/zstdruby/libzstd/zstd.h +489 -90
- data/ext/zstdruby/libzstd/zstd_errors.h +27 -8
- data/ext/zstdruby/main.c +4 -0
- data/ext/zstdruby/streaming_compress.c +1 -7
- data/ext/zstdruby/zstdruby.c +110 -26
- data/lib/zstd-ruby/version.rb +1 -1
- data/lib/zstd-ruby.rb +0 -1
- metadata +7 -6
@@ -1,6 +1,6 @@
|
|
1
1
|
/* ******************************************************************
|
2
2
|
* Huffman encoder, part of New Generation Entropy library
|
3
|
-
* Copyright (c)
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
4
4
|
*
|
5
5
|
* You can contact the author at :
|
6
6
|
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
@@ -29,9 +29,9 @@
|
|
29
29
|
#include "hist.h"
|
30
30
|
#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
|
31
31
|
#include "../common/fse.h" /* header compression */
|
32
|
-
#define HUF_STATIC_LINKING_ONLY
|
33
32
|
#include "../common/huf.h"
|
34
33
|
#include "../common/error_private.h"
|
34
|
+
#include "../common/bits.h" /* ZSTD_highbit32 */
|
35
35
|
|
36
36
|
|
37
37
|
/* **************************************************************
|
@@ -42,13 +42,67 @@
|
|
42
42
|
|
43
43
|
|
44
44
|
/* **************************************************************
|
45
|
-
*
|
45
|
+
* Required declarations
|
46
46
|
****************************************************************/
|
47
|
-
|
47
|
+
typedef struct nodeElt_s {
|
48
|
+
U32 count;
|
49
|
+
U16 parent;
|
50
|
+
BYTE byte;
|
51
|
+
BYTE nbBits;
|
52
|
+
} nodeElt;
|
53
|
+
|
54
|
+
|
55
|
+
/* **************************************************************
|
56
|
+
* Debug Traces
|
57
|
+
****************************************************************/
|
58
|
+
|
59
|
+
#if DEBUGLEVEL >= 2
|
60
|
+
|
61
|
+
static size_t showU32(const U32* arr, size_t size)
|
48
62
|
{
|
49
|
-
|
63
|
+
size_t u;
|
64
|
+
for (u=0; u<size; u++) {
|
65
|
+
RAWLOG(6, " %u", arr[u]); (void)arr;
|
66
|
+
}
|
67
|
+
RAWLOG(6, " \n");
|
68
|
+
return size;
|
50
69
|
}
|
51
70
|
|
71
|
+
static size_t HUF_getNbBits(HUF_CElt elt);
|
72
|
+
|
73
|
+
static size_t showCTableBits(const HUF_CElt* ctable, size_t size)
|
74
|
+
{
|
75
|
+
size_t u;
|
76
|
+
for (u=0; u<size; u++) {
|
77
|
+
RAWLOG(6, " %zu", HUF_getNbBits(ctable[u])); (void)ctable;
|
78
|
+
}
|
79
|
+
RAWLOG(6, " \n");
|
80
|
+
return size;
|
81
|
+
|
82
|
+
}
|
83
|
+
|
84
|
+
static size_t showHNodeSymbols(const nodeElt* hnode, size_t size)
|
85
|
+
{
|
86
|
+
size_t u;
|
87
|
+
for (u=0; u<size; u++) {
|
88
|
+
RAWLOG(6, " %u", hnode[u].byte); (void)hnode;
|
89
|
+
}
|
90
|
+
RAWLOG(6, " \n");
|
91
|
+
return size;
|
92
|
+
}
|
93
|
+
|
94
|
+
static size_t showHNodeBits(const nodeElt* hnode, size_t size)
|
95
|
+
{
|
96
|
+
size_t u;
|
97
|
+
for (u=0; u<size; u++) {
|
98
|
+
RAWLOG(6, " %u", hnode[u].nbBits); (void)hnode;
|
99
|
+
}
|
100
|
+
RAWLOG(6, " \n");
|
101
|
+
return size;
|
102
|
+
}
|
103
|
+
|
104
|
+
#endif
|
105
|
+
|
52
106
|
|
53
107
|
/* *******************************************************
|
54
108
|
* HUF : Huffman block compression
|
@@ -89,7 +143,10 @@ typedef struct {
|
|
89
143
|
S16 norm[HUF_TABLELOG_MAX+1];
|
90
144
|
} HUF_CompressWeightsWksp;
|
91
145
|
|
92
|
-
static size_t
|
146
|
+
static size_t
|
147
|
+
HUF_compressWeights(void* dst, size_t dstSize,
|
148
|
+
const void* weightTable, size_t wtSize,
|
149
|
+
void* workspace, size_t workspaceSize)
|
93
150
|
{
|
94
151
|
BYTE* const ostart = (BYTE*) dst;
|
95
152
|
BYTE* op = ostart;
|
@@ -140,7 +197,7 @@ static size_t HUF_getNbBitsFast(HUF_CElt elt)
|
|
140
197
|
|
141
198
|
static size_t HUF_getValue(HUF_CElt elt)
|
142
199
|
{
|
143
|
-
return elt & ~0xFF;
|
200
|
+
return elt & ~(size_t)0xFF;
|
144
201
|
}
|
145
202
|
|
146
203
|
static size_t HUF_getValueFast(HUF_CElt elt)
|
@@ -178,6 +235,8 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
|
|
178
235
|
U32 n;
|
179
236
|
HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32));
|
180
237
|
|
238
|
+
HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE >= sizeof(HUF_WriteCTableWksp));
|
239
|
+
|
181
240
|
/* check conditions */
|
182
241
|
if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC);
|
183
242
|
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
|
@@ -207,16 +266,6 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
|
|
207
266
|
return ((maxSymbolValue+1)/2) + 1;
|
208
267
|
}
|
209
268
|
|
210
|
-
/*! HUF_writeCTable() :
|
211
|
-
`CTable` : Huffman tree to save, using huf representation.
|
212
|
-
@return : size of saved CTable */
|
213
|
-
size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
214
|
-
const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog)
|
215
|
-
{
|
216
|
-
HUF_WriteCTableWksp wksp;
|
217
|
-
return HUF_writeCTable_wksp(dst, maxDstSize, CTable, maxSymbolValue, huffLog, &wksp, sizeof(wksp));
|
218
|
-
}
|
219
|
-
|
220
269
|
|
221
270
|
size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights)
|
222
271
|
{
|
@@ -272,68 +321,64 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void
|
|
272
321
|
|
273
322
|
U32 HUF_getNbBitsFromCTable(HUF_CElt const* CTable, U32 symbolValue)
|
274
323
|
{
|
275
|
-
const HUF_CElt* ct = CTable + 1;
|
324
|
+
const HUF_CElt* const ct = CTable + 1;
|
276
325
|
assert(symbolValue <= HUF_SYMBOLVALUE_MAX);
|
277
326
|
return (U32)HUF_getNbBits(ct[symbolValue]);
|
278
327
|
}
|
279
328
|
|
280
329
|
|
281
|
-
typedef struct nodeElt_s {
|
282
|
-
U32 count;
|
283
|
-
U16 parent;
|
284
|
-
BYTE byte;
|
285
|
-
BYTE nbBits;
|
286
|
-
} nodeElt;
|
287
|
-
|
288
330
|
/**
|
289
331
|
* HUF_setMaxHeight():
|
290
|
-
*
|
332
|
+
* Try to enforce @targetNbBits on the Huffman tree described in @huffNode.
|
291
333
|
*
|
292
|
-
* It
|
293
|
-
*
|
334
|
+
* It attempts to convert all nodes with nbBits > @targetNbBits
|
335
|
+
* to employ @targetNbBits instead. Then it adjusts the tree
|
336
|
+
* so that it remains a valid canonical Huffman tree.
|
294
337
|
*
|
295
338
|
* @pre The sum of the ranks of each symbol == 2^largestBits,
|
296
339
|
* where largestBits == huffNode[lastNonNull].nbBits.
|
297
340
|
* @post The sum of the ranks of each symbol == 2^largestBits,
|
298
|
-
* where largestBits is the return value <=
|
341
|
+
* where largestBits is the return value (expected <= targetNbBits).
|
299
342
|
*
|
300
|
-
* @param huffNode The Huffman tree modified in place to enforce
|
343
|
+
* @param huffNode The Huffman tree modified in place to enforce targetNbBits.
|
344
|
+
* It's presumed sorted, from most frequent to rarest symbol.
|
301
345
|
* @param lastNonNull The symbol with the lowest count in the Huffman tree.
|
302
|
-
* @param
|
346
|
+
* @param targetNbBits The allowed number of bits, which the Huffman tree
|
303
347
|
* may not respect. After this function the Huffman tree will
|
304
|
-
* respect
|
305
|
-
* @return The maximum number of bits of the Huffman tree after adjustment
|
306
|
-
* necessarily no more than maxNbBits.
|
348
|
+
* respect targetNbBits.
|
349
|
+
* @return The maximum number of bits of the Huffman tree after adjustment.
|
307
350
|
*/
|
308
|
-
static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32
|
351
|
+
static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits)
|
309
352
|
{
|
310
353
|
const U32 largestBits = huffNode[lastNonNull].nbBits;
|
311
|
-
/* early exit : no elt >
|
312
|
-
if (largestBits <=
|
354
|
+
/* early exit : no elt > targetNbBits, so the tree is already valid. */
|
355
|
+
if (largestBits <= targetNbBits) return largestBits;
|
356
|
+
|
357
|
+
DEBUGLOG(5, "HUF_setMaxHeight (targetNbBits = %u)", targetNbBits);
|
313
358
|
|
314
359
|
/* there are several too large elements (at least >= 2) */
|
315
360
|
{ int totalCost = 0;
|
316
|
-
const U32 baseCost = 1 << (largestBits -
|
361
|
+
const U32 baseCost = 1 << (largestBits - targetNbBits);
|
317
362
|
int n = (int)lastNonNull;
|
318
363
|
|
319
|
-
/* Adjust any ranks >
|
364
|
+
/* Adjust any ranks > targetNbBits to targetNbBits.
|
320
365
|
* Compute totalCost, which is how far the sum of the ranks is
|
321
366
|
* we are over 2^largestBits after adjust the offending ranks.
|
322
367
|
*/
|
323
|
-
while (huffNode[n].nbBits >
|
368
|
+
while (huffNode[n].nbBits > targetNbBits) {
|
324
369
|
totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
|
325
|
-
huffNode[n].nbBits = (BYTE)
|
370
|
+
huffNode[n].nbBits = (BYTE)targetNbBits;
|
326
371
|
n--;
|
327
372
|
}
|
328
|
-
/* n stops at huffNode[n].nbBits <=
|
329
|
-
assert(huffNode[n].nbBits <=
|
330
|
-
/* n end at index of smallest symbol using <
|
331
|
-
while (huffNode[n].nbBits ==
|
373
|
+
/* n stops at huffNode[n].nbBits <= targetNbBits */
|
374
|
+
assert(huffNode[n].nbBits <= targetNbBits);
|
375
|
+
/* n end at index of smallest symbol using < targetNbBits */
|
376
|
+
while (huffNode[n].nbBits == targetNbBits) --n;
|
332
377
|
|
333
|
-
/* renorm totalCost from 2^largestBits to 2^
|
378
|
+
/* renorm totalCost from 2^largestBits to 2^targetNbBits
|
334
379
|
* note : totalCost is necessarily a multiple of baseCost */
|
335
|
-
assert((totalCost & (baseCost - 1)) == 0);
|
336
|
-
totalCost >>= (largestBits -
|
380
|
+
assert(((U32)totalCost & (baseCost - 1)) == 0);
|
381
|
+
totalCost >>= (largestBits - targetNbBits);
|
337
382
|
assert(totalCost > 0);
|
338
383
|
|
339
384
|
/* repay normalized cost */
|
@@ -342,19 +387,19 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
|
342
387
|
|
343
388
|
/* Get pos of last (smallest = lowest cum. count) symbol per rank */
|
344
389
|
ZSTD_memset(rankLast, 0xF0, sizeof(rankLast));
|
345
|
-
{ U32 currentNbBits =
|
390
|
+
{ U32 currentNbBits = targetNbBits;
|
346
391
|
int pos;
|
347
392
|
for (pos=n ; pos >= 0; pos--) {
|
348
393
|
if (huffNode[pos].nbBits >= currentNbBits) continue;
|
349
|
-
currentNbBits = huffNode[pos].nbBits; /* <
|
350
|
-
rankLast[
|
394
|
+
currentNbBits = huffNode[pos].nbBits; /* < targetNbBits */
|
395
|
+
rankLast[targetNbBits-currentNbBits] = (U32)pos;
|
351
396
|
} }
|
352
397
|
|
353
398
|
while (totalCost > 0) {
|
354
399
|
/* Try to reduce the next power of 2 above totalCost because we
|
355
400
|
* gain back half the rank.
|
356
401
|
*/
|
357
|
-
U32 nBitsToDecrease =
|
402
|
+
U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1;
|
358
403
|
for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
|
359
404
|
U32 const highPos = rankLast[nBitsToDecrease];
|
360
405
|
U32 const lowPos = rankLast[nBitsToDecrease-1];
|
@@ -394,7 +439,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
|
394
439
|
rankLast[nBitsToDecrease] = noSymbol;
|
395
440
|
else {
|
396
441
|
rankLast[nBitsToDecrease]--;
|
397
|
-
if (huffNode[rankLast[nBitsToDecrease]].nbBits !=
|
442
|
+
if (huffNode[rankLast[nBitsToDecrease]].nbBits != targetNbBits-nBitsToDecrease)
|
398
443
|
rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
|
399
444
|
}
|
400
445
|
} /* while (totalCost > 0) */
|
@@ -406,11 +451,11 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
|
406
451
|
* TODO.
|
407
452
|
*/
|
408
453
|
while (totalCost < 0) { /* Sometimes, cost correction overshoot */
|
409
|
-
/* special case : no rank 1 symbol (using
|
410
|
-
* let's create one from largest rank 0 (using
|
454
|
+
/* special case : no rank 1 symbol (using targetNbBits-1);
|
455
|
+
* let's create one from largest rank 0 (using targetNbBits).
|
411
456
|
*/
|
412
457
|
if (rankLast[1] == noSymbol) {
|
413
|
-
while (huffNode[n].nbBits ==
|
458
|
+
while (huffNode[n].nbBits == targetNbBits) n--;
|
414
459
|
huffNode[n+1].nbBits--;
|
415
460
|
assert(n >= 0);
|
416
461
|
rankLast[1] = (U32)(n+1);
|
@@ -424,7 +469,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
|
|
424
469
|
} /* repay normalized cost */
|
425
470
|
} /* there are several too large elements (at least >= 2) */
|
426
471
|
|
427
|
-
return
|
472
|
+
return targetNbBits;
|
428
473
|
}
|
429
474
|
|
430
475
|
typedef struct {
|
@@ -432,7 +477,7 @@ typedef struct {
|
|
432
477
|
U16 curr;
|
433
478
|
} rankPos;
|
434
479
|
|
435
|
-
typedef nodeElt huffNodeTable[
|
480
|
+
typedef nodeElt huffNodeTable[2 * (HUF_SYMBOLVALUE_MAX + 1)];
|
436
481
|
|
437
482
|
/* Number of buckets available for HUF_sort() */
|
438
483
|
#define RANK_POSITION_TABLE_SIZE 192
|
@@ -451,8 +496,8 @@ typedef struct {
|
|
451
496
|
* Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing.
|
452
497
|
*/
|
453
498
|
#define RANK_POSITION_MAX_COUNT_LOG 32
|
454
|
-
#define RANK_POSITION_LOG_BUCKETS_BEGIN (RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */
|
455
|
-
#define RANK_POSITION_DISTINCT_COUNT_CUTOFF RANK_POSITION_LOG_BUCKETS_BEGIN +
|
499
|
+
#define RANK_POSITION_LOG_BUCKETS_BEGIN ((RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */)
|
500
|
+
#define RANK_POSITION_DISTINCT_COUNT_CUTOFF (RANK_POSITION_LOG_BUCKETS_BEGIN + ZSTD_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */)
|
456
501
|
|
457
502
|
/* Return the appropriate bucket index for a given count. See definition of
|
458
503
|
* RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy.
|
@@ -460,7 +505,7 @@ typedef struct {
|
|
460
505
|
static U32 HUF_getIndex(U32 const count) {
|
461
506
|
return (count < RANK_POSITION_DISTINCT_COUNT_CUTOFF)
|
462
507
|
? count
|
463
|
-
:
|
508
|
+
: ZSTD_highbit32(count) + RANK_POSITION_LOG_BUCKETS_BEGIN;
|
464
509
|
}
|
465
510
|
|
466
511
|
/* Helper swap function for HUF_quickSortPartition() */
|
@@ -583,7 +628,7 @@ static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSy
|
|
583
628
|
|
584
629
|
/* Sort each bucket. */
|
585
630
|
for (n = RANK_POSITION_DISTINCT_COUNT_CUTOFF; n < RANK_POSITION_TABLE_SIZE - 1; ++n) {
|
586
|
-
|
631
|
+
int const bucketSize = rankPosition[n].curr - rankPosition[n].base;
|
587
632
|
U32 const bucketStartIdx = rankPosition[n].base;
|
588
633
|
if (bucketSize > 1) {
|
589
634
|
assert(bucketStartIdx < maxSymbolValue1);
|
@@ -594,6 +639,7 @@ static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSy
|
|
594
639
|
assert(HUF_isSorted(huffNode, maxSymbolValue1));
|
595
640
|
}
|
596
641
|
|
642
|
+
|
597
643
|
/** HUF_buildCTable_wksp() :
|
598
644
|
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
|
599
645
|
* `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as sizeof(HUF_buildCTable_wksp_tables).
|
@@ -614,6 +660,7 @@ static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue)
|
|
614
660
|
int lowS, lowN;
|
615
661
|
int nodeNb = STARTNODE;
|
616
662
|
int n, nodeRoot;
|
663
|
+
DEBUGLOG(5, "HUF_buildTree (alphabet size = %u)", maxSymbolValue + 1);
|
617
664
|
/* init for parents */
|
618
665
|
nonNullRank = (int)maxSymbolValue;
|
619
666
|
while(huffNode[nonNullRank].count == 0) nonNullRank--;
|
@@ -640,6 +687,8 @@ static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue)
|
|
640
687
|
for (n=0; n<=nonNullRank; n++)
|
641
688
|
huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
|
642
689
|
|
690
|
+
DEBUGLOG(6, "Initial distribution of bits completed (%zu sorted symbols)", showHNodeBits(huffNode, maxSymbolValue+1));
|
691
|
+
|
643
692
|
return nonNullRank;
|
644
693
|
}
|
645
694
|
|
@@ -677,28 +726,36 @@ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, i
|
|
677
726
|
CTable[0] = maxNbBits;
|
678
727
|
}
|
679
728
|
|
680
|
-
size_t
|
729
|
+
size_t
|
730
|
+
HUF_buildCTable_wksp(HUF_CElt* CTable, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,
|
731
|
+
void* workSpace, size_t wkspSize)
|
681
732
|
{
|
682
|
-
HUF_buildCTable_wksp_tables* const wksp_tables =
|
733
|
+
HUF_buildCTable_wksp_tables* const wksp_tables =
|
734
|
+
(HUF_buildCTable_wksp_tables*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(U32));
|
683
735
|
nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
|
684
736
|
nodeElt* const huffNode = huffNode0+1;
|
685
737
|
int nonNullRank;
|
686
738
|
|
739
|
+
HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE == sizeof(HUF_buildCTable_wksp_tables));
|
740
|
+
|
741
|
+
DEBUGLOG(5, "HUF_buildCTable_wksp (alphabet size = %u)", maxSymbolValue+1);
|
742
|
+
|
687
743
|
/* safety checks */
|
688
744
|
if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
|
689
|
-
|
745
|
+
return ERROR(workSpace_tooSmall);
|
690
746
|
if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
|
691
747
|
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
|
692
|
-
|
748
|
+
return ERROR(maxSymbolValue_tooLarge);
|
693
749
|
ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable));
|
694
750
|
|
695
751
|
/* sort, decreasing order */
|
696
752
|
HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
|
753
|
+
DEBUGLOG(6, "sorted symbols completed (%zu symbols)", showHNodeSymbols(huffNode, maxSymbolValue+1));
|
697
754
|
|
698
755
|
/* build tree */
|
699
756
|
nonNullRank = HUF_buildTree(huffNode, maxSymbolValue);
|
700
757
|
|
701
|
-
/* enforce maxTableLog */
|
758
|
+
/* determine and enforce maxTableLog */
|
702
759
|
maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
|
703
760
|
if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
|
704
761
|
|
@@ -807,7 +864,7 @@ FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int id
|
|
807
864
|
#if DEBUGLEVEL >= 1
|
808
865
|
{
|
809
866
|
size_t const nbBits = HUF_getNbBits(elt);
|
810
|
-
size_t const dirtyBits = nbBits == 0 ? 0 :
|
867
|
+
size_t const dirtyBits = nbBits == 0 ? 0 : ZSTD_highbit32((U32)nbBits) + 1;
|
811
868
|
(void)dirtyBits;
|
812
869
|
/* Middle bits are 0. */
|
813
870
|
assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0);
|
@@ -887,7 +944,7 @@ static size_t HUF_closeCStream(HUF_CStream_t* bitC)
|
|
887
944
|
{
|
888
945
|
size_t const nbBits = bitC->bitPos[0] & 0xFF;
|
889
946
|
if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
|
890
|
-
return (bitC->ptr - bitC->startPtr) + (nbBits > 0);
|
947
|
+
return (size_t)(bitC->ptr - bitC->startPtr) + (nbBits > 0);
|
891
948
|
}
|
892
949
|
}
|
893
950
|
|
@@ -1048,9 +1105,9 @@ HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize,
|
|
1048
1105
|
static size_t
|
1049
1106
|
HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
|
1050
1107
|
const void* src, size_t srcSize,
|
1051
|
-
const HUF_CElt* CTable, const int
|
1108
|
+
const HUF_CElt* CTable, const int flags)
|
1052
1109
|
{
|
1053
|
-
if (
|
1110
|
+
if (flags & HUF_flags_bmi2) {
|
1054
1111
|
return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable);
|
1055
1112
|
}
|
1056
1113
|
return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable);
|
@@ -1061,28 +1118,23 @@ HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
|
|
1061
1118
|
static size_t
|
1062
1119
|
HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
|
1063
1120
|
const void* src, size_t srcSize,
|
1064
|
-
const HUF_CElt* CTable, const int
|
1121
|
+
const HUF_CElt* CTable, const int flags)
|
1065
1122
|
{
|
1066
|
-
(void)
|
1123
|
+
(void)flags;
|
1067
1124
|
return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
|
1068
1125
|
}
|
1069
1126
|
|
1070
1127
|
#endif
|
1071
1128
|
|
1072
|
-
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
|
1129
|
+
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags)
|
1073
1130
|
{
|
1074
|
-
return
|
1075
|
-
}
|
1076
|
-
|
1077
|
-
size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2)
|
1078
|
-
{
|
1079
|
-
return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2);
|
1131
|
+
return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags);
|
1080
1132
|
}
|
1081
1133
|
|
1082
1134
|
static size_t
|
1083
1135
|
HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
|
1084
1136
|
const void* src, size_t srcSize,
|
1085
|
-
const HUF_CElt* CTable, int
|
1137
|
+
const HUF_CElt* CTable, int flags)
|
1086
1138
|
{
|
1087
1139
|
size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */
|
1088
1140
|
const BYTE* ip = (const BYTE*) src;
|
@@ -1096,7 +1148,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
|
|
1096
1148
|
op += 6; /* jumpTable */
|
1097
1149
|
|
1098
1150
|
assert(op <= oend);
|
1099
|
-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable,
|
1151
|
+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
|
1100
1152
|
if (cSize == 0 || cSize > 65535) return 0;
|
1101
1153
|
MEM_writeLE16(ostart, (U16)cSize);
|
1102
1154
|
op += cSize;
|
@@ -1104,7 +1156,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
|
|
1104
1156
|
|
1105
1157
|
ip += segmentSize;
|
1106
1158
|
assert(op <= oend);
|
1107
|
-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable,
|
1159
|
+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
|
1108
1160
|
if (cSize == 0 || cSize > 65535) return 0;
|
1109
1161
|
MEM_writeLE16(ostart+2, (U16)cSize);
|
1110
1162
|
op += cSize;
|
@@ -1112,7 +1164,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
|
|
1112
1164
|
|
1113
1165
|
ip += segmentSize;
|
1114
1166
|
assert(op <= oend);
|
1115
|
-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable,
|
1167
|
+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
|
1116
1168
|
if (cSize == 0 || cSize > 65535) return 0;
|
1117
1169
|
MEM_writeLE16(ostart+4, (U16)cSize);
|
1118
1170
|
op += cSize;
|
@@ -1121,7 +1173,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
|
|
1121
1173
|
ip += segmentSize;
|
1122
1174
|
assert(op <= oend);
|
1123
1175
|
assert(ip <= iend);
|
1124
|
-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable,
|
1176
|
+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, flags) );
|
1125
1177
|
if (cSize == 0 || cSize > 65535) return 0;
|
1126
1178
|
op += cSize;
|
1127
1179
|
}
|
@@ -1129,14 +1181,9 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
|
|
1129
1181
|
return (size_t)(op-ostart);
|
1130
1182
|
}
|
1131
1183
|
|
1132
|
-
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
|
1133
|
-
{
|
1134
|
-
return HUF_compress4X_usingCTable_bmi2(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
|
1135
|
-
}
|
1136
|
-
|
1137
|
-
size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2)
|
1184
|
+
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags)
|
1138
1185
|
{
|
1139
|
-
return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable,
|
1186
|
+
return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags);
|
1140
1187
|
}
|
1141
1188
|
|
1142
1189
|
typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
|
@@ -1144,11 +1191,11 @@ typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
|
|
1144
1191
|
static size_t HUF_compressCTable_internal(
|
1145
1192
|
BYTE* const ostart, BYTE* op, BYTE* const oend,
|
1146
1193
|
const void* src, size_t srcSize,
|
1147
|
-
HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int
|
1194
|
+
HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int flags)
|
1148
1195
|
{
|
1149
1196
|
size_t const cSize = (nbStreams==HUF_singleStream) ?
|
1150
|
-
HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable,
|
1151
|
-
HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable,
|
1197
|
+
HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags) :
|
1198
|
+
HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags);
|
1152
1199
|
if (HUF_isError(cSize)) { return cSize; }
|
1153
1200
|
if (cSize==0) { return 0; } /* uncompressible */
|
1154
1201
|
op += cSize;
|
@@ -1171,6 +1218,79 @@ typedef struct {
|
|
1171
1218
|
#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096
|
1172
1219
|
#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */
|
1173
1220
|
|
1221
|
+
unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue)
|
1222
|
+
{
|
1223
|
+
unsigned cardinality = 0;
|
1224
|
+
unsigned i;
|
1225
|
+
|
1226
|
+
for (i = 0; i < maxSymbolValue + 1; i++) {
|
1227
|
+
if (count[i] != 0) cardinality += 1;
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
return cardinality;
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
unsigned HUF_minTableLog(unsigned symbolCardinality)
|
1234
|
+
{
|
1235
|
+
U32 minBitsSymbols = ZSTD_highbit32(symbolCardinality) + 1;
|
1236
|
+
return minBitsSymbols;
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
unsigned HUF_optimalTableLog(
|
1240
|
+
unsigned maxTableLog,
|
1241
|
+
size_t srcSize,
|
1242
|
+
unsigned maxSymbolValue,
|
1243
|
+
void* workSpace, size_t wkspSize,
|
1244
|
+
HUF_CElt* table,
|
1245
|
+
const unsigned* count,
|
1246
|
+
int flags)
|
1247
|
+
{
|
1248
|
+
assert(srcSize > 1); /* Not supported, RLE should be used instead */
|
1249
|
+
assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables));
|
1250
|
+
|
1251
|
+
if (!(flags & HUF_flags_optimalDepth)) {
|
1252
|
+
/* cheap evaluation, based on FSE */
|
1253
|
+
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
|
1254
|
+
}
|
1255
|
+
|
1256
|
+
{ BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp);
|
1257
|
+
size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp);
|
1258
|
+
size_t maxBits, hSize, newSize;
|
1259
|
+
const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue);
|
1260
|
+
const unsigned minTableLog = HUF_minTableLog(symbolCardinality);
|
1261
|
+
size_t optSize = ((size_t) ~0) - 1;
|
1262
|
+
unsigned optLog = maxTableLog, optLogGuess;
|
1263
|
+
|
1264
|
+
DEBUGLOG(6, "HUF_optimalTableLog: probing huf depth (srcSize=%zu)", srcSize);
|
1265
|
+
|
1266
|
+
/* Search until size increases */
|
1267
|
+
for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) {
|
1268
|
+
DEBUGLOG(7, "checking for huffLog=%u", optLogGuess);
|
1269
|
+
maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize);
|
1270
|
+
if (ERR_isError(maxBits)) continue;
|
1271
|
+
|
1272
|
+
if (maxBits < optLogGuess && optLogGuess > minTableLog) break;
|
1273
|
+
|
1274
|
+
hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize);
|
1275
|
+
|
1276
|
+
if (ERR_isError(hSize)) continue;
|
1277
|
+
|
1278
|
+
newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize;
|
1279
|
+
|
1280
|
+
if (newSize > optSize + 1) {
|
1281
|
+
break;
|
1282
|
+
}
|
1283
|
+
|
1284
|
+
if (newSize < optSize) {
|
1285
|
+
optSize = newSize;
|
1286
|
+
optLog = optLogGuess;
|
1287
|
+
}
|
1288
|
+
}
|
1289
|
+
assert(optLog <= HUF_TABLELOG_MAX);
|
1290
|
+
return optLog;
|
1291
|
+
}
|
1292
|
+
}
|
1293
|
+
|
1174
1294
|
/* HUF_compress_internal() :
|
1175
1295
|
* `workSpace_align4` must be aligned on 4-bytes boundaries,
|
1176
1296
|
* and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */
|
@@ -1180,14 +1300,14 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
|
1180
1300
|
unsigned maxSymbolValue, unsigned huffLog,
|
1181
1301
|
HUF_nbStreams_e nbStreams,
|
1182
1302
|
void* workSpace, size_t wkspSize,
|
1183
|
-
HUF_CElt* oldHufTable, HUF_repeat* repeat, int
|
1184
|
-
const int bmi2, unsigned suspectUncompressible)
|
1303
|
+
HUF_CElt* oldHufTable, HUF_repeat* repeat, int flags)
|
1185
1304
|
{
|
1186
1305
|
HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t));
|
1187
1306
|
BYTE* const ostart = (BYTE*)dst;
|
1188
1307
|
BYTE* const oend = ostart + dstSize;
|
1189
1308
|
BYTE* op = ostart;
|
1190
1309
|
|
1310
|
+
DEBUGLOG(5, "HUF_compress_internal (srcSize=%zu)", srcSize);
|
1191
1311
|
HUF_STATIC_ASSERT(sizeof(*table) + HUF_WORKSPACE_MAX_ALIGNMENT <= HUF_WORKSPACE_SIZE);
|
1192
1312
|
|
1193
1313
|
/* checks & inits */
|
@@ -1201,16 +1321,17 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
|
1201
1321
|
if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
|
1202
1322
|
|
1203
1323
|
/* Heuristic : If old table is valid, use it for small inputs */
|
1204
|
-
if (
|
1324
|
+
if ((flags & HUF_flags_preferRepeat) && repeat && *repeat == HUF_repeat_valid) {
|
1205
1325
|
return HUF_compressCTable_internal(ostart, op, oend,
|
1206
1326
|
src, srcSize,
|
1207
|
-
nbStreams, oldHufTable,
|
1327
|
+
nbStreams, oldHufTable, flags);
|
1208
1328
|
}
|
1209
1329
|
|
1210
1330
|
/* If uncompressible data is suspected, do a smaller sampling first */
|
1211
1331
|
DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2);
|
1212
|
-
if (
|
1332
|
+
if ((flags & HUF_flags_suspectUncompressible) && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) {
|
1213
1333
|
size_t largestTotal = 0;
|
1334
|
+
DEBUGLOG(5, "input suspected incompressible : sampling to check");
|
1214
1335
|
{ unsigned maxSymbolValueBegin = maxSymbolValue;
|
1215
1336
|
CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) );
|
1216
1337
|
largestTotal += largestBegin;
|
@@ -1227,6 +1348,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
|
1227
1348
|
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
|
1228
1349
|
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
|
1229
1350
|
}
|
1351
|
+
DEBUGLOG(6, "histogram detail completed (%zu symbols)", showU32(table->count, maxSymbolValue+1));
|
1230
1352
|
|
1231
1353
|
/* Check validity of previous table */
|
1232
1354
|
if ( repeat
|
@@ -1235,19 +1357,20 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
|
1235
1357
|
*repeat = HUF_repeat_none;
|
1236
1358
|
}
|
1237
1359
|
/* Heuristic : use existing table for small inputs */
|
1238
|
-
if (
|
1360
|
+
if ((flags & HUF_flags_preferRepeat) && repeat && *repeat != HUF_repeat_none) {
|
1239
1361
|
return HUF_compressCTable_internal(ostart, op, oend,
|
1240
1362
|
src, srcSize,
|
1241
|
-
nbStreams, oldHufTable,
|
1363
|
+
nbStreams, oldHufTable, flags);
|
1242
1364
|
}
|
1243
1365
|
|
1244
1366
|
/* Build Huffman Tree */
|
1245
|
-
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
1367
|
+
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, flags);
|
1246
1368
|
{ size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
|
1247
1369
|
maxSymbolValue, huffLog,
|
1248
1370
|
&table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp));
|
1249
1371
|
CHECK_F(maxBits);
|
1250
1372
|
huffLog = (U32)maxBits;
|
1373
|
+
DEBUGLOG(6, "bit distribution completed (%zu symbols)", showCTableBits(table->CTable + 1, maxSymbolValue+1));
|
1251
1374
|
}
|
1252
1375
|
/* Zero unused symbols in CTable, so we can check it for validity */
|
1253
1376
|
{
|
@@ -1266,7 +1389,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
|
1266
1389
|
if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
|
1267
1390
|
return HUF_compressCTable_internal(ostart, op, oend,
|
1268
1391
|
src, srcSize,
|
1269
|
-
nbStreams, oldHufTable,
|
1392
|
+
nbStreams, oldHufTable, flags);
|
1270
1393
|
} }
|
1271
1394
|
|
1272
1395
|
/* Use the new huffman table */
|
@@ -1278,46 +1401,20 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
|
1278
1401
|
}
|
1279
1402
|
return HUF_compressCTable_internal(ostart, op, oend,
|
1280
1403
|
src, srcSize,
|
1281
|
-
nbStreams, table->CTable,
|
1282
|
-
}
|
1283
|
-
|
1284
|
-
|
1285
|
-
size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
|
1286
|
-
const void* src, size_t srcSize,
|
1287
|
-
unsigned maxSymbolValue, unsigned huffLog,
|
1288
|
-
void* workSpace, size_t wkspSize)
|
1289
|
-
{
|
1290
|
-
return HUF_compress_internal(dst, dstSize, src, srcSize,
|
1291
|
-
maxSymbolValue, huffLog, HUF_singleStream,
|
1292
|
-
workSpace, wkspSize,
|
1293
|
-
NULL, NULL, 0, 0 /*bmi2*/, 0);
|
1404
|
+
nbStreams, table->CTable, flags);
|
1294
1405
|
}
|
1295
1406
|
|
1296
1407
|
size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
|
1297
1408
|
const void* src, size_t srcSize,
|
1298
1409
|
unsigned maxSymbolValue, unsigned huffLog,
|
1299
1410
|
void* workSpace, size_t wkspSize,
|
1300
|
-
HUF_CElt* hufTable, HUF_repeat* repeat, int
|
1301
|
-
int bmi2, unsigned suspectUncompressible)
|
1411
|
+
HUF_CElt* hufTable, HUF_repeat* repeat, int flags)
|
1302
1412
|
{
|
1413
|
+
DEBUGLOG(5, "HUF_compress1X_repeat (srcSize = %zu)", srcSize);
|
1303
1414
|
return HUF_compress_internal(dst, dstSize, src, srcSize,
|
1304
1415
|
maxSymbolValue, huffLog, HUF_singleStream,
|
1305
1416
|
workSpace, wkspSize, hufTable,
|
1306
|
-
repeat,
|
1307
|
-
}
|
1308
|
-
|
1309
|
-
/* HUF_compress4X_repeat():
|
1310
|
-
* compress input using 4 streams.
|
1311
|
-
* provide workspace to generate compression tables */
|
1312
|
-
size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
|
1313
|
-
const void* src, size_t srcSize,
|
1314
|
-
unsigned maxSymbolValue, unsigned huffLog,
|
1315
|
-
void* workSpace, size_t wkspSize)
|
1316
|
-
{
|
1317
|
-
return HUF_compress_internal(dst, dstSize, src, srcSize,
|
1318
|
-
maxSymbolValue, huffLog, HUF_fourStreams,
|
1319
|
-
workSpace, wkspSize,
|
1320
|
-
NULL, NULL, 0, 0 /*bmi2*/, 0);
|
1417
|
+
repeat, flags);
|
1321
1418
|
}
|
1322
1419
|
|
1323
1420
|
/* HUF_compress4X_repeat():
|
@@ -1328,43 +1425,11 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
|
|
1328
1425
|
const void* src, size_t srcSize,
|
1329
1426
|
unsigned maxSymbolValue, unsigned huffLog,
|
1330
1427
|
void* workSpace, size_t wkspSize,
|
1331
|
-
HUF_CElt* hufTable, HUF_repeat* repeat, int
|
1428
|
+
HUF_CElt* hufTable, HUF_repeat* repeat, int flags)
|
1332
1429
|
{
|
1430
|
+
DEBUGLOG(5, "HUF_compress4X_repeat (srcSize = %zu)", srcSize);
|
1333
1431
|
return HUF_compress_internal(dst, dstSize, src, srcSize,
|
1334
1432
|
maxSymbolValue, huffLog, HUF_fourStreams,
|
1335
1433
|
workSpace, wkspSize,
|
1336
|
-
hufTable, repeat,
|
1434
|
+
hufTable, repeat, flags);
|
1337
1435
|
}
|
1338
|
-
|
1339
|
-
#ifndef ZSTD_NO_UNUSED_FUNCTIONS
|
1340
|
-
/** HUF_buildCTable() :
|
1341
|
-
* @return : maxNbBits
|
1342
|
-
* Note : count is used before tree is written, so they can safely overlap
|
1343
|
-
*/
|
1344
|
-
size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
|
1345
|
-
{
|
1346
|
-
HUF_buildCTable_wksp_tables workspace;
|
1347
|
-
return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, &workspace, sizeof(workspace));
|
1348
|
-
}
|
1349
|
-
|
1350
|
-
size_t HUF_compress1X (void* dst, size_t dstSize,
|
1351
|
-
const void* src, size_t srcSize,
|
1352
|
-
unsigned maxSymbolValue, unsigned huffLog)
|
1353
|
-
{
|
1354
|
-
U64 workSpace[HUF_WORKSPACE_SIZE_U64];
|
1355
|
-
return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
|
1356
|
-
}
|
1357
|
-
|
1358
|
-
size_t HUF_compress2 (void* dst, size_t dstSize,
|
1359
|
-
const void* src, size_t srcSize,
|
1360
|
-
unsigned maxSymbolValue, unsigned huffLog)
|
1361
|
-
{
|
1362
|
-
U64 workSpace[HUF_WORKSPACE_SIZE_U64];
|
1363
|
-
return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
|
1364
|
-
}
|
1365
|
-
|
1366
|
-
size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
|
1367
|
-
{
|
1368
|
-
return HUF_compress2(dst, maxDstSize, src, srcSize, 255, HUF_TABLELOG_DEFAULT);
|
1369
|
-
}
|
1370
|
-
#endif
|