zstd-ruby 1.3.5.0 → 1.3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 */
|