Skip to content

Commit 730938e

Browse files
committed
Replace Huffman boolean args with flags bit set
1 parent fb093c5 commit 730938e

12 files changed

+208
-181
lines changed

lib/common/huf.h

+46-20
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,43 @@ typedef U32 HUF_DTable;
7878
* Advanced decompression functions
7979
******************************************/
8080

81+
/**
82+
* Huffman flags bitset.
83+
* For all flags, 0 is the default value.
84+
*/
85+
typedef enum {
86+
/**
87+
* If compiled with DYNAMIC_BMI2: Set flag only if the CPU supports BMI2 at runtime.
88+
* Otherwise: Ignored.
89+
*/
90+
HUF_flags_bmi2 = (1 << 0),
91+
/**
92+
* If set: Test possible table depths to find the one that produces the smallest header + encoded size.
93+
* If unset: Use heuristic to find the table depth.
94+
*/
95+
HUF_flags_optimalDepth = (1 << 1),
96+
/**
97+
* If set: If the previous table can encode the input, always reuse the previous table.
98+
* If unset: If the previous table can encode the input, reuse the previous table if it results in a smaller output.
99+
*/
100+
HUF_flags_preferRepeat = (1 << 2),
101+
/**
102+
* If set: Sample the input and check if the sample is uncompressible, if it is then don't attempt to compress.
103+
* If unset: Always histogram the entire input.
104+
*/
105+
HUF_flags_suspectUncompressible = (1 << 3),
106+
/**
107+
* If set: Don't use assembly implementations
108+
* If unset: Allow using assembly implementations
109+
*/
110+
HUF_flags_disableAsm = (1 << 4),
111+
} HUF_flags_e;
112+
81113

82114
/* ****************************************
83115
* HUF detailed API
84116
* ****************************************/
85117
#define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btultra
86-
typedef enum {
87-
HUF_depth_fast, /** Use heuristic to find the table depth**/
88-
HUF_depth_optimal /** Test possible table depths to find the one that produces the smallest header + encoded size**/
89-
} HUF_depth_mode;
90118

91119
/*! HUF_compress() does the following:
92120
* 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h")
@@ -102,9 +130,9 @@ typedef enum {
102130
unsigned HUF_minTableLog(unsigned symbolCardinality);
103131
unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue);
104132
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace,
105-
size_t wkspSize, HUF_CElt* table, const unsigned* count, HUF_depth_mode depthMode); /* table is used as scratch space for building and testing tables, not a return value */
133+
size_t wkspSize, HUF_CElt* table, const unsigned* count, int flags); /* table is used as scratch space for building and testing tables, not a return value */
106134
size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize);
107-
size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2);
135+
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags);
108136
size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
109137
int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
110138

@@ -124,8 +152,7 @@ size_t HUF_compress4X_repeat(void* dst, size_t dstSize,
124152
const void* src, size_t srcSize,
125153
unsigned maxSymbolValue, unsigned tableLog,
126154
void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
127-
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2,
128-
int suspectUncompressible, HUF_depth_mode depthMode);
155+
HUF_CElt* hufTable, HUF_repeat* repeat, int flags);
129156

130157
/** HUF_buildCTable_wksp() :
131158
* Same as HUF_buildCTable(), but using externally allocated scratch buffer.
@@ -157,7 +184,7 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize,
157184
U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
158185
const void* src, size_t srcSize,
159186
void* workspace, size_t wkspSize,
160-
int bmi2);
187+
int flags);
161188

162189
/** HUF_readCTable() :
163190
* Loading a CTable saved with HUF_writeCTable() */
@@ -200,7 +227,7 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
200227
/* single stream variants */
201228
/* ====================== */
202229

203-
size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2);
230+
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags);
204231
/** HUF_compress1X_repeat() :
205232
* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
206233
* If it uses hufTable it does not modify hufTable or repeat.
@@ -211,28 +238,27 @@ size_t HUF_compress1X_repeat(void* dst, size_t dstSize,
211238
const void* src, size_t srcSize,
212239
unsigned maxSymbolValue, unsigned tableLog,
213240
void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
214-
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2,
215-
int suspectUncompressible, HUF_depth_mode depthMode);
241+
HUF_CElt* hufTable, HUF_repeat* repeat, int flags);
216242

217-
size_t HUF_decompress1X_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
243+
size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
218244
#ifndef HUF_FORCE_DECOMPRESS_X1
219-
size_t HUF_decompress1X2_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2); /**< double-symbols decoder */
245+
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); /**< double-symbols decoder */
220246
#endif
221247

222248
/* BMI2 variants.
223249
* If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
224250
*/
225-
size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
251+
size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags);
226252
#ifndef HUF_FORCE_DECOMPRESS_X2
227-
size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
253+
size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
228254
#endif
229-
size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
230-
size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
255+
size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags);
256+
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
231257
#ifndef HUF_FORCE_DECOMPRESS_X2
232-
size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
258+
size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags);
233259
#endif
234260
#ifndef HUF_FORCE_DECOMPRESS_X1
235-
size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
261+
size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags);
236262
#endif
237263

238264
#endif /* HUF_H_298734234 */

lib/compress/huf_compress.c

+31-34
Original file line numberDiff line numberDiff line change
@@ -1105,9 +1105,9 @@ HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize,
11051105
static size_t
11061106
HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
11071107
const void* src, size_t srcSize,
1108-
const HUF_CElt* CTable, const int bmi2)
1108+
const HUF_CElt* CTable, const int flags)
11091109
{
1110-
if (bmi2) {
1110+
if (flags & HUF_flags_bmi2) {
11111111
return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable);
11121112
}
11131113
return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable);
@@ -1118,23 +1118,23 @@ HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
11181118
static size_t
11191119
HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
11201120
const void* src, size_t srcSize,
1121-
const HUF_CElt* CTable, const int bmi2)
1121+
const HUF_CElt* CTable, const int flags)
11221122
{
1123-
(void)bmi2;
1123+
(void)flags;
11241124
return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
11251125
}
11261126

11271127
#endif
11281128

1129-
size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2)
1129+
size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags)
11301130
{
1131-
return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2);
1131+
return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags);
11321132
}
11331133

11341134
static size_t
11351135
HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
11361136
const void* src, size_t srcSize,
1137-
const HUF_CElt* CTable, int bmi2)
1137+
const HUF_CElt* CTable, int flags)
11381138
{
11391139
size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */
11401140
const BYTE* ip = (const BYTE*) src;
@@ -1148,23 +1148,23 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
11481148
op += 6; /* jumpTable */
11491149

11501150
assert(op <= oend);
1151-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
1151+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
11521152
if (cSize == 0 || cSize > 65535) return 0;
11531153
MEM_writeLE16(ostart, (U16)cSize);
11541154
op += cSize;
11551155
}
11561156

11571157
ip += segmentSize;
11581158
assert(op <= oend);
1159-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
1159+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
11601160
if (cSize == 0 || cSize > 65535) return 0;
11611161
MEM_writeLE16(ostart+2, (U16)cSize);
11621162
op += cSize;
11631163
}
11641164

11651165
ip += segmentSize;
11661166
assert(op <= oend);
1167-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) );
1167+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
11681168
if (cSize == 0 || cSize > 65535) return 0;
11691169
MEM_writeLE16(ostart+4, (U16)cSize);
11701170
op += cSize;
@@ -1173,29 +1173,29 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
11731173
ip += segmentSize;
11741174
assert(op <= oend);
11751175
assert(ip <= iend);
1176-
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, bmi2) );
1176+
{ CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, flags) );
11771177
if (cSize == 0 || cSize > 65535) return 0;
11781178
op += cSize;
11791179
}
11801180

11811181
return (size_t)(op-ostart);
11821182
}
11831183

1184-
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)
11851185
{
1186-
return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2);
1186+
return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags);
11871187
}
11881188

11891189
typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
11901190

11911191
static size_t HUF_compressCTable_internal(
11921192
BYTE* const ostart, BYTE* op, BYTE* const oend,
11931193
const void* src, size_t srcSize,
1194-
HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int bmi2)
1194+
HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int flags)
11951195
{
11961196
size_t const cSize = (nbStreams==HUF_singleStream) ?
1197-
HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, bmi2) :
1198-
HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, bmi2);
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);
11991199
if (HUF_isError(cSize)) { return cSize; }
12001200
if (cSize==0) { return 0; } /* uncompressible */
12011201
op += cSize;
@@ -1243,12 +1243,12 @@ unsigned HUF_optimalTableLog(
12431243
void* workSpace, size_t wkspSize,
12441244
HUF_CElt* table,
12451245
const unsigned* count,
1246-
HUF_depth_mode depthMode)
1246+
int flags)
12471247
{
12481248
assert(srcSize > 1); /* Not supported, RLE should be used instead */
12491249
assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables));
12501250

1251-
if (depthMode != HUF_depth_optimal) {
1251+
if (!(flags & HUF_flags_optimalDepth)) {
12521252
/* cheap evaluation, based on FSE */
12531253
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
12541254
}
@@ -1300,8 +1300,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
13001300
unsigned maxSymbolValue, unsigned huffLog,
13011301
HUF_nbStreams_e nbStreams,
13021302
void* workSpace, size_t wkspSize,
1303-
HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
1304-
const int bmi2, int suspectUncompressible, HUF_depth_mode depthMode)
1303+
HUF_CElt* oldHufTable, HUF_repeat* repeat, int flags)
13051304
{
13061305
HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t));
13071306
BYTE* const ostart = (BYTE*)dst;
@@ -1322,15 +1321,15 @@ HUF_compress_internal (void* dst, size_t dstSize,
13221321
if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
13231322

13241323
/* Heuristic : If old table is valid, use it for small inputs */
1325-
if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
1324+
if ((flags & HUF_flags_preferRepeat) && repeat && *repeat == HUF_repeat_valid) {
13261325
return HUF_compressCTable_internal(ostart, op, oend,
13271326
src, srcSize,
1328-
nbStreams, oldHufTable, bmi2);
1327+
nbStreams, oldHufTable, flags);
13291328
}
13301329

13311330
/* If uncompressible data is suspected, do a smaller sampling first */
13321331
DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2);
1333-
if (suspectUncompressible && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) {
1332+
if ((flags & HUF_flags_suspectUncompressible) && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) {
13341333
size_t largestTotal = 0;
13351334
DEBUGLOG(5, "input suspected incompressible : sampling to check");
13361335
{ unsigned maxSymbolValueBegin = maxSymbolValue;
@@ -1358,14 +1357,14 @@ HUF_compress_internal (void* dst, size_t dstSize,
13581357
*repeat = HUF_repeat_none;
13591358
}
13601359
/* Heuristic : use existing table for small inputs */
1361-
if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
1360+
if ((flags & HUF_flags_preferRepeat) && repeat && *repeat != HUF_repeat_none) {
13621361
return HUF_compressCTable_internal(ostart, op, oend,
13631362
src, srcSize,
1364-
nbStreams, oldHufTable, bmi2);
1363+
nbStreams, oldHufTable, flags);
13651364
}
13661365

13671366
/* Build Huffman Tree */
1368-
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, depthMode);
1367+
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, flags);
13691368
{ size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
13701369
maxSymbolValue, huffLog,
13711370
&table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp));
@@ -1390,7 +1389,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
13901389
if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
13911390
return HUF_compressCTable_internal(ostart, op, oend,
13921391
src, srcSize,
1393-
nbStreams, oldHufTable, bmi2);
1392+
nbStreams, oldHufTable, flags);
13941393
} }
13951394

13961395
/* Use the new huffman table */
@@ -1402,21 +1401,20 @@ HUF_compress_internal (void* dst, size_t dstSize,
14021401
}
14031402
return HUF_compressCTable_internal(ostart, op, oend,
14041403
src, srcSize,
1405-
nbStreams, table->CTable, bmi2);
1404+
nbStreams, table->CTable, flags);
14061405
}
14071406

14081407
size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
14091408
const void* src, size_t srcSize,
14101409
unsigned maxSymbolValue, unsigned huffLog,
14111410
void* workSpace, size_t wkspSize,
1412-
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat,
1413-
int bmi2, int suspectUncompressible, HUF_depth_mode depthMode)
1411+
HUF_CElt* hufTable, HUF_repeat* repeat, int flags)
14141412
{
14151413
DEBUGLOG(5, "HUF_compress1X_repeat (srcSize = %zu)", srcSize);
14161414
return HUF_compress_internal(dst, dstSize, src, srcSize,
14171415
maxSymbolValue, huffLog, HUF_singleStream,
14181416
workSpace, wkspSize, hufTable,
1419-
repeat, preferRepeat, bmi2, suspectUncompressible, depthMode);
1417+
repeat, flags);
14201418
}
14211419

14221420
/* HUF_compress4X_repeat():
@@ -1427,12 +1425,11 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
14271425
const void* src, size_t srcSize,
14281426
unsigned maxSymbolValue, unsigned huffLog,
14291427
void* workSpace, size_t wkspSize,
1430-
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2,
1431-
int suspectUncompressible, HUF_depth_mode depthMode)
1428+
HUF_CElt* hufTable, HUF_repeat* repeat, int flags)
14321429
{
14331430
DEBUGLOG(5, "HUF_compress4X_repeat (srcSize = %zu)", srcSize);
14341431
return HUF_compress_internal(dst, dstSize, src, srcSize,
14351432
maxSymbolValue, huffLog, HUF_fourStreams,
14361433
workSpace, wkspSize,
1437-
hufTable, repeat, preferRepeat, bmi2, suspectUncompressible, depthMode);
1434+
hufTable, repeat, flags);
14381435
}

0 commit comments

Comments
 (0)