From 5697b3dece084e4098337a22fa4ef763295c5117 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 14 Sep 2023 16:48:14 +0200 Subject: [PATCH] zstd compression - set source size as hint if it is known e. g. by file compression (slightly better performance and/or compression ratio); although the feature still calling as "experimental", but zstd uses this in its own client since v.1.4 IIRC and the only known drawback would be significant regress of compression ration if guess considerably underestimates, but it does no matter in case of known file size. --- CPP/7zip/Archive/ZstdHandler.cpp | 1 + CPP/7zip/Compress/ZstdEncoder.cpp | 8 +++++++- CPP/7zip/Compress/ZstdEncoder.h | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CPP/7zip/Archive/ZstdHandler.cpp b/CPP/7zip/Archive/ZstdHandler.cpp index e5b0148f..b93e3f3a 100644 --- a/CPP/7zip/Archive/ZstdHandler.cpp +++ b/CPP/7zip/Archive/ZstdHandler.cpp @@ -286,6 +286,7 @@ static HRESULT UpdateArchive( CMyComPtr localProgress = localProgressSpec; localProgressSpec->Init(updateCallback, true); NCompress::NZSTD::CEncoder *encoderSpec = new NCompress::NZSTD::CEncoder; + encoderSpec->unpackSize = unpackSize; CMyComPtr encoder = encoderSpec; RINOK(props.SetCoderProps(encoderSpec, NULL)); RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress)); diff --git a/CPP/7zip/Compress/ZstdEncoder.cpp b/CPP/7zip/Compress/ZstdEncoder.cpp index bf5c8fa4..b7c6543e 100644 --- a/CPP/7zip/Compress/ZstdEncoder.cpp +++ b/CPP/7zip/Compress/ZstdEncoder.cpp @@ -30,7 +30,8 @@ CEncoder::CEncoder(): _LdmHashLog(-1), _LdmMinMatch(-1), _LdmBucketSizeLog(-1), - _LdmHashRateLog(-1) + _LdmHashRateLog(-1), + unpackSize(0) { _props.clear(); } @@ -251,6 +252,11 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_contentSizeFlag, 1); if (ZSTD_isError(err)) return E_INVALIDARG; + if (unpackSize) { + err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_srcSizeHint, (int)(unpackSize <= INT_MAX ? unpackSize : INT_MAX)); + if (ZSTD_isError(err)) return E_INVALIDARG; + } + /* enable ldm for large windowlog values */ if (_WindowLog > 27 && _Long == 0) _Long = 1; diff --git a/CPP/7zip/Compress/ZstdEncoder.h b/CPP/7zip/Compress/ZstdEncoder.h index 56fe0671..814bdad0 100644 --- a/CPP/7zip/Compress/ZstdEncoder.h +++ b/CPP/7zip/Compress/ZstdEncoder.h @@ -67,6 +67,9 @@ class CEncoder: Int32 _LdmHashRateLog; public: + + UInt64 unpackSize; + MY_QUERYINTERFACE_BEGIN2(ICompressCoder) MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt) MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties)