zstd-ruby 1.3.5.0 → 1.3.7.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/.travis.yml +4 -2
- data/README.md +2 -1
- data/ext/zstdruby/libzstd/BUCK +1 -0
- data/ext/zstdruby/libzstd/Makefile +25 -13
- data/ext/zstdruby/libzstd/README.md +11 -10
- data/ext/zstdruby/libzstd/common/bitstream.h +8 -11
- data/ext/zstdruby/libzstd/common/compiler.h +30 -8
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/mem.h +20 -2
- data/ext/zstdruby/libzstd/common/xxhash.c +1 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -2
- data/ext/zstdruby/libzstd/compress/fse_compress.c +55 -48
- data/ext/zstdruby/libzstd/compress/hist.h +1 -1
- data/ext/zstdruby/libzstd/compress/huf_compress.c +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +290 -147
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +5 -2
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +63 -51
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -4
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +44 -33
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -4
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +125 -116
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +13 -15
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +9 -11
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +0 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +42 -36
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +8 -9
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +96 -51
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +16 -6
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +3 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +169 -101
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +111 -87
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +83 -0
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +3 -3
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +728 -0
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +34 -31
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +60 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +9 -3
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +6 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +6 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +12 -9
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +10 -10
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +20 -18
- data/ext/zstdruby/libzstd/zstd.h +109 -50
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +4 -2
@@ -50,7 +50,7 @@
|
|
50
50
|
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
|
51
51
|
const void* src, size_t srcSize);
|
52
52
|
|
53
|
-
unsigned HIST_isError(size_t code);
|
53
|
+
unsigned HIST_isError(size_t code); /**< tells if a return value is an error code */
|
54
54
|
|
55
55
|
|
56
56
|
/* --- advanced histogram functions --- */
|
@@ -82,7 +82,7 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
|
82
82
|
* Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
|
83
83
|
*/
|
84
84
|
#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
|
85
|
-
size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
|
85
|
+
static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
|
86
86
|
{
|
87
87
|
BYTE* const ostart = (BYTE*) dst;
|
88
88
|
BYTE* op = ostart;
|
@@ -46,7 +46,6 @@ struct ZSTD_CDict_s {
|
|
46
46
|
size_t workspaceSize;
|
47
47
|
ZSTD_matchState_t matchState;
|
48
48
|
ZSTD_compressedBlockState_t cBlockState;
|
49
|
-
ZSTD_compressionParameters cParams;
|
50
49
|
ZSTD_customMem customMem;
|
51
50
|
U32 dictID;
|
52
51
|
}; /* typedef'd to ZSTD_CDict within "zstd.h" */
|
@@ -679,6 +678,9 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
679
678
|
CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
680
679
|
CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
681
680
|
CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
681
|
+
ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0);
|
682
|
+
if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX)
|
683
|
+
return ERROR(parameter_outOfBound);
|
682
684
|
if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
|
683
685
|
return ERROR(parameter_unsupported);
|
684
686
|
return 0;
|
@@ -699,6 +701,9 @@ ZSTD_clampCParams(ZSTD_compressionParameters cParams)
|
|
699
701
|
CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
700
702
|
CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
701
703
|
CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
704
|
+
ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0);
|
705
|
+
if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX)
|
706
|
+
cParams.targetLength = ZSTD_TARGETLENGTH_MAX;
|
702
707
|
CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra);
|
703
708
|
return cParams;
|
704
709
|
}
|
@@ -805,7 +810,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|
805
810
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
|
806
811
|
U32 const divider = (cParams.searchLength==3) ? 3 : 4;
|
807
812
|
size_t const maxNbSeq = blockSize / divider;
|
808
|
-
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
813
|
+
size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
|
809
814
|
size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
810
815
|
size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
|
811
816
|
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
|
@@ -900,9 +905,27 @@ ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx)
|
|
900
905
|
fp.ingested = cctx->consumedSrcSize + buffered;
|
901
906
|
fp.consumed = cctx->consumedSrcSize;
|
902
907
|
fp.produced = cctx->producedCSize;
|
908
|
+
fp.flushed = cctx->producedCSize; /* simplified; some data might still be left within streaming output buffer */
|
909
|
+
fp.currentJobID = 0;
|
910
|
+
fp.nbActiveWorkers = 0;
|
903
911
|
return fp;
|
904
912
|
} }
|
905
913
|
|
914
|
+
/*! ZSTD_toFlushNow()
|
915
|
+
* Only useful for multithreading scenarios currently (nbWorkers >= 1).
|
916
|
+
*/
|
917
|
+
size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx)
|
918
|
+
{
|
919
|
+
#ifdef ZSTD_MULTITHREAD
|
920
|
+
if (cctx->appliedParams.nbWorkers > 0) {
|
921
|
+
return ZSTDMT_toFlushNow(cctx->mtctx);
|
922
|
+
}
|
923
|
+
#endif
|
924
|
+
(void)cctx;
|
925
|
+
return 0; /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */
|
926
|
+
}
|
927
|
+
|
928
|
+
|
906
929
|
|
907
930
|
static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
|
908
931
|
ZSTD_compressionParameters cParams2)
|
@@ -913,6 +936,20 @@ static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
|
|
913
936
|
& ((cParams1.searchLength==3) == (cParams2.searchLength==3)); /* hashlog3 space */
|
914
937
|
}
|
915
938
|
|
939
|
+
static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
|
940
|
+
ZSTD_compressionParameters cParams2)
|
941
|
+
{
|
942
|
+
(void)cParams1;
|
943
|
+
(void)cParams2;
|
944
|
+
assert(cParams1.windowLog == cParams2.windowLog);
|
945
|
+
assert(cParams1.chainLog == cParams2.chainLog);
|
946
|
+
assert(cParams1.hashLog == cParams2.hashLog);
|
947
|
+
assert(cParams1.searchLog == cParams2.searchLog);
|
948
|
+
assert(cParams1.searchLength == cParams2.searchLength);
|
949
|
+
assert(cParams1.targetLength == cParams2.targetLength);
|
950
|
+
assert(cParams1.strategy == cParams2.strategy);
|
951
|
+
}
|
952
|
+
|
916
953
|
/** The parameters are equivalent if ldm is not enabled in both sets or
|
917
954
|
* all the parameters are equivalent. */
|
918
955
|
static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
|
@@ -931,33 +968,51 @@ typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
|
|
931
968
|
/* ZSTD_sufficientBuff() :
|
932
969
|
* check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
|
933
970
|
* Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
|
934
|
-
static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t
|
971
|
+
static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t maxNbSeq1,
|
972
|
+
size_t maxNbLit1,
|
935
973
|
ZSTD_buffered_policy_e buffPol2,
|
936
974
|
ZSTD_compressionParameters cParams2,
|
937
975
|
U64 pledgedSrcSize)
|
938
976
|
{
|
939
977
|
size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
|
940
978
|
size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
|
979
|
+
size_t const maxNbSeq2 = blockSize2 / ((cParams2.searchLength == 3) ? 3 : 4);
|
980
|
+
size_t const maxNbLit2 = blockSize2;
|
941
981
|
size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
|
942
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: is
|
943
|
-
(U32)
|
944
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: is
|
945
|
-
(U32)
|
946
|
-
|
982
|
+
DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
|
983
|
+
(U32)neededBufferSize2, (U32)bufferSize1);
|
984
|
+
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
|
985
|
+
(U32)maxNbSeq2, (U32)maxNbSeq1);
|
986
|
+
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbLit2=%u <= maxNbLit1=%u",
|
987
|
+
(U32)maxNbLit2, (U32)maxNbLit1);
|
988
|
+
return (maxNbLit2 <= maxNbLit1)
|
989
|
+
& (maxNbSeq2 <= maxNbSeq1)
|
947
990
|
& (neededBufferSize2 <= bufferSize1);
|
948
991
|
}
|
949
992
|
|
950
993
|
/** Equivalence for resetCCtx purposes */
|
951
994
|
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
|
952
995
|
ZSTD_CCtx_params params2,
|
953
|
-
size_t buffSize1,
|
996
|
+
size_t buffSize1,
|
997
|
+
size_t maxNbSeq1, size_t maxNbLit1,
|
954
998
|
ZSTD_buffered_policy_e buffPol2,
|
955
999
|
U64 pledgedSrcSize)
|
956
1000
|
{
|
957
1001
|
DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
|
958
|
-
|
959
|
-
|
960
|
-
|
1002
|
+
if (!ZSTD_equivalentCParams(params1.cParams, params2.cParams)) {
|
1003
|
+
DEBUGLOG(4, "ZSTD_equivalentCParams() == 0");
|
1004
|
+
return 0;
|
1005
|
+
}
|
1006
|
+
if (!ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams)) {
|
1007
|
+
DEBUGLOG(4, "ZSTD_equivalentLdmParams() == 0");
|
1008
|
+
return 0;
|
1009
|
+
}
|
1010
|
+
if (!ZSTD_sufficientBuff(buffSize1, maxNbSeq1, maxNbLit1, buffPol2,
|
1011
|
+
params2.cParams, pledgedSrcSize)) {
|
1012
|
+
DEBUGLOG(4, "ZSTD_sufficientBuff() == 0");
|
1013
|
+
return 0;
|
1014
|
+
}
|
1015
|
+
return 1;
|
961
1016
|
}
|
962
1017
|
|
963
1018
|
static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
@@ -996,6 +1051,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pl
|
|
996
1051
|
|
997
1052
|
cctx->blockSize = blockSize; /* previous block size could be different even for same windowLog, due to pledgedSrcSize */
|
998
1053
|
cctx->appliedParams = params;
|
1054
|
+
cctx->blockState.matchState.cParams = params.cParams;
|
999
1055
|
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
|
1000
1056
|
cctx->consumedSrcSize = 0;
|
1001
1057
|
cctx->producedCSize = 0;
|
@@ -1032,6 +1088,9 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
|
1032
1088
|
|
1033
1089
|
ms->hashLog3 = hashLog3;
|
1034
1090
|
memset(&ms->window, 0, sizeof(ms->window));
|
1091
|
+
ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
|
1092
|
+
ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
1093
|
+
ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
|
1035
1094
|
ZSTD_invalidateMatchState(ms);
|
1036
1095
|
|
1037
1096
|
/* opt parser space */
|
@@ -1057,6 +1116,8 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
|
1057
1116
|
ms->hashTable3 = ms->chainTable + chainSize;
|
1058
1117
|
ptr = ms->hashTable3 + h3Size;
|
1059
1118
|
|
1119
|
+
ms->cParams = *cParams;
|
1120
|
+
|
1060
1121
|
assert(((size_t)ptr & 3) == 0);
|
1061
1122
|
return ptr;
|
1062
1123
|
}
|
@@ -1082,8 +1143,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1082
1143
|
|
1083
1144
|
if (crp == ZSTDcrp_continue) {
|
1084
1145
|
if (ZSTD_equivalentParams(zc->appliedParams, params,
|
1085
|
-
|
1086
|
-
|
1146
|
+
zc->inBuffSize,
|
1147
|
+
zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
|
1148
|
+
zbuff, pledgedSrcSize)) {
|
1087
1149
|
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
|
1088
1150
|
zc->appliedParams.cParams.windowLog, zc->blockSize);
|
1089
1151
|
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
|
@@ -1104,7 +1166,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1104
1166
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
|
1105
1167
|
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
1106
1168
|
size_t const maxNbSeq = blockSize / divider;
|
1107
|
-
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
1169
|
+
size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq;
|
1108
1170
|
size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
|
1109
1171
|
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
1110
1172
|
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
@@ -1144,7 +1206,6 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1144
1206
|
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
1145
1207
|
zc->workSpaceSize = neededSpace;
|
1146
1208
|
zc->workSpaceOversizedDuration = 0;
|
1147
|
-
ptr = zc->workSpace;
|
1148
1209
|
|
1149
1210
|
/* Statically sized space.
|
1150
1211
|
* entropyWorkspace never moves,
|
@@ -1159,6 +1220,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1159
1220
|
|
1160
1221
|
/* init params */
|
1161
1222
|
zc->appliedParams = params;
|
1223
|
+
zc->blockState.matchState.cParams = params.cParams;
|
1162
1224
|
zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
|
1163
1225
|
zc->consumedSrcSize = 0;
|
1164
1226
|
zc->producedCSize = 0;
|
@@ -1195,13 +1257,18 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1195
1257
|
ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, ¶ms.cParams, crp, /* forCCtx */ 1);
|
1196
1258
|
|
1197
1259
|
/* sequences storage */
|
1260
|
+
zc->seqStore.maxNbSeq = maxNbSeq;
|
1198
1261
|
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
1199
1262
|
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
1200
1263
|
zc->seqStore.llCode = (BYTE*) ptr;
|
1201
1264
|
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
1202
1265
|
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
1203
1266
|
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
1204
|
-
|
1267
|
+
/* ZSTD_wildcopy() is used to copy into the literals buffer,
|
1268
|
+
* so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
|
1269
|
+
*/
|
1270
|
+
zc->seqStore.maxNbLit = blockSize;
|
1271
|
+
ptr = zc->seqStore.litStart + blockSize + WILDCOPY_OVERLENGTH;
|
1205
1272
|
|
1206
1273
|
/* ldm bucketOffsets table */
|
1207
1274
|
if (params.ldmParams.enableLdm) {
|
@@ -1235,54 +1302,59 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
|
|
1235
1302
|
assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));
|
1236
1303
|
}
|
1237
1304
|
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
32 KB, /* ZSTD_lazy2 */
|
1254
|
-
32 KB, /* ZSTD_btlazy2 */
|
1255
|
-
32 KB, /* ZSTD_btopt */
|
1256
|
-
8 KB /* ZSTD_btultra */
|
1257
|
-
};
|
1258
|
-
const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy]
|
1259
|
-
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
1260
|
-
|| params.attachDictPref == ZSTD_dictForceAttach )
|
1261
|
-
&& params.attachDictPref != ZSTD_dictForceCopy
|
1262
|
-
&& !params.forceWindow /* dictMatchState isn't correctly
|
1263
|
-
* handled in _enforceMaxDist */
|
1264
|
-
&& ZSTD_equivalentCParams(cctx->appliedParams.cParams,
|
1265
|
-
cdict->cParams);
|
1266
|
-
|
1267
|
-
DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
|
1305
|
+
/* These are the approximate sizes for each strategy past which copying the
|
1306
|
+
* dictionary tables into the working context is faster than using them
|
1307
|
+
* in-place.
|
1308
|
+
*/
|
1309
|
+
static const size_t attachDictSizeCutoffs[(unsigned)ZSTD_btultra+1] = {
|
1310
|
+
8 KB, /* unused */
|
1311
|
+
8 KB, /* ZSTD_fast */
|
1312
|
+
16 KB, /* ZSTD_dfast */
|
1313
|
+
32 KB, /* ZSTD_greedy */
|
1314
|
+
32 KB, /* ZSTD_lazy */
|
1315
|
+
32 KB, /* ZSTD_lazy2 */
|
1316
|
+
32 KB, /* ZSTD_btlazy2 */
|
1317
|
+
32 KB, /* ZSTD_btopt */
|
1318
|
+
8 KB /* ZSTD_btultra */
|
1319
|
+
};
|
1268
1320
|
|
1321
|
+
static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
|
1322
|
+
ZSTD_CCtx_params params,
|
1323
|
+
U64 pledgedSrcSize)
|
1324
|
+
{
|
1325
|
+
size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
|
1326
|
+
return ( pledgedSrcSize <= cutoff
|
1327
|
+
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
1328
|
+
|| params.attachDictPref == ZSTD_dictForceAttach )
|
1329
|
+
&& params.attachDictPref != ZSTD_dictForceCopy
|
1330
|
+
&& !params.forceWindow; /* dictMatchState isn't correctly
|
1331
|
+
* handled in _enforceMaxDist */
|
1332
|
+
}
|
1269
1333
|
|
1270
|
-
|
1334
|
+
static size_t ZSTD_resetCCtx_byAttachingCDict(
|
1335
|
+
ZSTD_CCtx* cctx,
|
1336
|
+
const ZSTD_CDict* cdict,
|
1337
|
+
ZSTD_CCtx_params params,
|
1338
|
+
U64 pledgedSrcSize,
|
1339
|
+
ZSTD_buffered_policy_e zbuff)
|
1340
|
+
{
|
1341
|
+
{
|
1342
|
+
const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
|
1343
|
+
unsigned const windowLog = params.cParams.windowLog;
|
1271
1344
|
assert(windowLog != 0);
|
1272
|
-
/*
|
1273
|
-
|
1345
|
+
/* Resize working context table params for input only, since the dict
|
1346
|
+
* has its own tables. */
|
1347
|
+
params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
|
1274
1348
|
params.cParams.windowLog = windowLog;
|
1275
1349
|
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1276
|
-
|
1277
|
-
|
1278
|
-
assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
|
1279
|
-
assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
|
1280
|
-
assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
|
1350
|
+
ZSTDcrp_continue, zbuff);
|
1351
|
+
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
|
1281
1352
|
}
|
1282
1353
|
|
1283
|
-
|
1284
|
-
const U32
|
1354
|
+
{
|
1355
|
+
const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
|
1285
1356
|
- cdict->matchState.window.base);
|
1357
|
+
const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
|
1286
1358
|
if (cdictLen == 0) {
|
1287
1359
|
/* don't even attach dictionaries with no contents */
|
1288
1360
|
DEBUGLOG(4, "skipping attaching empty dictionary");
|
@@ -1292,41 +1364,69 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
|
1292
1364
|
|
1293
1365
|
/* prep working match state so dict matches never have negative indices
|
1294
1366
|
* when they are translated to the working context's index space. */
|
1295
|
-
if (cctx->blockState.matchState.window.dictLimit <
|
1367
|
+
if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {
|
1296
1368
|
cctx->blockState.matchState.window.nextSrc =
|
1297
|
-
cctx->blockState.matchState.window.base +
|
1369
|
+
cctx->blockState.matchState.window.base + cdictEnd;
|
1298
1370
|
ZSTD_window_clear(&cctx->blockState.matchState.window);
|
1299
1371
|
}
|
1300
1372
|
cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
|
1301
1373
|
}
|
1302
|
-
}
|
1303
|
-
DEBUGLOG(4, "copying dictionary into context");
|
1304
|
-
/* copy tables */
|
1305
|
-
{ size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
|
1306
|
-
size_t const hSize = (size_t)1 << cdict->cParams.hashLog;
|
1307
|
-
size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
|
1308
|
-
assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1309
|
-
assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
|
1310
|
-
assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1311
|
-
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
|
1312
|
-
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
1313
|
-
}
|
1374
|
+
}
|
1314
1375
|
|
1315
|
-
|
1316
|
-
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
1317
|
-
assert(cdict->matchState.hashLog3 == 0);
|
1318
|
-
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
1319
|
-
}
|
1376
|
+
cctx->dictID = cdict->dictID;
|
1320
1377
|
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1378
|
+
/* copy block state */
|
1379
|
+
memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
|
1380
|
+
|
1381
|
+
return 0;
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
1385
|
+
const ZSTD_CDict* cdict,
|
1386
|
+
ZSTD_CCtx_params params,
|
1387
|
+
U64 pledgedSrcSize,
|
1388
|
+
ZSTD_buffered_policy_e zbuff)
|
1389
|
+
{
|
1390
|
+
const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
|
1391
|
+
|
1392
|
+
DEBUGLOG(4, "copying dictionary into context");
|
1393
|
+
|
1394
|
+
{ unsigned const windowLog = params.cParams.windowLog;
|
1395
|
+
assert(windowLog != 0);
|
1396
|
+
/* Copy only compression parameters related to tables. */
|
1397
|
+
params.cParams = *cdict_cParams;
|
1398
|
+
params.cParams.windowLog = windowLog;
|
1399
|
+
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1400
|
+
ZSTDcrp_noMemset, zbuff);
|
1401
|
+
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
|
1402
|
+
assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
|
1403
|
+
assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
|
1404
|
+
}
|
1405
|
+
|
1406
|
+
/* copy tables */
|
1407
|
+
{ size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
|
1408
|
+
size_t const hSize = (size_t)1 << cdict_cParams->hashLog;
|
1409
|
+
size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
|
1410
|
+
assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1411
|
+
assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
|
1412
|
+
assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1413
|
+
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
|
1414
|
+
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
/* Zero the hashTable3, since the cdict never fills it */
|
1418
|
+
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
1419
|
+
assert(cdict->matchState.hashLog3 == 0);
|
1420
|
+
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
1421
|
+
}
|
1422
|
+
|
1423
|
+
/* copy dictionary offsets */
|
1424
|
+
{ ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
1425
|
+
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
1426
|
+
dstMatchState->window = srcMatchState->window;
|
1427
|
+
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
1428
|
+
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
|
1429
|
+
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
1330
1430
|
}
|
1331
1431
|
|
1332
1432
|
cctx->dictID = cdict->dictID;
|
@@ -1337,6 +1437,27 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
|
1337
1437
|
return 0;
|
1338
1438
|
}
|
1339
1439
|
|
1440
|
+
/* We have a choice between copying the dictionary context into the working
|
1441
|
+
* context, or referencing the dictionary context from the working context
|
1442
|
+
* in-place. We decide here which strategy to use. */
|
1443
|
+
static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
1444
|
+
const ZSTD_CDict* cdict,
|
1445
|
+
ZSTD_CCtx_params params,
|
1446
|
+
U64 pledgedSrcSize,
|
1447
|
+
ZSTD_buffered_policy_e zbuff)
|
1448
|
+
{
|
1449
|
+
|
1450
|
+
DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
|
1451
|
+
|
1452
|
+
if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
|
1453
|
+
return ZSTD_resetCCtx_byAttachingCDict(
|
1454
|
+
cctx, cdict, params, pledgedSrcSize, zbuff);
|
1455
|
+
} else {
|
1456
|
+
return ZSTD_resetCCtx_byCopyingCDict(
|
1457
|
+
cctx, cdict, params, pledgedSrcSize, zbuff);
|
1458
|
+
}
|
1459
|
+
}
|
1460
|
+
|
1340
1461
|
/*! ZSTD_copyCCtx_internal() :
|
1341
1462
|
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
1342
1463
|
* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
|
@@ -1481,15 +1602,15 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
|
|
1481
1602
|
|
1482
1603
|
/* See doc/zstd_compression_format.md for detailed format description */
|
1483
1604
|
|
1484
|
-
size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
1605
|
+
static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
|
1485
1606
|
{
|
1607
|
+
U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
|
1486
1608
|
if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
|
1609
|
+
MEM_writeLE24(dst, cBlockHeader24);
|
1487
1610
|
memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
|
1488
|
-
|
1489
|
-
return ZSTD_blockHeaderSize+srcSize;
|
1611
|
+
return ZSTD_blockHeaderSize + srcSize;
|
1490
1612
|
}
|
1491
1613
|
|
1492
|
-
|
1493
1614
|
static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
1494
1615
|
{
|
1495
1616
|
BYTE* const ostart = (BYTE* const)dst;
|
@@ -1644,6 +1765,7 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
|
|
1644
1765
|
BYTE* const mlCodeTable = seqStorePtr->mlCode;
|
1645
1766
|
U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
1646
1767
|
U32 u;
|
1768
|
+
assert(nbSeq <= seqStorePtr->maxNbSeq);
|
1647
1769
|
for (u=0; u<nbSeq; u++) {
|
1648
1770
|
U32 const llv = sequences[u].litLength;
|
1649
1771
|
U32 const mlv = sequences[u].matchLength;
|
@@ -2040,7 +2162,7 @@ ZSTD_encodeSequences_bmi2(
|
|
2040
2162
|
|
2041
2163
|
#endif
|
2042
2164
|
|
2043
|
-
size_t ZSTD_encodeSequences(
|
2165
|
+
static size_t ZSTD_encodeSequences(
|
2044
2166
|
void* dst, size_t dstCapacity,
|
2045
2167
|
FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
|
2046
2168
|
FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
|
@@ -2232,13 +2354,6 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
|
2232
2354
|
if (cSize >= maxCSize) return 0; /* block not compressed */
|
2233
2355
|
}
|
2234
2356
|
|
2235
|
-
/* We check that dictionaries have offset codes available for the first
|
2236
|
-
* block. After the first block, the offcode table might not have large
|
2237
|
-
* enough codes to represent the offsets in the data.
|
2238
|
-
*/
|
2239
|
-
if (nextEntropy->fse.offcode_repeatMode == FSE_repeat_valid)
|
2240
|
-
nextEntropy->fse.offcode_repeatMode = FSE_repeat_check;
|
2241
|
-
|
2242
2357
|
return cSize;
|
2243
2358
|
}
|
2244
2359
|
|
@@ -2305,12 +2420,18 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
2305
2420
|
const void* src, size_t srcSize)
|
2306
2421
|
{
|
2307
2422
|
ZSTD_matchState_t* const ms = &zc->blockState.matchState;
|
2423
|
+
size_t cSize;
|
2308
2424
|
DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)",
|
2309
2425
|
dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
|
2426
|
+
assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
|
2427
|
+
|
2428
|
+
/* Assert that we have correctly flushed the ctx params into the ms's copy */
|
2429
|
+
ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
|
2310
2430
|
|
2311
2431
|
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
|
2312
2432
|
ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
|
2313
|
-
|
2433
|
+
cSize = 0;
|
2434
|
+
goto out; /* don't even attempt compression below a certain srcSize */
|
2314
2435
|
}
|
2315
2436
|
ZSTD_resetSeqStore(&(zc->seqStore));
|
2316
2437
|
ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; /* required for optimal parser to read stats from dictionary */
|
@@ -2343,7 +2464,6 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
2343
2464
|
ZSTD_ldm_blockCompress(&zc->externSeqStore,
|
2344
2465
|
ms, &zc->seqStore,
|
2345
2466
|
zc->blockState.nextCBlock->rep,
|
2346
|
-
&zc->appliedParams.cParams,
|
2347
2467
|
src, srcSize);
|
2348
2468
|
assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
|
2349
2469
|
} else if (zc->appliedParams.ldmParams.enableLdm) {
|
@@ -2360,31 +2480,38 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
2360
2480
|
ZSTD_ldm_blockCompress(&ldmSeqStore,
|
2361
2481
|
ms, &zc->seqStore,
|
2362
2482
|
zc->blockState.nextCBlock->rep,
|
2363
|
-
&zc->appliedParams.cParams,
|
2364
2483
|
src, srcSize);
|
2365
2484
|
assert(ldmSeqStore.pos == ldmSeqStore.size);
|
2366
2485
|
} else { /* not long range mode */
|
2367
2486
|
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
|
2368
|
-
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep,
|
2487
|
+
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
|
2369
2488
|
}
|
2370
2489
|
{ const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
|
2371
2490
|
ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
|
2372
2491
|
} }
|
2373
2492
|
|
2374
2493
|
/* encode sequences and literals */
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2494
|
+
cSize = ZSTD_compressSequences(&zc->seqStore,
|
2495
|
+
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
|
2496
|
+
&zc->appliedParams,
|
2497
|
+
dst, dstCapacity,
|
2498
|
+
srcSize, zc->entropyWorkspace, zc->bmi2);
|
2499
|
+
|
2500
|
+
out:
|
2501
|
+
if (!ZSTD_isError(cSize) && cSize != 0) {
|
2502
|
+
/* confirm repcodes and entropy tables when emitting a compressed block */
|
2503
|
+
ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
|
2504
|
+
zc->blockState.prevCBlock = zc->blockState.nextCBlock;
|
2505
|
+
zc->blockState.nextCBlock = tmp;
|
2387
2506
|
}
|
2507
|
+
/* We check that dictionaries have offset codes available for the first
|
2508
|
+
* block. After the first block, the offcode table might not have large
|
2509
|
+
* enough codes to represent the offsets in the data.
|
2510
|
+
*/
|
2511
|
+
if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
|
2512
|
+
zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
|
2513
|
+
|
2514
|
+
return cSize;
|
2388
2515
|
}
|
2389
2516
|
|
2390
2517
|
|
@@ -2426,7 +2553,6 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2426
2553
|
ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
|
2427
2554
|
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
|
2428
2555
|
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
|
2429
|
-
|
2430
2556
|
ZSTD_reduceIndex(cctx, correction);
|
2431
2557
|
if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
|
2432
2558
|
else ms->nextToUpdate -= correction;
|
@@ -2442,11 +2568,8 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2442
2568
|
if (ZSTD_isError(cSize)) return cSize;
|
2443
2569
|
|
2444
2570
|
if (cSize == 0) { /* block is not compressible */
|
2445
|
-
|
2446
|
-
if (
|
2447
|
-
MEM_writeLE32(op, cBlockHeader24); /* 4th byte will be overwritten */
|
2448
|
-
memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
|
2449
|
-
cSize = ZSTD_blockHeaderSize + blockSize;
|
2571
|
+
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
|
2572
|
+
if (ZSTD_isError(cSize)) return cSize;
|
2450
2573
|
} else {
|
2451
2574
|
U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
|
2452
2575
|
MEM_writeLE24(op, cBlockHeader24);
|
@@ -2545,7 +2668,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
2545
2668
|
const void* src, size_t srcSize,
|
2546
2669
|
U32 frame, U32 lastFrameChunk)
|
2547
2670
|
{
|
2548
|
-
ZSTD_matchState_t* ms = &cctx->blockState.matchState;
|
2671
|
+
ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
|
2549
2672
|
size_t fhSize = 0;
|
2550
2673
|
|
2551
2674
|
DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
|
@@ -2566,8 +2689,25 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
2566
2689
|
if (!ZSTD_window_update(&ms->window, src, srcSize)) {
|
2567
2690
|
ms->nextToUpdate = ms->window.dictLimit;
|
2568
2691
|
}
|
2569
|
-
if (cctx->appliedParams.ldmParams.enableLdm)
|
2692
|
+
if (cctx->appliedParams.ldmParams.enableLdm) {
|
2570
2693
|
ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
|
2694
|
+
}
|
2695
|
+
|
2696
|
+
if (!frame) {
|
2697
|
+
/* overflow check and correction for block mode */
|
2698
|
+
if (ZSTD_window_needOverflowCorrection(ms->window, (const char*)src + srcSize)) {
|
2699
|
+
U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
|
2700
|
+
U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, 1 << cctx->appliedParams.cParams.windowLog, src);
|
2701
|
+
ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
|
2702
|
+
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
|
2703
|
+
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
|
2704
|
+
ZSTD_reduceIndex(cctx, correction);
|
2705
|
+
if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
|
2706
|
+
else ms->nextToUpdate -= correction;
|
2707
|
+
ms->loadedDictEnd = 0;
|
2708
|
+
ms->dictMatchState = NULL;
|
2709
|
+
}
|
2710
|
+
}
|
2571
2711
|
|
2572
2712
|
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize);
|
2573
2713
|
{ size_t const cSize = frame ?
|
@@ -2609,6 +2749,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|
2609
2749
|
{
|
2610
2750
|
size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
|
2611
2751
|
if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
|
2752
|
+
|
2612
2753
|
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
|
2613
2754
|
}
|
2614
2755
|
|
@@ -2622,34 +2763,36 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
|
2622
2763
|
{
|
2623
2764
|
const BYTE* const ip = (const BYTE*) src;
|
2624
2765
|
const BYTE* const iend = ip + srcSize;
|
2625
|
-
ZSTD_compressionParameters const* cParams = ¶ms->cParams;
|
2626
2766
|
|
2627
2767
|
ZSTD_window_update(&ms->window, src, srcSize);
|
2628
2768
|
ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
|
2629
2769
|
|
2770
|
+
/* Assert that we the ms params match the params we're being given */
|
2771
|
+
ZSTD_assertEqualCParams(params->cParams, ms->cParams);
|
2772
|
+
|
2630
2773
|
if (srcSize <= HASH_READ_SIZE) return 0;
|
2631
2774
|
|
2632
2775
|
switch(params->cParams.strategy)
|
2633
2776
|
{
|
2634
2777
|
case ZSTD_fast:
|
2635
|
-
ZSTD_fillHashTable(ms,
|
2778
|
+
ZSTD_fillHashTable(ms, iend, dtlm);
|
2636
2779
|
break;
|
2637
2780
|
case ZSTD_dfast:
|
2638
|
-
ZSTD_fillDoubleHashTable(ms,
|
2781
|
+
ZSTD_fillDoubleHashTable(ms, iend, dtlm);
|
2639
2782
|
break;
|
2640
2783
|
|
2641
2784
|
case ZSTD_greedy:
|
2642
2785
|
case ZSTD_lazy:
|
2643
2786
|
case ZSTD_lazy2:
|
2644
2787
|
if (srcSize >= HASH_READ_SIZE)
|
2645
|
-
ZSTD_insertAndFindFirstIndex(ms,
|
2788
|
+
ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE);
|
2646
2789
|
break;
|
2647
2790
|
|
2648
2791
|
case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
|
2649
2792
|
case ZSTD_btopt:
|
2650
2793
|
case ZSTD_btultra:
|
2651
2794
|
if (srcSize >= HASH_READ_SIZE)
|
2652
|
-
ZSTD_updateTree(ms,
|
2795
|
+
ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
|
2653
2796
|
break;
|
2654
2797
|
|
2655
2798
|
default:
|
@@ -2813,13 +2956,13 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
|
2813
2956
|
|
2814
2957
|
/*! ZSTD_compressBegin_internal() :
|
2815
2958
|
* @return : 0, or an error code */
|
2816
|
-
size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
2820
|
-
|
2821
|
-
|
2822
|
-
|
2959
|
+
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
2960
|
+
const void* dict, size_t dictSize,
|
2961
|
+
ZSTD_dictContentType_e dictContentType,
|
2962
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
2963
|
+
const ZSTD_CDict* cdict,
|
2964
|
+
ZSTD_CCtx_params params, U64 pledgedSrcSize,
|
2965
|
+
ZSTD_buffered_policy_e zbuff)
|
2823
2966
|
{
|
2824
2967
|
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog);
|
2825
2968
|
/* params are supposed to be fully validated at this point */
|
@@ -3073,7 +3216,7 @@ static size_t ZSTD_initCDict_internal(
|
|
3073
3216
|
{
|
3074
3217
|
DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (U32)dictContentType);
|
3075
3218
|
assert(!ZSTD_checkCParams(cParams));
|
3076
|
-
cdict->cParams = cParams;
|
3219
|
+
cdict->matchState.cParams = cParams;
|
3077
3220
|
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
|
3078
3221
|
cdict->dictBuffer = NULL;
|
3079
3222
|
cdict->dictContent = dictBuffer;
|
@@ -3227,7 +3370,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
|
|
3227
3370
|
ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
|
3228
3371
|
{
|
3229
3372
|
assert(cdict != NULL);
|
3230
|
-
return cdict->cParams;
|
3373
|
+
return cdict->matchState.cParams;
|
3231
3374
|
}
|
3232
3375
|
|
3233
3376
|
/* ZSTD_compressBegin_usingCDict_advanced() :
|
@@ -3332,9 +3475,11 @@ size_t ZSTD_CStreamOutSize(void)
|
|
3332
3475
|
static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
|
3333
3476
|
const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,
|
3334
3477
|
const ZSTD_CDict* const cdict,
|
3335
|
-
ZSTD_CCtx_params
|
3478
|
+
ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize)
|
3336
3479
|
{
|
3337
3480
|
DEBUGLOG(4, "ZSTD_resetCStream_internal");
|
3481
|
+
/* Finalize the compression parameters */
|
3482
|
+
params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, dictSize);
|
3338
3483
|
/* params are supposed to be fully validated at this point */
|
3339
3484
|
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
3340
3485
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
@@ -3363,7 +3508,6 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
|
3363
3508
|
DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize);
|
3364
3509
|
if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
|
3365
3510
|
params.fParams.contentSizeFlag = 1;
|
3366
|
-
params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, 0);
|
3367
3511
|
return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
|
3368
3512
|
}
|
3369
3513
|
|
@@ -3376,6 +3520,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
|
3376
3520
|
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
|
3377
3521
|
{
|
3378
3522
|
DEBUGLOG(4, "ZSTD_initCStream_internal");
|
3523
|
+
params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, dictSize);
|
3379
3524
|
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
3380
3525
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
3381
3526
|
|
@@ -3442,25 +3587,21 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
|
3442
3587
|
(U32)pledgedSrcSize, params.fParams.contentSizeFlag);
|
3443
3588
|
CHECK_F( ZSTD_checkCParams(params.cParams) );
|
3444
3589
|
if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */
|
3445
|
-
|
3446
|
-
|
3447
|
-
}
|
3590
|
+
zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
|
3591
|
+
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, zcs->requestedParams, pledgedSrcSize);
|
3448
3592
|
}
|
3449
3593
|
|
3450
3594
|
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
|
3451
3595
|
{
|
3452
|
-
|
3453
|
-
|
3454
|
-
ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
|
3455
|
-
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN);
|
3596
|
+
ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel);
|
3597
|
+
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, zcs->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN);
|
3456
3598
|
}
|
3457
3599
|
|
3458
3600
|
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
|
3459
3601
|
{
|
3460
3602
|
U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; /* temporary : 0 interpreted as "unknown" during transition period. Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. `0` will be interpreted as "empty" in the future */
|
3461
|
-
|
3462
|
-
|
3463
|
-
return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, pledgedSrcSize);
|
3603
|
+
ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel);
|
3604
|
+
return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, zcs->requestedParams, pledgedSrcSize);
|
3464
3605
|
}
|
3465
3606
|
|
3466
3607
|
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
|
@@ -3701,6 +3842,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
3701
3842
|
|| (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
|
3702
3843
|
ZSTD_CCtx_reset(cctx);
|
3703
3844
|
}
|
3845
|
+
DEBUGLOG(5, "completed ZSTD_compress_generic delegating to ZSTDMT_compressStream_generic");
|
3704
3846
|
return flushMin;
|
3705
3847
|
} }
|
3706
3848
|
#endif
|
@@ -3756,6 +3898,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|
3756
3898
|
|
3757
3899
|
#define ZSTD_MAX_CLEVEL 22
|
3758
3900
|
int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
3901
|
+
int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
|
3759
3902
|
|
3760
3903
|
static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
|
3761
3904
|
{ /* "default" - guarantees a monotonically increasing memory budget */
|