Add zstd advanced compression options

This commit is contained in:
Tino Reichardt
2018-11-16 22:30:44 +01:00
parent 8474b3b70c
commit a24bf9aca1
4 changed files with 226 additions and 9 deletions

View File

@@ -279,7 +279,20 @@ static const CNameToPropID g_NameToPropID[] =
{ VT_UI4, "b" },
{ VT_UI4, "check" },
{ VT_BSTR, "filter" },
{ VT_UI8, "memuse" }
{ VT_UI8, "memuse" },
{ VT_UI4, "strat" },
{ VT_UI4, "long" },
{ VT_UI4, "wlog" },
{ VT_UI4, "hlog" },
{ VT_UI4, "clog" },
{ VT_UI4, "slog" },
{ VT_UI4, "slen" },
{ VT_UI4, "tlen" },
{ VT_UI4, "ovlog" },
{ VT_UI4, "ldmhlog" },
{ VT_UI4, "ldmslen" },
{ VT_UI4, "ldmblog" },
{ VT_UI4, "ldmhevery" }
};
static int FindPropIdExact(const UString &name)

View File

@@ -22,7 +22,20 @@ CEncoder::CEncoder():
_dstBufSize(ZSTD_CStreamOutSize()),
_processedIn(0),
_processedOut(0),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
_numThreads(NWindows::NSystem::GetNumberOfProcessors()),
_Long(1),
_Strategy(-1),
_WindowLog(-1),
_HashLog(-1),
_ChainLog(-1),
_SearchLog(-1),
_SearchLength(-1),
_TargetLen(-1),
_OverlapLog(-1),
_LdmHashLog(-1),
_LdmSearchLength(-1),
_LdmBucketSizeLog(-1),
_LdmHashEveryLog(-1)
{
_props.clear();
_hMutex = CreateMutex(NULL, FALSE, NULL);
@@ -67,6 +80,103 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
SetNumberOfThreads(v);
break;
}
case NCoderPropID::kStrategy:
{
if (v < 1) v = 1;
if (v > 8) v = 8;
_Strategy = v;
break;
}
case NCoderPropID::kWindowLog:
{
if (v < ZSTD_WINDOWLOG_MIN) v = ZSTD_WINDOWLOG_MIN;
if (v > ZSTD_WINDOWLOG_MAX) v = ZSTD_WINDOWLOG_MAX;
_WindowLog = v;
break;
}
case NCoderPropID::kHashLog:
{
if (v < ZSTD_HASHLOG_MIN) v = ZSTD_HASHLOG_MIN;
if (v > ZSTD_HASHLOG_MAX) v = ZSTD_HASHLOG_MAX;
_HashLog = v;
break;
}
case NCoderPropID::kChainLog:
{
if (v < ZSTD_CHAINLOG_MIN) v = ZSTD_CHAINLOG_MIN;
if (v > ZSTD_CHAINLOG_MAX) v = ZSTD_CHAINLOG_MAX;
_ChainLog = v;
break;
}
case NCoderPropID::kSearchLog:
{
if (v < ZSTD_SEARCHLOG_MIN) v = ZSTD_SEARCHLOG_MIN;
if (v > ZSTD_SEARCHLOG_MAX) v = ZSTD_SEARCHLOG_MAX;
_SearchLog = v;
break;
}
case NCoderPropID::kSearchLength:
{
if (v < ZSTD_SEARCHLENGTH_MIN) v = ZSTD_SEARCHLENGTH_MIN;
if (v > ZSTD_SEARCHLENGTH_MAX) v = ZSTD_SEARCHLENGTH_MAX;
_SearchLength = v;
break;
}
case NCoderPropID::kTargetLen:
{
if (v < ZSTD_TARGETLENGTH_MIN) v = ZSTD_TARGETLENGTH_MIN;
if (v > ZSTD_TARGETLENGTH_MAX) v = ZSTD_TARGETLENGTH_MAX;
_TargetLen = 0;
break;
}
case NCoderPropID::kOverlapLog:
{
if (v < 0) v = 0; /* no overlap */
if (v > 9) v = 9; /* full size */
_OverlapLog = v;
break;
}
case NCoderPropID::kLong:
{
/* not exact like --long in zstd cli program */
if (v == 0) _Long = 0; // disable
else if (v == 1) _Long = 1; // just enable
else if (v >= 10 && v <= ZSTD_WINDOWLOG_MAX) {
// enable and resize WindowLog
_Long = 1;
_WindowLog = v;
} else return E_INVALIDARG;
break;
}
case NCoderPropID::kLdmHashLog:
{
if (v < ZSTD_HASHLOG_MIN) v = ZSTD_HASHLOG_MIN;
if (v > ZSTD_HASHLOG_MAX) v = ZSTD_HASHLOG_MAX;
_LdmHashLog = v;
break;
}
case NCoderPropID::kLdmSearchLength:
{
if (v < ZSTD_LDM_MINMATCH_MIN) v = ZSTD_LDM_MINMATCH_MIN;
if (v > ZSTD_LDM_MINMATCH_MAX) v = ZSTD_LDM_MINMATCH_MAX;
_LdmSearchLength = v;
break;
}
case NCoderPropID::kLdmBucketSizeLog:
{
if (v < 1) v = 1;
if (v > ZSTD_LDM_BUCKETSIZELOG_MAX) v = ZSTD_LDM_BUCKETSIZELOG_MAX;
_LdmBucketSizeLog = v;
break;
}
case NCoderPropID::kLdmHashEveryLog:
{
if (v < 0) v = 0; /* 0 => automatic mode */
if (v > (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)) v = (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN);
_LdmHashEveryLog = v;
break;
}
default:
{
break;
@@ -106,19 +216,83 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
/* setup level */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_compressionLevel, _props._level);
if (ZSTD_isError(err)) return E_FAIL;
if (ZSTD_isError(err)) return E_INVALIDARG;
/* setup thread count */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_nbWorkers, _numThreads);
if (ZSTD_isError(err)) return E_FAIL;
if (ZSTD_isError(err)) return E_INVALIDARG;
/* set the content size flag */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_contentSizeFlag, 1);
if (ZSTD_isError(err)) return E_FAIL;
if (ZSTD_isError(err)) return E_INVALIDARG;
/* todo: make this optional */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_enableLongDistanceMatching, 1);
if (ZSTD_isError(err)) return E_FAIL;
/* set ldm */
if (_Long == 1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_enableLongDistanceMatching, _Long);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_Strategy != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_compressionStrategy, _Strategy);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_WindowLog != -1) {
if (_WindowLog > 27 && _Long == 0)
return E_INVALIDARG;
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_windowLog, _WindowLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_HashLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_hashLog, _HashLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_ChainLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_chainLog, _ChainLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_SearchLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_searchLog, _SearchLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_SearchLength != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_minMatch, _SearchLength);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_TargetLen != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_targetLength, _TargetLen);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_OverlapLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_overlapSizeLog, _OverlapLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmHashLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_ldmHashLog, _LdmHashLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmSearchLength != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_ldmMinMatch, _LdmSearchLength);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmBucketSizeLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_ldmBucketSizeLog, _LdmBucketSizeLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmHashEveryLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_ldmHashEveryLog, _LdmHashEveryLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
}
for (;;) {

View File

@@ -51,6 +51,21 @@ class CEncoder:
UInt32 _numThreads;
HANDLE _hMutex;
/* zstd advanced compression options */
Int32 _Strategy;
Int32 _WindowLog;
Int32 _HashLog;
Int32 _ChainLog;
Int32 _SearchLog;
Int32 _SearchLength;
Int32 _TargetLen;
Int32 _OverlapLog;
Int32 _Long;
Int32 _LdmHashLog;
Int32 _LdmSearchLength;
Int32 _LdmBucketSizeLog;
Int32 _LdmHashEveryLog;
public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)

View File

@@ -131,7 +131,22 @@ namespace NCoderPropID
kBlockSize2, // VT_UI4 or VT_UI8
kCheckSize, // VT_UI4 : size of digest in bytes
kFilter, // VT_BSTR
kMemUse // VT_UI8
kMemUse, // VT_UI8
/* zstd props */
kStrategy, // VT_UI4 1=ZSTD_fast, 2=ZSTD_dfast, 3=ZSTD_greedy, 4=ZSTD_lazy, 5=ZSTD_lazy2, 6=ZSTD_btlazy2, 7=ZSTD_btopt, 8=ZSTD_btultra
kLong, // VT_UI4 0=disable ldm (default: 27)
kWindowLog, // VT_UI4 x32=10(1KiB)..30(1GiB) x64=10(1KiB)..31(2GiB)
kHashLog, // VT_UI4 The minimum hlog is 6 (64 B) and the maximum is 26 (128 MiB).
kChainLog, // VT_UI4 The minimum clog is 6 (64 B) and the maximum is 28 (256 MiB)
kSearchLog, // VT_UI4 The minimum slog is 1 and the maximum is 26
kSearchLength, // VT_UI4 The minimum slen is 3 and the maximum is 7.
kTargetLen, // VT_UI4 The minimum tlen is 0 and the maximum is 999.
kOverlapLog, // VT_UI4 The minimum ovlog is 0 and the maximum is 9. (default: 6)
kLdmHashLog, // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20).
kLdmSearchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64).
kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3).
kLdmHashEveryLog // VT_UI4 The default value is wlog - ldmhlog.
};
}