initial commit

This commit is contained in:
Danielle Rozenblit
2023-01-04 13:01:54 -08:00
parent ef566c8d68
commit 908e812733
328 changed files with 3340 additions and 1426 deletions
+23 -23
View File
@@ -13,7 +13,7 @@ jobs:
make-all: make-all:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: make all - name: make all
run: make all run: make all
@@ -24,7 +24,7 @@ jobs:
DEVNULLRIGHTS: 1 DEVNULLRIGHTS: 1
READFROMBLOCKDEVICE: 1 READFROMBLOCKDEVICE: 1
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: make test - name: make test
run: make test run: make test
@@ -32,28 +32,28 @@ jobs:
make-test-osx: make-test-osx:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: OS-X test - name: OS-X test
run: make test # make -c lib all doesn't work because of the fact that it's not a tty run: make test # make -c lib all doesn't work because of the fact that it's not a tty
no-intrinsics-fuzztest: no-intrinsics-fuzztest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: no intrinsics fuzztest - name: no intrinsics fuzztest
run: MOREFLAGS="-DZSTD_NO_INTRINSICS" make -C tests fuzztest run: MOREFLAGS="-DZSTD_NO_INTRINSICS" make -C tests fuzztest
tsan-zstreamtest: tsan-zstreamtest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: thread sanitizer zstreamtest - name: thread sanitizer zstreamtest
run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream
ubsan-zstreamtest: ubsan-zstreamtest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: undefined behavior sanitizer zstreamtest - name: undefined behavior sanitizer zstreamtest
run: CC=clang make uasan-test-zstream run: CC=clang make uasan-test-zstream
@@ -61,7 +61,7 @@ jobs:
tsan-fuzztest: tsan-fuzztest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: thread sanitizer fuzztest - name: thread sanitizer fuzztest
run: CC=clang make tsan-fuzztest run: CC=clang make tsan-fuzztest
@@ -69,7 +69,7 @@ jobs:
gcc-8-asan-ubsan-testzstd: gcc-8-asan-ubsan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: gcc-8 + ASan + UBSan + Test Zstd - name: gcc-8 + ASan + UBSan + Test Zstd
# See https://askubuntu.com/a/1428822 # See https://askubuntu.com/a/1428822
run: | run: |
@@ -81,14 +81,14 @@ jobs:
clang-asan-ubsan-testzstd: clang-asan-ubsan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: clang + ASan + UBSan + Test Zstd - name: clang + ASan + UBSan + Test Zstd
run: CC=clang make -j uasan-test-zstd </dev/null V=1 run: CC=clang make -j uasan-test-zstd </dev/null V=1
gcc-asan-ubsan-testzstd-32bit: gcc-asan-ubsan-testzstd-32bit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: ASan + UBSan + Test Zstd, 32bit mode - name: ASan + UBSan + Test Zstd, 32bit mode
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -102,7 +102,7 @@ jobs:
gcc-8-asan-ubsan-fuzz: gcc-8-asan-ubsan-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: gcc-8 + ASan + UBSan + Fuzz Test - name: gcc-8 + ASan + UBSan + Fuzz Test
# See https://askubuntu.com/a/1428822 # See https://askubuntu.com/a/1428822
run: | run: |
@@ -114,14 +114,14 @@ jobs:
clang-asan-ubsan-fuzz: clang-asan-ubsan-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: clang + ASan + UBSan + Fuzz Test - name: clang + ASan + UBSan + Fuzz Test
run: CC=clang FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest run: CC=clang FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest
gcc-asan-ubsan-fuzz32: gcc-asan-ubsan-fuzz32:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: ASan + UBSan + Fuzz Test 32bit - name: ASan + UBSan + Fuzz Test 32bit
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -131,7 +131,7 @@ jobs:
clang-asan-ubsan-fuzz32: clang-asan-ubsan-fuzz32:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: clang + ASan + UBSan + Fuzz Test 32bit - name: clang + ASan + UBSan + Fuzz Test 32bit
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -141,28 +141,28 @@ jobs:
asan-ubsan-regression: asan-ubsan-regression:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: ASan + UBSan + Regression Test - name: ASan + UBSan + Regression Test
run: make -j uasanregressiontest run: make -j uasanregressiontest
clang-ubsan-regression: clang-ubsan-regression:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: clang + ASan + UBSan + Regression Test - name: clang + ASan + UBSan + Regression Test
run: CC=clang make -j uasanregressiontest run: CC=clang make -j uasanregressiontest
msan-regression: msan-regression:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: MSan + Regression Test - name: MSan + Regression Test
run: make -j msanregressiontest run: make -j msanregressiontest
clang-msan-fuzz: clang-msan-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: clang + MSan + Fuzz Test - name: clang + MSan + Fuzz Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -173,7 +173,7 @@ jobs:
clang-msan-testzstd: clang-msan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: clang + MSan + Test Zstd - name: clang + MSan + Test Zstd
run: | run: |
sudo apt-get update sudo apt-get update
@@ -183,7 +183,7 @@ jobs:
armfuzz: armfuzz:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Qemu ARM emulation + Fuzz Test - name: Qemu ARM emulation + Fuzz Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -193,7 +193,7 @@ jobs:
valgrind-fuzz-test: valgrind-fuzz-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: valgrind + fuzz test stack mode # ~ 7mn - name: valgrind + fuzz test stack mode # ~ 7mn
shell: 'script -q -e -c "bash {0}"' shell: 'script -q -e -c "bash {0}"'
run: | run: |
@@ -213,7 +213,7 @@ jobs:
{ compiler: gcc, platform: x64, action: test, script: ""}, { compiler: gcc, platform: x64, action: test, script: ""},
] ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Mingw long test - name: Mingw long test
run: | run: |
$env:PATH_ORIGINAL = $env:PATH $env:PATH_ORIGINAL = $env:PATH
@@ -279,7 +279,7 @@ jobs:
dry-run: false dry-run: false
sanitizer: ${{ matrix.sanitizer }} sanitizer: ${{ matrix.sanitizer }}
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # tag=v3.1.1
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: ${{ matrix.sanitizer }}-artifacts name: ${{ matrix.sanitizer }}-artifacts
+104 -42
View File
@@ -14,21 +14,21 @@ jobs:
linux-kernel: linux-kernel:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: linux kernel, library + build + test - name: linux kernel, library + build + test
run: make -C contrib/linux-kernel test CFLAGS="-Werror -Wunused-const-variable -Wunused-but-set-variable" run: make -C contrib/linux-kernel test CFLAGS="-Werror -Wunused-const-variable -Wunused-but-set-variable"
benchmarking: benchmarking:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: make benchmarking - name: make benchmarking
run: make benchmarking run: make benchmarking
check-32bit: # designed to catch https://github.com/facebook/zstd/issues/2428 check-32bit: # designed to catch https://github.com/facebook/zstd/issues/2428
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: make check on 32-bit - name: make check on 32-bit
run: | run: |
sudo apt update sudo apt update
@@ -38,7 +38,7 @@ jobs:
check-x32: check-x32:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: make check on x32 ABI # https://en.wikipedia.org/wiki/X32_ABI - name: make check on x32 ABI # https://en.wikipedia.org/wiki/X32_ABI
env: env:
CHECK_CONSTRAINED_MEM: true CHECK_CONSTRAINED_MEM: true
@@ -50,7 +50,7 @@ jobs:
gcc-7-libzstd: gcc-7-libzstd:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: gcc-7 + libzstdmt compilation - name: gcc-7 + libzstdmt compilation
# See https://askubuntu.com/a/1428822 # See https://askubuntu.com/a/1428822
run: | run: |
@@ -67,7 +67,7 @@ jobs:
cmake-build-and-test-check: cmake-build-and-test-check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: cmake build and test check - name: cmake build and test check
run: | run: |
FUZZERTEST=-T1mn ZSTREAM_TESTTIME=-T1mn make cmakebuild FUZZERTEST=-T1mn ZSTREAM_TESTTIME=-T1mn make cmakebuild
@@ -78,7 +78,7 @@ jobs:
cpp-gnu90-c99-compatibility: cpp-gnu90-c99-compatibility:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: C++, gnu90 and c99 compatibility - name: C++, gnu90 and c99 compatibility
run: | run: |
make cxxtest make cxxtest
@@ -92,7 +92,7 @@ jobs:
mingw-cross-compilation: mingw-cross-compilation:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: mingw cross-compilation - name: mingw cross-compilation
run: | run: |
# sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; (doesn't work) # sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; (doesn't work)
@@ -103,7 +103,7 @@ jobs:
armbuild: armbuild:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: ARM Build Test - name: ARM Build Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -113,7 +113,7 @@ jobs:
bourne-shell: bourne-shell:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Bourne shell compatibility (shellcheck) - name: Bourne shell compatibility (shellcheck)
run: | run: |
wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz wget https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz
@@ -123,7 +123,7 @@ jobs:
zlib-wrapper: zlib-wrapper:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: zlib wrapper test - name: zlib wrapper test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -134,7 +134,7 @@ jobs:
lz4-threadpool-libs: lz4-threadpool-libs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: LZ4, thread pool, and libs build testslib wrapper test - name: LZ4, thread pool, and libs build testslib wrapper test
run: | run: |
make lz4install make lz4install
@@ -148,7 +148,7 @@ jobs:
gcc-make-tests-32bit: gcc-make-tests-32bit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Make all, 32bit mode - name: Make all, 32bit mode
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@@ -158,7 +158,7 @@ jobs:
gcc-8-make: gcc-8-make:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: gcc-8 build - name: gcc-8 build
# See https://askubuntu.com/a/1428822 # See https://askubuntu.com/a/1428822
run: | run: |
@@ -170,7 +170,7 @@ jobs:
implicit-fall-through: implicit-fall-through:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: -Wimplicit-fallthrough build - name: -Wimplicit-fallthrough build
run: | run: |
make clean make clean
@@ -178,6 +178,51 @@ jobs:
make clean make clean
CC=clang MOREFLAGS="-Werror -Wimplicit-fallthrough -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0 CC=clang MOREFLAGS="-Werror -Wimplicit-fallthrough -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0
meson-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Install packages
run: |
sudo apt-get update
sudo apt-get -y install build-essential python3-pip ninja-build liblz4-dev
pip install --pre meson
- name: Build with Meson
run: |
meson setup \
--buildtype=debugoptimized \
-Db_lundef=false \
-Dauto_features=enabled \
-Dbin_programs=true \
-Dbin_tests=true \
-Dbin_contrib=true \
-Ddefault_library=both \
build/meson builddir
ninja -C builddir/
meson test -C builddir/ --print-errorlogs
meson install -C builddir --destdir staging/
meson-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Install packages
run: pip install --pre meson
- name: Initialize the MSVC dev command prompt
uses: ilammy/msvc-dev-cmd@7315a94840631165970262a99c72cfb48a65d25d
- name: Configure with Meson
run: |
meson setup build/meson/ builddir -Dbin_tests=true -Dbin_programs=true -Dbin_contrib=true
- name: Build with Meson
run: |
ninja -C builddir/
- name: Test with Meson
run: |
meson test -C builddir/ --print-errorlogs
- name: Install with Meson
run: |
meson install -C builddir --destdir staging/
cmake-visual-2019: cmake-visual-2019:
runs-on: windows-2019 runs-on: windows-2019
strategy: strategy:
@@ -189,9 +234,9 @@ jobs:
flags: "-A Win32" flags: "-A Win32"
- generator: "MinGW Makefiles" - generator: "MinGW Makefiles"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Add MSBuild to PATH - name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.1.3 uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506 # tag=v1.1.3
- name: Build - name: Build
working-directory: ${{env.GITHUB_WORKSPACE}} working-directory: ${{env.GITHUB_WORKSPACE}}
run: | run: |
@@ -208,9 +253,9 @@ jobs:
platform: [x64, Win32] platform: [x64, Win32]
configuration: [Debug, Release] configuration: [Debug, Release]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Add MSBuild to PATH - name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.1.3 uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506 # tag=v1.1.3
- name: Build - name: Build
working-directory: ${{env.GITHUB_WORKSPACE}} working-directory: ${{env.GITHUB_WORKSPACE}}
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
@@ -227,19 +272,33 @@ jobs:
# platform: [x64, Win32] # platform: [x64, Win32]
# configuration: [Debug, Release] # configuration: [Debug, Release]
# steps: # steps:
# - uses: actions/checkout@v3 # - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
# - name: Add MSBuild to PATH # - name: Add MSBuild to PATH
# uses: microsoft/setup-msbuild@v1.1.3 # uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506 # tag=v1.1.3
# - name: Build # - name: Build
# working-directory: ${{env.GITHUB_WORKSPACE}} # working-directory: ${{env.GITHUB_WORKSPACE}}
# run: > # run: >
# msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 # msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140
# /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} # /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}}
# This tests that we don't accidently grow the size too much.
# If the size grows intentionally, you can raise these numbers.
# But we do need to think about binary size, since it is a concern.
libzstd-size:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: libzstd size test
run: |
make clean && make -j -C lib libzstd && ./tests/check_size.py lib/libzstd.so 1100000
make clean && make -j -C lib libzstd ZSTD_LIB_COMPRESSION=0 ZSTD_LIB_DICTBUILDER=0 && ./tests/check_size.py lib/libzstd.so 400000
make clean && make -j -C lib libzstd ZSTD_LIB_MINIFY=1 && ./tests/check_size.py lib/libzstd.so 300000
make clean && make -j -C lib libzstd ZSTD_LIB_MINIFY=1 ZSTD_LIB_COMPRESSION=0 ZSTD_LIB_DICTBUILDER=0 && ./tests/check_size.py lib/libzstd.so 80000
minimal-decompressor-macros: minimal-decompressor-macros:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: minimal decompressor macros - name: minimal decompressor macros
run: | run: |
make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror"
@@ -254,7 +313,7 @@ jobs:
dynamic-bmi2: dynamic-bmi2:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: dynamic bmi2 tests - name: dynamic bmi2 tests
run: | run: |
make clean && make -j check MOREFLAGS="-O0 -Werror -mbmi2" make clean && make -j check MOREFLAGS="-O0 -Werror -mbmi2"
@@ -266,7 +325,7 @@ jobs:
test-variants: test-variants:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: make all variants & validate - name: make all variants & validate
run: | run: |
make -j -C programs allVariants MOREFLAGS=-O0 make -j -C programs allVariants MOREFLAGS=-O0
@@ -292,7 +351,7 @@ jobs:
XCC: ${{ matrix.xcc }} XCC: ${{ matrix.xcc }}
XEMU: ${{ matrix.xemu }} XEMU: ${{ matrix.xemu }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: apt update & install - name: apt update & install
run: | run: |
sudo apt-get update sudo apt-get update
@@ -345,7 +404,7 @@ jobs:
{ compiler: clang, platform: x64, script: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1"}, { compiler: clang, platform: x64, script: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1"},
] ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Mingw short test - name: Mingw short test
run: | run: |
ECHO "Building ${{matrix.compiler}} ${{matrix.platform}}" ECHO "Building ${{matrix.compiler}} ${{matrix.platform}}"
@@ -378,9 +437,9 @@ jobs:
platform: [x64, Win32] platform: [x64, Win32]
configuration: [Release] configuration: [Release]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Add MSBuild to PATH - name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1.1.3 uses: microsoft/setup-msbuild@34cfbaee7f672c76950673338facd8a73f637506 # tag=v1.1.3
- name: Build and run tests - name: Build and run tests
working-directory: ${{env.GITHUB_WORKSPACE}} working-directory: ${{env.GITHUB_WORKSPACE}}
env: env:
@@ -398,7 +457,7 @@ jobs:
intel-cet-compatibility: intel-cet-compatibility:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Build Zstd - name: Build Zstd
run: | run: |
make -j zstd V=1 make -j zstd V=1
@@ -419,7 +478,7 @@ jobs:
container: container:
image: debian:testing image: debian:testing
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Install dependencies - name: Install dependencies
run: | run: |
apt -y update apt -y update
@@ -431,18 +490,21 @@ jobs:
cc -Wall -Wextra -Wpedantic -Werror -o simple examples/simple_compression.c $(pkg-config --cflags --libs libzstd) cc -Wall -Wextra -Wpedantic -Werror -o simple examples/simple_compression.c $(pkg-config --cflags --libs libzstd)
./simple LICENSE ./simple LICENSE
versions-compatibility:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Versions Compatibility Test
run: |
make -C tests versionsTest
# This test currently fails on Github Actions specifically. clangbuild:
# Possible reason : TTY emulation. runs-on: ubuntu-latest
# Note that the same test works fine locally and on travisCI. steps:
# This will have to be fixed before transferring the test to GA. - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
# versions-compatibility: - name: make clangbuild
# runs-on: ubuntu-latest run: |
# steps: make clangbuild
# - uses: actions/checkout@v3
# - name: Versions Compatibility Test
# run: |
# make -C tests versionsTest
# For reference : icc tests # For reference : icc tests
@@ -463,7 +525,7 @@ jobs:
# sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main" # sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main"
# sudo apt-get update # sudo apt-get update
# sudo apt-get install -y intel-basekit intel-hpckit # sudo apt-get install -y intel-basekit intel-hpckit
# - uses: actions/checkout@v3 # - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
# - name: make check # - name: make check
# run: | # run: |
# make CC=/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc check # make CC=/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc check
@@ -19,7 +19,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
- name: Archive - name: Archive
env: env:
+4 -4
View File
@@ -27,12 +27,12 @@ jobs:
steps: steps:
- name: "Checkout code" - name: "Checkout code"
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 # tag=v3.0.0 uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # tag=v3
with: with:
persist-credentials: false persist-credentials: false
- name: "Run analysis" - name: "Run analysis"
uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # tag=v2.0.6 uses: ossf/scorecard-action@937ffa90d79c7d720498178154ad4c7ba1e4ad8c # tag=v2.1.0
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: sarif
@@ -51,7 +51,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab. # format to the repository Actions tab.
- name: "Upload artifact" - name: "Upload artifact"
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # tag=v3.0.0 uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # tag=v3.1.1
with: with:
name: SARIF file name: SARIF file
path: results.sarif path: results.sarif
@@ -59,6 +59,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard. # Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning" - name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@5f532563584d71fdef14ee64d17bafb34f751ce5 # tag=v1.0.26 uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # tag=v2.1.37
with: with:
sarif_file: results.sarif sarif_file: results.sarif
+4 -4
View File
@@ -2,7 +2,7 @@ BSD License
For Zstandard software For Zstandard software
Copyright (c) 2016-present, Facebook, Inc. All rights reserved. Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met: are permitted provided that the following conditions are met:
@@ -14,9 +14,9 @@ are permitted provided that the following conditions are met:
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.
* Neither the name Facebook nor the names of its contributors may be used to * Neither the name Facebook, nor Meta, nor the names of its contributors may
endorse or promote products derived from this software without specific be used to endorse or promote products derived from this software without
prior written permission. specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+3 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2015-2021, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -123,6 +123,7 @@ contrib: lib
$(MAKE) -C contrib/seekable_format/examples all $(MAKE) -C contrib/seekable_format/examples all
$(MAKE) -C contrib/seekable_format/tests test $(MAKE) -C contrib/seekable_format/tests test
$(MAKE) -C contrib/largeNbDicts all $(MAKE) -C contrib/largeNbDicts all
$(MAKE) -C contrib/externalMatchfinder all
cd build/single_file_libs/ ; ./build_decoder_test.sh cd build/single_file_libs/ ; ./build_decoder_test.sh
cd build/single_file_libs/ ; ./build_library_test.sh cd build/single_file_libs/ ; ./build_library_test.sh
@@ -142,6 +143,7 @@ clean:
$(Q)$(MAKE) -C contrib/seekable_format/examples $@ > $(VOID) $(Q)$(MAKE) -C contrib/seekable_format/examples $@ > $(VOID)
$(Q)$(MAKE) -C contrib/seekable_format/tests $@ > $(VOID) $(Q)$(MAKE) -C contrib/seekable_format/tests $@ > $(VOID)
$(Q)$(MAKE) -C contrib/largeNbDicts $@ > $(VOID) $(Q)$(MAKE) -C contrib/largeNbDicts $@ > $(VOID)
$(Q)$(MAKE) -C contrib/externalMatchfinder $@ > $(VOID)
$(Q)$(RM) zstd$(EXT) zstdmt$(EXT) tmp* $(Q)$(RM) zstd$(EXT) zstdmt$(EXT) tmp*
$(Q)$(RM) -r lz4 $(Q)$(RM) -r lz4
@echo Cleaning completed @echo Cleaning completed
+2 -2
View File
@@ -32,11 +32,11 @@ BEGIN
BEGIN BEGIN
BLOCK "040904B0" BLOCK "040904B0"
BEGIN BEGIN
VALUE "CompanyName", "Yann Collet, Facebook, Inc." VALUE "CompanyName", "Meta Platforms, Inc."
VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm" VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm"
VALUE "FileVersion", ZSTD_VERSION_STRING VALUE "FileVersion", ZSTD_VERSION_STRING
VALUE "InternalName", "libzstd.dll" VALUE "InternalName", "libzstd.dll"
VALUE "LegalCopyright", "Copyright (c) 2013-present, Yann Collet, Facebook, Inc." VALUE "LegalCopyright", "Copyright (c) Meta Platforms, Inc. and affiliates."
VALUE "OriginalFilename", "libzstd.dll" VALUE "OriginalFilename", "libzstd.dll"
VALUE "ProductName", "Zstandard" VALUE "ProductName", "Zstandard"
VALUE "ProductVersion", ZSTD_VERSION_STRING VALUE "ProductVersion", ZSTD_VERSION_STRING
+2 -2
View File
@@ -32,11 +32,11 @@ BEGIN
BEGIN BEGIN
BLOCK "040904B0" BLOCK "040904B0"
BEGIN BEGIN
VALUE "CompanyName", "Yann Collet, Facebook, Inc." VALUE "CompanyName", "Meta Platforms, Inc."
VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm" VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm"
VALUE "FileVersion", ZSTD_VERSION_STRING VALUE "FileVersion", ZSTD_VERSION_STRING
VALUE "InternalName", "zstd.exe" VALUE "InternalName", "zstd.exe"
VALUE "LegalCopyright", "Copyright (c) 2013-present, Yann Collet, Facebook, Inc." VALUE "LegalCopyright", "Copyright (c) Meta Platforms, Inc. and affiliates."
VALUE "OriginalFilename", "zstd.exe" VALUE "OriginalFilename", "zstd.exe"
VALUE "ProductName", "Zstandard" VALUE "ProductName", "Zstandard"
VALUE "ProductVersion", ZSTD_VERSION_STRING VALUE "ProductVersion", ZSTD_VERSION_STRING
+12 -10
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -8,18 +8,18 @@
# ################################################################ # ################################################################
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
# As of 2018-12-26 ZSTD has been validated to build with cmake version 3.13.2 new policies. # As of 2018-12-26 ZSTD has been validated to build with cmake version 3.13.2 new policies.
# Set and use the newest cmake policies that are validated to work # Set and use the newest cmake policies that are validated to work
set(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3") set(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3")
set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13") #Policies never changed at PATCH level set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13") #Policies never changed at PATCH level
if("${CMAKE_MAJOR_VERSION}" LESS 3) if("${CMAKE_MAJOR_VERSION}" LESS 3)
set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}")
elseif( "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}" EQUAL "${CMAKE_MAJOR_VERSION}" AND elseif( "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}" EQUAL "${CMAKE_MAJOR_VERSION}" AND
"${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}" GREATER "${CMAKE_MINOR_VERSION}") "${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}" GREATER "${CMAKE_MINOR_VERSION}")
set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}")
else() else()
set(ZSTD_CMAKE_POLICY_VERSION "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}.${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}.0") set(ZSTD_CMAKE_POLICY_VERSION "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}.${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}.0")
endif() endif()
cmake_policy(VERSION ${ZSTD_CMAKE_POLICY_VERSION}) cmake_policy(VERSION ${ZSTD_CMAKE_POLICY_VERSION})
@@ -40,11 +40,13 @@ if( CMAKE_MAJOR_VERSION LESS 3 )
set(PROJECT_VERSION_PATCH ${zstd_VERSION_PATCH}) set(PROJECT_VERSION_PATCH ${zstd_VERSION_PATCH})
set(PROJECT_VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}") set(PROJECT_VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}")
enable_language(C) # Main library is in C enable_language(C) # Main library is in C
enable_language(ASM) # And ASM
enable_language(CXX) # Testing contributed code also utilizes CXX enable_language(CXX) # Testing contributed code also utilizes CXX
else() else()
project(zstd project(zstd
VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}" VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}"
LANGUAGES C # Main library is in C LANGUAGES C # Main library is in C
ASM # And ASM
CXX # Testing contributed code also utilizes CXX CXX # Testing contributed code also utilizes CXX
) )
endif() endif()
@@ -1,7 +1,8 @@
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
include(CheckLinkerFlag)
function(EnableCompilerFlag _flag _C _CXX) function(EnableCompilerFlag _flag _C _CXX _LD)
string(REGEX REPLACE "\\+" "PLUS" varname "${_flag}") string(REGEX REPLACE "\\+" "PLUS" varname "${_flag}")
string(REGEX REPLACE "[^A-Za-z0-9]+" "_" varname "${varname}") string(REGEX REPLACE "[^A-Za-z0-9]+" "_" varname "${varname}")
string(REGEX REPLACE "^_+" "" varname "${varname}") string(REGEX REPLACE "^_+" "" varname "${varname}")
@@ -18,6 +19,13 @@ function(EnableCompilerFlag _flag _C _CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE)
endif () endif ()
endif () endif ()
if (_LD)
CHECK_LINKER_FLAG(C ${_flag} LD_FLAG_${varname})
if (LD_FLAG_${varname})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${_flag}" PARENT_SCOPE)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${_flag}" PARENT_SCOPE)
endif ()
endif ()
endfunction() endfunction()
macro(ADD_ZSTD_COMPILATION_FLAGS) macro(ADD_ZSTD_COMPILATION_FLAGS)
@@ -30,33 +38,39 @@ macro(ADD_ZSTD_COMPILATION_FLAGS)
# EnableCompilerFlag("-std=c99" true false) # Set C compiation to c99 standard # EnableCompilerFlag("-std=c99" true false) # Set C compiation to c99 standard
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC)
# clang-cl normally maps -Wall to -Weverything. # clang-cl normally maps -Wall to -Weverything.
EnableCompilerFlag("/clang:-Wall" true true) EnableCompilerFlag("/clang:-Wall" true true false)
else () else ()
EnableCompilerFlag("-Wall" true true) EnableCompilerFlag("-Wall" true true false)
endif () endif ()
EnableCompilerFlag("-Wextra" true true) EnableCompilerFlag("-Wextra" true true false)
EnableCompilerFlag("-Wundef" true true) EnableCompilerFlag("-Wundef" true true false)
EnableCompilerFlag("-Wshadow" true true) EnableCompilerFlag("-Wshadow" true true false)
EnableCompilerFlag("-Wcast-align" true true) EnableCompilerFlag("-Wcast-align" true true false)
EnableCompilerFlag("-Wcast-qual" true true) EnableCompilerFlag("-Wcast-qual" true true false)
EnableCompilerFlag("-Wstrict-prototypes" true false) EnableCompilerFlag("-Wstrict-prototypes" true false false)
# Enable asserts in Debug mode # Enable asserts in Debug mode
if (CMAKE_BUILD_TYPE MATCHES "Debug") if (CMAKE_BUILD_TYPE MATCHES "Debug")
EnableCompilerFlag("-DDEBUGLEVEL=1" true true) EnableCompilerFlag("-DDEBUGLEVEL=1" true true false)
endif () endif ()
# Add noexecstack flags
# LDFLAGS
EnableCompilerFlag("-z noexecstack" false false true)
# CFLAGS & CXXFLAGS
EnableCompilerFlag("-Qunused-arguments" true true false)
EnableCompilerFlag("-Wa,--noexecstack" true true false)
elseif (MSVC) # Add specific compilation flags for Windows Visual elseif (MSVC) # Add specific compilation flags for Windows Visual
set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)") set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)")
if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION) if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION)
EnableCompilerFlag("/MP" true true) EnableCompilerFlag("/MP" true true false)
endif () endif ()
# UNICODE SUPPORT # UNICODE SUPPORT
EnableCompilerFlag("/D_UNICODE" true true) EnableCompilerFlag("/D_UNICODE" true true false)
EnableCompilerFlag("/DUNICODE" true true) EnableCompilerFlag("/DUNICODE" true true false)
# Enable asserts in Debug mode # Enable asserts in Debug mode
if (CMAKE_BUILD_TYPE MATCHES "Debug") if (CMAKE_BUILD_TYPE MATCHES "Debug")
EnableCompilerFlag("/DDEBUGLEVEL=1" true true) EnableCompilerFlag("/DDEBUGLEVEL=1" true true false)
endif () endif ()
endif () endif ()
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2015-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2016-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+7 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2015-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -77,6 +77,12 @@ if (MSVC)
set(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc) set(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc)
endif () endif ()
# Explicitly set the language to C for all files, including ASM files.
# Our assembly expects to be compiled by a C compiler, and is only enabled for
# __GNUC__ compatible compilers. Otherwise all the ASM code is disabled by
# macros.
set_source_files_properties(${Sources} PROPERTIES LANGUAGE C)
# Split project to static and shared libraries build # Split project to static and shared libraries build
set(library_targets) set(library_targets)
if (ZSTD_BUILD_SHARED) if (ZSTD_BUILD_SHARED)
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2015-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+5 -4
View File
@@ -1,6 +1,6 @@
# ################################################################ # ################################################################
# zstd - Makefile # zstd - Makefile
# Copyright (C) Yann Collet 2014-present # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# BSD license # BSD license
@@ -81,7 +81,7 @@ add_test(NAME fuzzer COMMAND fuzzer ${ZSTD_FUZZER_FLAGS})
# #
# zstreamtest # zstreamtest
# #
add_executable(zstreamtest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/seqgen.c ${TESTS_DIR}/zstreamtest.c) add_executable(zstreamtest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/seqgen.c ${TESTS_DIR}/zstreamtest.c ${TESTS_DIR}/external_matchfinder.c)
if (NOT MSVC) if (NOT MSVC)
target_compile_options(zstreamtest PRIVATE "-Wno-deprecated-declarations") target_compile_options(zstreamtest PRIVATE "-Wno-deprecated-declarations")
endif() endif()
@@ -96,13 +96,14 @@ add_test(NAME zstreamtest COMMAND zstreamtest ${ZSTD_ZSTREAM_FLAGS})
AddTestFlagsOption(ZSTD_PLAYTESTS_FLAGS "$ENV{PLAYTESTS_FLAGS}" AddTestFlagsOption(ZSTD_PLAYTESTS_FLAGS "$ENV{PLAYTESTS_FLAGS}"
"Semicolon-separated list of flags to pass to the playTests.sh test") "Semicolon-separated list of flags to pass to the playTests.sh test")
add_test(NAME playTests COMMAND sh -c "\"${TESTS_DIR}/playTests.sh\" ${ZSTD_PLAYTESTS_FLAGS}") add_test(NAME playTests COMMAND sh -c "\"${TESTS_DIR}/playTests.sh\" ${ZSTD_PLAYTESTS_FLAGS}")
if (ZSTD_BUILD_PROGRAMS) find_program(UNAME uname) # Run script only in unix shell environments
if (ZSTD_BUILD_PROGRAMS AND UNAME)
set_property(TEST playTests APPEND PROPERTY ENVIRONMENT set_property(TEST playTests APPEND PROPERTY ENVIRONMENT
"ZSTD_BIN=$<TARGET_FILE:zstd>" "ZSTD_BIN=$<TARGET_FILE:zstd>"
"DATAGEN_BIN=$<TARGET_FILE:datagen>" "DATAGEN_BIN=$<TARGET_FILE:datagen>"
) )
else() else()
message(STATUS "Disabling playTests.sh test because ZSTD_BUILD_PROGRAMS is not enabled") message(STATUS "Disabling playTests.sh test because requirements not met")
set_tests_properties(playTests PROPERTIES DISABLED YES) set_tests_properties(playTests PROPERTIES DISABLED YES)
endif() endif()
+39 -16
View File
@@ -21,7 +21,6 @@ FUZZER_FLAGS = ['--no-big-tests']
FUZZERTEST = '-T200s' FUZZERTEST = '-T200s'
ZSTREAM_TESTTIME = '-T90s' ZSTREAM_TESTTIME = '-T90s'
DECODECORPUS_TESTTIME = '-T30' DECODECORPUS_TESTTIME = '-T30'
ZSTDRTTEST = ['--test-large-data']
# ============================================================================= # =============================================================================
# Executables # Executables
@@ -66,8 +65,10 @@ fuzzer = executable('fuzzer',
dependencies: [ testcommon_dep, thread_dep ], dependencies: [ testcommon_dep, thread_dep ],
install: false) install: false)
zstreamtest_sources = [join_paths(zstd_rootdir, 'tests/seqgen.c'), zstreamtest_sources = [
join_paths(zstd_rootdir, 'tests/zstreamtest.c')] join_paths(zstd_rootdir, 'tests/seqgen.c'),
join_paths(zstd_rootdir, 'tests/zstreamtest.c'),
join_paths(zstd_rootdir, 'tests/external_matchfinder.c')]
zstreamtest = executable('zstreamtest', zstreamtest = executable('zstreamtest',
zstreamtest_sources, zstreamtest_sources,
include_directories: test_includes, include_directories: test_includes,
@@ -134,24 +135,38 @@ checkTag = executable('checkTag',
# ============================================================================= # =============================================================================
if tests_supported_oses.contains(host_machine_os) if tests_supported_oses.contains(host_machine_os)
valgrind_prog = find_program('valgrind', ['/usr/bin/valgrind'], required: true) valgrind_prog = find_program('valgrind', ['/usr/bin/valgrind'], required: false)
valgrindTest_py = files('valgrindTest.py') valgrindTest_py = files('valgrindTest.py')
test('valgrindTest', if valgrind_prog.found()
valgrindTest_py, test('valgrindTest',
args: [valgrind_prog.path(), zstd, datagen, fuzzer, fullbench], valgrindTest_py,
depends: [zstd, datagen, fuzzer, fullbench], args: [valgrind_prog.path(), zstd, datagen, fuzzer, fullbench],
timeout: 600) # Timeout should work on HDD drive depends: [zstd, datagen, fuzzer, fullbench],
timeout: 600) # Timeout should work on HDD drive
endif
endif endif
if host_machine_os != os_windows if host_machine_os != os_windows
playTests_sh = find_program(join_paths(zstd_rootdir, 'tests/playTests.sh'), required: true) playTests_sh = find_program(join_paths(zstd_rootdir, 'tests/playTests.sh'), required: true)
test('test-zstd',
playTests_sh, # add slow tests only if the meson version is new enough to support
args: ZSTDRTTEST, # test setups with default-excluded suites
env: ['ZSTD_BIN=' + zstd.full_path(), 'DATAGEN_BIN=./datagen'], if meson.version().version_compare('>=0.57.0')
depends: [datagen], matrix = {'fast': [], 'slow': ['--test-large-data']}
workdir: meson.current_build_dir(), else
timeout: 2800) # Timeout should work on HDD drive matrix = {'fast': []}
endif
foreach suite, opt: matrix
test('test-zstd-'+suite,
playTests_sh,
args: opt,
env: ['ZSTD_BIN=' + zstd.full_path(), 'DATAGEN_BIN=./datagen'],
depends: [datagen],
suite: suite,
workdir: meson.current_build_dir(),
timeout: 2800) # Timeout should work on HDD drive
endforeach
endif endif
test('test-fullbench-1', test('test-fullbench-1',
@@ -190,3 +205,11 @@ test('test-decodecorpus',
args: ['-t', DECODECORPUS_TESTTIME], args: ['-t', DECODECORPUS_TESTTIME],
timeout: 60) timeout: 60)
test('test-poolTests', poolTests) # should be fast test('test-poolTests', poolTests) # should be fast
if meson.version().version_compare('>=0.57.0')
add_test_setup('fast',
is_default: true,
exclude_suites: ['slow'])
add_test_setup('slow',
exclude_suites: ['fast'])
endif
+1 -1
View File
@@ -8,7 +8,7 @@
* \endcode * \endcode
*/ */
/* /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -8,7 +8,7 @@
* \endcode * \endcode
*/ */
/* /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2019-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+2
View File
@@ -0,0 +1,2 @@
# build artifacts
externalMatchfinder
+40
View File
@@ -0,0 +1,40 @@
# ################################################################
# Copyright (c) Yann Collet, Meta Platforms, Inc.
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# ################################################################
PROGDIR = ../../programs
LIBDIR = ../../lib
LIBZSTD = $(LIBDIR)/libzstd.a
CPPFLAGS+= -I$(LIBDIR) -I$(LIBDIR)/compress -I$(LIBDIR)/common
CFLAGS ?= -O3
CFLAGS += -std=gnu99
DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wstrict-aliasing=1 -Wswitch-enum \
-Wstrict-prototypes -Wundef -Wpointer-arith \
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
-Wredundant-decls
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
default: externalMatchfinder
all: externalMatchfinder
externalMatchfinder: matchfinder.c main.c $(LIBZSTD)
$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@
.PHONY: $(LIBZSTD)
$(LIBZSTD):
$(MAKE) -C $(LIBDIR) libzstd.a CFLAGS="$(CFLAGS)"
clean:
$(RM) *.o
$(MAKE) -C $(LIBDIR) clean > /dev/null
$(RM) externalMatchfinder
+14
View File
@@ -0,0 +1,14 @@
externalMatchfinder
=====================
`externalMatchfinder` is a test tool for the external matchfinder API.
It demonstrates how to use the API to perform a simple round-trip test.
A sample matchfinder is provided in matchfinder.c, but the user can swap
this out with a different one if desired. The sample matchfinder implements
LZ compression with a 1KB hashtable. Dictionary compression is not currently supported.
Command line :
```
externalMatchfinder filename
```
+107
View File
@@ -0,0 +1,107 @@
/*
* Copyright (c) Yann Collet, Meta Platforms, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h"
#include "zstd_errors.h"
#include "matchfinder.h" // simpleExternalMatchFinder
#define CHECK(res) \
do { \
if (ZSTD_isError(res)) { \
printf("ERROR: %s\n", ZSTD_getErrorName(res)); \
return 1; \
} \
} while (0) \
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: exampleMatchfinder <file>\n");
return 1;
}
ZSTD_CCtx* const zc = ZSTD_createCCtx();
int simpleExternalMatchState = 0xdeadbeef;
// Here is the crucial bit of code!
ZSTD_registerExternalMatchFinder(
zc,
&simpleExternalMatchState,
simpleExternalMatchFinder
);
{
size_t const res = ZSTD_CCtx_setParameter(zc, ZSTD_c_enableMatchFinderFallback, 1);
CHECK(res);
}
FILE *f = fopen(argv[1], "rb");
assert(f);
{
int const ret = fseek(f, 0, SEEK_END);
assert(ret == 0);
}
size_t const srcSize = ftell(f);
{
int const ret = fseek(f, 0, SEEK_SET);
assert(ret == 0);
}
char* const src = malloc(srcSize + 1);
assert(src);
{
size_t const ret = fread(src, srcSize, 1, f);
assert(ret == 1);
int const ret2 = fclose(f);
assert(ret2 == 0);
}
size_t const dstSize = ZSTD_compressBound(srcSize);
char* const dst = malloc(dstSize);
assert(dst);
size_t const cSize = ZSTD_compress2(zc, dst, dstSize, src, srcSize);
CHECK(cSize);
char* const val = malloc(srcSize);
assert(val);
{
size_t const res = ZSTD_decompress(val, srcSize, dst, cSize);
CHECK(res);
}
if (memcmp(src, val, srcSize) == 0) {
printf("Compression and decompression were successful!\n");
printf("Original size: %lu\n", srcSize);
printf("Compressed size: %lu\n", cSize);
} else {
printf("ERROR: input and validation buffers don't match!\n");
for (size_t i = 0; i < srcSize; i++) {
if (src[i] != val[i]) {
printf("First bad index: %zu\n", i);
break;
}
}
return 1;
}
ZSTD_freeCCtx(zc);
free(src);
free(dst);
free(val);
return 0;
}
+80
View File
@@ -0,0 +1,80 @@
/*
* Copyright (c) Yann Collet, Meta Platforms, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
#include "zstd_compress_internal.h"
#include "matchfinder.h"
#define HSIZE 1024
static U32 const HLOG = 10;
static U32 const MLS = 4;
static U32 const BADIDX = 0xffffffff;
size_t simpleExternalMatchFinder(
void* externalMatchState,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize,
const void* dict, size_t dictSize,
int compressionLevel,
size_t windowSize
) {
const BYTE* const istart = (const BYTE*)src;
const BYTE* const iend = istart + srcSize;
const BYTE* ip = istart;
const BYTE* anchor = istart;
size_t seqCount = 0;
U32 hashTable[HSIZE];
(void)externalMatchState;
(void)dict;
(void)dictSize;
(void)outSeqsCapacity;
(void)compressionLevel;
{ int i;
for (i=0; i < HSIZE; i++) {
hashTable[i] = BADIDX;
} }
while (ip + MLS < iend) {
size_t const hash = ZSTD_hashPtr(ip, HLOG, MLS);
U32 const matchIndex = hashTable[hash];
hashTable[hash] = (U32)(ip - istart);
if (matchIndex != BADIDX) {
const BYTE* const match = istart + matchIndex;
U32 const matchLen = (U32)ZSTD_count(ip, match, iend);
if (matchLen >= ZSTD_MINMATCH_MIN) {
U32 const litLen = (U32)(ip - anchor);
U32 const offset = (U32)(ip - match);
ZSTD_Sequence const seq = {
offset, litLen, matchLen, 0
};
/* Note: it's crucial to stay within the window size! */
if (offset <= windowSize) {
outSeqs[seqCount++] = seq;
ip += matchLen;
anchor = ip;
continue;
}
}
}
ip++;
}
{ ZSTD_Sequence const finalSeq = {
0, (U32)(iend - anchor), 0, 0
};
outSeqs[seqCount++] = finalSeq;
}
return seqCount;
}
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright (c) Yann Collet, Meta Platforms, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
#ifndef MATCHFINDER_H
#define MATCHFINDER_H
#define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h"
size_t simpleExternalMatchFinder(
void* externalMatchState,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize,
const void* dict, size_t dictSize,
int compressionLevel,
size_t windowSize
);
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# ################################################################ # ################################################################
# Copyright (c) 2021-2021, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2016-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2018-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-present, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -856,7 +856,7 @@ int bench(const char **fileNameTable, unsigned nbFiles, const char *dictionary,
CONTROL(cTotalSizeNoDict != 0); CONTROL(cTotalSizeNoDict != 0);
DISPLAYLEVEL(3, "compressing at level %u without dictionary : Ratio=%.2f (%u bytes) \n", DISPLAYLEVEL(3, "compressing at level %u without dictionary : Ratio=%.2f (%u bytes) \n",
clevel, clevel,
(double)totalSrcSlicesSize / cTotalSizeNoDict, (unsigned)cTotalSizeNoDict); (double)totalSrcSlicesSize / (double)cTotalSizeNoDict, (unsigned)cTotalSizeNoDict);
size_t* const cSizes = malloc(nbBlocks * sizeof(size_t)); size_t* const cSizes = malloc(nbBlocks * sizeof(size_t));
CONTROL(cSizes != NULL); CONTROL(cSizes != NULL);
@@ -865,7 +865,7 @@ int bench(const char **fileNameTable, unsigned nbFiles, const char *dictionary,
CONTROL(cTotalSize != 0); CONTROL(cTotalSize != 0);
DISPLAYLEVEL(3, "compressed using a %u bytes dictionary : Ratio=%.2f (%u bytes) \n", DISPLAYLEVEL(3, "compressed using a %u bytes dictionary : Ratio=%.2f (%u bytes) \n",
(unsigned)dictBuffer.size, (unsigned)dictBuffer.size,
(double)totalSrcSlicesSize / cTotalSize, (unsigned)cTotalSize); (double)totalSrcSlicesSize / (double)cTotalSize, (unsigned)cTotalSize);
/* now dstSlices contain the real compressed size of each block, instead of the maximum capacity */ /* now dstSlices contain the real compressed size of each block, instead of the maximum capacity */
shrinkSizes(dstSlices, cSizes); shrinkSizes(dstSlices, cSizes);
+3 -3
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -49,8 +49,8 @@ libzstd:
-UZSTD_MULTITHREAD \ -UZSTD_MULTITHREAD \
-U_MSC_VER \ -U_MSC_VER \
-U_WIN32 \ -U_WIN32 \
-RZSTDLIB_VISIBILITY= \ -RZSTDLIB_VISIBLE= \
-RZSTDERRORLIB_VISIBILITY= \ -RZSTDERRORLIB_VISIBLE= \
-RZSTD_FALLTHROUGH=fallthrough \ -RZSTD_FALLTHROUGH=fallthrough \
-DZSTD_HAVE_WEAK_SYMBOLS=0 \ -DZSTD_HAVE_WEAK_SYMBOLS=0 \
-DZSTD_TRACE=0 \ -DZSTD_TRACE=0 \
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause # SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2016-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+9 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -10,11 +10,13 @@
#include "Pzstd.h" #include "Pzstd.h"
#include "SkippableFrame.h" #include "SkippableFrame.h"
#include "utils/FileSystem.h" #include "utils/FileSystem.h"
#include "utils/Portability.h"
#include "utils/Range.h" #include "utils/Range.h"
#include "utils/ScopeGuard.h" #include "utils/ScopeGuard.h"
#include "utils/ThreadPool.h" #include "utils/ThreadPool.h"
#include "utils/WorkQueue.h" #include "utils/WorkQueue.h"
#include <algorithm>
#include <chrono> #include <chrono>
#include <cinttypes> #include <cinttypes>
#include <cstddef> #include <cstddef>
@@ -336,6 +338,10 @@ static size_t calculateStep(
const ZSTD_parameters &params) { const ZSTD_parameters &params) {
(void)size; (void)size;
(void)numThreads; (void)numThreads;
// Not validated to work correctly for window logs > 23.
// It will definitely fail if windowLog + 2 is >= 4GB because
// the skippable frame can only store sizes up to 4GB.
assert(params.cParams.windowLog <= 23);
return size_t{1} << (params.cParams.windowLog + 2); return size_t{1} << (params.cParams.windowLog + 2);
} }
@@ -587,7 +593,8 @@ std::uint64_t writeFile(
// start writing before compression is done because we need to know the // start writing before compression is done because we need to know the
// compressed size. // compressed size.
// Wait for the compressed size to be available and write skippable frame // Wait for the compressed size to be available and write skippable frame
SkippableFrame frame(out->size()); assert(uint64_t(out->size()) < uint64_t(1) << 32);
SkippableFrame frame(uint32_t(out->size()));
if (!writeData(frame.data(), outputFd)) { if (!writeData(frame.data(), outputFd)) {
errorHolder.setError("Failed to write output"); errorHolder.setError("Failed to write output");
return bytesWritten; return bytesWritten;
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+5 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -8,11 +8,13 @@
*/ */
#pragma once #pragma once
#include "utils/Portability.h"
#include "utils/Range.h" #include "utils/Range.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <cerrno> #include <cerrno>
#include <cstdint> #include <cstdint>
#include <limits>
#include <system_error> #include <system_error>
// A small subset of `std::filesystem`. // A small subset of `std::filesystem`.
@@ -82,11 +84,11 @@ inline std::uintmax_t file_size(
std::error_code& ec) noexcept { std::error_code& ec) noexcept {
auto stat = status(path, ec); auto stat = status(path, ec);
if (ec) { if (ec) {
return -1; return std::numeric_limits<uintmax_t>::max();
} }
if (!is_regular_file(stat)) { if (!is_regular_file(stat)) {
ec.assign(ENOTSUP, std::generic_category()); ec.assign(ENOTSUP, std::generic_category());
return -1; return std::numeric_limits<uintmax_t>::max();
} }
ec.clear(); ec.clear();
return stat.st_size; return stat.st_size;
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
*/
#pragma once
#include <algorithm>
// Required for windows, which defines min/max, but we want the std:: version.
#undef min
#undef max
+3 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -14,7 +14,9 @@
#pragma once #pragma once
#include "utils/Likely.h" #include "utils/Likely.h"
#include "utils/Portability.h"
#include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2019-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2017-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2017-present, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -2,7 +2,7 @@
### Notices ### Notices
Copyright (c) 2017-present Facebook, Inc. Copyright (c) Meta Platforms, Inc. and affiliates.
Permission is granted to copy and distribute this document Permission is granted to copy and distribute this document
for any purpose and without charge, for any purpose and without charge,
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-present, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) 2018-present, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+20 -6
View File
@@ -3,7 +3,7 @@ Zstandard Compression Format
### Notices ### Notices
Copyright (c) 2016-2021 Yann Collet, Facebook, Inc. Copyright (c) Meta Platforms, Inc. and affiliates.
Permission is granted to copy and distribute this document Permission is granted to copy and distribute this document
for any purpose and without charge, for any purpose and without charge,
@@ -435,7 +435,7 @@ They can be decoded first, and then copied during [Sequence Execution],
or they can be decoded on the flow during [Sequence Execution]. or they can be decoded on the flow during [Sequence Execution].
Literals can be stored uncompressed or compressed using Huffman prefix codes. Literals can be stored uncompressed or compressed using Huffman prefix codes.
When compressed, an optional tree description can be present, When compressed, a tree description may optionally be present,
followed by 1 or 4 streams. followed by 1 or 4 streams.
| `Literals_Section_Header` | [`Huffman_Tree_Description`] | [jumpTable] | Stream1 | [Stream2] | [Stream3] | [Stream4] | | `Literals_Section_Header` | [`Huffman_Tree_Description`] | [jumpTable] | Stream1 | [Stream2] | [Stream3] | [Stream4] |
@@ -510,7 +510,7 @@ Its value is : `Size_Format = (Literals_Section_Header[0]>>2) & 3`
`Regenerated_Size = (Literals_Section_Header[0]>>4) + (Literals_Section_Header[1]<<4) + (Literals_Section_Header[2]<<12)` `Regenerated_Size = (Literals_Section_Header[0]>>4) + (Literals_Section_Header[1]<<4) + (Literals_Section_Header[2]<<12)`
Only Stream1 is present for these cases. Only Stream1 is present for these cases.
Note : it's allowed to represent a short value (for example `13`) Note : it's allowed to represent a short value (for example `27`)
using a long format, even if it's less efficient. using a long format, even if it's less efficient.
__`Size_Format` for `Compressed_Literals_Block` and `Treeless_Literals_Block`__ : __`Size_Format` for `Compressed_Literals_Block` and `Treeless_Literals_Block`__ :
@@ -521,19 +521,33 @@ __`Size_Format` for `Compressed_Literals_Block` and `Treeless_Literals_Block`__
Both `Regenerated_Size` and `Compressed_Size` use 10 bits (0-1023). Both `Regenerated_Size` and `Compressed_Size` use 10 bits (0-1023).
`Literals_Section_Header` uses 3 bytes. `Literals_Section_Header` uses 3 bytes.
- `Size_Format` == 01 : 4 streams. - `Size_Format` == 01 : 4 streams.
Both `Regenerated_Size` and `Compressed_Size` use 10 bits (0-1023). Both `Regenerated_Size` and `Compressed_Size` use 10 bits (6-1023).
`Literals_Section_Header` uses 3 bytes. `Literals_Section_Header` uses 3 bytes.
- `Size_Format` == 10 : 4 streams. - `Size_Format` == 10 : 4 streams.
Both `Regenerated_Size` and `Compressed_Size` use 14 bits (0-16383). Both `Regenerated_Size` and `Compressed_Size` use 14 bits (6-16383).
`Literals_Section_Header` uses 4 bytes. `Literals_Section_Header` uses 4 bytes.
- `Size_Format` == 11 : 4 streams. - `Size_Format` == 11 : 4 streams.
Both `Regenerated_Size` and `Compressed_Size` use 18 bits (0-262143). Both `Regenerated_Size` and `Compressed_Size` use 18 bits (6-262143).
`Literals_Section_Header` uses 5 bytes. `Literals_Section_Header` uses 5 bytes.
Both `Compressed_Size` and `Regenerated_Size` fields follow __little-endian__ convention. Both `Compressed_Size` and `Regenerated_Size` fields follow __little-endian__ convention.
Note: `Compressed_Size` __includes__ the size of the Huffman Tree description Note: `Compressed_Size` __includes__ the size of the Huffman Tree description
_when_ it is present. _when_ it is present.
4 streams is superior to 1 stream in decompression speed,
by exploiting instruction level parallelism.
But it's also more expensive,
costing on average ~7.3 bytes more than the 1 stream mode, mostly from the jump table.
In general, use the 4 streams mode when there are more literals to decode,
to favor higher decompression speeds.
Beyond 1KB, the 4 streams mode is compulsory anyway.
Note that a minimum of 6 bytes is required for the 4 streams mode.
That's a technical minimum, but it's not recommended to employ the 4 streams mode
for such a small quantity, that would be wasteful.
A more practical lower bound would be around ~256 bytes.
#### Raw Literals Block #### Raw Literals Block
The data in Stream1 is `Regenerated_Size` bytes long, The data in Stream1 is `Regenerated_Size` bytes long,
it contains the raw literals data to be used during [Sequence Execution]. it contains the raw literals data to be used during [Sequence Execution].
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Martin Liska, SUSE, Facebook, Inc. * Copyright (c) Martin Liska, SUSE, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+7
View File
@@ -161,6 +161,13 @@ The file structure is designed to make this selection manually achievable for an
`ZSTD_DCtx` decompression contexts, `ZSTD_DCtx` decompression contexts,
but might also result in a small decompression speed cost. but might also result in a small decompression speed cost.
- The C compiler macros `ZSTDLIB_VISIBLE`, `ZSTDERRORLIB_VISIBLE` and `ZDICTLIB_VISIBLE`
can be overridden to control the visibility of zstd's API. Additionally,
`ZSTDLIB_STATIC_API` and `ZDICTLIB_STATIC_API` can be overridden to control the visibility
of zstd's static API. Specifically, it can be set to `ZSTDLIB_HIDDEN` to hide the symbols
from the shared library. These macros default to `ZSTDLIB_VISIBILITY`,
`ZSTDERRORLIB_VSIBILITY`, and `ZDICTLIB_VISIBILITY` if unset, for backwards compatibility
with the old macro names.
#### Windows : using MinGW+MSYS to create DLL #### Windows : using MinGW+MSYS to create DLL
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* bitstream * bitstream
* Part of FSE library * Part of FSE library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* debug * debug
* Part of FSE library * Part of FSE library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+1 -1
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* debug * debug
* Part of FSE library * Part of FSE library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+1 -1
View File
@@ -1,6 +1,6 @@
/* ****************************************************************** /* ******************************************************************
* Common functions of New Generation Entropy library * Common functions of New Generation Entropy library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+4 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -29,7 +29,9 @@ const char* ERR_getErrorString(ERR_enum code)
case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding";
case PREFIX(corruption_detected): return "Data corruption detected"; case PREFIX(corruption_detected): return "Data corruption detected";
case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
case PREFIX(literals_headerWrong): return "Header of Literals' block doesn't respect format specification";
case PREFIX(parameter_unsupported): return "Unsupported parameter"; case PREFIX(parameter_unsupported): return "Unsupported parameter";
case PREFIX(parameter_combination_unsupported): return "Unsupported combination of parameters";
case PREFIX(parameter_outOfBound): return "Parameter is out of bound"; case PREFIX(parameter_outOfBound): return "Parameter is out of bound";
case PREFIX(init_missing): return "Context should be init first"; case PREFIX(init_missing): return "Context should be init first";
case PREFIX(memory_allocation): return "Allocation error : not enough memory"; case PREFIX(memory_allocation): return "Allocation error : not enough memory";
@@ -50,6 +52,7 @@ const char* ERR_getErrorString(ERR_enum code)
case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";
case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong"; case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; case PREFIX(srcBuffer_wrong): return "Source buffer is wrong";
case PREFIX(externalMatchFinder_failed): return "External matchfinder returned an error code";
case PREFIX(maxCode): case PREFIX(maxCode):
default: return notErrorCode; default: return notErrorCode;
} }
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* FSE : Finite State Entropy codec * FSE : Finite State Entropy codec
* Public Prototypes declaration * Public Prototypes declaration
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+1 -1
View File
@@ -1,6 +1,6 @@
/* ****************************************************************** /* ******************************************************************
* FSE : Finite State Entropy decoder * FSE : Finite State Entropy decoder
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+5 -3
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* huff0 huffman codec, * huff0 huffman codec,
* part of Finite State Entropy library * part of Finite State Entropy library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -88,8 +88,10 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,
unsigned maxSymbolValue, unsigned tableLog); unsigned maxSymbolValue, unsigned tableLog);
/** HUF_compress4X_wksp() : /** HUF_compress4X_wksp() :
* Same as HUF_compress2(), but uses externally allocated `workSpace`. * Same as HUF_compress2(), but uses externally allocated @workSpace.
* `workspace` must be at least as large as HUF_WORKSPACE_SIZE */ * @workSpace's size, aka @wkspSize, must be >= HUF_WORKSPACE_SIZE
* @srcSize must be >= 6
*/
#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */) #define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */)
#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) #define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64))
HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -173,7 +173,7 @@ static void POOL_join(POOL_ctx* ctx) {
/* Join all of the threads */ /* Join all of the threads */
{ size_t i; { size_t i;
for (i = 0; i < ctx->threadCapacity; ++i) { for (i = 0; i < ctx->threadCapacity; ++i) {
ZSTD_pthread_join(ctx->threads[i], NULL); /* note : could fail */ ZSTD_pthread_join(ctx->threads[i]); /* note : could fail */
} } } }
} }
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+66 -13
View File
@@ -34,39 +34,92 @@ int g_ZSTD_threading_useless_symbol;
/* === Implementation === */ /* === Implementation === */
typedef struct {
void* (*start_routine)(void*);
void* arg;
int initialized;
ZSTD_pthread_cond_t initialized_cond;
ZSTD_pthread_mutex_t initialized_mutex;
} ZSTD_thread_params_t;
static unsigned __stdcall worker(void *arg) static unsigned __stdcall worker(void *arg)
{ {
ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg; void* (*start_routine)(void*);
thread->arg = thread->start_routine(thread->arg); void* thread_arg;
/* Inialized thread_arg and start_routine and signal main thread that we don't need it
* to wait any longer.
*/
{
ZSTD_thread_params_t* thread_param = (ZSTD_thread_params_t*)arg;
thread_arg = thread_param->arg;
start_routine = thread_param->start_routine;
/* Signal main thread that we are running and do not depend on its memory anymore */
ZSTD_pthread_mutex_lock(&thread_param->initialized_mutex);
thread_param->initialized = 1;
ZSTD_pthread_cond_signal(&thread_param->initialized_cond);
ZSTD_pthread_mutex_unlock(&thread_param->initialized_mutex);
}
start_routine(thread_arg);
return 0; return 0;
} }
int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
void* (*start_routine) (void*), void* arg) void* (*start_routine) (void*), void* arg)
{ {
ZSTD_thread_params_t thread_param;
(void)unused; (void)unused;
thread->arg = arg;
thread->start_routine = start_routine;
thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
if (!thread->handle) thread_param.start_routine = start_routine;
thread_param.arg = arg;
thread_param.initialized = 0;
*thread = NULL;
/* Setup thread initialization synchronization */
if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {
/* Should never happen on Windows */
return -1;
}
if(ZSTD_pthread_mutex_init(&thread_param.initialized_mutex, NULL)) {
/* Should never happen on Windows */
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
return -1;
}
/* Spawn thread */
*thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);
if (!thread) {
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
return errno; return errno;
else }
return 0;
/* Wait for thread to be initialized */
ZSTD_pthread_mutex_lock(&thread_param.initialized_mutex);
while(!thread_param.initialized) {
ZSTD_pthread_cond_wait(&thread_param.initialized_cond, &thread_param.initialized_mutex);
}
ZSTD_pthread_mutex_unlock(&thread_param.initialized_mutex);
ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
return 0;
} }
int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr) int ZSTD_pthread_join(ZSTD_pthread_t thread)
{ {
DWORD result; DWORD result;
if (!thread.handle) return 0; if (!thread) return 0;
result = WaitForSingleObject(thread.handle, INFINITE); result = WaitForSingleObject(thread, INFINITE);
CloseHandle(thread.handle); CloseHandle(thread);
switch (result) { switch (result) {
case WAIT_OBJECT_0: case WAIT_OBJECT_0:
if (value_ptr) *value_ptr = thread.arg;
return 0; return 0;
case WAIT_ABANDONED: case WAIT_ABANDONED:
return EINVAL; return EINVAL;
+4 -8
View File
@@ -61,16 +61,12 @@ extern "C" {
#define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a)) #define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a))
/* ZSTD_pthread_create() and ZSTD_pthread_join() */ /* ZSTD_pthread_create() and ZSTD_pthread_join() */
typedef struct { typedef HANDLE ZSTD_pthread_t;
HANDLE handle;
void* (*start_routine)(void*);
void* arg;
} ZSTD_pthread_t;
int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused, int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
void* (*start_routine) (void*), void* arg); void* (*start_routine) (void*), void* arg);
int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr); int ZSTD_pthread_join(ZSTD_pthread_t thread);
/** /**
* add here more wrappers as required * add here more wrappers as required
@@ -98,7 +94,7 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);
#define ZSTD_pthread_t pthread_t #define ZSTD_pthread_t pthread_t
#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d)) #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
#define ZSTD_pthread_join(a, b) pthread_join((a),(b)) #define ZSTD_pthread_join(a) pthread_join((a),NULL)
#else /* DEBUGLEVEL >= 1 */ #else /* DEBUGLEVEL >= 1 */
@@ -123,7 +119,7 @@ int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond);
#define ZSTD_pthread_t pthread_t #define ZSTD_pthread_t pthread_t
#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d)) #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
#define ZSTD_pthread_join(a, b) pthread_join((a),(b)) #define ZSTD_pthread_join(a) pthread_join((a),NULL)
#endif #endif
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* xxHash - Fast Hash algorithm * xxHash - Fast Hash algorithm
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - xxHash homepage: https://cyan4973.github.io/xxHash/ * - xxHash homepage: https://cyan4973.github.io/xxHash/
+1 -1
View File
@@ -1,6 +1,6 @@
/* /*
* xxHash - Fast Hash algorithm * xxHash - Fast Hash algorithm
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - xxHash homepage: https://cyan4973.github.io/xxHash/ * - xxHash homepage: https://cyan4973.github.io/xxHash/
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+2 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -94,6 +94,7 @@ typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */) /* for a non-null block */ #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */) /* for a non-null block */
#define MIN_LITERALS_FOR_4_STREAMS 6
typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e; typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,6 +1,6 @@
/* ****************************************************************** /* ******************************************************************
* FSE : Finite State Entropy encoder * FSE : Finite State Entropy encoder
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+1 -1
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* hist : Histogram functions * hist : Histogram functions
* part of Finite State Entropy project * part of Finite State Entropy project
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+1 -1
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* hist : Histogram functions * hist : Histogram functions
* part of Finite State Entropy project * part of Finite State Entropy project
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+36 -18
View File
@@ -1,6 +1,6 @@
/* ****************************************************************** /* ******************************************************************
* Huffman encoder, part of New Generation Entropy library * Huffman encoder, part of New Generation Entropy library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -386,7 +386,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits
/* renorm totalCost from 2^largestBits to 2^targetNbBits /* renorm totalCost from 2^largestBits to 2^targetNbBits
* note : totalCost is necessarily a multiple of baseCost */ * note : totalCost is necessarily a multiple of baseCost */
assert((totalCost & (baseCost - 1)) == 0); assert(((U32)totalCost & (baseCost - 1)) == 0);
totalCost >>= (largestBits - targetNbBits); totalCost >>= (largestBits - targetNbBits);
assert(totalCost > 0); assert(totalCost > 0);
@@ -1253,41 +1253,59 @@ unsigned HUF_minTableLog(unsigned symbolCardinality)
return minBitsSymbols; return minBitsSymbols;
} }
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace, size_t wkspSize, HUF_CElt* table, const unsigned* count, HUF_depth_mode depthMode) unsigned HUF_optimalTableLog(
unsigned maxTableLog,
size_t srcSize,
unsigned maxSymbolValue,
void* workSpace, size_t wkspSize,
HUF_CElt* table,
const unsigned* count,
HUF_depth_mode depthMode)
{ {
unsigned optLog = FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
assert(srcSize > 1); /* Not supported, RLE should be used instead */ assert(srcSize > 1); /* Not supported, RLE should be used instead */
assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables));
if (depthMode == HUF_depth_optimal) { /** Test valid depths and return optimal **/ if (depthMode != HUF_depth_optimal) {
BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp); /* cheap evaluation, based on FSE */
return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
}
{ BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp);
size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp); size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp);
size_t optSize = ((size_t) ~0);
unsigned huffLog;
size_t maxBits, hSize, newSize; size_t maxBits, hSize, newSize;
const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue); const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue);
const unsigned minTableLog = HUF_minTableLog(symbolCardinality);
size_t optSize = ((size_t) ~0) - 1;
unsigned optLog = maxTableLog, optLogGuess;
if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) return optLog; DEBUGLOG(6, "HUF_optimalTableLog: probing huf depth (srcSize=%zu)", srcSize);
for (huffLog = HUF_minTableLog(symbolCardinality); huffLog <= maxTableLog; huffLog++) { /* Search until size increases */
maxBits = HUF_buildCTable_wksp(table, count, for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) {
maxSymbolValue, huffLog, DEBUGLOG(7, "checking for huffLog=%u", optLogGuess);
workSpace, wkspSize); maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize);
if (ERR_isError(maxBits)) continue; if (ERR_isError(maxBits)) continue;
hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, if (maxBits < optLogGuess && optLogGuess > minTableLog) break;
workSpace, wkspSize);
hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize);
if (ERR_isError(hSize)) continue; if (ERR_isError(hSize)) continue;
newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize; newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize;
if (newSize > optSize + 1) {
break;
}
if (newSize < optSize) { if (newSize < optSize) {
optSize = newSize; optSize = newSize;
optLog = huffLog; optLog = optLogGuess;
} }
} }
assert(optLog <= HUF_TABLELOG_MAX);
return optLog;
} }
assert(optLog <= HUF_TABLELOG_MAX);
return optLog;
} }
/* HUF_compress_internal() : /* HUF_compress_internal() :
+478 -238
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -59,14 +59,17 @@
* Helper functions * Helper functions
***************************************/ ***************************************/
/* ZSTD_compressBound() /* ZSTD_compressBound()
* Note that the result from this function is only compatible with the "normal" * Note that the result from this function is only valid for
* full-block strategy. * the one-pass compression functions.
* When there are a lot of small blocks due to frequent flush in streaming mode * When employing the streaming mode,
* the overhead of headers can make the compressed data to be larger than the * if flushes are frequently altering the size of blocks,
* return value of ZSTD_compressBound(). * the overhead from block headers can make the compressed data larger
* than the return value of ZSTD_compressBound().
*/ */
size_t ZSTD_compressBound(size_t srcSize) { size_t ZSTD_compressBound(size_t srcSize) {
return ZSTD_COMPRESSBOUND(srcSize); size_t const r = ZSTD_COMPRESSBOUND(srcSize);
if (r==0) return ERROR(srcSize_wrong);
return r;
} }
@@ -275,6 +278,16 @@ static ZSTD_paramSwitch_e ZSTD_resolveEnableLdm(ZSTD_paramSwitch_e mode,
return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable; return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable;
} }
/* Enables validation for external sequences in debug builds. */
static int ZSTD_resolveExternalSequenceValidation(int mode) {
#if defined(DEBUGLEVEL) && (DEBUGLEVEL>=2)
(void)mode;
return 1;
#else
return mode;
#endif
}
/* Returns 1 if compression parameters are such that CDict hashtable and chaintable indices are tagged. /* Returns 1 if compression parameters are such that CDict hashtable and chaintable indices are tagged.
* If so, the tags need to be removed in ZSTD_resetCCtx_byCopyingCDict. */ * If so, the tags need to be removed in ZSTD_resetCCtx_byCopyingCDict. */
static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters* const cParams) { static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters* const cParams) {
@@ -298,6 +311,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
} }
cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams); cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams);
cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences);
assert(!ZSTD_checkCParams(cParams)); assert(!ZSTD_checkCParams(cParams));
return cctxParams; return cctxParams;
} }
@@ -343,10 +357,13 @@ size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel)
#define ZSTD_NO_CLEVEL 0 #define ZSTD_NO_CLEVEL 0
/** /**
* Initializes the cctxParams from params and compressionLevel. * Initializes `cctxParams` from `params` and `compressionLevel`.
* @param compressionLevel If params are derived from a compression level then that compression level, otherwise ZSTD_NO_CLEVEL. * @param compressionLevel If params are derived from a compression level then that compression level, otherwise ZSTD_NO_CLEVEL.
*/ */
static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_parameters const* params, int compressionLevel) static void
ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams,
const ZSTD_parameters* params,
int compressionLevel)
{ {
assert(!ZSTD_checkCParams(params->cParams)); assert(!ZSTD_checkCParams(params->cParams));
ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
@@ -359,6 +376,7 @@ static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_par
cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, &params->cParams); cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, &params->cParams);
cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, &params->cParams); cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, &params->cParams);
cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, &params->cParams); cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, &params->cParams);
cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences);
DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d", DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d",
cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter, cctxParams->ldmParams.enableLdm); cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter, cctxParams->ldmParams.enableLdm);
} }
@@ -373,7 +391,7 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete
/** /**
* Sets cctxParams' cParams and fParams from params, but otherwise leaves them alone. * Sets cctxParams' cParams and fParams from params, but otherwise leaves them alone.
* @param param Validated zstd parameters. * @param params Validated zstd parameters.
*/ */
static void ZSTD_CCtxParams_setZstdParams( static void ZSTD_CCtxParams_setZstdParams(
ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params) ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params)
@@ -581,6 +599,16 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
bounds.upperBound = (int)ZSTD_ps_disable; bounds.upperBound = (int)ZSTD_ps_disable;
return bounds; return bounds;
case ZSTD_c_enableMatchFinderFallback:
bounds.lowerBound = 0;
bounds.upperBound = 1;
return bounds;
case ZSTD_c_maxBlockSize:
bounds.lowerBound = 1;
bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
return bounds;
default: default:
bounds.error = ERROR(parameter_unsupported); bounds.error = ERROR(parameter_unsupported);
return bounds; return bounds;
@@ -646,6 +674,8 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
case ZSTD_c_useRowMatchFinder: case ZSTD_c_useRowMatchFinder:
case ZSTD_c_deterministicRefPrefix: case ZSTD_c_deterministicRefPrefix:
case ZSTD_c_prefetchCDictTables: case ZSTD_c_prefetchCDictTables:
case ZSTD_c_enableMatchFinderFallback:
case ZSTD_c_maxBlockSize:
default: default:
return 0; return 0;
} }
@@ -658,7 +688,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
if (ZSTD_isUpdateAuthorized(param)) { if (ZSTD_isUpdateAuthorized(param)) {
cctx->cParamsChanged = 1; cctx->cParamsChanged = 1;
} else { } else {
RETURN_ERROR(stage_wrong, "can only set params in ctx init stage"); RETURN_ERROR(stage_wrong, "can only set params in cctx init stage");
} } } }
switch(param) switch(param)
@@ -702,6 +732,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
case ZSTD_c_useRowMatchFinder: case ZSTD_c_useRowMatchFinder:
case ZSTD_c_deterministicRefPrefix: case ZSTD_c_deterministicRefPrefix:
case ZSTD_c_prefetchCDictTables: case ZSTD_c_prefetchCDictTables:
case ZSTD_c_enableMatchFinderFallback:
case ZSTD_c_maxBlockSize:
break; break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
@@ -793,14 +825,14 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
case ZSTD_c_forceAttachDict : { case ZSTD_c_forceAttachDict : {
const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value; const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value;
BOUNDCHECK(ZSTD_c_forceAttachDict, pref); BOUNDCHECK(ZSTD_c_forceAttachDict, (int)pref);
CCtxParams->attachDictPref = pref; CCtxParams->attachDictPref = pref;
return CCtxParams->attachDictPref; return CCtxParams->attachDictPref;
} }
case ZSTD_c_literalCompressionMode : { case ZSTD_c_literalCompressionMode : {
const ZSTD_paramSwitch_e lcm = (ZSTD_paramSwitch_e)value; const ZSTD_paramSwitch_e lcm = (ZSTD_paramSwitch_e)value;
BOUNDCHECK(ZSTD_c_literalCompressionMode, lcm); BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm);
CCtxParams->literalCompressionMode = lcm; CCtxParams->literalCompressionMode = lcm;
return CCtxParams->literalCompressionMode; return CCtxParams->literalCompressionMode;
} }
@@ -934,6 +966,16 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
CCtxParams->prefetchCDictTables = (ZSTD_paramSwitch_e)value; CCtxParams->prefetchCDictTables = (ZSTD_paramSwitch_e)value;
return CCtxParams->prefetchCDictTables; return CCtxParams->prefetchCDictTables;
case ZSTD_c_enableMatchFinderFallback:
BOUNDCHECK(ZSTD_c_enableMatchFinderFallback, value);
CCtxParams->enableMatchFinderFallback = value;
return CCtxParams->enableMatchFinderFallback;
case ZSTD_c_maxBlockSize:
BOUNDCHECK(ZSTD_c_maxBlockSize, value);
CCtxParams->maxBlockSize = value;
return CCtxParams->prefetchCDictTables;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
} }
} }
@@ -1069,6 +1111,12 @@ size_t ZSTD_CCtxParams_getParameter(
case ZSTD_c_prefetchCDictTables: case ZSTD_c_prefetchCDictTables:
*value = (int)CCtxParams->prefetchCDictTables; *value = (int)CCtxParams->prefetchCDictTables;
break; break;
case ZSTD_c_enableMatchFinderFallback:
*value = CCtxParams->enableMatchFinderFallback;
break;
case ZSTD_c_maxBlockSize:
*value = (int)CCtxParams->maxBlockSize;
break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
} }
return 0; return 0;
@@ -1095,6 +1143,21 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
return 0; return 0;
} }
size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams)
{
DEBUGLOG(4, "ZSTD_CCtx_setCParams");
assert(cctx != NULL);
if (cctx->streamStage != zcss_init) {
/* All parameters in @cparams are allowed to be updated during MT compression.
* This must be signaled, so that MT compression picks up the changes */
cctx->cParamsChanged = 1;
}
/* only update if parameters are valid */
FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), "");
cctx->requestedParams.cParams = cparams;
return 0;
}
size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
{ {
DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize); DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize);
@@ -1240,6 +1303,7 @@ size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)
RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
"Can't reset parameters only when not in init stage."); "Can't reset parameters only when not in init stage.");
ZSTD_clearAllDicts(cctx); ZSTD_clearAllDicts(cctx);
ZSTD_memset(&cctx->externalMatchCtx, 0, sizeof(cctx->externalMatchCtx));
return ZSTD_CCtxParams_reset(&cctx->requestedParams); return ZSTD_CCtxParams_reset(&cctx->requestedParams);
} }
return 0; return 0;
@@ -1482,6 +1546,13 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
return tableSpace + optSpace + slackSpace + lazyAdditionalSpace; return tableSpace + optSpace + slackSpace + lazyAdditionalSpace;
} }
/* Helper function for calculating memory requirements.
* Gives a tighter bound than ZSTD_sequenceBound() by taking minMatch into account. */
static size_t ZSTD_maxNbSeq(size_t blockSize, unsigned minMatch, int useExternalMatchFinder) {
U32 const divider = (minMatch==3 || useExternalMatchFinder) ? 3 : 4;
return blockSize / divider;
}
static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
const ZSTD_compressionParameters* cParams, const ZSTD_compressionParameters* cParams,
const ldmParams_t* ldmParams, const ldmParams_t* ldmParams,
@@ -1489,12 +1560,12 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
const ZSTD_paramSwitch_e useRowMatchFinder, const ZSTD_paramSwitch_e useRowMatchFinder,
const size_t buffInSize, const size_t buffInSize,
const size_t buffOutSize, const size_t buffOutSize,
const U64 pledgedSrcSize) const U64 pledgedSrcSize,
int useExternalMatchFinder)
{ {
size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize); size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
U32 const divider = (cParams->minMatch==3) ? 3 : 4; size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useExternalMatchFinder);
size_t const maxNbSeq = blockSize / divider;
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
+ ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef)) + ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef))
+ 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
@@ -1513,6 +1584,11 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0; size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
size_t const externalSeqSpace = useExternalMatchFinder
? ZSTD_cwksp_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
: 0;
size_t const neededSpace = size_t const neededSpace =
cctxSpace + cctxSpace +
entropySpace + entropySpace +
@@ -1521,7 +1597,8 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
ldmSeqSpace + ldmSeqSpace +
matchStateSize + matchStateSize +
tokenSpace + tokenSpace +
bufferSpace; bufferSpace +
externalSeqSpace;
DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace); DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
return neededSpace; return neededSpace;
@@ -1539,7 +1616,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
* be needed. However, we still allocate two 0-sized buffers, which can * be needed. However, we still allocate two 0-sized buffers, which can
* take space under ASAN. */ * take space under ASAN. */
return ZSTD_estimateCCtxSize_usingCCtxParams_internal( return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&cParams, &params->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN); &cParams, &params->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, params->useExternalMatchFinder);
} }
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
@@ -1600,7 +1677,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
return ZSTD_estimateCCtxSize_usingCCtxParams_internal( return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize, &cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
ZSTD_CONTENTSIZE_UNKNOWN); ZSTD_CONTENTSIZE_UNKNOWN, params->useExternalMatchFinder);
} }
} }
@@ -1883,8 +1960,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
{ size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize)); { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize));
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
U32 const divider = (params->cParams.minMatch==3) ? 3 : 4; size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, params->useExternalMatchFinder);
size_t const maxNbSeq = blockSize / divider;
size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered) size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered)
? ZSTD_compressBound(blockSize) + 1 ? ZSTD_compressBound(blockSize) + 1
: 0; : 0;
@@ -1901,7 +1977,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const neededSpace = size_t const neededSpace =
ZSTD_estimateCCtxSize_usingCCtxParams_internal( ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&params->cParams, &params->ldmParams, zc->staticSize != 0, params->useRowMatchFinder, &params->cParams, &params->ldmParams, zc->staticSize != 0, params->useRowMatchFinder,
buffInSize, buffOutSize, pledgedSrcSize); buffInSize, buffOutSize, pledgedSrcSize, params->useExternalMatchFinder);
int resizeWorkspace; int resizeWorkspace;
FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!");
@@ -2014,6 +2090,14 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->ldmState.loadedDictEnd = 0; zc->ldmState.loadedDictEnd = 0;
} }
/* reserve space for block-level external sequences */
if (params->useExternalMatchFinder) {
size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
zc->externalMatchCtx.seqBufferCapacity = maxNbExternalSeq;
zc->externalMatchCtx.seqBuffer =
(ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
}
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace)); assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace));
@@ -2493,11 +2577,13 @@ typedef struct {
* entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32) * entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32)
*/ */
static ZSTD_symbolEncodingTypeStats_t static ZSTD_symbolEncodingTypeStats_t
ZSTD_buildSequencesStatistics(seqStore_t* seqStorePtr, size_t nbSeq, ZSTD_buildSequencesStatistics(
const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy, const seqStore_t* seqStorePtr, size_t nbSeq,
BYTE* dst, const BYTE* const dstEnd, const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy,
ZSTD_strategy strategy, unsigned* countWorkspace, BYTE* dst, const BYTE* const dstEnd,
void* entropyWorkspace, size_t entropyWkspSize) { ZSTD_strategy strategy, unsigned* countWorkspace,
void* entropyWorkspace, size_t entropyWkspSize)
{
BYTE* const ostart = dst; BYTE* const ostart = dst;
const BYTE* const oend = dstEnd; const BYTE* const oend = dstEnd;
BYTE* op = ostart; BYTE* op = ostart;
@@ -2616,13 +2702,14 @@ ZSTD_buildSequencesStatistics(seqStore_t* seqStorePtr, size_t nbSeq,
*/ */
#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20 #define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20
MEM_STATIC size_t MEM_STATIC size_t
ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr, ZSTD_entropyCompressSeqStore_internal(
const ZSTD_entropyCTables_t* prevEntropy, const seqStore_t* seqStorePtr,
ZSTD_entropyCTables_t* nextEntropy, const ZSTD_entropyCTables_t* prevEntropy,
const ZSTD_CCtx_params* cctxParams, ZSTD_entropyCTables_t* nextEntropy,
void* dst, size_t dstCapacity, const ZSTD_CCtx_params* cctxParams,
void* entropyWorkspace, size_t entropyWkspSize, void* dst, size_t dstCapacity,
const int bmi2) void* entropyWorkspace, size_t entropyWkspSize,
const int bmi2)
{ {
const int longOffsets = cctxParams->cParams.windowLog >= STREAM_ACCUMULATOR_MIN; const int longOffsets = cctxParams->cParams.windowLog >= STREAM_ACCUMULATOR_MIN;
ZSTD_strategy const strategy = cctxParams->cParams.strategy; ZSTD_strategy const strategy = cctxParams->cParams.strategy;
@@ -2631,7 +2718,7 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
const seqDef* const sequences = seqStorePtr->sequencesStart; const seqDef* const sequences = seqStorePtr->sequencesStart;
const size_t nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
const BYTE* const ofCodeTable = seqStorePtr->ofCode; const BYTE* const ofCodeTable = seqStorePtr->ofCode;
const BYTE* const llCodeTable = seqStorePtr->llCode; const BYTE* const llCodeTable = seqStorePtr->llCode;
const BYTE* const mlCodeTable = seqStorePtr->mlCode; const BYTE* const mlCodeTable = seqStorePtr->mlCode;
@@ -2649,21 +2736,20 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
/* Compress literals */ /* Compress literals */
{ const BYTE* const literals = seqStorePtr->litStart; { const BYTE* const literals = seqStorePtr->litStart;
size_t const numSequences = seqStorePtr->sequences - seqStorePtr->sequencesStart; size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
size_t const numLiterals = seqStorePtr->lit - seqStorePtr->litStart; size_t const numLiterals = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
/* Base suspicion of uncompressibility on ratio of literals to sequences */ /* Base suspicion of uncompressibility on ratio of literals to sequences */
unsigned const suspectUncompressible = (numSequences == 0) || (numLiterals / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO); unsigned const suspectUncompressible = (numSequences == 0) || (numLiterals / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
size_t const litSize = (size_t)(seqStorePtr->lit - literals); size_t const litSize = (size_t)(seqStorePtr->lit - literals);
HUF_depth_mode depthMode = cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD ? HUF_depth_optimal : HUF_depth_fast;
size_t const cSize = ZSTD_compressLiterals( size_t const cSize = ZSTD_compressLiterals(
&prevEntropy->huf, &nextEntropy->huf,
cctxParams->cParams.strategy,
ZSTD_literalsCompressionIsDisabled(cctxParams),
op, dstCapacity, op, dstCapacity,
literals, litSize, literals, litSize,
entropyWorkspace, entropyWkspSize, entropyWorkspace, entropyWkspSize,
bmi2, suspectUncompressible, depthMode); &prevEntropy->huf, &nextEntropy->huf,
cctxParams->cParams.strategy,
ZSTD_literalsCompressionIsDisabled(cctxParams),
suspectUncompressible, bmi2);
FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed"); FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed");
assert(cSize <= dstCapacity); assert(cSize <= dstCapacity);
op += cSize; op += cSize;
@@ -2735,14 +2821,15 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
} }
MEM_STATIC size_t MEM_STATIC size_t
ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr, ZSTD_entropyCompressSeqStore(
const ZSTD_entropyCTables_t* prevEntropy, const seqStore_t* seqStorePtr,
ZSTD_entropyCTables_t* nextEntropy, const ZSTD_entropyCTables_t* prevEntropy,
const ZSTD_CCtx_params* cctxParams, ZSTD_entropyCTables_t* nextEntropy,
void* dst, size_t dstCapacity, const ZSTD_CCtx_params* cctxParams,
size_t srcSize, void* dst, size_t dstCapacity,
void* entropyWorkspace, size_t entropyWkspSize, size_t srcSize,
int bmi2) void* entropyWorkspace, size_t entropyWkspSize,
int bmi2)
{ {
size_t const cSize = ZSTD_entropyCompressSeqStore_internal( size_t const cSize = ZSTD_entropyCompressSeqStore_internal(
seqStorePtr, prevEntropy, nextEntropy, cctxParams, seqStorePtr, prevEntropy, nextEntropy, cctxParams,
@@ -2763,6 +2850,10 @@ ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr,
if (cSize >= maxCSize) return 0; /* block not compressed */ if (cSize >= maxCSize) return 0; /* block not compressed */
} }
DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize); DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize);
/* libzstd decoder before > v1.5.4 is not compatible with compressed blocks of size ZSTD_BLOCKSIZE_MAX exactly.
* This restriction is indirectly already fulfilled by respecting ZSTD_minGain() condition above.
*/
assert(cSize < ZSTD_BLOCKSIZE_MAX);
return cSize; return cSize;
} }
@@ -2857,6 +2948,55 @@ void ZSTD_resetSeqStore(seqStore_t* ssPtr)
ssPtr->longLengthType = ZSTD_llt_none; ssPtr->longLengthType = ZSTD_llt_none;
} }
/* ZSTD_postProcessExternalMatchFinderResult() :
* Validates and post-processes sequences obtained through the external matchfinder API:
* - Checks whether nbExternalSeqs represents an error condition.
* - Appends a block delimiter to outSeqs if one is not already present.
* See zstd.h for context regarding block delimiters.
* Returns the number of sequences after post-processing, or an error code. */
static size_t ZSTD_postProcessExternalMatchFinderResult(
ZSTD_Sequence* outSeqs, size_t nbExternalSeqs, size_t outSeqsCapacity, size_t srcSize
) {
RETURN_ERROR_IF(
nbExternalSeqs > outSeqsCapacity,
externalMatchFinder_failed,
"External matchfinder returned error code %lu",
(unsigned long)nbExternalSeqs
);
RETURN_ERROR_IF(
nbExternalSeqs == 0 && srcSize > 0,
externalMatchFinder_failed,
"External matchfinder produced zero sequences for a non-empty src buffer!"
);
if (srcSize == 0) {
ZSTD_memset(&outSeqs[0], 0, sizeof(ZSTD_Sequence));
return 1;
}
{
ZSTD_Sequence const lastSeq = outSeqs[nbExternalSeqs - 1];
/* We can return early if lastSeq is already a block delimiter. */
if (lastSeq.offset == 0 && lastSeq.matchLength == 0) {
return nbExternalSeqs;
}
/* This error condition is only possible if the external matchfinder
* produced an invalid parse, by definition of ZSTD_sequenceBound(). */
RETURN_ERROR_IF(
nbExternalSeqs == outSeqsCapacity,
externalMatchFinder_failed,
"nbExternalSeqs == outSeqsCapacity but lastSeq is not a block delimiter!"
);
/* lastSeq is not a block delimiter, so we need to append one. */
ZSTD_memset(&outSeqs[nbExternalSeqs], 0, sizeof(ZSTD_Sequence));
return nbExternalSeqs + 1;
}
}
typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e; typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e;
static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
@@ -2904,6 +3044,15 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
} }
if (zc->externSeqStore.pos < zc->externSeqStore.size) { if (zc->externSeqStore.pos < zc->externSeqStore.size) {
assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable); assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable);
/* External matchfinder + LDM is technically possible, just not implemented yet.
* We need to revisit soon and implement it. */
RETURN_ERROR_IF(
zc->appliedParams.useExternalMatchFinder,
parameter_combination_unsupported,
"Long-distance matching with external matchfinder enabled is not currently supported."
);
/* Updates ldmSeqStore.pos */ /* Updates ldmSeqStore.pos */
lastLLSize = lastLLSize =
ZSTD_ldm_blockCompress(&zc->externSeqStore, ZSTD_ldm_blockCompress(&zc->externSeqStore,
@@ -2915,6 +3064,14 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
} else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
rawSeqStore_t ldmSeqStore = kNullRawSeqStore; rawSeqStore_t ldmSeqStore = kNullRawSeqStore;
/* External matchfinder + LDM is technically possible, just not implemented yet.
* We need to revisit soon and implement it. */
RETURN_ERROR_IF(
zc->appliedParams.useExternalMatchFinder,
parameter_combination_unsupported,
"Long-distance matching with external matchfinder enabled is not currently supported."
);
ldmSeqStore.seq = zc->ldmSequences; ldmSeqStore.seq = zc->ldmSequences;
ldmSeqStore.capacity = zc->maxNbLdmSequences; ldmSeqStore.capacity = zc->maxNbLdmSequences;
/* Updates ldmSeqStore.size */ /* Updates ldmSeqStore.size */
@@ -2929,10 +3086,64 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
zc->appliedParams.useRowMatchFinder, zc->appliedParams.useRowMatchFinder,
src, srcSize); src, srcSize);
assert(ldmSeqStore.pos == ldmSeqStore.size); assert(ldmSeqStore.pos == ldmSeqStore.size);
} else { /* not long range mode */ } else if (zc->appliedParams.useExternalMatchFinder) {
assert(
zc->externalMatchCtx.seqBufferCapacity >= ZSTD_sequenceBound(srcSize)
);
assert(zc->externalMatchCtx.mFinder != NULL);
{ U32 const windowSize = (U32)1 << zc->appliedParams.cParams.windowLog;
size_t const nbExternalSeqs = (zc->externalMatchCtx.mFinder)(
zc->externalMatchCtx.mState,
zc->externalMatchCtx.seqBuffer,
zc->externalMatchCtx.seqBufferCapacity,
src, srcSize,
NULL, 0, /* dict and dictSize, currently not supported */
zc->appliedParams.compressionLevel,
windowSize
);
size_t const nbPostProcessedSeqs = ZSTD_postProcessExternalMatchFinderResult(
zc->externalMatchCtx.seqBuffer,
nbExternalSeqs,
zc->externalMatchCtx.seqBufferCapacity,
srcSize
);
/* Return early if there is no error, since we don't need to worry about last literals */
if (!ZSTD_isError(nbPostProcessedSeqs)) {
ZSTD_sequencePosition seqPos = {0,0,0};
ZSTD_copySequencesToSeqStoreExplicitBlockDelim(
zc, &seqPos, zc->externalMatchCtx.seqBuffer, nbPostProcessedSeqs, src, srcSize
);
ms->ldmSeqStore = NULL;
DEBUGLOG(5, "Copied %lu sequences from external matchfinder to internal seqStore.", (unsigned long)nbExternalSeqs);
return ZSTDbss_compress;
}
/* Propagate the error if fallback is disabled */
if (!zc->appliedParams.enableMatchFinderFallback) {
return nbPostProcessedSeqs;
}
/* Fallback to software matchfinder */
{ ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
zc->appliedParams.useRowMatchFinder,
dictMode);
ms->ldmSeqStore = NULL;
DEBUGLOG(
5,
"External matchfinder returned error code %lu. Falling back to internal matchfinder.",
(unsigned long)nbExternalSeqs
);
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
} }
} else { /* not long range mode and no external matchfinder */
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
zc->appliedParams.useRowMatchFinder, zc->appliedParams.useRowMatchFinder,
dictMode); dictMode);
assert(zc->externalMatchCtx.mFinder == NULL);
ms->ldmSeqStore = NULL; ms->ldmSeqStore = NULL;
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
} }
@@ -3055,19 +3266,17 @@ static int ZSTD_isRLE(const BYTE* src, size_t length) {
const size_t unrollMask = unrollSize - 1; const size_t unrollMask = unrollSize - 1;
const size_t prefixLength = length & unrollMask; const size_t prefixLength = length & unrollMask;
size_t i; size_t i;
size_t u;
if (length == 1) return 1; if (length == 1) return 1;
/* Check if prefix is RLE first before using unrolled loop */ /* Check if prefix is RLE first before using unrolled loop */
if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) { if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) {
return 0; return 0;
} }
for (i = prefixLength; i != length; i += unrollSize) { for (i = prefixLength; i != length; i += unrollSize) {
size_t u;
for (u = 0; u < unrollSize; u += sizeof(size_t)) { for (u = 0; u < unrollSize; u += sizeof(size_t)) {
if (MEM_readST(ip + i + u) != valueST) { if (MEM_readST(ip + i + u) != valueST) {
return 0; return 0;
} } } }
}
}
return 1; return 1;
} }
@@ -3083,7 +3292,8 @@ static int ZSTD_maybeRLE(seqStore_t const* seqStore)
return nbSeqs < 4 && nbLits < 10; return nbSeqs < 4 && nbLits < 10;
} }
static void ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs) static void
ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs)
{ {
ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock; ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock;
bs->prevCBlock = bs->nextCBlock; bs->prevCBlock = bs->nextCBlock;
@@ -3091,7 +3301,9 @@ static void ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* c
} }
/* Writes the block header */ /* Writes the block header */
static void writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock) { static void
writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock)
{
U32 const cBlockHeader = cSize == 1 ? U32 const cBlockHeader = cSize == 1 ?
lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
@@ -3104,13 +3316,16 @@ static void writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastB
* Stores literals block type (raw, rle, compressed, repeat) and * Stores literals block type (raw, rle, compressed, repeat) and
* huffman description table to hufMetadata. * huffman description table to hufMetadata.
* Requires ENTROPY_WORKSPACE_SIZE workspace * Requires ENTROPY_WORKSPACE_SIZE workspace
* @return : size of huffman description table or error code */ * @return : size of huffman description table, or an error code
static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize, */
const ZSTD_hufCTables_t* prevHuf, static size_t
ZSTD_hufCTables_t* nextHuf, ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize,
ZSTD_hufCTablesMetadata_t* hufMetadata, const ZSTD_hufCTables_t* prevHuf,
const int literalsCompressionIsDisabled, ZSTD_hufCTables_t* nextHuf,
void* workspace, size_t wkspSize, HUF_depth_mode depthMode) ZSTD_hufCTablesMetadata_t* hufMetadata,
const int literalsCompressionIsDisabled,
void* workspace, size_t wkspSize,
HUF_depth_mode depthMode)
{ {
BYTE* const wkspStart = (BYTE*)workspace; BYTE* const wkspStart = (BYTE*)workspace;
BYTE* const wkspEnd = wkspStart + wkspSize; BYTE* const wkspEnd = wkspStart + wkspSize;
@@ -3135,33 +3350,37 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi
/* small ? don't even attempt compression (speed opt) */ /* small ? don't even attempt compression (speed opt) */
#ifndef COMPRESS_LITERALS_SIZE_MIN #ifndef COMPRESS_LITERALS_SIZE_MIN
#define COMPRESS_LITERALS_SIZE_MIN 63 # define COMPRESS_LITERALS_SIZE_MIN 63 /* heuristic */
#endif #endif
{ size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
if (srcSize <= minLitSize) { if (srcSize <= minLitSize) {
DEBUGLOG(5, "set_basic - too small"); DEBUGLOG(5, "set_basic - too small");
hufMetadata->hType = set_basic; hufMetadata->hType = set_basic;
return 0; return 0;
} } }
}
/* Scan input and build symbol stats */ /* Scan input and build symbol stats */
{ size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize); { size_t const largest =
HIST_count_wksp (countWksp, &maxSymbolValue,
(const BYTE*)src, srcSize,
workspace, wkspSize);
FORWARD_IF_ERROR(largest, "HIST_count_wksp failed"); FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
if (largest == srcSize) { if (largest == srcSize) {
/* only one literal symbol */
DEBUGLOG(5, "set_rle"); DEBUGLOG(5, "set_rle");
hufMetadata->hType = set_rle; hufMetadata->hType = set_rle;
return 0; return 0;
} }
if (largest <= (srcSize >> 7)+4) { if (largest <= (srcSize >> 7)+4) {
/* heuristic: likely not compressible */
DEBUGLOG(5, "set_basic - no gain"); DEBUGLOG(5, "set_basic - no gain");
hufMetadata->hType = set_basic; hufMetadata->hType = set_basic;
return 0; return 0;
} } }
}
/* Validate the previous Huffman table */ /* Validate the previous Huffman table */
if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) { if (repeat == HUF_repeat_check
&& !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
repeat = HUF_repeat_none; repeat = HUF_repeat_none;
} }
@@ -3174,35 +3393,34 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi
nodeWksp, nodeWkspSize); nodeWksp, nodeWkspSize);
FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp"); FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
huffLog = (U32)maxBits; huffLog = (U32)maxBits;
{ /* Build and write the CTable */ }
size_t const newCSize = HUF_estimateCompressedSize( { /* Build and write the CTable */
(HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue); size_t const newCSize = HUF_estimateCompressedSize(
size_t const hSize = HUF_writeCTable_wksp( (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer), size_t const hSize = HUF_writeCTable_wksp(
(HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog, hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
nodeWksp, nodeWkspSize); (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog,
/* Check against repeating the previous CTable */ nodeWksp, nodeWkspSize);
if (repeat != HUF_repeat_none) { /* Check against repeating the previous CTable */
size_t const oldCSize = HUF_estimateCompressedSize( if (repeat != HUF_repeat_none) {
(HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue); size_t const oldCSize = HUF_estimateCompressedSize(
if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) { (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
DEBUGLOG(5, "set_repeat - smaller"); if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); DEBUGLOG(5, "set_repeat - smaller");
hufMetadata->hType = set_repeat;
return 0;
}
}
if (newCSize + hSize >= srcSize) {
DEBUGLOG(5, "set_basic - no gains");
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_basic; hufMetadata->hType = set_repeat;
return 0; return 0;
} } }
DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize); if (newCSize + hSize >= srcSize) {
hufMetadata->hType = set_compressed; DEBUGLOG(5, "set_basic - no gains");
nextHuf->repeatMode = HUF_repeat_check; ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
return hSize; hufMetadata->hType = set_basic;
return 0;
} }
DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
hufMetadata->hType = set_compressed;
nextHuf->repeatMode = HUF_repeat_check;
return hSize;
} }
} }
@@ -3212,7 +3430,8 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi
* and updates nextEntropy to the appropriate repeatMode. * and updates nextEntropy to the appropriate repeatMode.
*/ */
static ZSTD_symbolEncodingTypeStats_t static ZSTD_symbolEncodingTypeStats_t
ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) { ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy)
{
ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0}; ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0};
nextEntropy->litlength_repeatMode = FSE_repeat_none; nextEntropy->litlength_repeatMode = FSE_repeat_none;
nextEntropy->offcode_repeatMode = FSE_repeat_none; nextEntropy->offcode_repeatMode = FSE_repeat_none;
@@ -3224,16 +3443,18 @@ ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) {
* Builds entropy for the sequences. * Builds entropy for the sequences.
* Stores symbol compression modes and fse table to fseMetadata. * Stores symbol compression modes and fse table to fseMetadata.
* Requires ENTROPY_WORKSPACE_SIZE wksp. * Requires ENTROPY_WORKSPACE_SIZE wksp.
* @return : size of fse tables or error code */ * @return : size of fse tables or error code */
static size_t ZSTD_buildBlockEntropyStats_sequences(seqStore_t* seqStorePtr, static size_t
const ZSTD_fseCTables_t* prevEntropy, ZSTD_buildBlockEntropyStats_sequences(
ZSTD_fseCTables_t* nextEntropy, const seqStore_t* seqStorePtr,
const ZSTD_CCtx_params* cctxParams, const ZSTD_fseCTables_t* prevEntropy,
ZSTD_fseCTablesMetadata_t* fseMetadata, ZSTD_fseCTables_t* nextEntropy,
void* workspace, size_t wkspSize) const ZSTD_CCtx_params* cctxParams,
ZSTD_fseCTablesMetadata_t* fseMetadata,
void* workspace, size_t wkspSize)
{ {
ZSTD_strategy const strategy = cctxParams->cParams.strategy; ZSTD_strategy const strategy = cctxParams->cParams.strategy;
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
BYTE* const ostart = fseMetadata->fseTablesBuffer; BYTE* const ostart = fseMetadata->fseTablesBuffer;
BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer); BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
BYTE* op = ostart; BYTE* op = ostart;
@@ -3260,18 +3481,20 @@ static size_t ZSTD_buildBlockEntropyStats_sequences(seqStore_t* seqStorePtr,
/** ZSTD_buildBlockEntropyStats() : /** ZSTD_buildBlockEntropyStats() :
* Builds entropy for the block. * Builds entropy for the block.
* Requires workspace size ENTROPY_WORKSPACE_SIZE * Requires workspace size ENTROPY_WORKSPACE_SIZE
* * @return : 0 on success, or an error code
* @return : 0 on success or error code * Note : also employed in superblock
*/ */
size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr, size_t ZSTD_buildBlockEntropyStats(
const ZSTD_entropyCTables_t* prevEntropy, const seqStore_t* seqStorePtr,
ZSTD_entropyCTables_t* nextEntropy, const ZSTD_entropyCTables_t* prevEntropy,
const ZSTD_CCtx_params* cctxParams, ZSTD_entropyCTables_t* nextEntropy,
ZSTD_entropyCTablesMetadata_t* entropyMetadata, const ZSTD_CCtx_params* cctxParams,
void* workspace, size_t wkspSize) ZSTD_entropyCTablesMetadata_t* entropyMetadata,
void* workspace, size_t wkspSize)
{ {
size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart; size_t const litSize = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
HUF_depth_mode depthMode = cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD ? HUF_depth_optimal : HUF_depth_fast; int const huf_useOptDepth = (cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD);
HUF_depth_mode const depthMode = huf_useOptDepth ? HUF_depth_optimal : HUF_depth_fast;
entropyMetadata->hufMetadata.hufDesSize = entropyMetadata->hufMetadata.hufDesSize =
ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize, ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize,
@@ -3292,11 +3515,12 @@ size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
} }
/* Returns the size estimate for the literals section (header + content) of a block */ /* Returns the size estimate for the literals section (header + content) of a block */
static size_t ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize, static size_t
const ZSTD_hufCTables_t* huf, ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize,
const ZSTD_hufCTablesMetadata_t* hufMetadata, const ZSTD_hufCTables_t* huf,
void* workspace, size_t wkspSize, const ZSTD_hufCTablesMetadata_t* hufMetadata,
int writeEntropy) void* workspace, size_t wkspSize,
int writeEntropy)
{ {
unsigned* const countWksp = (unsigned*)workspace; unsigned* const countWksp = (unsigned*)workspace;
unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX;
@@ -3318,12 +3542,13 @@ static size_t ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSiz
} }
/* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */ /* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */
static size_t ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type, static size_t
const BYTE* codeTable, size_t nbSeq, unsigned maxCode, ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type,
const FSE_CTable* fseCTable, const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
const U8* additionalBits, const FSE_CTable* fseCTable,
short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, const U8* additionalBits,
void* workspace, size_t wkspSize) short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
void* workspace, size_t wkspSize)
{ {
unsigned* const countWksp = (unsigned*)workspace; unsigned* const countWksp = (unsigned*)workspace;
const BYTE* ctp = codeTable; const BYTE* ctp = codeTable;
@@ -3355,99 +3580,107 @@ static size_t ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type,
} }
/* Returns the size estimate for the sequences section (header + content) of a block */ /* Returns the size estimate for the sequences section (header + content) of a block */
static size_t ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable, static size_t
const BYTE* llCodeTable, ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable,
const BYTE* mlCodeTable, const BYTE* llCodeTable,
size_t nbSeq, const BYTE* mlCodeTable,
const ZSTD_fseCTables_t* fseTables, size_t nbSeq,
const ZSTD_fseCTablesMetadata_t* fseMetadata, const ZSTD_fseCTables_t* fseTables,
void* workspace, size_t wkspSize, const ZSTD_fseCTablesMetadata_t* fseMetadata,
int writeEntropy) void* workspace, size_t wkspSize,
int writeEntropy)
{ {
size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ); size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ);
size_t cSeqSizeEstimate = 0; size_t cSeqSizeEstimate = 0;
cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff, cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff,
fseTables->offcodeCTable, NULL, fseTables->offcodeCTable, NULL,
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
workspace, wkspSize); workspace, wkspSize);
cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL, cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL,
fseTables->litlengthCTable, LL_bits, fseTables->litlengthCTable, LL_bits,
LL_defaultNorm, LL_defaultNormLog, MaxLL, LL_defaultNorm, LL_defaultNormLog, MaxLL,
workspace, wkspSize); workspace, wkspSize);
cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML, cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML,
fseTables->matchlengthCTable, ML_bits, fseTables->matchlengthCTable, ML_bits,
ML_defaultNorm, ML_defaultNormLog, MaxML, ML_defaultNorm, ML_defaultNormLog, MaxML,
workspace, wkspSize); workspace, wkspSize);
if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
return cSeqSizeEstimate + sequencesSectionHeaderSize; return cSeqSizeEstimate + sequencesSectionHeaderSize;
} }
/* Returns the size estimate for a given stream of literals, of, ll, ml */ /* Returns the size estimate for a given stream of literals, of, ll, ml */
static size_t ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, static size_t
const BYTE* ofCodeTable, ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize,
const BYTE* llCodeTable, const BYTE* ofCodeTable,
const BYTE* mlCodeTable, const BYTE* llCodeTable,
size_t nbSeq, const BYTE* mlCodeTable,
const ZSTD_entropyCTables_t* entropy, size_t nbSeq,
const ZSTD_entropyCTablesMetadata_t* entropyMetadata, const ZSTD_entropyCTables_t* entropy,
void* workspace, size_t wkspSize, const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
int writeLitEntropy, int writeSeqEntropy) { void* workspace, size_t wkspSize,
int writeLitEntropy, int writeSeqEntropy)
{
size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize, size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize,
&entropy->huf, &entropyMetadata->hufMetadata, &entropy->huf, &entropyMetadata->hufMetadata,
workspace, wkspSize, writeLitEntropy); workspace, wkspSize, writeLitEntropy);
size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable,
nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, nbSeq, &entropy->fse, &entropyMetadata->fseMetadata,
workspace, wkspSize, writeSeqEntropy); workspace, wkspSize, writeSeqEntropy);
return seqSize + literalsSize + ZSTD_blockHeaderSize; return seqSize + literalsSize + ZSTD_blockHeaderSize;
} }
/* Builds entropy statistics and uses them for blocksize estimation. /* Builds entropy statistics and uses them for blocksize estimation.
* *
* Returns the estimated compressed size of the seqStore, or a zstd error. * @return: estimated compressed size of the seqStore, or a zstd error.
*/ */
static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CCtx* zc) { static size_t
ZSTD_entropyCTablesMetadata_t* entropyMetadata = &zc->blockSplitCtx.entropyMetadata; ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CCtx* zc)
{
ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata;
DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()"); DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()");
FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore, FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore,
&zc->blockState.prevCBlock->entropy, &zc->blockState.prevCBlock->entropy,
&zc->blockState.nextCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams, &zc->appliedParams,
entropyMetadata, entropyMetadata,
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), ""); zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE), "");
return ZSTD_estimateBlockSize(seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart), return ZSTD_estimateBlockSize(
seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
seqStore->ofCode, seqStore->llCode, seqStore->mlCode, seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
(size_t)(seqStore->sequences - seqStore->sequencesStart), (size_t)(seqStore->sequences - seqStore->sequencesStart),
&zc->blockState.nextCBlock->entropy, entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE, &zc->blockState.nextCBlock->entropy,
entropyMetadata,
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE,
(int)(entropyMetadata->hufMetadata.hType == set_compressed), 1); (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1);
} }
/* Returns literals bytes represented in a seqStore */ /* Returns literals bytes represented in a seqStore */
static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore) { static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore)
{
size_t literalsBytes = 0; size_t literalsBytes = 0;
size_t const nbSeqs = seqStore->sequences - seqStore->sequencesStart; size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
size_t i; size_t i;
for (i = 0; i < nbSeqs; ++i) { for (i = 0; i < nbSeqs; ++i) {
seqDef seq = seqStore->sequencesStart[i]; seqDef const seq = seqStore->sequencesStart[i];
literalsBytes += seq.litLength; literalsBytes += seq.litLength;
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) { if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) {
literalsBytes += 0x10000; literalsBytes += 0x10000;
} } }
}
return literalsBytes; return literalsBytes;
} }
/* Returns match bytes represented in a seqStore */ /* Returns match bytes represented in a seqStore */
static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore) { static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore)
{
size_t matchBytes = 0; size_t matchBytes = 0;
size_t const nbSeqs = seqStore->sequences - seqStore->sequencesStart; size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
size_t i; size_t i;
for (i = 0; i < nbSeqs; ++i) { for (i = 0; i < nbSeqs; ++i) {
seqDef seq = seqStore->sequencesStart[i]; seqDef seq = seqStore->sequencesStart[i];
matchBytes += seq.mlBase + MINMATCH; matchBytes += seq.mlBase + MINMATCH;
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) { if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
matchBytes += 0x10000; matchBytes += 0x10000;
} } }
}
return matchBytes; return matchBytes;
} }
@@ -3496,6 +3729,7 @@ ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, c
U32 const adjustedRepCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; /* [ 0 - 3 ] */ U32 const adjustedRepCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; /* [ 0 - 3 ] */
assert(OFFBASE_IS_REPCODE(offBase)); assert(OFFBASE_IS_REPCODE(offBase));
if (adjustedRepCode == ZSTD_REP_NUM) { if (adjustedRepCode == ZSTD_REP_NUM) {
assert(ll0);
/* litlength == 0 and offCode == 2 implies selection of first repcode - 1 /* litlength == 0 and offCode == 2 implies selection of first repcode - 1
* This is only valid if it results in a valid offset value, aka > 0. * This is only valid if it results in a valid offset value, aka > 0.
* Note : it may happen that `rep[0]==1` in exceptional circumstances. * Note : it may happen that `rep[0]==1` in exceptional circumstances.
@@ -3521,14 +3755,16 @@ ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, c
* 1-3 : repcode 1-3 * 1-3 : repcode 1-3
* 4+ : real_offset+3 * 4+ : real_offset+3
*/ */
static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRepcodes, static void
seqStore_t* const seqStore, U32 const nbSeq) { ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRepcodes,
const seqStore_t* const seqStore, U32 const nbSeq)
{
U32 idx = 0; U32 idx = 0;
for (; idx < nbSeq; ++idx) { for (; idx < nbSeq; ++idx) {
seqDef* const seq = seqStore->sequencesStart + idx; seqDef* const seq = seqStore->sequencesStart + idx;
U32 const ll0 = (seq->litLength == 0); U32 const ll0 = (seq->litLength == 0);
U32 const offBase = seq->offBase; U32 const offBase = seq->offBase;
assert(seq->offBase > 0); assert(offBase > 0);
if (OFFBASE_IS_REPCODE(offBase)) { if (OFFBASE_IS_REPCODE(offBase)) {
U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offBase, ll0); U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offBase, ll0);
U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offBase, ll0); U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offBase, ll0);
@@ -3537,7 +3773,7 @@ static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_
* repcode history. * repcode history.
*/ */
if (dRawOffset != cRawOffset) { if (dRawOffset != cRawOffset) {
seq->offBase = cRawOffset + ZSTD_REP_NUM; seq->offBase = OFFSET_TO_OFFBASE(cRawOffset);
} }
} }
/* Compression repcode history is always updated with values directly from the unmodified seqStore. /* Compression repcode history is always updated with values directly from the unmodified seqStore.
@@ -3554,10 +3790,11 @@ static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_
* Returns the total size of that block (including header) or a ZSTD error code. * Returns the total size of that block (including header) or a ZSTD error code.
*/ */
static size_t static size_t
ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const seqStore, ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
const seqStore_t* const seqStore,
repcodes_t* const dRep, repcodes_t* const cRep, repcodes_t* const dRep, repcodes_t* const cRep,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
U32 lastBlock, U32 isPartition) U32 lastBlock, U32 isPartition)
{ {
const U32 rleMaxLength = 25; const U32 rleMaxLength = 25;
@@ -3631,10 +3868,11 @@ typedef struct {
/* Helper function to perform the recursive search for block splits. /* Helper function to perform the recursive search for block splits.
* Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half. * Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half.
* If advantageous to split, then we recurse down the two sub-blocks. If not, or if an error occurred in estimation, then * If advantageous to split, then we recurse down the two sub-blocks.
* we do not recurse. * If not, or if an error occurred in estimation, then we do not recurse.
* *
* Note: The recursion depth is capped by a heuristic minimum number of sequences, defined by MIN_SEQUENCES_BLOCK_SPLITTING. * Note: The recursion depth is capped by a heuristic minimum number of sequences,
* defined by MIN_SEQUENCES_BLOCK_SPLITTING.
* In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING). * In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING).
* In practice, recursion depth usually doesn't go beyond 4. * In practice, recursion depth usually doesn't go beyond 4.
* *
@@ -3646,19 +3884,20 @@ static void
ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx, ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
ZSTD_CCtx* zc, const seqStore_t* origSeqStore) ZSTD_CCtx* zc, const seqStore_t* origSeqStore)
{ {
seqStore_t* fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk; seqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
seqStore_t* firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore; seqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
seqStore_t* secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore; seqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
size_t estimatedOriginalSize; size_t estimatedOriginalSize;
size_t estimatedFirstHalfSize; size_t estimatedFirstHalfSize;
size_t estimatedSecondHalfSize; size_t estimatedSecondHalfSize;
size_t midIdx = (startIdx + endIdx)/2; size_t midIdx = (startIdx + endIdx)/2;
DEBUGLOG(5, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx);
assert(endIdx >= startIdx);
if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) { if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) {
DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences"); DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences (%zu)", endIdx - startIdx);
return; return;
} }
DEBUGLOG(5, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx);
ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx); ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx);
ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx); ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx);
ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx); ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx);
@@ -3679,15 +3918,16 @@ ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t end
} }
} }
/* Base recursive function. Populates a table with intra-block partition indices that can improve compression ratio. /* Base recursive function.
* Populates a table with intra-block partition indices that can improve compression ratio.
* *
* Returns the number of splits made (which equals the size of the partition table - 1). * @return: number of splits made (which equals the size of the partition table - 1).
*/ */
static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq) static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq)
{ {
seqStoreSplits splits = {partitions, 0}; seqStoreSplits splits = {partitions, 0};
if (nbSeq <= 4) { if (nbSeq <= 4) {
DEBUGLOG(5, "ZSTD_deriveBlockSplits: Too few sequences to split"); DEBUGLOG(5, "ZSTD_deriveBlockSplits: Too few sequences to split (%u <= 4)", nbSeq);
/* Refuse to try and split anything with less than 4 sequences */ /* Refuse to try and split anything with less than 4 sequences */
return 0; return 0;
} }
@@ -3703,18 +3943,20 @@ static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq)
* Returns combined size of all blocks (which includes headers), or a ZSTD error code. * Returns combined size of all blocks (which includes headers), or a ZSTD error code.
*/ */
static size_t static size_t
ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
const void* src, size_t blockSize, U32 lastBlock, U32 nbSeq) void* dst, size_t dstCapacity,
const void* src, size_t blockSize,
U32 lastBlock, U32 nbSeq)
{ {
size_t cSize = 0; size_t cSize = 0;
const BYTE* ip = (const BYTE*)src; const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst; BYTE* op = (BYTE*)dst;
size_t i = 0; size_t i = 0;
size_t srcBytesTotal = 0; size_t srcBytesTotal = 0;
U32* partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */ U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */
seqStore_t* nextSeqStore = &zc->blockSplitCtx.nextSeqStore; seqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
seqStore_t* currSeqStore = &zc->blockSplitCtx.currSeqStore; seqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore;
size_t numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq); size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
/* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
* may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two * may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two
@@ -3736,19 +3978,21 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapac
ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
ZSTD_memset(nextSeqStore, 0, sizeof(seqStore_t)); ZSTD_memset(nextSeqStore, 0, sizeof(seqStore_t));
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
(unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
(unsigned)zc->blockState.matchState.nextToUpdate); (unsigned)zc->blockState.matchState.nextToUpdate);
if (numSplits == 0) { if (numSplits == 0) {
size_t cSizeSingleBlock = ZSTD_compressSeqStore_singleBlock(zc, &zc->seqStore, size_t cSizeSingleBlock =
&dRep, &cRep, ZSTD_compressSeqStore_singleBlock(zc, &zc->seqStore,
op, dstCapacity, &dRep, &cRep,
ip, blockSize, op, dstCapacity,
lastBlock, 0 /* isPartition */); ip, blockSize,
lastBlock, 0 /* isPartition */);
FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!"); FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!");
DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits"); DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits");
assert(cSizeSingleBlock <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize); assert(zc->blockSize <= ZSTD_BLOCKSIZE_MAX);
assert(cSizeSingleBlock <= zc->blockSize + ZSTD_blockHeaderSize);
return cSizeSingleBlock; return cSizeSingleBlock;
} }
@@ -3773,7 +4017,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapac
op, dstCapacity, op, dstCapacity,
ip, srcBytes, ip, srcBytes,
lastBlockEntireSrc, 1 /* isPartition */); lastBlockEntireSrc, 1 /* isPartition */);
DEBUGLOG(5, "Estimated size: %zu actual size: %zu", ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk); DEBUGLOG(5, "Estimated size: %zu vs %zu : actual size",
ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk);
FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!"); FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!");
ip += srcBytes; ip += srcBytes;
@@ -3781,10 +4026,10 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapac
dstCapacity -= cSizeChunk; dstCapacity -= cSizeChunk;
cSize += cSizeChunk; cSize += cSizeChunk;
*currSeqStore = *nextSeqStore; *currSeqStore = *nextSeqStore;
assert(cSizeChunk <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize); assert(cSizeChunk <= zc->blockSize + ZSTD_blockHeaderSize);
} }
/* cRep and dRep may have diverged during the compression. If so, we use the dRep repcodes /* cRep and dRep may have diverged during the compression.
* for the next block. * If so, we use the dRep repcodes for the next block.
*/ */
ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(repcodes_t)); ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(repcodes_t));
return cSize; return cSize;
@@ -3795,8 +4040,6 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, U32 lastBlock) const void* src, size_t srcSize, U32 lastBlock)
{ {
const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst;
U32 nbSeq; U32 nbSeq;
size_t cSize; size_t cSize;
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock"); DEBUGLOG(4, "ZSTD_compressBlock_splitBlock");
@@ -3807,7 +4050,7 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
if (bss == ZSTDbss_noCompress) { if (bss == ZSTDbss_noCompress) {
if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock); cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock: Nocompress block"); DEBUGLOG(4, "ZSTD_compressBlock_splitBlock: Nocompress block");
return cSize; return cSize;
@@ -3919,10 +4162,11 @@ static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc,
* * cSize >= blockBound(srcSize): We have expanded the block too much so * * cSize >= blockBound(srcSize): We have expanded the block too much so
* emit an uncompressed block. * emit an uncompressed block.
*/ */
{ { size_t const cSize =
size_t const cSize = ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock); ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock);
if (cSize != ERROR(dstSize_tooSmall)) { if (cSize != ERROR(dstSize_tooSmall)) {
size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy); size_t const maxCSize =
srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy);
FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed"); FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed");
if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) { if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) {
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState);
@@ -3930,7 +4174,7 @@ static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc,
} }
} }
} }
} } /* if (bss == ZSTDbss_compress)*/
DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()"); DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()");
/* Superblock compression failed, attempt to emit a single no compress block. /* Superblock compression failed, attempt to emit a single no compress block.
@@ -3988,7 +4232,7 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
* All blocks will be terminated, all input will be consumed. * All blocks will be terminated, all input will be consumed.
* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content. * Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.
* Frame is supposed already started (header already produced) * Frame is supposed already started (header already produced)
* @return : compressed size, or an error code * @return : compressed size, or an error code
*/ */
static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
@@ -4053,7 +4297,7 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
MEM_writeLE24(op, cBlockHeader); MEM_writeLE24(op, cBlockHeader);
cSize += ZSTD_blockHeaderSize; cSize += ZSTD_blockHeaderSize;
} }
} } /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/
ip += blockSize; ip += blockSize;
@@ -5682,6 +5926,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, &params.cParams); params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, &params.cParams);
params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, &params.cParams); params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, &params.cParams);
params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, &params.cParams); params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, &params.cParams);
params.validateSequences = ZSTD_resolveExternalSequenceValidation(params.validateSequences);
#ifdef ZSTD_MULTITHREAD #ifdef ZSTD_MULTITHREAD
if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
@@ -5883,12 +6128,6 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
} }
} }
typedef struct {
U32 idx; /* Index in array of ZSTD_Sequence */
U32 posInSequence; /* Position within sequence at idx */
size_t posInSrc; /* Number of bytes given by sequences provided so far */
} ZSTD_sequencePosition;
/* ZSTD_validateSequence() : /* ZSTD_validateSequence() :
* @offCode : is presumed to follow format required by ZSTD_storeSeq() * @offCode : is presumed to follow format required by ZSTD_storeSeq()
* @returns a ZSTD error code if sequence is not valid * @returns a ZSTD error code if sequence is not valid
@@ -5926,10 +6165,7 @@ static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32
return offBase; return offBase;
} }
/* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of size_t
* ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter.
*/
static size_t
ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
ZSTD_sequencePosition* seqPos, ZSTD_sequencePosition* seqPos,
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
@@ -5983,19 +6219,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
return 0; return 0;
} }
/* Returns the number of bytes to move the current read position back by. size_t
* Only non-zero if we ended up splitting a sequence.
* Otherwise, it may return a ZSTD error if something went wrong.
*
* This function will attempt to scan through blockSize bytes
* represented by the sequences in @inSeqs,
* storing any (partial) sequences.
*
* Occasionally, we may want to change the actual number of bytes we consumed from inSeqs to
* avoid splitting a match, or to avoid splitting a match such that it would produce a match
* smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block.
*/
static size_t
ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos, ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
const void* src, size_t blockSize) const void* src, size_t blockSize)
@@ -6528,3 +6752,19 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH
if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
} }
void ZSTD_registerExternalMatchFinder(
ZSTD_CCtx* zc, void* mState,
ZSTD_externalMatchFinder_F* mFinder
) {
ZSTD_externalMatchCtx emctx = {
mState,
mFinder,
/* seqBuffer is allocated later (from the cwskp) */
NULL, /* seqBuffer */
0 /* seqBufferCapacity */
};
zc->externalMatchCtx = emctx;
zc->requestedParams.useExternalMatchFinder = 1;
}
+64 -7
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -118,12 +118,13 @@ typedef struct {
/** ZSTD_buildBlockEntropyStats() : /** ZSTD_buildBlockEntropyStats() :
* Builds entropy for the block. * Builds entropy for the block.
* @return : 0 on success or error code */ * @return : 0 on success or error code */
size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr, size_t ZSTD_buildBlockEntropyStats(
const ZSTD_entropyCTables_t* prevEntropy, const seqStore_t* seqStorePtr,
ZSTD_entropyCTables_t* nextEntropy, const ZSTD_entropyCTables_t* prevEntropy,
const ZSTD_CCtx_params* cctxParams, ZSTD_entropyCTables_t* nextEntropy,
ZSTD_entropyCTablesMetadata_t* entropyMetadata, const ZSTD_CCtx_params* cctxParams,
void* workspace, size_t wkspSize); ZSTD_entropyCTablesMetadata_t* entropyMetadata,
void* workspace, size_t wkspSize);
/********************************* /*********************************
* Compression internals structs * * Compression internals structs *
@@ -149,6 +150,12 @@ typedef struct {
size_t capacity; /* The capacity starting from `seq` pointer */ size_t capacity; /* The capacity starting from `seq` pointer */
} rawSeqStore_t; } rawSeqStore_t;
typedef struct {
U32 idx; /* Index in array of ZSTD_Sequence */
U32 posInSequence; /* Position within sequence at idx */
size_t posInSrc; /* Number of bytes given by sequences provided so far */
} ZSTD_sequencePosition;
UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
typedef struct { typedef struct {
@@ -339,6 +346,18 @@ struct ZSTD_CCtx_params_s {
/* Controls prefetching in some dictMatchState matchfinders */ /* Controls prefetching in some dictMatchState matchfinders */
ZSTD_paramSwitch_e prefetchCDictTables; ZSTD_paramSwitch_e prefetchCDictTables;
/* Controls whether zstd will fall back to an internal matchfinder
* if the external matchfinder returns an error code. */
int enableMatchFinderFallback;
/* Indicates whether an external matchfinder has been referenced.
* Users can't set this externally.
* It is set internally in ZSTD_registerExternalMatchFinder(). */
int useExternalMatchFinder;
/* Adjust the max block size*/
size_t maxBlockSize;
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */ }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
#define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2)) #define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
@@ -370,6 +389,14 @@ typedef struct {
ZSTD_entropyCTablesMetadata_t entropyMetadata; ZSTD_entropyCTablesMetadata_t entropyMetadata;
} ZSTD_blockSplitCtx; } ZSTD_blockSplitCtx;
/* Context for block-level external matchfinder API */
typedef struct {
void* mState;
ZSTD_externalMatchFinder_F* mFinder;
ZSTD_Sequence* seqBuffer;
size_t seqBufferCapacity;
} ZSTD_externalMatchCtx;
struct ZSTD_CCtx_s { struct ZSTD_CCtx_s {
ZSTD_compressionStage_e stage; ZSTD_compressionStage_e stage;
int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */ int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
@@ -439,6 +466,9 @@ struct ZSTD_CCtx_s {
/* Workspace for block splitter */ /* Workspace for block splitter */
ZSTD_blockSplitCtx blockSplitCtx; ZSTD_blockSplitCtx blockSplitCtx;
/* Workspace for external matchfinder */
ZSTD_externalMatchCtx externalMatchCtx;
}; };
typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e; typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
@@ -1410,4 +1440,31 @@ U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
*/ */
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize); void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize);
/* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of
* ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter.
* Note that the block delimiter must include the last literals of the block.
*/
size_t
ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
ZSTD_sequencePosition* seqPos,
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
const void* src, size_t blockSize);
/* Returns the number of bytes to move the current read position back by.
* Only non-zero if we ended up splitting a sequence.
* Otherwise, it may return a ZSTD error if something went wrong.
*
* This function will attempt to scan through blockSize bytes
* represented by the sequences in @inSeqs,
* storing any (partial) sequences.
*
* Occasionally, we may want to change the actual number of bytes we consumed from inSeqs to
* avoid splitting a match, or to avoid splitting a match such that it would produce a match
* smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block.
*/
size_t
ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
const void* src, size_t blockSize);
#endif /* ZSTD_COMPRESS_H */ #endif /* ZSTD_COMPRESS_H */
+43 -19
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -92,16 +92,37 @@ size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void*
return flSize+1; return flSize+1;
} }
size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, /* ZSTD_minLiteralsToCompress() :
ZSTD_hufCTables_t* nextHuf, * returns minimal amount of literals
ZSTD_strategy strategy, int disableLiteralCompression, * for literal compression to even be attempted.
void* dst, size_t dstCapacity, * Minimum is made tighter as compression strategy increases.
const void* src, size_t srcSize, */
void* entropyWorkspace, size_t entropyWorkspaceSize, static size_t
const int bmi2, ZSTD_minLiteralsToCompress(ZSTD_strategy strategy, HUF_repeat huf_repeat)
unsigned suspectUncompressible, HUF_depth_mode depthMode) {
assert((int)strategy >= 0);
assert((int)strategy <= 9);
/* btultra2 : min 8 bytes;
* then 2x larger for each successive compression strategy
* max threshold 64 bytes */
{ int const shift = MIN(9-strategy, 3);
size_t const mintc = (huf_repeat == HUF_repeat_valid) ? 6 : 8 << shift;
DEBUGLOG(7, "minLiteralsToCompress = %zu", mintc);
return mintc;
}
}
size_t ZSTD_compressLiterals (
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
void* entropyWorkspace, size_t entropyWorkspaceSize,
const ZSTD_hufCTables_t* prevHuf,
ZSTD_hufCTables_t* nextHuf,
ZSTD_strategy strategy,
int disableLiteralCompression,
int suspectUncompressible,
int bmi2)
{ {
size_t const minGain = ZSTD_minGain(srcSize, strategy);
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
BYTE* const ostart = (BYTE*)dst; BYTE* const ostart = (BYTE*)dst;
U32 singleStream = srcSize < 256; U32 singleStream = srcSize < 256;
@@ -119,15 +140,14 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
if (disableLiteralCompression) if (disableLiteralCompression)
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
/* small ? don't even attempt compression (speed opt) */ /* if too small, don't even attempt compression (speed opt) */
# define COMPRESS_LITERALS_SIZE_MIN 63 if (srcSize < ZSTD_minLiteralsToCompress(strategy, prevHuf->repeatMode))
{ size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
}
RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression"); RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression");
{ HUF_repeat repeat = prevHuf->repeatMode; { HUF_repeat repeat = prevHuf->repeatMode;
int const preferRepeat = (strategy < ZSTD_lazy) ? srcSize <= 1024 : 0; int const preferRepeat = (strategy < ZSTD_lazy) ? srcSize <= 1024 : 0;
HUF_depth_mode const depthMode = (strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD) ? HUF_depth_optimal : HUF_depth_fast;
typedef size_t (*huf_compress_f)(void*, size_t, const void*, size_t, unsigned, unsigned, void*, size_t, HUF_CElt*, HUF_repeat*, int, int, unsigned, HUF_depth_mode); typedef size_t (*huf_compress_f)(void*, size_t, const void*, size_t, unsigned, unsigned, void*, size_t, HUF_CElt*, HUF_repeat*, int, int, unsigned, HUF_depth_mode);
huf_compress_f huf_compress; huf_compress_f huf_compress;
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
@@ -146,10 +166,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
} }
} }
if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) { { size_t const minGain = ZSTD_minGain(srcSize, strategy);
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) {
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
} return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
} }
if (cLitSize==1) { if (cLitSize==1) {
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
@@ -164,16 +185,19 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
switch(lhSize) switch(lhSize)
{ {
case 3: /* 2 - 2 - 10 - 10 */ case 3: /* 2 - 2 - 10 - 10 */
if (!singleStream) assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS);
{ U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14); { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
MEM_writeLE24(ostart, lhc); MEM_writeLE24(ostart, lhc);
break; break;
} }
case 4: /* 2 - 2 - 14 - 14 */ case 4: /* 2 - 2 - 14 - 14 */
assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS);
{ U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18); { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
MEM_writeLE32(ostart, lhc); MEM_writeLE32(ostart, lhc);
break; break;
} }
case 5: /* 2 - 2 - 18 - 18 */ case 5: /* 2 - 2 - 18 - 18 */
assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS);
{ U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22); { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
MEM_writeLE32(ostart, lhc); MEM_writeLE32(ostart, lhc);
ostart[4] = (BYTE)(cLitSize >> 10); ostart[4] = (BYTE)(cLitSize >> 10);
+12 -8
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -18,14 +18,18 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize); size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
/* If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ /* ZSTD_compressLiterals():
size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, * @entropyWorkspace: must be aligned on 4-bytes boundaries
ZSTD_hufCTables_t* nextHuf, * @entropyWorkspaceSize : must be >= HUF_WORKSPACE_SIZE
ZSTD_strategy strategy, int disableLiteralCompression, * @suspectUncompressible: sampling checks, to potentially skip huffman coding
void* dst, size_t dstCapacity, */
size_t ZSTD_compressLiterals (void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
void* entropyWorkspace, size_t entropyWorkspaceSize, void* entropyWorkspace, size_t entropyWorkspaceSize,
const int bmi2, const ZSTD_hufCTables_t* prevHuf,
unsigned suspectUncompressible, HUF_depth_mode depthMode); ZSTD_hufCTables_t* nextHuf,
ZSTD_strategy strategy, int disableLiteralCompression,
int suspectUncompressible,
int bmi2);
#endif /* ZSTD_COMPRESS_LITERALS_H */ #endif /* ZSTD_COMPRESS_LITERALS_H */
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+55 -35
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -16,7 +16,7 @@
#define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */ #define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */
#define ZSTD_MAX_PRICE (1<<30) #define ZSTD_MAX_PRICE (1<<30)
#define ZSTD_PREDEF_THRESHOLD 1024 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */ #define ZSTD_PREDEF_THRESHOLD 8 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */
/*-************************************* /*-*************************************
@@ -26,27 +26,35 @@
#if 0 /* approximation at bit level (for tests) */ #if 0 /* approximation at bit level (for tests) */
# define BITCOST_ACCURACY 0 # define BITCOST_ACCURACY 0
# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
# define WEIGHT(stat, opt) ((void)opt, ZSTD_bitWeight(stat)) # define WEIGHT(stat, opt) ((void)(opt), ZSTD_bitWeight(stat))
#elif 0 /* fractional bit accuracy (for tests) */ #elif 0 /* fractional bit accuracy (for tests) */
# define BITCOST_ACCURACY 8 # define BITCOST_ACCURACY 8
# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
# define WEIGHT(stat,opt) ((void)opt, ZSTD_fracWeight(stat)) # define WEIGHT(stat,opt) ((void)(opt), ZSTD_fracWeight(stat))
#else /* opt==approx, ultra==accurate */ #else /* opt==approx, ultra==accurate */
# define BITCOST_ACCURACY 8 # define BITCOST_ACCURACY 8
# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
# define WEIGHT(stat,opt) (opt ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat)) # define WEIGHT(stat,opt) ((opt) ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat))
#endif #endif
/* ZSTD_bitWeight() :
* provide estimated "cost" of a stat in full bits only */
MEM_STATIC U32 ZSTD_bitWeight(U32 stat) MEM_STATIC U32 ZSTD_bitWeight(U32 stat)
{ {
return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER); return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER);
} }
/* ZSTD_fracWeight() :
* provide fractional-bit "cost" of a stat,
* using linear interpolation approximation */
MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat) MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat)
{ {
U32 const stat = rawStat + 1; U32 const stat = rawStat + 1;
U32 const hb = ZSTD_highbit32(stat); U32 const hb = ZSTD_highbit32(stat);
U32 const BWeight = hb * BITCOST_MULTIPLIER; U32 const BWeight = hb * BITCOST_MULTIPLIER;
/* Fweight was meant for "Fractional weight"
* but it's effectively a value between 1 and 2
* using fixed point arithmetic */
U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb; U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb;
U32 const weight = BWeight + FWeight; U32 const weight = BWeight + FWeight;
assert(hb + BITCOST_ACCURACY < 31); assert(hb + BITCOST_ACCURACY < 31);
@@ -88,20 +96,26 @@ static U32 sum_u32(const unsigned table[], size_t nbElts)
return total; return total;
} }
static U32 ZSTD_downscaleStats(unsigned* table, U32 lastEltIndex, U32 shift) typedef enum { base_0possible=0, base_1guaranteed=1 } base_directive_e;
static U32
ZSTD_downscaleStats(unsigned* table, U32 lastEltIndex, U32 shift, base_directive_e base1)
{ {
U32 s, sum=0; U32 s, sum=0;
DEBUGLOG(5, "ZSTD_downscaleStats (nbElts=%u, shift=%u)", (unsigned)lastEltIndex+1, (unsigned)shift); DEBUGLOG(5, "ZSTD_downscaleStats (nbElts=%u, shift=%u)",
(unsigned)lastEltIndex+1, (unsigned)shift );
assert(shift < 30); assert(shift < 30);
for (s=0; s<lastEltIndex+1; s++) { for (s=0; s<lastEltIndex+1; s++) {
table[s] = 1 + (table[s] >> shift); unsigned const base = base1 ? 1 : (table[s]>0);
sum += table[s]; unsigned const newStat = base + (table[s] >> shift);
sum += newStat;
table[s] = newStat;
} }
return sum; return sum;
} }
/* ZSTD_scaleStats() : /* ZSTD_scaleStats() :
* reduce all elements in table is sum too large * reduce all elt frequencies in table if sum too large
* return the resulting sum of elements */ * return the resulting sum of elements */
static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget) static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget)
{ {
@@ -110,7 +124,7 @@ static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget)
DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget); DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget);
assert(logTarget < 30); assert(logTarget < 30);
if (factor <= 1) return prevsum; if (factor <= 1) return prevsum;
return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor)); return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor), base_1guaranteed);
} }
/* ZSTD_rescaleFreqs() : /* ZSTD_rescaleFreqs() :
@@ -129,18 +143,22 @@ ZSTD_rescaleFreqs(optState_t* const optPtr,
DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize); DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize);
optPtr->priceType = zop_dynamic; optPtr->priceType = zop_dynamic;
if (optPtr->litLengthSum == 0) { /* first block : init */ if (optPtr->litLengthSum == 0) { /* no literals stats collected -> first block assumed -> init */
if (srcSize <= ZSTD_PREDEF_THRESHOLD) { /* heuristic */
DEBUGLOG(5, "(srcSize <= ZSTD_PREDEF_THRESHOLD) => zop_predef"); /* heuristic: use pre-defined stats for too small inputs */
if (srcSize <= ZSTD_PREDEF_THRESHOLD) {
DEBUGLOG(5, "srcSize <= %i : use predefined stats", ZSTD_PREDEF_THRESHOLD);
optPtr->priceType = zop_predef; optPtr->priceType = zop_predef;
} }
assert(optPtr->symbolCosts != NULL); assert(optPtr->symbolCosts != NULL);
if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) {
/* huffman table presumed generated by dictionary */
/* huffman stats covering the full value set : table presumed generated by dictionary */
optPtr->priceType = zop_dynamic; optPtr->priceType = zop_dynamic;
if (compressedLiterals) { if (compressedLiterals) {
/* generate literals statistics from huffman table */
unsigned lit; unsigned lit;
assert(optPtr->litFreq != NULL); assert(optPtr->litFreq != NULL);
optPtr->litSum = 0; optPtr->litSum = 0;
@@ -188,13 +206,14 @@ ZSTD_rescaleFreqs(optState_t* const optPtr,
optPtr->offCodeSum += optPtr->offCodeFreq[of]; optPtr->offCodeSum += optPtr->offCodeFreq[of];
} } } }
} else { /* not a dictionary */ } else { /* first block, no dictionary */
assert(optPtr->litFreq != NULL); assert(optPtr->litFreq != NULL);
if (compressedLiterals) { if (compressedLiterals) {
/* base initial cost of literals on direct frequency within src */
unsigned lit = MaxLit; unsigned lit = MaxLit;
HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */ HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */
optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8); optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8, base_0possible);
} }
{ unsigned const baseLLfreqs[MaxLL+1] = { { unsigned const baseLLfreqs[MaxLL+1] = {
@@ -224,10 +243,9 @@ ZSTD_rescaleFreqs(optState_t* const optPtr,
optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1);
} }
} }
} else { /* new block : re-use previous statistics, scaled down */ } else { /* new block : scale down accumulated statistics */
if (compressedLiterals) if (compressedLiterals)
optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12); optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12);
@@ -275,10 +293,11 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
assert(litLength <= ZSTD_BLOCKSIZE_MAX); assert(litLength <= ZSTD_BLOCKSIZE_MAX);
if (optPtr->priceType == zop_predef) if (optPtr->priceType == zop_predef)
return WEIGHT(litLength, optLevel); return WEIGHT(litLength, optLevel);
/* We can't compute the litLength price for sizes >= ZSTD_BLOCKSIZE_MAX
* because it isn't representable in the zstd format. So instead just /* ZSTD_LLcode() can't compute litLength price for sizes >= ZSTD_BLOCKSIZE_MAX
* call it 1 bit more than ZSTD_BLOCKSIZE_MAX - 1. In this case the block * because it isn't representable in the zstd format.
* would be all literals. * So instead just pretend it would cost 1 bit more than ZSTD_BLOCKSIZE_MAX - 1.
* In such a case, the block would be all literals.
*/ */
if (litLength == ZSTD_BLOCKSIZE_MAX) if (litLength == ZSTD_BLOCKSIZE_MAX)
return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel); return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel);
@@ -292,7 +311,7 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
} }
/* ZSTD_getMatchPrice() : /* ZSTD_getMatchPrice() :
* Provides the cost of the match part (offset + matchLength) of a sequence * Provides the cost of the match part (offset + matchLength) of a sequence.
* Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence. * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
* @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq() * @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq()
* @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency)
@@ -308,8 +327,9 @@ ZSTD_getMatchPrice(U32 const offBase,
U32 const mlBase = matchLength - MINMATCH; U32 const mlBase = matchLength - MINMATCH;
assert(matchLength >= MINMATCH); assert(matchLength >= MINMATCH);
if (optPtr->priceType == zop_predef) /* fixed scheme, do not use statistics */ if (optPtr->priceType == zop_predef) /* fixed scheme, does not use statistics */
return WEIGHT(mlBase, optLevel) + ((16 + offCode) * BITCOST_MULTIPLIER); return WEIGHT(mlBase, optLevel)
+ ((16 + offCode) * BITCOST_MULTIPLIER); /* emulated offset cost */
/* dynamic statistics */ /* dynamic statistics */
price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel)); price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel));
@@ -347,7 +367,7 @@ static void ZSTD_updateStats(optState_t* const optPtr,
optPtr->litLengthSum++; optPtr->litLengthSum++;
} }
/* offset code : expected to follow storeSeq() numeric representation */ /* offset code : follows storeSeq() numeric representation */
{ U32 const offCode = ZSTD_highbit32(offBase); { U32 const offCode = ZSTD_highbit32(offBase);
assert(offCode <= MaxOff); assert(offCode <= MaxOff);
optPtr->offCodeFreq[offCode]++; optPtr->offCodeFreq[offCode]++;
@@ -1352,7 +1372,7 @@ size_t ZSTD_compressBlock_btopt(
/* ZSTD_initStats_ultra(): /* ZSTD_initStats_ultra():
* make a first compression pass, just to seed stats with more accurate starting values. * make a first compression pass, just to seed stats with more accurate starting values.
* only works on first block, with no dictionary and no ldm. * only works on first block, with no dictionary and no ldm.
* this function cannot error, hence its contract must be respected. * this function cannot error out, its narrow contract must be respected.
*/ */
static void static void
ZSTD_initStats_ultra(ZSTD_matchState_t* ms, ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
@@ -1371,7 +1391,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/ ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/
/* invalidate first scan from history */ /* invalidate first scan from history, only keep entropy stats */
ZSTD_resetSeqStore(seqStore); ZSTD_resetSeqStore(seqStore);
ms->window.base -= srcSize; ms->window.base -= srcSize;
ms->window.dictLimit += (U32)srcSize; ms->window.dictLimit += (U32)srcSize;
@@ -1395,20 +1415,20 @@ size_t ZSTD_compressBlock_btultra2(
U32 const curr = (U32)((const BYTE*)src - ms->window.base); U32 const curr = (U32)((const BYTE*)src - ms->window.base);
DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize); DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize);
/* 2-pass strategy: /* 2-passes strategy:
* this strategy makes a first pass over first block to collect statistics * this strategy makes a first pass over first block to collect statistics
* and seed next round's statistics with it. * in order to seed next round's statistics with it.
* After 1st pass, function forgets everything, and starts a new block. * After 1st pass, function forgets history, and starts a new block.
* Consequently, this can only work if no data has been previously loaded in tables, * Consequently, this can only work if no data has been previously loaded in tables,
* aka, no dictionary, no prefix, no ldm preprocessing. * aka, no dictionary, no prefix, no ldm preprocessing.
* The compression ratio gain is generally small (~0.5% on first block), * The compression ratio gain is generally small (~0.5% on first block),
* the cost is 2x cpu time on first block. */ ** the cost is 2x cpu time on first block. */
assert(srcSize <= ZSTD_BLOCKSIZE_MAX); assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
if ( (ms->opt.litLengthSum==0) /* first block */ if ( (ms->opt.litLengthSum==0) /* first block */
&& (seqStore->sequences == seqStore->sequencesStart) /* no ldm */ && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */
&& (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */ && (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */
&& (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */ && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */
&& (srcSize > ZSTD_PREDEF_THRESHOLD) && (srcSize > ZSTD_PREDEF_THRESHOLD) /* input large enough to not employ default stats */
) { ) {
ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize); ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
} }
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+25 -17
View File
@@ -1,7 +1,7 @@
/* ****************************************************************** /* ******************************************************************
* huff0 huffman decoder, * huff0 huffman decoder,
* part of Finite State Entropy library * part of Finite State Entropy library
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* *
* You can contact the author at : * You can contact the author at :
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
@@ -289,10 +289,11 @@ typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decodi
static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) { static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
U64 D4; U64 D4;
if (MEM_isLittleEndian()) { if (MEM_isLittleEndian()) {
D4 = (symbol << 8) + nbBits; D4 = (U64)((symbol << 8) + nbBits);
} else { } else {
D4 = symbol + (nbBits << 8); D4 = (U64)(symbol + (nbBits << 8));
} }
assert(D4 < (1U << 16));
D4 *= 0x0001000100010001ULL; D4 *= 0x0001000100010001ULL;
return D4; return D4;
} }
@@ -383,9 +384,8 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr
* rankStart[0] is not filled because there are no entries in the table for * rankStart[0] is not filled because there are no entries in the table for
* weight 0. * weight 0.
*/ */
{ { int n;
int n; U32 nextRankStart = 0;
int nextRankStart = 0;
int const unroll = 4; int const unroll = 4;
int const nLimit = (int)nbSymbols - unroll + 1; int const nLimit = (int)nbSymbols - unroll + 1;
for (n=0; n<(int)tableLog+1; n++) { for (n=0; n<(int)tableLog+1; n++) {
@@ -412,10 +412,9 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr
* We can switch based on the length to a different inner loop which is * We can switch based on the length to a different inner loop which is
* optimized for that particular case. * optimized for that particular case.
*/ */
{ { U32 w;
U32 w; int symbol = wksp->rankVal[0];
int symbol=wksp->rankVal[0]; int rankStart = 0;
int rankStart=0;
for (w=1; w<tableLog+1; ++w) { for (w=1; w<tableLog+1; ++w) {
int const symbolCount = wksp->rankVal[w]; int const symbolCount = wksp->rankVal[w];
int const length = (1 << w) >> 1; int const length = (1 << w) >> 1;
@@ -525,7 +524,7 @@ HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, cons
while (p < pEnd) while (p < pEnd)
HUF_DECODE_SYMBOLX1_0(p, bitDPtr); HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
return pEnd-pStart; return (size_t)(pEnd-pStart);
} }
FORCE_INLINE_TEMPLATE size_t FORCE_INLINE_TEMPLATE size_t
@@ -551,6 +550,10 @@ HUF_decompress1X1_usingDTable_internal_body(
return dstSize; return dstSize;
} }
/* HUF_decompress4X1_usingDTable_internal_body():
* Conditions :
* @dstSize >= 6
*/
FORCE_INLINE_TEMPLATE size_t FORCE_INLINE_TEMPLATE size_t
HUF_decompress4X1_usingDTable_internal_body( HUF_decompress4X1_usingDTable_internal_body(
void* dst, size_t dstSize, void* dst, size_t dstSize,
@@ -594,6 +597,7 @@ HUF_decompress4X1_usingDTable_internal_body(
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */
CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
@@ -679,8 +683,7 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm(
const BYTE* const iend = (const BYTE*)cSrc + 6; const BYTE* const iend = (const BYTE*)cSrc + 6;
BYTE* const oend = (BYTE*)dst + dstSize; BYTE* const oend = (BYTE*)dst + dstSize;
HUF_DecompressAsmArgs args; HUF_DecompressAsmArgs args;
{ { size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
FORWARD_IF_ERROR(ret, "Failed to init asm args"); FORWARD_IF_ERROR(ret, "Failed to init asm args");
if (ret != 0) if (ret != 0)
return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
@@ -700,8 +703,7 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm(
(void)iend; (void)iend;
/* finish bit streams one by one. */ /* finish bit streams one by one. */
{ { size_t const segmentSize = (dstSize+3) / 4;
size_t const segmentSize = (dstSize+3) / 4;
BYTE* segmentEnd = (BYTE*)dst; BYTE* segmentEnd = (BYTE*)dst;
int i; int i;
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
@@ -1246,6 +1248,11 @@ HUF_decompress1X2_usingDTable_internal_body(
/* decoded size */ /* decoded size */
return dstSize; return dstSize;
} }
/* HUF_decompress4X2_usingDTable_internal_body():
* Conditions:
* @dstSize >= 6
*/
FORCE_INLINE_TEMPLATE size_t FORCE_INLINE_TEMPLATE size_t
HUF_decompress4X2_usingDTable_internal_body( HUF_decompress4X2_usingDTable_internal_body(
void* dst, size_t dstSize, void* dst, size_t dstSize,
@@ -1286,8 +1293,9 @@ HUF_decompress4X2_usingDTable_internal_body(
DTableDesc const dtd = HUF_getDTableDesc(DTable); DTableDesc const dtd = HUF_getDTableDesc(DTable);
U32 const dtLog = dtd.tableLog; U32 const dtLog = dtd.tableLog;
if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */
CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -785,7 +785,7 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
frameSizeInfo.compressedSize = (size_t)(ip - ipstart); frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
? zfh.frameContentSize ? zfh.frameContentSize
: nbBlocks * zfh.blockSizeMax; : (unsigned long long)nbBlocks * zfh.blockSizeMax;
return frameSizeInfo; return frameSizeInfo;
} }
} }
+18 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -166,6 +166,10 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
} }
RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
if (!singleStream)
RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,
"Not enough literals (%zu) for the 4-streams mode (min %u)",
litSize, MIN_LITERALS_FOR_4_STREAMS);
RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, ""); RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, ""); RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");
ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0); ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);
@@ -181,6 +185,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->litBuffer, litSize, istart+lhSize, litCSize,
dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx)); dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
} else { } else {
assert(litSize >= MIN_LITERALS_FOR_4_STREAMS);
hufSuccess = HUF_decompress4X_usingDTable_bmi2( hufSuccess = HUF_decompress4X_usingDTable_bmi2(
dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->litBuffer, litSize, istart+lhSize, litCSize,
dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx)); dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
@@ -509,7 +514,8 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
for (i = 8; i < n; i += 8) { for (i = 8; i < n; i += 8) {
MEM_write64(spread + pos + i, sv); MEM_write64(spread + pos + i, sv);
} }
pos += n; assert(n>=0);
pos += (size_t)n;
} }
} }
/* Now we spread those positions across the table. /* Now we spread those positions across the table.
@@ -2010,12 +2016,20 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
* Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN. * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.
* We don't expect that to be the case in 64-bit mode. * We don't expect that to be the case in 64-bit mode.
* In block mode, window size is not known, so we have to be conservative. * In block mode, window size is not known, so we have to be conservative.
* (note: but it could be evaluated from current-lowLimit) * (note: it could possibly be evaluated from current-lowLimit)
*/ */
ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || (dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN)))); ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || (dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))));
DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize); DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong, ""); /* Note : the wording of the specification
* allows compressed block to be sized exactly ZSTD_BLOCKSIZE_MAX.
* This generally does not happen, as it makes little sense,
* since an uncompressed block would feature same size and have no decompression cost.
* Also, note that decoder from reference libzstd before < v1.5.4
* would consider this edge case as an error.
* As a consequence, avoid generating compressed blocks of size ZSTD_BLOCKSIZE_MAX
* for broader compatibility with the deployed ecosystem of zstd decoders */
RETURN_ERROR_IF(srcSize > ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
/* Decode literals section */ /* Decode literals section */
{ size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming); { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -647,7 +647,7 @@ static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel) void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel)
{ {
const double ratio = (double)nbDmers / maxDictSize; const double ratio = (double)nbDmers / (double)maxDictSize;
if (ratio >= 10) { if (ratio >= 10) {
return; return;
} }
@@ -1040,7 +1040,7 @@ COVER_dictSelection_t COVER_selectDict(BYTE* customDictContent, size_t dictBuffe
return COVER_dictSelectionError(totalCompressedSize); return COVER_dictSelectionError(totalCompressedSize);
} }
if (totalCompressedSize <= largestCompressed * regressionTolerance) { if ((double)totalCompressedSize <= (double)largestCompressed * regressionTolerance) {
COVER_dictSelection_t selection = { candidateDictBuffer, dictContentSize, totalCompressedSize }; COVER_dictSelection_t selection = { candidateDictBuffer, dictContentSize, totalCompressedSize };
free(largestDictbuffer); free(largestDictbuffer);
return selection; return selection;
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -373,7 +373,7 @@ static U32 ZDICT_tryMerge(dictItem* table, dictItem elt, U32 eltNbToSkip, const
elt = table[u]; elt = table[u];
/* sort : improve rank */ /* sort : improve rank */
while ((u>1) && (table[u-1].savings < elt.savings)) while ((u>1) && (table[u-1].savings < elt.savings))
table[u] = table[u-1], u--; table[u] = table[u-1], u--;
table[u] = elt; table[u] = elt;
return u; return u;
} } } }
@@ -524,7 +524,7 @@ static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
if (solution.length==0) { cursor++; continue; } if (solution.length==0) { cursor++; continue; }
ZDICT_insertDictItem(dictList, dictListSize, solution, buffer); ZDICT_insertDictItem(dictList, dictListSize, solution, buffer);
cursor += solution.length; cursor += solution.length;
DISPLAYUPDATE(2, "\r%4.2f %% \r", (double)cursor / bufferSize * 100); DISPLAYUPDATE(2, "\r%4.2f %% \r", (double)cursor / (double)bufferSize * 100.0);
} } } }
_cleanup: _cleanup:
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+25 -17
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -15,17 +15,34 @@
# Zstd lib directory # Zstd lib directory
LIBZSTD ?= ./ LIBZSTD ?= ./
# ZSTD_LIB_MINIFY is a helper variable that
# configures a bunch of other variables to space-optimized defaults.
ZSTD_LIB_MINIFY ?= 0
# Legacy support # Legacy support
ZSTD_LEGACY_SUPPORT ?= 5 ifneq ($(ZSTD_LIB_MINIFY), 0)
ZSTD_LEGACY_SUPPORT ?= 0
else
ZSTD_LEGACY_SUPPORT ?= 5
endif
ZSTD_LEGACY_MULTITHREADED_API ?= 0 ZSTD_LEGACY_MULTITHREADED_API ?= 0
# Build size optimizations # Build size optimizations
HUF_FORCE_DECOMPRESS_X1 ?= 0 ifneq ($(ZSTD_LIB_MINIFY), 0)
HUF_FORCE_DECOMPRESS_X2 ?= 0 HUF_FORCE_DECOMPRESS_X1 ?= 1
ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 0 HUF_FORCE_DECOMPRESS_X2 ?= 0
ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG ?= 0 ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 1
ZSTD_NO_INLINE ?= 0 ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG ?= 0
ZSTD_STRIP_ERROR_STRINGS ?= 0 ZSTD_NO_INLINE ?= 1
ZSTD_STRIP_ERROR_STRINGS ?= 1
else
HUF_FORCE_DECOMPRESS_X1 ?= 0
HUF_FORCE_DECOMPRESS_X2 ?= 0
ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 0
ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG ?= 0
ZSTD_NO_INLINE ?= 0
ZSTD_STRIP_ERROR_STRINGS ?= 0
endif
# Assembly support # Assembly support
ZSTD_NO_ASM ?= 0 ZSTD_NO_ASM ?= 0
@@ -61,17 +78,8 @@ LIBVER := $(shell echo $(LIBVER_SCRIPT))
CCVER := $(shell $(CC) --version) CCVER := $(shell $(CC) --version)
ZSTD_VERSION?= $(LIBVER) ZSTD_VERSION?= $(LIBVER)
# ZSTD_LIB_MINIFY is a helper variable that
# configures a bunch of other variables to space-optimized defaults.
ZSTD_LIB_MINIFY ?= 0
ifneq ($(ZSTD_LIB_MINIFY), 0) ifneq ($(ZSTD_LIB_MINIFY), 0)
HAVE_CC_OZ ?= $(shell echo "" | $(CC) -Oz -x c -c - -o /dev/null 2> /dev/null && echo 1 || echo 0) HAVE_CC_OZ ?= $(shell echo "" | $(CC) -Oz -x c -c - -o /dev/null 2> /dev/null && echo 1 || echo 0)
ZSTD_LEGACY_SUPPORT ?= 0
ZSTD_LIB_DEPRECATED ?= 0
HUF_FORCE_DECOMPRESS_X1 ?= 1
ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 1
ZSTD_NO_INLINE ?= 1
ZSTD_STRIP_ERROR_STRINGS ?= 1
ifneq ($(HAVE_CC_OZ), 0) ifneq ($(HAVE_CC_OZ), 0)
# Some compilers (clang) support an even more space-optimized setting. # Some compilers (clang) support an even more space-optimized setting.
CFLAGS += -Oz CFLAGS += -Oz
+1 -1
View File
@@ -1,5 +1,5 @@
# ZSTD - standard compression algorithm # ZSTD - standard compression algorithm
# Copyright (C) 2014-2016, Yann Collet, Facebook # Copyright (c) Meta Platforms, Inc. and affiliates.
# BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php) # BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
prefix=@PREFIX@ prefix=@PREFIX@
+13 -3
View File
@@ -1,17 +1,27 @@
module libzstd [extern_c] { module libzstd [extern_c] {
header "zstd.h" header "zstd.h"
export * export *
config_macros [exhaustive] /* zstd.h */ \ config_macros [exhaustive] \
/* zstd.h */ \
ZSTD_STATIC_LINKING_ONLY, \ ZSTD_STATIC_LINKING_ONLY, \
ZSTDLIB_VISIBILITY, \
ZSTDLIB_VISIBLE, \ ZSTDLIB_VISIBLE, \
ZSTDLIB_HIDDEN, \
ZSTD_DLL_EXPORT, \ ZSTD_DLL_EXPORT, \
ZSTDLIB_STATIC_API, \ ZSTDLIB_STATIC_API, \
ZSTD_DISABLE_DEPRECATE_WARNINGS, \ ZSTD_DISABLE_DEPRECATE_WARNINGS, \
ZSTD_CLEVEL_DEFAULT, \ ZSTD_CLEVEL_DEFAULT, \
/* zdict.h */ ZDICT_STATIC_LINKING_ONLY, \ /* zdict.h */ \
ZDICT_STATIC_LINKING_ONLY, \
ZDICTLIB_VISIBLE, \
ZDICTLIB_HIDDEN, \
ZDICTLIB_VISIBILITY, \ ZDICTLIB_VISIBILITY, \
ZDICTLIB_STATIC_API, \
ZDICT_DISABLE_DEPRECATE_WARNINGS, \ ZDICT_DISABLE_DEPRECATE_WARNINGS, \
/* zstd_errors.h */ ZSTDERRORLIB_VISIBILITY /* zstd_errors.h */ \
ZSTDERRORLIB_VISIBLE, \
ZSTDERRORLIB_HIDDEN, \
ZSTDERRORLIB_VISIBILITY
module dictbuilder [extern_c] { module dictbuilder [extern_c] {
header "zdict.h" header "zdict.h"
+51 -29
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -8,32 +8,43 @@
* You may select, at your option, one of the above-listed licenses. * You may select, at your option, one of the above-listed licenses.
*/ */
#ifndef DICTBUILDER_H_001
#define DICTBUILDER_H_001
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
#ifndef ZSTD_ZDICT_H
#define ZSTD_ZDICT_H
/*====== Dependencies ======*/ /*====== Dependencies ======*/
#include <stddef.h> /* size_t */ #include <stddef.h> /* size_t */
/* ===== ZDICTLIB_API : control library symbols visibility ===== */ /* ===== ZDICTLIB_API : control library symbols visibility ===== */
#ifndef ZDICTLIB_VISIBILITY #ifndef ZDICTLIB_VISIBLE
# if defined(__GNUC__) && (__GNUC__ >= 4) /* Backwards compatibility with old macro name */
# define ZDICTLIB_VISIBILITY __attribute__ ((visibility ("default"))) # ifdef ZDICTLIB_VISIBILITY
# define ZDICTLIB_VISIBLE ZDICTLIB_VISIBILITY
# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
# define ZDICTLIB_VISIBLE __attribute__ ((visibility ("default")))
# else # else
# define ZDICTLIB_VISIBILITY # define ZDICTLIB_VISIBLE
# endif # endif
#endif #endif
#ifndef ZDICTLIB_HIDDEN
# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
# define ZDICTLIB_HIDDEN __attribute__ ((visibility ("hidden")))
# else
# define ZDICTLIB_HIDDEN
# endif
#endif
#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
# define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBILITY # define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBLE
#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
# define ZDICTLIB_API __declspec(dllimport) ZDICTLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ # define ZDICTLIB_API __declspec(dllimport) ZDICTLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
#else #else
# define ZDICTLIB_API ZDICTLIB_VISIBILITY # define ZDICTLIB_API ZDICTLIB_VISIBLE
#endif #endif
/******************************************************************************* /*******************************************************************************
@@ -201,9 +212,9 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCap
const size_t* samplesSizes, unsigned nbSamples); const size_t* samplesSizes, unsigned nbSamples);
typedef struct { typedef struct {
int compressionLevel; /*< optimize for a specific zstd compression level; 0 means default */ int compressionLevel; /**< optimize for a specific zstd compression level; 0 means default */
unsigned notificationLevel; /*< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */ unsigned notificationLevel; /**< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
unsigned dictID; /*< force dictID value; 0 means auto mode (32-bits random value) unsigned dictID; /**< force dictID value; 0 means auto mode (32-bits random value)
* NOTE: The zstd format reserves some dictionary IDs for future use. * NOTE: The zstd format reserves some dictionary IDs for future use.
* You may use them in private settings, but be warned that they * You may use them in private settings, but be warned that they
* may be used by zstd in a public dictionary registry in the future. * may be used by zstd in a public dictionary registry in the future.
@@ -260,9 +271,21 @@ ZDICTLIB_API size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictS
ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode); ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode);
ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode); ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode);
#endif /* ZSTD_ZDICT_H */
#if defined(ZDICT_STATIC_LINKING_ONLY) && !defined(ZSTD_ZDICT_H_STATIC)
#define ZSTD_ZDICT_H_STATIC
#ifdef ZDICT_STATIC_LINKING_ONLY /* This can be overridden externally to hide static symbols. */
#ifndef ZDICTLIB_STATIC_API
# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
# define ZDICTLIB_STATIC_API __declspec(dllexport) ZDICTLIB_VISIBLE
# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
# define ZDICTLIB_STATIC_API __declspec(dllimport) ZDICTLIB_VISIBLE
# else
# define ZDICTLIB_STATIC_API ZDICTLIB_VISIBLE
# endif
#endif
/* ==================================================================================== /* ====================================================================================
* The definitions in this section are considered experimental. * The definitions in this section are considered experimental.
@@ -318,7 +341,7 @@ typedef struct {
* In general, it's recommended to provide a few thousands samples, though this can vary a lot. * In general, it's recommended to provide a few thousands samples, though this can vary a lot.
* It's recommended that total size of all samples be about ~x100 times the target size of dictionary. * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
*/ */
ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover( ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
void *dictBuffer, size_t dictBufferCapacity, void *dictBuffer, size_t dictBufferCapacity,
const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples,
ZDICT_cover_params_t parameters); ZDICT_cover_params_t parameters);
@@ -340,7 +363,7 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover(
* See ZDICT_trainFromBuffer() for details on failure modes. * See ZDICT_trainFromBuffer() for details on failure modes.
* Note: ZDICT_optimizeTrainFromBuffer_cover() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread. * Note: ZDICT_optimizeTrainFromBuffer_cover() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread.
*/ */
ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover( ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
void* dictBuffer, size_t dictBufferCapacity, void* dictBuffer, size_t dictBufferCapacity,
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
ZDICT_cover_params_t* parameters); ZDICT_cover_params_t* parameters);
@@ -361,7 +384,7 @@ ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
* In general, it's recommended to provide a few thousands samples, though this can vary a lot. * In general, it's recommended to provide a few thousands samples, though this can vary a lot.
* It's recommended that total size of all samples be about ~x100 times the target size of dictionary. * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
*/ */
ZDICTLIB_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer, ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer,
size_t dictBufferCapacity, const void *samplesBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
const size_t *samplesSizes, unsigned nbSamples, const size_t *samplesSizes, unsigned nbSamples,
ZDICT_fastCover_params_t parameters); ZDICT_fastCover_params_t parameters);
@@ -384,7 +407,7 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer,
* See ZDICT_trainFromBuffer() for details on failure modes. * See ZDICT_trainFromBuffer() for details on failure modes.
* Note: ZDICT_optimizeTrainFromBuffer_fastCover() requires about 6 * 2^f bytes of memory for each thread. * Note: ZDICT_optimizeTrainFromBuffer_fastCover() requires about 6 * 2^f bytes of memory for each thread.
*/ */
ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer, ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer,
size_t dictBufferCapacity, const void* samplesBuffer, size_t dictBufferCapacity, const void* samplesBuffer,
const size_t* samplesSizes, unsigned nbSamples, const size_t* samplesSizes, unsigned nbSamples,
ZDICT_fastCover_params_t* parameters); ZDICT_fastCover_params_t* parameters);
@@ -409,7 +432,7 @@ typedef struct {
* It's recommended that total size of all samples be about ~x100 times the target size of dictionary. * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
* Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0. * Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0.
*/ */
ZDICTLIB_API size_t ZDICT_trainFromBuffer_legacy( ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_legacy(
void* dictBuffer, size_t dictBufferCapacity, void* dictBuffer, size_t dictBufferCapacity,
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
ZDICT_legacy_params_t parameters); ZDICT_legacy_params_t parameters);
@@ -421,32 +444,31 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer_legacy(
or _CRT_SECURE_NO_WARNINGS in Visual. or _CRT_SECURE_NO_WARNINGS in Visual.
Otherwise, it's also possible to manually define ZDICT_DISABLE_DEPRECATE_WARNINGS */ Otherwise, it's also possible to manually define ZDICT_DISABLE_DEPRECATE_WARNINGS */
#ifdef ZDICT_DISABLE_DEPRECATE_WARNINGS #ifdef ZDICT_DISABLE_DEPRECATE_WARNINGS
# define ZDICT_DEPRECATED(message) ZDICTLIB_API /* disable deprecation warnings */ # define ZDICT_DEPRECATED(message) /* disable deprecation warnings */
#else #else
# define ZDICT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) # define ZDICT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ # if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
# define ZDICT_DEPRECATED(message) [[deprecated(message)]] ZDICTLIB_API # define ZDICT_DEPRECATED(message) [[deprecated(message)]]
# elif defined(__clang__) || (ZDICT_GCC_VERSION >= 405) # elif defined(__clang__) || (ZDICT_GCC_VERSION >= 405)
# define ZDICT_DEPRECATED(message) ZDICTLIB_API __attribute__((deprecated(message))) # define ZDICT_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (ZDICT_GCC_VERSION >= 301) # elif (ZDICT_GCC_VERSION >= 301)
# define ZDICT_DEPRECATED(message) ZDICTLIB_API __attribute__((deprecated)) # define ZDICT_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
# define ZDICT_DEPRECATED(message) ZDICTLIB_API __declspec(deprecated(message)) # define ZDICT_DEPRECATED(message) __declspec(deprecated(message))
# else # else
# pragma message("WARNING: You need to implement ZDICT_DEPRECATED for this compiler") # pragma message("WARNING: You need to implement ZDICT_DEPRECATED for this compiler")
# define ZDICT_DEPRECATED(message) ZDICTLIB_API # define ZDICT_DEPRECATED(message)
# endif # endif
#endif /* ZDICT_DISABLE_DEPRECATE_WARNINGS */ #endif /* ZDICT_DISABLE_DEPRECATE_WARNINGS */
ZDICT_DEPRECATED("use ZDICT_finalizeDictionary() instead") ZDICT_DEPRECATED("use ZDICT_finalizeDictionary() instead")
ZDICTLIB_STATIC_API
size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples); const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
#endif /* ZDICT_STATIC_LINKING_ONLY */ #endif /* ZSTD_ZDICT_H_STATIC */
#if defined (__cplusplus) #if defined (__cplusplus)
} }
#endif #endif
#endif /* DICTBUILDER_H_001 */
+227 -24
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -21,14 +21,24 @@ extern "C" {
/* ===== ZSTDLIB_API : control library symbols visibility ===== */ /* ===== ZSTDLIB_API : control library symbols visibility ===== */
#ifndef ZSTDLIB_VISIBLE #ifndef ZSTDLIB_VISIBLE
# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) /* Backwards compatibility with old macro name */
# ifdef ZSTDLIB_VISIBILITY
# define ZSTDLIB_VISIBLE ZSTDLIB_VISIBILITY
# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
# define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default"))) # define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default")))
# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden")))
# else # else
# define ZSTDLIB_VISIBLE # define ZSTDLIB_VISIBLE
# endif
#endif
#ifndef ZSTDLIB_HIDDEN
# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden")))
# else
# define ZSTDLIB_HIDDEN # define ZSTDLIB_HIDDEN
# endif # endif
#endif #endif
#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE # define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE
#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
@@ -201,8 +211,30 @@ ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize)
/*====== Helper functions ======*/ /*====== Helper functions ======*/
#define ZSTD_COMPRESSBOUND(srcSize) ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ /* ZSTD_compressBound() :
ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ * maximum compressed size in worst case single-pass scenario.
* When invoking `ZSTD_compress()` or any other one-pass compression function,
* it's recommended to provide @dstCapacity >= ZSTD_compressBound(srcSize)
* as it eliminates one potential failure scenario,
* aka not enough room in dst buffer to write the compressed frame.
* Note : ZSTD_compressBound() itself can fail, if @srcSize > ZSTD_MAX_INPUT_SIZE .
* In which case, ZSTD_compressBound() will return an error code
* which can be tested using ZSTD_isError().
*
* ZSTD_COMPRESSBOUND() :
* same as ZSTD_compressBound(), but as a macro.
* It can be used to produce constants, which can be useful for static allocation,
* for example to size a static array on stack.
* Will produce constant value 0 if srcSize too large.
*/
#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00LLU : 0xFF00FF00U)
#define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */
ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */
/* ZSTD_isError() :
* Most ZSTD_* functions returning a size_t value can be tested for error,
* using ZSTD_isError().
* @return 1 if error, 0 otherwise
*/
ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */ ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */
ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed, requires v1.4.0+ */ ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed, requires v1.4.0+ */
@@ -446,6 +478,8 @@ typedef enum {
* ZSTD_c_useBlockSplitter * ZSTD_c_useBlockSplitter
* ZSTD_c_useRowMatchFinder * ZSTD_c_useRowMatchFinder
* ZSTD_c_prefetchCDictTables * ZSTD_c_prefetchCDictTables
* ZSTD_c_enableMatchFinderFallback
* ZSTD_c_maxBlockSize
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly; * note : never ever use experimentalParam? names directly;
* also, the enums values themselves are unstable and can still change. * also, the enums values themselves are unstable and can still change.
@@ -465,7 +499,10 @@ typedef enum {
ZSTD_c_experimentalParam13=1010, ZSTD_c_experimentalParam13=1010,
ZSTD_c_experimentalParam14=1011, ZSTD_c_experimentalParam14=1011,
ZSTD_c_experimentalParam15=1012, ZSTD_c_experimentalParam15=1012,
ZSTD_c_experimentalParam16=1013 ZSTD_c_experimentalParam16=1013,
ZSTD_c_experimentalParam17=1014,
ZSTD_c_experimentalParam18=1015,
} ZSTD_cParameter; } ZSTD_cParameter;
typedef struct { typedef struct {
@@ -528,7 +565,7 @@ typedef enum {
* They will be used to compress next frame. * They will be used to compress next frame.
* Resetting session never fails. * Resetting session never fails.
* - The parameters : changes all parameters back to "default". * - The parameters : changes all parameters back to "default".
* This removes any reference to any dictionary too. * This also removes any reference to any dictionary or external matchfinder.
* Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing) * Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing)
* otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError()) * otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError())
* - Both : similar to resetting the session, followed by resetting parameters. * - Both : similar to resetting the session, followed by resetting parameters.
@@ -990,8 +1027,9 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
* @result : 0, or an error code (which can be tested with ZSTD_isError()). * @result : 0, or an error code (which can be tested with ZSTD_isError()).
* Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary, * Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary,
* meaning "return to no-dictionary mode". * meaning "return to no-dictionary mode".
* Note 1 : Dictionary is sticky, it will be used for all future compressed frames. * Note 1 : Dictionary is sticky, it will be used for all future compressed frames,
* To return to "no-dictionary" situation, load a NULL dictionary (or reset parameters). * until parameters are reset, a new dictionary is loaded, or the dictionary
* is explicitly invalidated by loading a NULL dictionary.
* Note 2 : Loading a dictionary involves building tables. * Note 2 : Loading a dictionary involves building tables.
* It's also a CPU consuming operation, with non-negligible impact on latency. * It's also a CPU consuming operation, with non-negligible impact on latency.
* Tables are dependent on compression parameters, and for this reason, * Tables are dependent on compression parameters, and for this reason,
@@ -1004,7 +1042,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
/*! ZSTD_CCtx_refCDict() : Requires v1.4.0+ /*! ZSTD_CCtx_refCDict() : Requires v1.4.0+
* Reference a prepared dictionary, to be used for all next compressed frames. * Reference a prepared dictionary, to be used for all future compressed frames.
* Note that compression parameters are enforced from within CDict, * Note that compression parameters are enforced from within CDict,
* and supersede any compression parameter previously set within CCtx. * and supersede any compression parameter previously set within CCtx.
* The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs. * The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs.
@@ -1039,9 +1077,9 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx,
const void* prefix, size_t prefixSize); const void* prefix, size_t prefixSize);
/*! ZSTD_DCtx_loadDictionary() : Requires v1.4.0+ /*! ZSTD_DCtx_loadDictionary() : Requires v1.4.0+
* Create an internal DDict from dict buffer, * Create an internal DDict from dict buffer, to be used to decompress all future frames.
* to be used to decompress next frames. * The dictionary remains valid for all future frames, until explicitly invalidated, or
* The dictionary remains valid for all future frames, until explicitly invalidated. * a new dictionary is loaded.
* @result : 0, or an error code (which can be tested with ZSTD_isError()). * @result : 0, or an error code (which can be tested with ZSTD_isError()).
* Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
* meaning "return to no-dictionary mode". * meaning "return to no-dictionary mode".
@@ -1065,9 +1103,10 @@ ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, s
* The memory for the table is allocated on the first call to refDDict, and can be * The memory for the table is allocated on the first call to refDDict, and can be
* freed with ZSTD_freeDCtx(). * freed with ZSTD_freeDCtx().
* *
* If called with ZSTD_d_refMultipleDDicts disabled (the default), only one dictionary
* will be managed, and referencing a dictionary effectively "discards" any previous one.
*
* @result : 0, or an error code (which can be tested with ZSTD_isError()). * @result : 0, or an error code (which can be tested with ZSTD_isError()).
* Note 1 : Currently, only one dictionary can be managed.
* Referencing a new dictionary effectively "discards" any previous one.
* Special: referencing a NULL DDict means "return to no-dictionary mode". * Special: referencing a NULL DDict means "return to no-dictionary mode".
* Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. * Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx.
*/ */
@@ -1706,6 +1745,13 @@ ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
* This function never fails (wide contract) */ * This function never fails (wide contract) */
ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
/*! ZSTD_CCtx_setCParams() :
* Set all parameters provided within @cparams into the working @cctx.
* Note : if modifying parameters during compression (MT mode only),
* note that changes to the .windowLog parameter will be ignored.
* @return 0 on success, or an error code (can be checked with ZSTD_isError()) */
ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams);
/*! ZSTD_compress_advanced() : /*! ZSTD_compress_advanced() :
* Note : this function is now DEPRECATED. * Note : this function is now DEPRECATED.
* It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters.
@@ -1713,10 +1759,10 @@ ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressio
ZSTD_DEPRECATED("use ZSTD_compress2") ZSTD_DEPRECATED("use ZSTD_compress2")
ZSTDLIB_STATIC_API ZSTDLIB_STATIC_API
size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx, size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const void* dict,size_t dictSize, const void* dict,size_t dictSize,
ZSTD_parameters params); ZSTD_parameters params);
/*! ZSTD_compress_usingCDict_advanced() : /*! ZSTD_compress_usingCDict_advanced() :
* Note : this function is now DEPRECATED. * Note : this function is now DEPRECATED.
@@ -2010,6 +2056,27 @@ ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const vo
*/ */
#define ZSTD_c_prefetchCDictTables ZSTD_c_experimentalParam16 #define ZSTD_c_prefetchCDictTables ZSTD_c_experimentalParam16
/* ZSTD_c_enableMatchFinderFallback
* Allowed values are 0 (disable) and 1 (enable). The default setting is 0.
*
* Controls whether zstd will fall back to an internal matchfinder if an
* external matchfinder is registered and returns an error code. This fallback is
* block-by-block: the internal matchfinder will only be called for blocks where
* the external matchfinder returns an error code. Fallback compression will
* follow any other cParam settings, such as compression level, the same as in a
* normal (fully-internal) compression operation.
*
* The user is strongly encouraged to read the full external matchfinder API
* documentation (below) before setting this parameter. */
#define ZSTD_c_enableMatchFinderFallback ZSTD_c_experimentalParam17
/* ZSTD_c_maxBlockSize
*
* Default is ZSTD_BLOCKSIZE_MAX.
*
*/
#define ZSTD_c_maxBlockSize ZSTD_c_experimentalParam18
/*! ZSTD_CCtx_getParameter() : /*! ZSTD_CCtx_getParameter() :
* Get the requested compression parameter value, selected by enum ZSTD_cParameter, * Get the requested compression parameter value, selected by enum ZSTD_cParameter,
* and store it into int* value. * and store it into int* value.
@@ -2476,8 +2543,8 @@ ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLev
ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
ZSTDLIB_STATIC_API
ZSTD_DEPRECATED("This function will likely be removed in a future release. It is misleading and has very limited utility.") ZSTD_DEPRECATED("This function will likely be removed in a future release. It is misleading and has very limited utility.")
ZSTDLIB_STATIC_API
size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
@@ -2501,8 +2568,8 @@ size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_
Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.
Data fragment must be large enough to ensure successful decoding. Data fragment must be large enough to ensure successful decoding.
`ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough.
@result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled.
>0 : `srcSize` is too small, please provide at least @result bytes on next attempt. >0 : `srcSize` is too small, please provide at least result bytes on next attempt.
errorCode, which can be tested using ZSTD_isError(). errorCode, which can be tested using ZSTD_isError().
It fills a ZSTD_frameHeader structure with important information to correctly decode the frame, It fills a ZSTD_frameHeader structure with important information to correctly decode the frame,
@@ -2521,7 +2588,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_
The most memory efficient way is to use a round buffer of sufficient size. The most memory efficient way is to use a round buffer of sufficient size.
Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(),
which can @return an error code if required value is too large for current system (in 32-bits mode). which can return an error code if required value is too large for current system (in 32-bits mode).
In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one,
up to the moment there is not enough room left in the buffer to guarantee decoding another full block, up to the moment there is not enough room left in the buffer to guarantee decoding another full block,
which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`.
@@ -2541,7 +2608,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_
ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
@result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item.
It can also be an error code, which can be tested with ZSTD_isError(). It can also be an error code, which can be tested with ZSTD_isError().
@@ -2642,6 +2709,142 @@ ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_
ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
/* ********************** EXTERNAL MATCHFINDER API **********************
*
* *** OVERVIEW ***
* This API allows users to replace the zstd internal block-level matchfinder
* with an external matchfinder function. Potential applications of the API
* include hardware-accelerated matchfinders and matchfinders specialized to
* particular types of data.
*
* See contrib/externalMatchfinder for an example program employing the
* external matchfinder API.
*
* *** USAGE ***
* The user is responsible for implementing a function of type
* ZSTD_externalMatchFinder_F. For each block, zstd will pass the following
* arguments to the user-provided function:
*
* - externalMatchState: a pointer to a user-managed state for the external
* matchfinder.
*
* - outSeqs, outSeqsCapacity: an output buffer for sequences produced by the
* external matchfinder. outSeqsCapacity is guaranteed >=
* ZSTD_sequenceBound(srcSize). The memory backing outSeqs is managed by
* the CCtx.
*
* - src, srcSize: an input buffer which the external matchfinder must parse
* into sequences. srcSize is guaranteed to be <= ZSTD_BLOCKSIZE_MAX.
*
* - dict, dictSize: a history buffer, which may be empty, which the external
* matchfinder may reference as it produces sequences for the src buffer.
* Currently, zstd will always pass dictSize == 0 into external matchfinders,
* but this will change in the future.
*
* - compressionLevel: a signed integer representing the zstd compression level
* set by the user for the current operation. The external matchfinder may
* choose to use this information to change its compression strategy and
* speed/ratio tradeoff. Note: The compression level does not reflect zstd
* parameters set through the advanced API.
*
* - windowSize: a size_t representing the maximum allowed offset for external
* sequences. Note that sequence offsets are sometimes allowed to exceed the
* windowSize if a dictionary is present, see doc/zstd_compression_format.md
* for details.
*
* The user-provided function shall return a size_t representing the number of
* sequences written to outSeqs. This return value will be treated as an error
* code if it is greater than outSeqsCapacity. The return value must be non-zero
* if srcSize is non-zero. The ZSTD_EXTERNAL_MATCHFINDER_ERROR macro is provided
* for convenience, but any value greater than outSeqsCapacity will be treated as
* an error code.
*
* If the user-provided function does not return an error code, the sequences
* written to outSeqs must be a valid parse of the src buffer. Data corruption may
* occur if the parse is not valid. A parse is defined to be valid if the
* following conditions hold:
* - The sum of matchLengths and literalLengths is equal to srcSize.
* - All sequences in the parse have matchLength != 0, except for the final
* sequence. matchLength is not constrained for the final sequence.
* - All offsets respect the windowSize parameter as specified in
* doc/zstd_compression_format.md.
*
* zstd will only validate these conditions (and fail compression if they do not
* hold) if the ZSTD_c_validateSequences cParam is enabled. Note that sequence
* validation has a performance cost.
*
* If the user-provided function returns an error, zstd will either fall back
* to an internal matchfinder or fail the compression operation. The user can
* choose between the two behaviors by setting the
* ZSTD_c_enableMatchFinderFallback cParam. Fallback compression will follow any
* other cParam settings, such as compression level, the same as in a normal
* compression operation.
*
* The user shall instruct zstd to use a particular ZSTD_externalMatchFinder_F
* function by calling ZSTD_registerExternalMatchFinder(cctx, externalMatchState,
* externalMatchFinder). This setting will persist until the next parameter reset
* of the CCtx.
*
* The externalMatchState must be initialized by the user before calling
* ZSTD_registerExternalMatchFinder. The user is responsible for destroying the
* externalMatchState.
*
* *** LIMITATIONS ***
* External matchfinders are compatible with all zstd compression APIs. There are
* only two limitations.
*
* First, the ZSTD_c_enableLongDistanceMatching cParam is not supported.
* COMPRESSION WILL FAIL if it is enabled and the user tries to compress with an
* external matchfinder.
* - Note that ZSTD_c_enableLongDistanceMatching is auto-enabled by default in
* some cases (see its documentation for details). Users must explicitly set
* ZSTD_c_enableLongDistanceMatching to ZSTD_ps_disable in such cases if an
* external matchfinder is registered.
* - As of this writing, ZSTD_c_enableLongDistanceMatching is disabled by default
* whenever ZSTD_c_windowLog < 128MB, but that's subject to change. Users should
* check the docs on ZSTD_c_enableLongDistanceMatching whenever the external
* matchfinder API is used in conjunction with advanced settings (like windowLog).
*
* Second, history buffers are not supported. Concretely, zstd will always pass
* dictSize == 0 to the external matchfinder (for now). This has two implications:
* - Dictionaries are not supported. Compression will *not* fail if the user
* references a dictionary, but the dictionary won't have any effect.
* - Stream history is not supported. All compression APIs, including streaming
* APIs, work with the external matchfinder, but the external matchfinder won't
* receive any history from the previous block. Each block is an independent chunk.
*
* Long-term, we plan to overcome both limitations. There is no technical blocker to
* overcoming them. It is purely a question of engineering effort.
*/
#define ZSTD_EXTERNAL_MATCHFINDER_ERROR ((size_t)(-1))
typedef size_t ZSTD_externalMatchFinder_F (
void* externalMatchState,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize,
const void* dict, size_t dictSize,
int compressionLevel,
size_t windowSize
);
/*! ZSTD_registerExternalMatchFinder() :
* Instruct zstd to use an external matchfinder function.
*
* The externalMatchState must be initialized by the caller, and the caller is
* responsible for managing its lifetime. This parameter is sticky across
* compressions. It will remain set until the user explicitly resets compression
* parameters.
*
* The user is strongly encouraged to read the full API documentation (above)
* before calling this function. */
ZSTDLIB_STATIC_API void
ZSTD_registerExternalMatchFinder(
ZSTD_CCtx* cctx,
void* externalMatchState,
ZSTD_externalMatchFinder_F* externalMatchFinder
);
#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ #endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */
#if defined (__cplusplus) #if defined (__cplusplus)
+23 -8
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -20,19 +20,31 @@ extern "C" {
/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */ /* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */
#ifndef ZSTDERRORLIB_VISIBILITY #ifndef ZSTDERRORLIB_VISIBLE
# if defined(__GNUC__) && (__GNUC__ >= 4) /* Backwards compatibility with old macro name */
# define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default"))) # ifdef ZSTDERRORLIB_VISIBILITY
# define ZSTDERRORLIB_VISIBLE ZSTDERRORLIB_VISIBILITY
# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
# define ZSTDERRORLIB_VISIBLE __attribute__ ((visibility ("default")))
# else # else
# define ZSTDERRORLIB_VISIBILITY # define ZSTDERRORLIB_VISIBLE
# endif # endif
#endif #endif
#ifndef ZSTDERRORLIB_HIDDEN
# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
# define ZSTDERRORLIB_HIDDEN __attribute__ ((visibility ("hidden")))
# else
# define ZSTDERRORLIB_HIDDEN
# endif
#endif
#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY # define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBLE
#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ # define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
#else #else
# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY # define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBLE
#endif #endif
/*-********************************************* /*-*********************************************
@@ -58,10 +70,12 @@ typedef enum {
ZSTD_error_frameParameter_windowTooLarge = 16, ZSTD_error_frameParameter_windowTooLarge = 16,
ZSTD_error_corruption_detected = 20, ZSTD_error_corruption_detected = 20,
ZSTD_error_checksum_wrong = 22, ZSTD_error_checksum_wrong = 22,
ZSTD_error_literals_headerWrong = 24,
ZSTD_error_dictionary_corrupted = 30, ZSTD_error_dictionary_corrupted = 30,
ZSTD_error_dictionary_wrong = 32, ZSTD_error_dictionary_wrong = 32,
ZSTD_error_dictionaryCreation_failed = 34, ZSTD_error_dictionaryCreation_failed = 34,
ZSTD_error_parameter_unsupported = 40, ZSTD_error_parameter_unsupported = 40,
ZSTD_error_parameter_combination_unsupported = 41,
ZSTD_error_parameter_outOfBound = 42, ZSTD_error_parameter_outOfBound = 42,
ZSTD_error_tableLog_tooLarge = 44, ZSTD_error_tableLog_tooLarge = 44,
ZSTD_error_maxSymbolValue_tooLarge = 46, ZSTD_error_maxSymbolValue_tooLarge = 46,
@@ -79,6 +93,7 @@ typedef enum {
ZSTD_error_seekableIO = 102, ZSTD_error_seekableIO = 102,
ZSTD_error_dstBuffer_wrong = 104, ZSTD_error_dstBuffer_wrong = 104,
ZSTD_error_srcBuffer_wrong = 105, ZSTD_error_srcBuffer_wrong = 105,
ZSTD_error_externalMatchFinder_failed = 106,
ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
} ZSTD_ErrorCode; } ZSTD_ErrorCode;
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+4 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -229,9 +229,9 @@ BMK_runOutcome_t BMK_benchTimedFn(BMK_timedFnState_t* cont,
cont->timeSpent_ns += (unsigned long long)loopDuration_ns; cont->timeSpent_ns += (unsigned long long)loopDuration_ns;
/* estimate nbLoops for next run to last approximately 1 second */ /* estimate nbLoops for next run to last approximately 1 second */
if (loopDuration_ns > (runBudget_ns / 50)) { if (loopDuration_ns > ((double)runBudget_ns / 50)) {
double const fastestRun_ns = MIN(bestRunTime.nanoSecPerRun, newRunTime.nanoSecPerRun); double const fastestRun_ns = MIN(bestRunTime.nanoSecPerRun, newRunTime.nanoSecPerRun);
cont->nbLoops = (unsigned)(runBudget_ns / fastestRun_ns) + 1; cont->nbLoops = (unsigned)((double)runBudget_ns / fastestRun_ns) + 1;
} else { } else {
/* previous run was too short : blindly increase workload by x multiplier */ /* previous run was too short : blindly increase workload by x multiplier */
const unsigned multiplier = 10; const unsigned multiplier = 10;
@@ -239,7 +239,7 @@ BMK_runOutcome_t BMK_benchTimedFn(BMK_timedFnState_t* cont,
cont->nbLoops *= multiplier; cont->nbLoops *= multiplier;
} }
if(loopDuration_ns < runTimeMin_ns) { if(loopDuration_ns < (double)runTimeMin_ns) {
/* don't report results for which benchmark run time was too small : increased risks of rounding errors */ /* don't report results for which benchmark run time was too small : increased risks of rounding errors */
assert(completed == 0); assert(completed == 0);
continue; continue;
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+7 -7
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -1059,12 +1059,12 @@ FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but no
DISPLAYUPDATE_PROGRESS( DISPLAYUPDATE_PROGRESS(
"\rRead : %u MB ==> %.2f%% ", "\rRead : %u MB ==> %.2f%% ",
(unsigned)(inFileSize>>20), (unsigned)(inFileSize>>20),
(double)outFileSize/inFileSize*100) (double)outFileSize/(double)inFileSize*100)
} else { } else {
DISPLAYUPDATE_PROGRESS( DISPLAYUPDATE_PROGRESS(
"\rRead : %u / %u MB ==> %.2f%% ", "\rRead : %u / %u MB ==> %.2f%% ",
(unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20), (unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20),
(double)outFileSize/inFileSize*100); (double)outFileSize/(double)inFileSize*100);
} } } }
while (1) { while (1) {
@@ -1157,11 +1157,11 @@ FIO_compressLzmaFrame(cRess_t* ress,
if (srcFileSize == UTIL_FILESIZE_UNKNOWN) if (srcFileSize == UTIL_FILESIZE_UNKNOWN)
DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%", DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%",
(unsigned)(inFileSize>>20), (unsigned)(inFileSize>>20),
(double)outFileSize/inFileSize*100) (double)outFileSize/(double)inFileSize*100)
else else
DISPLAYUPDATE_PROGRESS("\rRead : %u / %u MB ==> %.2f%%", DISPLAYUPDATE_PROGRESS("\rRead : %u / %u MB ==> %.2f%%",
(unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20), (unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20),
(double)outFileSize/inFileSize*100); (double)outFileSize/(double)inFileSize*100);
if (ret == LZMA_STREAM_END) break; if (ret == LZMA_STREAM_END) break;
} }
@@ -1241,11 +1241,11 @@ FIO_compressLz4Frame(cRess_t* ress,
if (srcFileSize == UTIL_FILESIZE_UNKNOWN) { if (srcFileSize == UTIL_FILESIZE_UNKNOWN) {
DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%", DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%",
(unsigned)(inFileSize>>20), (unsigned)(inFileSize>>20),
(double)outFileSize/inFileSize*100) (double)outFileSize/(double)inFileSize*100)
} else { } else {
DISPLAYUPDATE_PROGRESS("\rRead : %u / %u MB ==> %.2f%%", DISPLAYUPDATE_PROGRESS("\rRead : %u / %u MB ==> %.2f%%",
(unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20), (unsigned)(inFileSize>>20), (unsigned)(srcFileSize>>20),
(double)outFileSize/inFileSize*100); (double)outFileSize/(double)inFileSize*100);
} }
/* Write Block */ /* Write Block */
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+132 -35
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -66,6 +66,27 @@ extern "C" {
#define UTIL_DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define UTIL_DISPLAY(...) fprintf(stderr, __VA_ARGS__)
#define UTIL_DISPLAYLEVEL(l, ...) { if (g_utilDisplayLevel>=l) { UTIL_DISPLAY(__VA_ARGS__); } } #define UTIL_DISPLAYLEVEL(l, ...) { if (g_utilDisplayLevel>=l) { UTIL_DISPLAY(__VA_ARGS__); } }
static int g_traceDepth = 0;
int g_traceFileStat = 0;
#define UTIL_TRACE_CALL(...) \
{ \
if (g_traceFileStat) { \
UTIL_DISPLAY("Trace:FileStat: %*s> ", g_traceDepth, ""); \
UTIL_DISPLAY(__VA_ARGS__); \
UTIL_DISPLAY("\n"); \
++g_traceDepth; \
} \
}
#define UTIL_TRACE_RET(ret) \
{ \
if (g_traceFileStat) { \
--g_traceDepth; \
UTIL_DISPLAY("Trace:FileStat: %*s< %d\n", g_traceDepth, "", (ret)); \
} \
}
/* A modified version of realloc(). /* A modified version of realloc().
* If UTIL_realloc() fails the original block is freed. * If UTIL_realloc() fails the original block is freed.
*/ */
@@ -121,21 +142,34 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg,
* Functions * Functions
***************************************/ ***************************************/
void UTIL_traceFileStat(void)
{
g_traceFileStat = 1;
}
int UTIL_stat(const char* filename, stat_t* statbuf) int UTIL_stat(const char* filename, stat_t* statbuf)
{ {
int ret;
UTIL_TRACE_CALL("UTIL_stat(%s)", filename);
#if defined(_MSC_VER) #if defined(_MSC_VER)
return !_stat64(filename, statbuf); ret = !_stat64(filename, statbuf);
#elif defined(__MINGW32__) && defined (__MSVCRT__) #elif defined(__MINGW32__) && defined (__MSVCRT__)
return !_stati64(filename, statbuf); ret = !_stati64(filename, statbuf);
#else #else
return !stat(filename, statbuf); ret = !stat(filename, statbuf);
#endif #endif
UTIL_TRACE_RET(ret);
return ret;
} }
int UTIL_isRegularFile(const char* infilename) int UTIL_isRegularFile(const char* infilename)
{ {
stat_t statbuf; stat_t statbuf;
return UTIL_stat(infilename, &statbuf) && UTIL_isRegularFileStat(&statbuf); int ret;
UTIL_TRACE_CALL("UTIL_isRegularFile(%s)", infilename);
ret = UTIL_stat(infilename, &statbuf) && UTIL_isRegularFileStat(&statbuf);
UTIL_TRACE_RET(ret);
return ret;
} }
int UTIL_isRegularFileStat(const stat_t* statbuf) int UTIL_isRegularFileStat(const stat_t* statbuf)
@@ -151,44 +185,66 @@ int UTIL_isRegularFileStat(const stat_t* statbuf)
int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions) int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions)
{ {
stat_t localStatBuf; stat_t localStatBuf;
UTIL_TRACE_CALL("UTIL_chmod(%s, %u)", filename, (unsigned)permissions);
if (statbuf == NULL) { if (statbuf == NULL) {
if (!UTIL_stat(filename, &localStatBuf)) return 0; if (!UTIL_stat(filename, &localStatBuf)) {
UTIL_TRACE_RET(0);
return 0;
}
statbuf = &localStatBuf; statbuf = &localStatBuf;
} }
if (!UTIL_isRegularFileStat(statbuf)) return 0; /* pretend success, but don't change anything */ if (!UTIL_isRegularFileStat(statbuf)) {
return chmod(filename, permissions); UTIL_TRACE_RET(0);
return 0; /* pretend success, but don't change anything */
}
UTIL_TRACE_CALL("chmod");
{
int const ret = chmod(filename, permissions);
UTIL_TRACE_RET(ret);
UTIL_TRACE_RET(ret);
return ret;
}
} }
/* set access and modification times */ /* set access and modification times */
int UTIL_utime(const char* filename, const stat_t *statbuf) int UTIL_utime(const char* filename, const stat_t *statbuf)
{ {
int ret; int ret;
UTIL_TRACE_CALL("UTIL_utime(%s)", filename);
/* We check that st_mtime is a macro here in order to give us confidence /* We check that st_mtime is a macro here in order to give us confidence
* that struct stat has a struct timespec st_mtim member. We need this * that struct stat has a struct timespec st_mtim member. We need this
* check because there are some platforms that claim to be POSIX 2008 * check because there are some platforms that claim to be POSIX 2008
* compliant but which do not have st_mtim... */ * compliant but which do not have st_mtim... */
#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime) #if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime)
/* (atime, mtime) */ {
struct timespec timebuf[2] = { {0, UTIME_NOW} }; /* (atime, mtime) */
timebuf[1] = statbuf->st_mtim; struct timespec timebuf[2] = { {0, UTIME_NOW} };
ret = utimensat(AT_FDCWD, filename, timebuf, 0); timebuf[1] = statbuf->st_mtim;
ret = utimensat(AT_FDCWD, filename, timebuf, 0);
}
#else #else
struct utimbuf timebuf; {
timebuf.actime = time(NULL); struct utimbuf timebuf;
timebuf.modtime = statbuf->st_mtime; timebuf.actime = time(NULL);
ret = utime(filename, &timebuf); timebuf.modtime = statbuf->st_mtime;
ret = utime(filename, &timebuf);
}
#endif #endif
errno = 0; errno = 0;
UTIL_TRACE_RET(ret);
return ret; return ret;
} }
int UTIL_setFileStat(const char *filename, const stat_t *statbuf) int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
{ {
int res = 0; int res = 0;
stat_t curStatBuf; stat_t curStatBuf;
if (!UTIL_stat(filename, &curStatBuf) || !UTIL_isRegularFileStat(&curStatBuf)) UTIL_TRACE_CALL("UTIL_setFileStat(%s)", filename);
if (!UTIL_stat(filename, &curStatBuf) || !UTIL_isRegularFileStat(&curStatBuf)) {
UTIL_TRACE_RET(-1);
return -1; return -1;
}
/* set access and modification times */ /* set access and modification times */
res += UTIL_utime(filename, statbuf); res += UTIL_utime(filename, statbuf);
@@ -200,13 +256,18 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 07777); /* Copy file permissions */ res += UTIL_chmod(filename, &curStatBuf, statbuf->st_mode & 07777); /* Copy file permissions */
errno = 0; errno = 0;
UTIL_TRACE_RET(-res);
return -res; /* number of errors is returned */ return -res; /* number of errors is returned */
} }
int UTIL_isDirectory(const char* infilename) int UTIL_isDirectory(const char* infilename)
{ {
stat_t statbuf; stat_t statbuf;
return UTIL_stat(infilename, &statbuf) && UTIL_isDirectoryStat(&statbuf); int ret;
UTIL_TRACE_CALL("UTIL_isDirectory(%s)", infilename);
ret = UTIL_stat(infilename, &statbuf) && UTIL_isDirectoryStat(&statbuf);
UTIL_TRACE_RET(ret);
return ret;
} }
int UTIL_isDirectoryStat(const stat_t* statbuf) int UTIL_isDirectoryStat(const stat_t* statbuf)
@@ -224,33 +285,44 @@ int UTIL_compareStr(const void *p1, const void *p2) {
int UTIL_isSameFile(const char* fName1, const char* fName2) int UTIL_isSameFile(const char* fName1, const char* fName2)
{ {
int ret;
assert(fName1 != NULL); assert(fName2 != NULL); assert(fName1 != NULL); assert(fName2 != NULL);
UTIL_TRACE_CALL("UTIL_isSameFile(%s, %s)", fName1, fName2);
#if defined(_MSC_VER) || defined(_WIN32) #if defined(_MSC_VER) || defined(_WIN32)
/* note : Visual does not support file identification by inode. /* note : Visual does not support file identification by inode.
* inode does not work on Windows, even with a posix layer, like msys2. * inode does not work on Windows, even with a posix layer, like msys2.
* The following work-around is limited to detecting exact name repetition only, * The following work-around is limited to detecting exact name repetition only,
* aka `filename` is considered different from `subdir/../filename` */ * aka `filename` is considered different from `subdir/../filename` */
return !strcmp(fName1, fName2); ret = !strcmp(fName1, fName2);
#else #else
{ stat_t file1Stat; { stat_t file1Stat;
stat_t file2Stat; stat_t file2Stat;
return UTIL_stat(fName1, &file1Stat) ret = UTIL_stat(fName1, &file1Stat)
&& UTIL_stat(fName2, &file2Stat) && UTIL_stat(fName2, &file2Stat)
&& (file1Stat.st_dev == file2Stat.st_dev) && (file1Stat.st_dev == file2Stat.st_dev)
&& (file1Stat.st_ino == file2Stat.st_ino); && (file1Stat.st_ino == file2Stat.st_ino);
} }
#endif #endif
UTIL_TRACE_RET(ret);
return ret;
} }
/* UTIL_isFIFO : distinguish named pipes */ /* UTIL_isFIFO : distinguish named pipes */
int UTIL_isFIFO(const char* infilename) int UTIL_isFIFO(const char* infilename)
{ {
UTIL_TRACE_CALL("UTIL_isFIFO(%s)", infilename);
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */ /* macro guards, as defined in : https://linux.die.net/man/2/lstat */
#if PLATFORM_POSIX_VERSION >= 200112L #if PLATFORM_POSIX_VERSION >= 200112L
stat_t statbuf; {
if (UTIL_stat(infilename, &statbuf) && UTIL_isFIFOStat(&statbuf)) return 1; stat_t statbuf;
if (UTIL_stat(infilename, &statbuf) && UTIL_isFIFOStat(&statbuf)) {
UTIL_TRACE_RET(1);
return 1;
}
}
#endif #endif
(void)infilename; (void)infilename;
UTIL_TRACE_RET(0);
return 0; return 0;
} }
@@ -278,13 +350,20 @@ int UTIL_isBlockDevStat(const stat_t* statbuf)
int UTIL_isLink(const char* infilename) int UTIL_isLink(const char* infilename)
{ {
UTIL_TRACE_CALL("UTIL_isLink(%s)", infilename);
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */ /* macro guards, as defined in : https://linux.die.net/man/2/lstat */
#if PLATFORM_POSIX_VERSION >= 200112L #if PLATFORM_POSIX_VERSION >= 200112L
stat_t statbuf; {
int const r = lstat(infilename, &statbuf); stat_t statbuf;
if (!r && S_ISLNK(statbuf.st_mode)) return 1; int const r = lstat(infilename, &statbuf);
if (!r && S_ISLNK(statbuf.st_mode)) {
UTIL_TRACE_RET(1);
return 1;
}
}
#endif #endif
(void)infilename; (void)infilename;
UTIL_TRACE_RET(0);
return 0; return 0;
} }
@@ -294,13 +373,18 @@ static int g_fakeStdoutIsConsole = 0;
int UTIL_isConsole(FILE* file) int UTIL_isConsole(FILE* file)
{ {
int ret;
UTIL_TRACE_CALL("UTIL_isConsole(%d)", fileno(file));
if (file == stdin && g_fakeStdinIsConsole) if (file == stdin && g_fakeStdinIsConsole)
return 1; ret = 1;
if (file == stderr && g_fakeStderrIsConsole) else if (file == stderr && g_fakeStderrIsConsole)
return 1; ret = 1;
if (file == stdout && g_fakeStdoutIsConsole) else if (file == stdout && g_fakeStdoutIsConsole)
return 1; ret = 1;
return IS_CONSOLE(file); else
ret = IS_CONSOLE(file);
UTIL_TRACE_RET(ret);
return ret;
} }
void UTIL_fakeStdinIsConsole(void) void UTIL_fakeStdinIsConsole(void)
@@ -319,8 +403,16 @@ void UTIL_fakeStderrIsConsole(void)
U64 UTIL_getFileSize(const char* infilename) U64 UTIL_getFileSize(const char* infilename)
{ {
stat_t statbuf; stat_t statbuf;
if (!UTIL_stat(infilename, &statbuf)) return UTIL_FILESIZE_UNKNOWN; UTIL_TRACE_CALL("UTIL_getFileSize(%s)", infilename);
return UTIL_getFileSizeStat(&statbuf); if (!UTIL_stat(infilename, &statbuf)) {
UTIL_TRACE_RET(-1);
return UTIL_FILESIZE_UNKNOWN;
}
{
U64 const size = UTIL_getFileSizeStat(&statbuf);
UTIL_TRACE_RET((int)size);
return size;
}
} }
U64 UTIL_getFileSizeStat(const stat_t* statbuf) U64 UTIL_getFileSizeStat(const stat_t* statbuf)
@@ -397,11 +489,16 @@ U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles)
{ {
U64 total = 0; U64 total = 0;
unsigned n; unsigned n;
UTIL_TRACE_CALL("UTIL_getTotalFileSize(%u)", nbFiles);
for (n=0; n<nbFiles; n++) { for (n=0; n<nbFiles; n++) {
U64 const size = UTIL_getFileSize(fileNamesTable[n]); U64 const size = UTIL_getFileSize(fileNamesTable[n]);
if (size == UTIL_FILESIZE_UNKNOWN) return UTIL_FILESIZE_UNKNOWN; if (size == UTIL_FILESIZE_UNKNOWN) {
UTIL_TRACE_RET(-1);
return UTIL_FILESIZE_UNKNOWN;
}
total += size; total += size;
} }
UTIL_TRACE_RET((int)total);
return total; return total;
} }
+6 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -189,6 +189,11 @@ void UTIL_fakeStdinIsConsole(void);
void UTIL_fakeStdoutIsConsole(void); void UTIL_fakeStdoutIsConsole(void);
void UTIL_fakeStderrIsConsole(void); void UTIL_fakeStderrIsConsole(void);
/**
* Emit traces for functions that read, or modify file metadata.
*/
void UTIL_traceFileStat(void);
#define UTIL_FILESIZE_UNKNOWN ((U64)(-1)) #define UTIL_FILESIZE_UNKNOWN ((U64)(-1))
U64 UTIL_getFileSize(const char* infilename); U64 UTIL_getFileSize(const char* infilename);
U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles);
@@ -262,7 +267,6 @@ UTIL_mergeFileNamesTable(FileNamesTable* table1, FileNamesTable* table2);
/*! UTIL_expandFNT() : /*! UTIL_expandFNT() :
* read names from @fnt, and expand those corresponding to directories * read names from @fnt, and expand those corresponding to directories
* update @fnt, now containing only file names, * update @fnt, now containing only file names,
* @return : 0 in case of success, 1 if error
* note : in case of error, @fnt[0] is NULL * note : in case of error, @fnt[0] is NULL
*/ */
void UTIL_expandFNT(FileNamesTable** fnt, int followLinks); void UTIL_expandFNT(FileNamesTable** fnt, int followLinks);
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+2 -2
View File
@@ -32,11 +32,11 @@ BEGIN
BEGIN BEGIN
BLOCK "040904B0" BLOCK "040904B0"
BEGIN BEGIN
VALUE "CompanyName", "Yann Collet, Facebook, Inc." VALUE "CompanyName", "Meta Platforms, Inc."
VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm" VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm"
VALUE "FileVersion", ZSTD_VERSION_STRING VALUE "FileVersion", ZSTD_VERSION_STRING
VALUE "InternalName", "zstd.exe" VALUE "InternalName", "zstd.exe"
VALUE "LegalCopyright", "Copyright (c) 2013-present, Yann Collet, Facebook, Inc." VALUE "LegalCopyright", "Copyright (c) Meta Platforms, Inc. and affiliates."
VALUE "OriginalFilename", "zstd.exe" VALUE "OriginalFilename", "zstd.exe"
VALUE "ProductName", "Zstandard" VALUE "ProductName", "Zstandard"
VALUE "ProductVersion", ZSTD_VERSION_STRING VALUE "ProductVersion", ZSTD_VERSION_STRING
+74 -41
View File
@@ -1,5 +1,5 @@
. .
.TH "ZSTD" "1" "August 2022" "zstd 1.5.3" "User Commands" .TH "ZSTD" "1" "December 2022" "zstd 1.5.3" "User Commands"
. .
.SH "NAME" .SH "NAME"
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files \fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
@@ -17,10 +17,10 @@
\fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR \fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR
. .
.SH "DESCRIPTION" .SH "DESCRIPTION"
\fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip (1)\fR and \fBxz (1)\fR\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core\. \fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip\fR(1) and \fBxz\fR(1)\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core\.
. .
.P .P
\fBzstd\fR command line syntax is generally similar to gzip, but features the following differences : \fBzstd\fR command line syntax is generally similar to gzip, but features the following differences:
. .
.IP "\(bu" 4 .IP "\(bu" 4
Source files are preserved by default\. It\'s possible to remove them automatically by using the \fB\-\-rm\fR command\. Source files are preserved by default\. It\'s possible to remove them automatically by using the \fB\-\-rm\fR command\.
@@ -34,10 +34,13 @@ When compressing a single file, \fBzstd\fR displays progress notifications and r
.IP "\(bu" 4 .IP "\(bu" 4
\fBzstd\fR does not accept input from console, though it does accept \fBstdin\fR when it\'s not the console\. \fBzstd\fR does not accept input from console, though it does accept \fBstdin\fR when it\'s not the console\.
. .
.IP "\(bu" 4
\fBzstd\fR does not store the input\'s filename or attributes, only its contents\.
.
.IP "" 0 .IP "" 0
. .
.P .P
\fBzstd\fR processes each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal : it will display an error message and skip the \fIfile\fR\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\. \fBzstd\fR processes each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal: it will display an error message and skip the file\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\.
. .
.P .P
Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name: Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name:
@@ -50,12 +53,12 @@ When decompressing, the \fB\.zst\fR suffix is removed from the source filename t
. .
.IP "" 0 .IP "" 0
. .
.SS "Concatenation with \.zst files" .SS "Concatenation with \.zst Files"
It is possible to concatenate multiple \fB\.zst\fR files\. \fBzstd\fR will decompress such agglomerated file as if it was a single \fB\.zst\fR file\. It is possible to concatenate multiple \fB\.zst\fR files\. \fBzstd\fR will decompress such agglomerated file as if it was a single \fB\.zst\fR file\.
. .
.SH "OPTIONS" .SH "OPTIONS"
. .
.SS "Integer suffixes and special values" .SS "Integer Suffixes and Special Values"
In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\. In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\.
. .
.TP .TP
@@ -66,7 +69,7 @@ Multiply the integer by 1,024 (2^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accep
\fBMiB\fR \fBMiB\fR
Multiply the integer by 1,048,576 (2^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\. Multiply the integer by 1,048,576 (2^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\.
. .
.SS "Operation mode" .SS "Operation Mode"
If multiple operation mode options are given, the last one takes effect\. If multiple operation mode options are given, the last one takes effect\.
. .
.TP .TP
@@ -83,20 +86,20 @@ Test the integrity of compressed \fIfiles\fR\. This option is equivalent to \fB\
. .
.TP .TP
\fB\-b#\fR \fB\-b#\fR
Benchmark file(s) using compression level # Benchmark file(s) using compression level \fI#\fR\. See \fIBENCHMARK\fR below for a description of this operation\.
. .
.TP .TP
\fB\-\-train FILEs\fR \fB\-\-train FILES\fR
Use FILEs as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. Use \fIFILES\fR as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. See \fIDICTIONARY BUILDER\fR below for a description of this operation\.
. .
.TP .TP
\fB\-l\fR, \fB\-\-list\fR \fB\-l\fR, \fB\-\-list\fR
Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command\'s output can be augmented with the \fB\-v\fR modifier\. Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command\'s output can be augmented with the \fB\-v\fR modifier\.
. .
.SS "Operation modifiers" .SS "Operation Modifiers"
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-#\fR: \fB#\fR compression level [1\-19] (default: 3) \fB\-#\fR: selects \fB#\fR compression level [1\-19] (default: 3)
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\. \fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\.
@@ -108,13 +111,22 @@ Display information related to a zstd compressed file, such as size, ratio, and
\fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\. \fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-single\-thread\fR: Use a single thread for both I/O and compression\. As compression is serialized with I/O, this can be slightly slower\. Single\-thread mode features significantly lower memory usage, which can be useful for systems with limited amount of memory, such as 32\-bit systems\. Note 1 : this mode is the only available one when multithread support is disabled\. Note 2 : this mode is different from \fB\-T1\fR, which spawns 1 compression thread in parallel with I/O\. Final compressed result is also slightly different from \fB\-T1\fR\. \fB\-\-single\-thread\fR: Use a single thread for both I/O and compression\. As compression is serialized with I/O, this can be slightly slower\. Single\-thread mode features significantly lower memory usage, which can be useful for systems with limited amount of memory, such as 32\-bit systems\.
.
.IP
Note 1: this mode is the only available one when multithread support is disabled\.
.
.IP
Note 2: this mode is different from \fB\-T1\fR, which spawns 1 compression thread in parallel with I/O\. Final compressed result is also slightly different from \fB\-T1\fR\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\. \fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-adapt[=min=#,max=#]\fR : \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\. \fInote\fR : at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\. \fB\-\-adapt[=min=#,max=#]\fR: \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MiB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\.
.
.IP
\fINote\fR: at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\. \fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\.
@@ -126,40 +138,49 @@ Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \
\fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s) \fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s)
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd\'s diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that windowSize > srcSize\. \fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd\'s diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that \fIwindowSize\fR > \fIsrcSize\fR\.
. .
.IP .IP
Note: cannot use both this and \-D together Note: \fB\-\-long\fR mode will be automatically activated if chainLog < fileLog (fileLog being the windowLog required to cover the whole file)\. You can also manually force it\. Note: for all levels, you can use \-\-patch\-from in \-\-single\-thread mode to improve compression ratio at the cost of speed Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e\. 4096), and by setting a large \fB\-\-zstd=chainLog=\fR Note: cannot use both this and \fB\-D\fR together\.
.
.IP
Note: \fB\-\-long\fR mode will be automatically activated if \fIchainLog\fR < \fIfileLog\fR (\fIfileLog\fR being the \fIwindowLog\fR required to cover the whole file)\. You can also manually force it\.
.
.IP
Note: for all levels, you can use \fB\-\-patch\-from\fR in \fB\-\-single\-thread\fR mode to improve compression ratio at the cost of speed\.
.
.IP
Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e\. 4096), and by setting a large \fB\-\-zstd=chainLog=\fR\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-rsyncable\fR : \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and the faster compression levels will see a small compression speed hit\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\. \fB\-\-rsyncable\fR: \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and the faster compression levels will see a small compression speed hit\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled) \fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled)
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \-\-content\-size (meaning that the original size will be placed in the header)\. \fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \fB\-\-content\-size\fR (meaning that the original size will be placed in the header)\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won\'t be able to check if it\'s correct\. \fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won\'t be able to check if it\'s correct\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, \fBzstd\fR uses 128 MB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (i\.e\. you can increase or decrease it)\. \fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, \fBzstd\fR uses 128 MiB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (i\.e\. you can increase or decrease it)\.
. .
.IP .IP
This is also used during compression when using with \-\-patch\-from=\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MB)\. This is also used during compression when using with \fB\-\-patch\-from=\fR\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MiB)\.
. .
.IP .IP
Additionally, this can be used to limit memory for dictionary training\. This parameter overrides the default limit of 2 GB\. zstd will load training samples up to the memory limit and ignore the rest\. Additionally, this can be used to limit memory for dictionary training\. This parameter overrides the default limit of 2 GiB\. zstd will load training samples up to the memory limit and ignore the rest\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-stream\-size=#\fR : Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\. \fB\-\-stream\-size=#\fR: Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\. \fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-o FILE\fR: save result into \fBFILE\fR \fB\-o FILE\fR: save result into \fBFILE\fR\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. During decompression and when the output destination is stdout, pass\-through unrecognized formats as\-is\. \fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. During decompression and when the output destination is stdout, pass\-through unrecognized formats as\-is\.
@@ -171,10 +192,10 @@ Additionally, this can be used to limit memory for dictionary training\. This pa
\fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\. \fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-[no\-]pass\-through\fR enable / disable passing through uncompressed files as\-is\. During decompression when pass\-through is enabled, unrecognized formats will be copied as\-is from the input to the output\. By default, pass\-through will occur when the output destination is stdout and the force (\-f) option is set\. \fB\-\-[no\-]pass\-through\fR enable / disable passing through uncompressed files as\-is\. During decompression when pass\-through is enabled, unrecognized formats will be copied as\-is from the input to the output\. By default, pass\-through will occur when the output destination is stdout and the force (\fB\-f\fR) option is set\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. If used in combination with \-o, will trigger a confirmation prompt (which can be silenced with \-f), as this is a destructive operation\. \fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. If used in combination with \fB\-o\fR, will trigger a confirmation prompt (which can be silenced with \fB\-f\fR), as this is a destructive operation\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\. \fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\.
@@ -201,7 +222,7 @@ If input directory contains "\.\.", the files in this directory will be ignored\
\fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit \fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-V\fR, \fB\-\-version\fR: display version number and exit\. Advanced : \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-q\fR will only display the version number, suitable for machine reading\. \fB\-V\fR, \fB\-\-version\fR: display version number and exit\. Advanced: \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-q\fR will only display the version number, suitable for machine reading\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information \fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information
@@ -213,14 +234,14 @@ If input directory contains "\.\.", the files in this directory will be ignored\
\fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\. \fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-show\-default\-cparams\fR: Shows the default compression parameters that will be used for a particular src file\. If the provided src file is not a regular file (e\.g\. named pipe), the cli will just output the default parameters\. That is, the parameters that are used when the src size is unknown\. \fB\-\-show\-default\-cparams\fR: shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size\. If the provided file is not a regular file (e\.g\. a pipe), this flag will output the parameters used for inputs of unknown size\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files \fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files
. .
.IP "" 0 .IP "" 0
. .
.SS "gzip Operation modifiers" .SS "gzip Operation Modifiers"
When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior: When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior:
. .
.TP .TP
@@ -231,7 +252,7 @@ do not store the original filename and timestamps when compressing a file\. This
\fB\-\-best\fR \fB\-\-best\fR
alias to the option \fB\-9\fR\. alias to the option \fB\-9\fR\.
. .
.SS "Interactions with Environment Variables" .SS "Environment Variables"
Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the compression level and number of threads to use during compression, respectively\. Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the compression level and number of threads to use during compression, respectively\.
. .
.P .P
@@ -251,7 +272,7 @@ They can both be overridden by corresponding command line arguments: \fB\-#\fR f
Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\. Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\.
. .
.IP .IP
Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KB of these samples will be used for training\. Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KiB of these samples will be used for training\.
. .
.IP .IP
\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\. \fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\.
@@ -281,7 +302,10 @@ In situations where the training set is larger than maximum memory, the CLI will
. .
.TP .TP
\fB\-\-dictID=#\fR \fB\-\-dictID=#\fR
A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It\'s possible to provide an explicit number ID instead\. It\'s up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage : an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\. A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It\'s possible to provide an explicit number ID instead\. It\'s up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage: an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\.
.
.IP
Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2^31, so they should not be used in public\.
. .
.TP .TP
\fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR \fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR
@@ -366,7 +390,7 @@ cut file(s) into independent chunks of size # (default: no chunking)
set process priority to real\-time set process priority to real\-time
. .
.P .P
\fBOutput Format:\fR CompressionLevel#Filename : InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed \fBOutput Format:\fR CompressionLevel#Filename: InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed
. .
.P .P
\fBMethodology:\fR For both compression and decompression speed, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\. \fBMethodology:\fR For both compression and decompression speed, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\.
@@ -377,14 +401,14 @@ set process priority to real\-time
Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\. Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\.
. .
.SS "\-\-zstd[=options]:" .SS "\-\-zstd[=options]:"
\fBzstd\fR provides 22 predefined compression levels\. The selected or default predefined compression level can be changed with advanced compression options\. The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR: \fBzstd\fR provides 22 predefined regular compression levels plus the fast levels\. This compression level is translated internally into a number of specific parameters that actually control the behavior of the compressor\. (You can see the result of this translation with \fB\-\-show\-default\-cparams\fR\.) These specific parameters can be overridden with advanced compression options\. The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR:
. .
.TP .TP
\fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR \fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR
Specify a strategy used by a match finder\. Specify a strategy used by a match finder\.
. .
.IP .IP
There are 9 strategies numbered from 1 to 9, from faster to stronger: 1=ZSTD_fast, 2=ZSTD_dfast, 3=ZSTD_greedy, 4=ZSTD_lazy, 5=ZSTD_lazy2, 6=ZSTD_btlazy2, 7=ZSTD_btopt, 8=ZSTD_btultra, 9=ZSTD_btultra2\. There are 9 strategies numbered from 1 to 9, from fastest to strongest: 1=\fBZSTD_fast\fR, 2=\fBZSTD_dfast\fR, 3=\fBZSTD_greedy\fR, 4=\fBZSTD_lazy\fR, 5=\fBZSTD_lazy2\fR, 6=\fBZSTD_btlazy2\fR, 7=\fBZSTD_btopt\fR, 8=\fBZSTD_btultra\fR, 9=\fBZSTD_btultra2\fR\.
. .
.TP .TP
\fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR \fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR
@@ -404,17 +428,17 @@ Specify the maximum number of bits for a hash table\.
Bigger hash tables cause fewer collisions which usually makes compression faster, but requires more memory during compression\. Bigger hash tables cause fewer collisions which usually makes compression faster, but requires more memory during compression\.
. .
.IP .IP
The minimum \fIhlog\fR is 6 (64 B) and the maximum is 30 (1 GiB)\. The minimum \fIhlog\fR is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB)\.
. .
.TP .TP
\fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR \fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR
Specify the maximum number of bits for a hash chain or a binary tree\. Specify the maximum number of bits for the secondary search structure, whose form depends on the selected \fBstrategy\fR\.
. .
.IP .IP
Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the ZSTD_fast strategy\. Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the \fBZSTD_fast\fR \fBstrategy\fR, which only has the primary hash table\.
. .
.IP .IP
The minimum \fIclog\fR is 6 (64 B) and the maximum is 29 (524 Mib) on 32\-bit platforms and 30 (1 Gib) on 64\-bit platforms\. The minimum \fIclog\fR is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32\-bit platforms and 30 (1B entries / 4 GiB) on 64\-bit platforms\.
. .
.TP .TP
\fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR \fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR
@@ -441,20 +465,23 @@ The minimum \fImml\fR is 3 and the maximum is 7\.
The impact of this field vary depending on selected strategy\. The impact of this field vary depending on selected strategy\.
. .
.IP .IP
For ZSTD_btopt, ZSTD_btultra and ZSTD_btultra2, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\. t For ZSTD_fast, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed : a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\. For \fBZSTD_btopt\fR, \fBZSTD_btultra\fR and \fBZSTD_btultra2\fR, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\.
.
.IP
For \fBZSTD_fast\fR, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed: a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\.
. .
.IP .IP
For all other strategies, this field has no impact\. For all other strategies, this field has no impact\.
. .
.IP .IP
The minimum \fItlen\fR is 0 and the maximum is 128 Kib\. The minimum \fItlen\fR is 0 and the maximum is 128 KiB\.
. .
.TP .TP
\fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR \fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR
Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\. Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\.
. .
.IP .IP
The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default" : \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\. The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default": \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\.
. .
.TP .TP
\fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR \fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR
@@ -514,6 +541,12 @@ The following parameters sets advanced compression options to something similar
.P .P
\fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 \fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
. .
.SH "SEE ALSO"
\fBzstdgrep\fR(1), \fBzstdless\fR(1), \fBgzip\fR(1), \fBxz\fR(1)
.
.P
The \fIzstandard\fR format is specified in Y\. Collet, "Zstandard Compression and the \'application/zstd\' Media Type", https://www\.ietf\.org/rfc/rfc8878\.txt, Internet RFC 8878 (February 2021)\.
.
.SH "BUGS" .SH "BUGS"
Report bugs at: https://github\.com/facebook/zstd/issues Report bugs at: https://github\.com/facebook/zstd/issues
. .
+80 -62
View File
@@ -4,7 +4,7 @@ zstd(1) -- zstd, zstdmt, unzstd, zstdcat - Compress or decompress .zst files
SYNOPSIS SYNOPSIS
-------- --------
`zstd` [*OPTIONS*] [-|_INPUT-FILE_] [-o _OUTPUT-FILE_] `zstd` [<OPTIONS>] [-|<INPUT-FILE>] [-o <OUTPUT-FILE>]
`zstdmt` is equivalent to `zstd -T0` `zstdmt` is equivalent to `zstd -T0`
@@ -16,7 +16,7 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
`zstd` is a fast lossless compression algorithm and data compression tool, `zstd` is a fast lossless compression algorithm and data compression tool,
with command line syntax similar to `gzip (1)` and `xz (1)`. with command line syntax similar to `gzip`(1) and `xz`(1).
It is based on the **LZ77** family, with further FSE & huff0 entropy stages. It is based on the **LZ77** family, with further FSE & huff0 entropy stages.
`zstd` offers highly configurable compression speed, `zstd` offers highly configurable compression speed,
from fast modes at > 200 MB/s per core, from fast modes at > 200 MB/s per core,
@@ -24,7 +24,7 @@ to strong modes with excellent compression ratios.
It also features a very fast decoder, with speeds > 500 MB/s per core. It also features a very fast decoder, with speeds > 500 MB/s per core.
`zstd` command line syntax is generally similar to gzip, `zstd` command line syntax is generally similar to gzip,
but features the following differences : but features the following differences:
- Source files are preserved by default. - Source files are preserved by default.
It's possible to remove them automatically by using the `--rm` command. It's possible to remove them automatically by using the `--rm` command.
@@ -35,12 +35,13 @@ but features the following differences :
Use `-q` to turn it off. Use `-q` to turn it off.
- `zstd` does not accept input from console, - `zstd` does not accept input from console,
though it does accept `stdin` when it's not the console. though it does accept `stdin` when it's not the console.
- `zstd` does not store the input's filename or attributes, only its contents.
`zstd` processes each _file_ according to the selected operation mode. `zstd` processes each _file_ according to the selected operation mode.
If no _files_ are given or _file_ is `-`, `zstd` reads from standard input If no _files_ are given or _file_ is `-`, `zstd` reads from standard input
and writes the processed data to standard output. and writes the processed data to standard output.
`zstd` will refuse to write compressed data to standard output `zstd` will refuse to write compressed data to standard output
if it is a terminal : it will display an error message and skip the _file_. if it is a terminal: it will display an error message and skip the file.
Similarly, `zstd` will refuse to read compressed data from standard input Similarly, `zstd` will refuse to read compressed data from standard input
if it is a terminal. if it is a terminal.
@@ -52,14 +53,15 @@ whose name is derived from the source _file_ name:
* When decompressing, the `.zst` suffix is removed from the source filename to * When decompressing, the `.zst` suffix is removed from the source filename to
get the target filename get the target filename
### Concatenation with .zst files ### Concatenation with .zst Files
It is possible to concatenate multiple `.zst` files. `zstd` will decompress It is possible to concatenate multiple `.zst` files. `zstd` will decompress
such agglomerated file as if it was a single `.zst` file. such agglomerated file as if it was a single `.zst` file.
OPTIONS OPTIONS
------- -------
### Integer suffixes and special values ### Integer Suffixes and Special Values
In most places where an integer argument is expected, In most places where an integer argument is expected,
an optional suffix is supported to easily indicate large integers. an optional suffix is supported to easily indicate large integers.
There must be no space between the integer and the suffix. There must be no space between the integer and the suffix.
@@ -71,7 +73,8 @@ There must be no space between the integer and the suffix.
Multiply the integer by 1,048,576 (2\^20). Multiply the integer by 1,048,576 (2\^20).
`Mi`, `M`, and `MB` are accepted as synonyms for `MiB`. `Mi`, `M`, and `MB` are accepted as synonyms for `MiB`.
### Operation mode ### Operation Mode
If multiple operation mode options are given, If multiple operation mode options are given,
the last one takes effect. the last one takes effect.
@@ -88,19 +91,21 @@ the last one takes effect.
decompressed data is discarded and checksummed for errors. decompressed data is discarded and checksummed for errors.
No files are created or removed. No files are created or removed.
* `-b#`: * `-b#`:
Benchmark file(s) using compression level # Benchmark file(s) using compression level _#_.
* `--train FILEs`: See _BENCHMARK_ below for a description of this operation.
Use FILEs as a training set to create a dictionary. * `--train FILES`:
Use _FILES_ as a training set to create a dictionary.
The training set should contain a lot of small files (> 100). The training set should contain a lot of small files (> 100).
See _DICTIONARY BUILDER_ below for a description of this operation.
* `-l`, `--list`: * `-l`, `--list`:
Display information related to a zstd compressed file, such as size, ratio, and checksum. Display information related to a zstd compressed file, such as size, ratio, and checksum.
Some of these fields may not be available. Some of these fields may not be available.
This command's output can be augmented with the `-v` modifier. This command's output can be augmented with the `-v` modifier.
### Operation modifiers ### Operation Modifiers
* `-#`: * `-#`:
`#` compression level \[1-19] (default: 3) selects `#` compression level \[1-19\] (default: 3)
* `--ultra`: * `--ultra`:
unlocks high compression levels 20+ (maximum 22), using a lot more memory. unlocks high compression levels 20+ (maximum 22), using a lot more memory.
Note that decompression will also require more memory when using these levels. Note that decompression will also require more memory when using these levels.
@@ -122,21 +127,24 @@ the last one takes effect.
As compression is serialized with I/O, this can be slightly slower. As compression is serialized with I/O, this can be slightly slower.
Single-thread mode features significantly lower memory usage, Single-thread mode features significantly lower memory usage,
which can be useful for systems with limited amount of memory, such as 32-bit systems. which can be useful for systems with limited amount of memory, such as 32-bit systems.
Note 1 : this mode is the only available one when multithread support is disabled.
Note 2 : this mode is different from `-T1`, which spawns 1 compression thread in parallel with I/O. Note 1: this mode is the only available one when multithread support is disabled.
Note 2: this mode is different from `-T1`, which spawns 1 compression thread in parallel with I/O.
Final compressed result is also slightly different from `-T1`. Final compressed result is also slightly different from `-T1`.
* `--auto-threads={physical,logical} (default: physical)`: * `--auto-threads={physical,logical} (default: physical)`:
When using a default amount of threads via `-T0`, choose the default based on the number When using a default amount of threads via `-T0`, choose the default based on the number
of detected physical or logical cores. of detected physical or logical cores.
* `--adapt[=min=#,max=#]` : * `--adapt[=min=#,max=#]`:
`zstd` will dynamically adapt compression level to perceived I/O conditions. `zstd` will dynamically adapt compression level to perceived I/O conditions.
Compression level adaptation can be observed live by using command `-v`. Compression level adaptation can be observed live by using command `-v`.
Adaptation can be constrained between supplied `min` and `max` levels. Adaptation can be constrained between supplied `min` and `max` levels.
The feature works when combined with multi-threading and `--long` mode. The feature works when combined with multi-threading and `--long` mode.
It does not work with `--single-thread`. It does not work with `--single-thread`.
It sets window size to 8 MB by default (can be changed manually, see `wlog`). It sets window size to 8 MiB by default (can be changed manually, see `wlog`).
Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible.
_note_ : at the time of this writing, `--adapt` can remain stuck at low speed
_Note_: at the time of this writing, `--adapt` can remain stuck at low speed
when combined with multiple worker threads (>=2). when combined with multiple worker threads (>=2).
* `--long[=#]`: * `--long[=#]`:
enables long distance matching with `#` `windowLog`, if `#` is not enables long distance matching with `#` `windowLog`, if `#` is not
@@ -153,18 +161,21 @@ the last one takes effect.
* `--patch-from FILE`: * `--patch-from FILE`:
Specify the file to be used as a reference point for zstd's diff engine. Specify the file to be used as a reference point for zstd's diff engine.
This is effectively dictionary compression with some convenient parameter This is effectively dictionary compression with some convenient parameter
selection, namely that windowSize > srcSize. selection, namely that _windowSize_ > _srcSize_.
Note: cannot use both this and -D together Note: cannot use both this and `-D` together.
Note: `--long` mode will be automatically activated if chainLog < fileLog
(fileLog being the windowLog required to cover the whole file). You Note: `--long` mode will be automatically activated if _chainLog_ < _fileLog_
(_fileLog_ being the _windowLog_ required to cover the whole file). You
can also manually force it. can also manually force it.
Note: for all levels, you can use --patch-from in --single-thread mode
to improve compression ratio at the cost of speed Note: for all levels, you can use `--patch-from` in `--single-thread` mode
to improve compression ratio at the cost of speed.
Note: for level 19, you can get increased compression ratio at the cost Note: for level 19, you can get increased compression ratio at the cost
of speed by specifying `--zstd=targetLength=` to be something large of speed by specifying `--zstd=targetLength=` to be something large
(i.e. 4096), and by setting a large `--zstd=chainLog=` (i.e. 4096), and by setting a large `--zstd=chainLog=`.
* `--rsyncable` : * `--rsyncable`:
`zstd` will periodically synchronize the compression state to make the `zstd` will periodically synchronize the compression state to make the
compressed file more rsync-friendly. There is a negligible impact to compressed file more rsync-friendly. There is a negligible impact to
compression ratio, and the faster compression levels will see a small compression ratio, and the faster compression levels will see a small
@@ -177,24 +188,24 @@ the last one takes effect.
* `--[no-]content-size`: * `--[no-]content-size`:
enable / disable whether or not the original size of the file is placed in enable / disable whether or not the original size of the file is placed in
the header of the compressed file. The default option is the header of the compressed file. The default option is
--content-size (meaning that the original size will be placed in the header). `--content-size` (meaning that the original size will be placed in the header).
* `--no-dictID`: * `--no-dictID`:
do not store dictionary ID within frame header (dictionary compression). do not store dictionary ID within frame header (dictionary compression).
The decoder will have to rely on implicit knowledge about which dictionary to use, The decoder will have to rely on implicit knowledge about which dictionary to use,
it won't be able to check if it's correct. it won't be able to check if it's correct.
* `-M#`, `--memory=#`: * `-M#`, `--memory=#`:
Set a memory usage limit. By default, `zstd` uses 128 MB for decompression Set a memory usage limit. By default, `zstd` uses 128 MiB for decompression
as the maximum amount of memory the decompressor is allowed to use, but you can as the maximum amount of memory the decompressor is allowed to use, but you can
override this manually if need be in either direction (i.e. you can increase or override this manually if need be in either direction (i.e. you can increase or
decrease it). decrease it).
This is also used during compression when using with --patch-from=. In this case, This is also used during compression when using with `--patch-from=`. In this case,
this parameter overrides that maximum size allowed for a dictionary. (128 MB). this parameter overrides that maximum size allowed for a dictionary. (128 MiB).
Additionally, this can be used to limit memory for dictionary training. This parameter Additionally, this can be used to limit memory for dictionary training. This parameter
overrides the default limit of 2 GB. zstd will load training samples up to the memory limit overrides the default limit of 2 GiB. zstd will load training samples up to the memory limit
and ignore the rest. and ignore the rest.
* `--stream-size=#` : * `--stream-size=#`:
Sets the pledged source size of input coming from a stream. This value must be exact, as it Sets the pledged source size of input coming from a stream. This value must be exact, as it
will be included in the produced frame header. Incorrect stream sizes will cause an error. will be included in the produced frame header. Incorrect stream sizes will cause an error.
This information will be used to better optimize compression parameters, resulting in This information will be used to better optimize compression parameters, resulting in
@@ -207,7 +218,7 @@ the last one takes effect.
Exact guesses result in better compression ratios. Overestimates result in slightly Exact guesses result in better compression ratios. Overestimates result in slightly
degraded compression ratios, while underestimates may result in significant degradation. degraded compression ratios, while underestimates may result in significant degradation.
* `-o FILE`: * `-o FILE`:
save result into `FILE` save result into `FILE`.
* `-f`, `--force`: * `-f`, `--force`:
disable input and output checks. Allows overwriting existing files, input disable input and output checks. Allows overwriting existing files, input
from console, output to stdout, operating on links, block devices, etc. from console, output to stdout, operating on links, block devices, etc.
@@ -227,11 +238,11 @@ the last one takes effect.
enable / disable passing through uncompressed files as-is. During enable / disable passing through uncompressed files as-is. During
decompression when pass-through is enabled, unrecognized formats will be decompression when pass-through is enabled, unrecognized formats will be
copied as-is from the input to the output. By default, pass-through will copied as-is from the input to the output. By default, pass-through will
occur when the output destination is stdout and the force (-f) option is occur when the output destination is stdout and the force (`-f`) option is
set. set.
* `--rm`: * `--rm`:
remove source file(s) after successful compression or decompression. If used in combination with remove source file(s) after successful compression or decompression. If used in combination with
-o, will trigger a confirmation prompt (which can be silenced with -f), as this is a destructive operation. `-o`, will trigger a confirmation prompt (which can be silenced with `-f`), as this is a destructive operation.
* `-k`, `--keep`: * `-k`, `--keep`:
keep source file(s) after successful compression or decompression. keep source file(s) after successful compression or decompression.
This is the default behavior. This is the default behavior.
@@ -270,7 +281,7 @@ the last one takes effect.
display help/long help and exit display help/long help and exit
* `-V`, `--version`: * `-V`, `--version`:
display version number and exit. display version number and exit.
Advanced : `-vV` also displays supported formats. Advanced: `-vV` also displays supported formats.
`-vvV` also displays POSIX support. `-vvV` also displays POSIX support.
`-q` will only display the version number, suitable for machine reading. `-q` will only display the version number, suitable for machine reading.
* `-v`, `--verbose`: * `-v`, `--verbose`:
@@ -281,15 +292,13 @@ the last one takes effect.
* `--no-progress`: * `--no-progress`:
do not display the progress bar, but keep all other messages. do not display the progress bar, but keep all other messages.
* `--show-default-cparams`: * `--show-default-cparams`:
Shows the default compression parameters that will be used for a shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size.
particular src file. If the provided src file is not a regular file If the provided file is not a regular file (e.g. a pipe), this flag will output the parameters used for inputs of unknown size.
(e.g. named pipe), the cli will just output the default parameters.
That is, the parameters that are used when the src size is unknown.
* `--`: * `--`:
All arguments after `--` are treated as files All arguments after `--` are treated as files
### gzip Operation modifiers ### gzip Operation Modifiers
When invoked via a `gzip` symlink, `zstd` will support further When invoked via a `gzip` symlink, `zstd` will support further
options that intend to mimic the `gzip` behavior: options that intend to mimic the `gzip` behavior:
@@ -300,7 +309,7 @@ options that intend to mimic the `gzip` behavior:
alias to the option `-9`. alias to the option `-9`.
### Interactions with Environment Variables ### Environment Variables
Employing environment variables to set parameters has security implications. Employing environment variables to set parameters has security implications.
Therefore, this avenue is intentionally limited. Therefore, this avenue is intentionally limited.
@@ -341,7 +350,7 @@ Compression of small files similar to the sample set will be greatly improved.
Since dictionary compression is mostly effective for small files, Since dictionary compression is mostly effective for small files,
the expectation is that the training set will only contain small files. the expectation is that the training set will only contain small files.
In the case where some samples happen to be large, In the case where some samples happen to be large,
only the first 128 KB of these samples will be used for training. only the first 128 KiB of these samples will be used for training.
`--train` supports multithreading if `zstd` is compiled with threading support (default). `--train` supports multithreading if `zstd` is compiled with threading support (default).
Additional advanced parameters can be specified with `--train-fastcover`. Additional advanced parameters can be specified with `--train-fastcover`.
@@ -389,11 +398,13 @@ Compression of small files similar to the sample set will be greatly improved.
It's possible to provide an explicit number ID instead. It's possible to provide an explicit number ID instead.
It's up to the dictionary manager to not assign twice the same ID to It's up to the dictionary manager to not assign twice the same ID to
2 different dictionaries. 2 different dictionaries.
Note that short numbers have an advantage : Note that short numbers have an advantage:
an ID < 256 will only need 1 byte in the compressed frame header, an ID < 256 will only need 1 byte in the compressed frame header,
and an ID < 65536 will only need 2 bytes. and an ID < 65536 will only need 2 bytes.
This compares favorably to 4 bytes default. This compares favorably to 4 bytes default.
Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2\^31, so they should not be used in public.
* `--train-cover[=k#,d=#,steps=#,split=#,shrink[=#]]`: * `--train-cover[=k#,d=#,steps=#,split=#,shrink[=#]]`:
Select parameters for the default dictionary builder algorithm named cover. Select parameters for the default dictionary builder algorithm named cover.
If _d_ is not specified, then it tries _d_ = 6 and _d_ = 8. If _d_ is not specified, then it tries _d_ = 6 and _d_ = 8.
@@ -482,7 +493,7 @@ BENCHMARK
* `--priority=rt`: * `--priority=rt`:
set process priority to real-time set process priority to real-time
**Output Format:** CompressionLevel#Filename : InputSize -> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed **Output Format:** CompressionLevel#Filename: InputSize -> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed
**Methodology:** For both compression and decompression speed, the entire input is compressed/decompressed in-memory to measure speed. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy. **Methodology:** For both compression and decompression speed, the entire input is compressed/decompressed in-memory to measure speed. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy.
@@ -499,9 +510,10 @@ This minimum is either 512 KB, or `overlapSize`, whichever is largest.
Different job sizes will lead to non-identical compressed frames. Different job sizes will lead to non-identical compressed frames.
### --zstd[=options]: ### --zstd[=options]:
`zstd` provides 22 predefined compression levels. `zstd` provides 22 predefined regular compression levels plus the fast levels.
The selected or default predefined compression level can be changed with This compression level is translated internally into a number of specific parameters that actually control the behavior of the compressor.
advanced compression options. (You can see the result of this translation with `--show-default-cparams`.)
These specific parameters can be overridden with advanced compression options.
The _options_ are provided as a comma-separated list. The _options_ are provided as a comma-separated list.
You may specify only the options you want to change and the rest will be You may specify only the options you want to change and the rest will be
taken from the selected or default compression level. taken from the selected or default compression level.
@@ -510,10 +522,10 @@ The list of available _options_:
- `strategy`=_strat_, `strat`=_strat_: - `strategy`=_strat_, `strat`=_strat_:
Specify a strategy used by a match finder. Specify a strategy used by a match finder.
There are 9 strategies numbered from 1 to 9, from faster to stronger: There are 9 strategies numbered from 1 to 9, from fastest to strongest:
1=ZSTD\_fast, 2=ZSTD\_dfast, 3=ZSTD\_greedy, 1=`ZSTD_fast`, 2=`ZSTD_dfast`, 3=`ZSTD_greedy`,
4=ZSTD\_lazy, 5=ZSTD\_lazy2, 6=ZSTD\_btlazy2, 4=`ZSTD_lazy`, 5=`ZSTD_lazy2`, 6=`ZSTD_btlazy2`,
7=ZSTD\_btopt, 8=ZSTD\_btultra, 9=ZSTD\_btultra2. 7=`ZSTD_btopt`, 8=`ZSTD_btultra`, 9=`ZSTD_btultra2`.
- `windowLog`=_wlog_, `wlog`=_wlog_: - `windowLog`=_wlog_, `wlog`=_wlog_:
Specify the maximum number of bits for a match distance. Specify the maximum number of bits for a match distance.
@@ -533,19 +545,20 @@ The list of available _options_:
Bigger hash tables cause fewer collisions which usually makes compression Bigger hash tables cause fewer collisions which usually makes compression
faster, but requires more memory during compression. faster, but requires more memory during compression.
The minimum _hlog_ is 6 (64 B) and the maximum is 30 (1 GiB). The minimum _hlog_ is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB).
- `chainLog`=_clog_, `clog`=_clog_: - `chainLog`=_clog_, `clog`=_clog_:
Specify the maximum number of bits for a hash chain or a binary tree. Specify the maximum number of bits for the secondary search structure,
whose form depends on the selected `strategy`.
Higher numbers of bits increases the chance to find a match which usually Higher numbers of bits increases the chance to find a match which usually
improves compression ratio. improves compression ratio.
It also slows down compression speed and increases memory requirements for It also slows down compression speed and increases memory requirements for
compression. compression.
This option is ignored for the ZSTD_fast strategy. This option is ignored for the `ZSTD_fast` `strategy`, which only has the primary hash table.
The minimum _clog_ is 6 (64 B) and the maximum is 29 (524 Mib) on 32-bit platforms The minimum _clog_ is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32-bit platforms
and 30 (1 Gib) on 64-bit platforms. and 30 (1B entries / 4 GiB) on 64-bit platforms.
- `searchLog`=_slog_, `slog`=_slog_: - `searchLog`=_slog_, `slog`=_slog_:
Specify the maximum number of searches in a hash chain or a binary tree Specify the maximum number of searches in a hash chain or a binary tree
@@ -567,19 +580,19 @@ The list of available _options_:
- `targetLength`=_tlen_, `tlen`=_tlen_: - `targetLength`=_tlen_, `tlen`=_tlen_:
The impact of this field vary depending on selected strategy. The impact of this field vary depending on selected strategy.
For ZSTD\_btopt, ZSTD\_btultra and ZSTD\_btultra2, it specifies For `ZSTD_btopt`, `ZSTD_btultra` and `ZSTD_btultra2`, it specifies
the minimum match length that causes match finder to stop searching. the minimum match length that causes match finder to stop searching.
A larger `targetLength` usually improves compression ratio A larger `targetLength` usually improves compression ratio
but decreases compression speed. but decreases compression speed.
t
For ZSTD\_fast, it triggers ultra-fast mode when > 0. For `ZSTD_fast`, it triggers ultra-fast mode when > 0.
The value represents the amount of data skipped between match sampling. The value represents the amount of data skipped between match sampling.
Impact is reversed : a larger `targetLength` increases compression speed Impact is reversed: a larger `targetLength` increases compression speed
but decreases compression ratio. but decreases compression ratio.
For all other strategies, this field has no impact. For all other strategies, this field has no impact.
The minimum _tlen_ is 0 and the maximum is 128 Kib. The minimum _tlen_ is 0 and the maximum is 128 KiB.
- `overlapLog`=_ovlog_, `ovlog`=_ovlog_: - `overlapLog`=_ovlog_, `ovlog`=_ovlog_:
Determine `overlapSize`, amount of data reloaded from previous job. Determine `overlapSize`, amount of data reloaded from previous job.
@@ -591,7 +604,7 @@ t
9 means "full overlap", meaning up to `windowSize` is reloaded from previous job. 9 means "full overlap", meaning up to `windowSize` is reloaded from previous job.
Reducing _ovlog_ by 1 reduces the reloaded amount by a factor 2. Reducing _ovlog_ by 1 reduces the reloaded amount by a factor 2.
For example, 8 means "windowSize/2", and 6 means "windowSize/8". For example, 8 means "windowSize/2", and 6 means "windowSize/8".
Value 0 is special and means "default" : _ovlog_ is automatically determined by `zstd`. Value 0 is special and means "default": _ovlog_ is automatically determined by `zstd`.
In which case, _ovlog_ will range from 6 to 9, depending on selected _strat_. In which case, _ovlog_ will range from 6 to 9, depending on selected _strat_.
- `ldmHashLog`=_lhlog_, `lhlog`=_lhlog_: - `ldmHashLog`=_lhlog_, `lhlog`=_lhlog_:
@@ -641,6 +654,11 @@ similar to predefined level 19 for files bigger than 256 KB:
`--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 `--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
SEE ALSO
--------
`zstdgrep`(1), `zstdless`(1), `gzip`(1), `xz`(1)
The <zstandard> format is specified in Y. Collet, "Zstandard Compression and the 'application/zstd' Media Type", https://www.ietf.org/rfc/rfc8878.txt, Internet RFC 8878 (February 2021).
BUGS BUGS
---- ----
+107 -92
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -52,12 +52,12 @@
/*-************************************ /*-************************************
* Constants * Constants
**************************************/ **************************************/
#define COMPRESSOR_NAME "zstd command line interface" #define COMPRESSOR_NAME "Zstandard CLI"
#ifndef ZSTD_VERSION #ifndef ZSTD_VERSION
# define ZSTD_VERSION "v" ZSTD_VERSION_STRING # define ZSTD_VERSION "v" ZSTD_VERSION_STRING
#endif #endif
#define AUTHOR "Yann Collet" #define AUTHOR "Yann Collet"
#define WELCOME_MESSAGE "*** %s %i-bits %s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(size_t)*8), ZSTD_VERSION, AUTHOR #define WELCOME_MESSAGE "*** %s (%i-bit) %s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(size_t)*8), ZSTD_VERSION, AUTHOR
#define ZSTD_ZSTDMT "zstdmt" #define ZSTD_ZSTDMT "zstdmt"
#define ZSTD_UNZSTD "unzstd" #define ZSTD_UNZSTD "unzstd"
@@ -143,160 +143,174 @@ static int exeNameMatch(const char* exeName, const char* test)
*/ */
static void usage(FILE* f, const char* programName) static void usage(FILE* f, const char* programName)
{ {
DISPLAY_F(f, "Usage: %s [OPTION]... [FILE]... [-o file]\n", programName); DISPLAY_F(f, "Compress or decompress the INPUT file(s); reads from STDIN if INPUT is `-` or not provided.\n\n");
DISPLAY_F(f, "Compress or uncompress FILEs (with no FILE or when FILE is `-`, read from standard input).\n\n"); DISPLAY_F(f, "Usage: %s [OPTIONS...] [INPUT... | -] [-o OUTPUT]\n\n", programName);
DISPLAY_F(f, " -o file result stored into `file` (only 1 output file)\n"); DISPLAY_F(f, "Options:\n");
#ifndef ZSTD_NOCOMPRESS DISPLAY_F(f, " -o OUTPUT Write output to a single file, OUTPUT.\n");
DISPLAY_F(f, " -1 .. -%d compression level (faster .. better; default: %d)\n", ZSTDCLI_CLEVEL_MAX, ZSTDCLI_CLEVEL_DEFAULT); DISPLAY_F(f, " -k, --keep Preserve INPUT file(s). [Default] \n");
#endif DISPLAY_F(f, " --rm Remove INPUT file(s) after successful (de)compression.\n");
#ifndef ZSTD_NODECOMPRESS
DISPLAY_F(f, " -d, --decompress decompression\n");
#endif
DISPLAY_F(f, " -f, --force disable input and output checks. Allows overwriting existing files,\n");
DISPLAY_F(f, " input from console, output to stdout, operating on links,\n");
DISPLAY_F(f, " block devices, etc. During decompression and when the output\n");
DISPLAY_F(f, " destination is stdout, pass-through unrecognized formats as-is.\n");
DISPLAY_F(f, " --rm remove source file(s) after successful de/compression\n");
DISPLAY_F(f, " -k, --keep preserve source file(s) (default) \n");
#ifdef ZSTD_GZCOMPRESS #ifdef ZSTD_GZCOMPRESS
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */ if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
DISPLAY_F(f, " -n, --no-name do not store original filename when compressing\n"); DISPLAY_F(f, " -n, --no-name Do not store original filename when compressing.\n\n");
} }
#endif #endif
DISPLAY_F(f, " -D DICT use DICT as Dictionary for compression or decompression\n"); DISPLAY_F(f, "\n");
DISPLAY_F(f, " -h display usage and exit\n"); #ifndef ZSTD_NOCOMPRESS
DISPLAY_F(f, " -H,--help display long help and exit\n"); DISPLAY_F(f, " -# Desired compression level, where `#` is a number between 1 and %d;\n", ZSTDCLI_CLEVEL_MAX);
DISPLAY_F(f, " lower numbers provide faster compression, higher numbers yield\n");
DISPLAY_F(f, " better compression ratios. [Default: %d]\n\n", ZSTDCLI_CLEVEL_DEFAULT);
#endif
#ifndef ZSTD_NODECOMPRESS
DISPLAY_F(f, " -d, --decompress Perform decompression.\n");
#endif
DISPLAY_F(f, " -D DICT Use DICT as the dictionary for compression or decompression.\n\n");
DISPLAY_F(f, " -f, --force Disable input and output checks. Allows overwriting existing files,\n");
DISPLAY_F(f, " receiving input from the console, printing ouput to STDOUT, and\n");
DISPLAY_F(f, " operating on links, block devices, etc. Unrecognized formats will be\n");
DISPLAY_F(f, " passed-through through as-is.\n\n");
DISPLAY_F(f, " -h Display short usage and exit.\n");
DISPLAY_F(f, " -H, --help Display full help and exit.\n");
DISPLAY_F(f, " -V, --version Display the program version and exit.\n");
DISPLAY_F(f, "\n"); DISPLAY_F(f, "\n");
} }
static void usage_advanced(const char* programName) static void usage_advanced(const char* programName)
{ {
DISPLAYOUT(WELCOME_MESSAGE); DISPLAYOUT(WELCOME_MESSAGE);
DISPLAYOUT("\n");
usage(stdout, programName); usage(stdout, programName);
DISPLAYOUT("Advanced options :\n"); DISPLAYOUT("Advanced options:\n");
DISPLAYOUT(" -V, --version display Version number and exit\n"); DISPLAYOUT(" -c, --stdout Write to STDOUT (even if it is a console) and keep the INPUT file(s).\n\n");
DISPLAYOUT(" -c, --stdout write to standard output (even if it is the console), keep original file\n"); DISPLAYOUT(" -v, --verbose Enable verbose output; pass multiple times to increase verbosity.\n");
DISPLAYOUT(" -q, --quiet Suppress warnings; pass twice to suppress errors.\n");
DISPLAYOUT(" -v, --verbose verbose mode; specify multiple times to increase verbosity\n"); #ifndef ZSTD_NOTRACE
DISPLAYOUT(" -q, --quiet suppress warnings; specify twice to suppress errors too\n"); DISPLAYOUT(" --trace LOG Log tracing information to LOG.\n");
DISPLAYOUT(" --[no-]progress forcibly display, or never display the progress counter\n"); #endif
DISPLAYOUT(" note: any (de)compressed output to terminal will mix with progress counter text\n"); DISPLAYOUT("\n");
DISPLAYOUT(" --[no-]progress Forcibly show/hide the progress counter. NOTE: Any (de)compressed\n");
DISPLAYOUT(" output to terminal will mix with progress counter text.\n\n");
#ifdef UTIL_HAS_CREATEFILELIST #ifdef UTIL_HAS_CREATEFILELIST
DISPLAYOUT(" -r operate recursively on directories\n"); DISPLAYOUT(" -r Operate recursively on directories.\n");
DISPLAYOUT(" --filelist FILE read list of files to operate upon from FILE\n"); DISPLAYOUT(" --filelist LIST Read a list of files to operate on from LIST.\n");
DISPLAYOUT(" --output-dir-flat DIR : processed files are stored into DIR\n"); DISPLAYOUT(" --output-dir-flat DIR Store processed files in DIR.\n");
#endif #endif
#ifdef UTIL_HAS_MIRRORFILELIST #ifdef UTIL_HAS_MIRRORFILELIST
DISPLAYOUT(" --output-dir-mirror DIR : processed files are stored into DIR respecting original directory structure\n"); DISPLAYOUT(" --output-dir-mirror DIR Store processed files in DIR, respecting original directory structure.\n");
#endif #endif
if (AIO_supported()) if (AIO_supported())
DISPLAYOUT(" --[no-]asyncio use asynchronous IO (default: enabled)\n"); DISPLAYOUT(" --[no-]asyncio Use asynchronous IO. [Default: Enabled]\n");
DISPLAYOUT("\n");
#ifndef ZSTD_NOCOMPRESS #ifndef ZSTD_NOCOMPRESS
DISPLAYOUT(" --[no-]check during compression, add XXH64 integrity checksum to frame (default: enabled)\n"); DISPLAYOUT(" --[no-]check Add XXH64 integrity checksums during compression. [Default: Add, Validate]\n");
#ifndef ZSTD_NODECOMPRESS #ifndef ZSTD_NODECOMPRESS
DISPLAYOUT(" if specified with -d, decompressor will ignore/validate checksums in compressed frame (default: validate)\n"); DISPLAYOUT(" If `-d` is present, ignore/validate checksums during decompression.\n");
#endif #endif
#else #else
#ifdef ZSTD_NOCOMPRESS #ifdef ZSTD_NOCOMPRESS
DISPLAYOUT(" --[no-]check during decompression, ignore/validate checksums in compressed frame (default: validate)"); DISPLAYOUT(" --[no-]check Ignore/validate checksums during decompression. [Default: Validate]");
#endif #endif
DISPLAYOUT("\n");
#endif /* ZSTD_NOCOMPRESS */ #endif /* ZSTD_NOCOMPRESS */
#ifndef ZSTD_NOTRACE DISPLAYOUT("\n");
DISPLAYOUT(" --trace FILE log tracing information to FILE\n"); DISPLAYOUT(" -- Treat remaining arguments after `--` as files.\n");
#endif
DISPLAYOUT(" -- all arguments after \"--\" are treated as files\n");
#ifndef ZSTD_NOCOMPRESS #ifndef ZSTD_NOCOMPRESS
DISPLAYOUT("\n"); DISPLAYOUT("\n");
DISPLAYOUT("Advanced compression options :\n"); DISPLAYOUT("Advanced compression options:\n");
DISPLAYOUT(" --ultra enable levels beyond %i, up to %i (requires more memory)\n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel()); DISPLAYOUT(" --ultra Enable levels beyond %i, up to %i; requires more memory.\n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
DISPLAYOUT(" --fast[=#] switch to very fast compression levels (default: %u)\n", 1); DISPLAYOUT(" --fast[=#] Use to very fast compression levels. [Default: %u]\n", 1);
#ifdef ZSTD_GZCOMPRESS #ifdef ZSTD_GZCOMPRESS
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */ if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
DISPLAYOUT(" --best compatibility alias for -9 \n"); DISPLAYOUT(" --best Compatibility alias for `-9`.\n");
DISPLAYOUT(" --no-name do not store original filename when compressing\n");
} }
#endif #endif
DISPLAYOUT(" --long[=#] enable long distance matching with given window log (default: %u)\n", g_defaultMaxWindowLog); DISPLAYOUT(" --adapt Dynamically adapt compression level to I/O conditions.\n");
DISPLAYOUT(" --patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n"); DISPLAYOUT(" --long[=#] Enable long distance matching with window log #. [Default: %u]\n", g_defaultMaxWindowLog);
DISPLAYOUT(" --adapt dynamically adapt compression level to I/O conditions\n"); DISPLAYOUT(" --patch-from=REF Use REF as the reference point for Zstandard's diff engine. \n\n");
# ifdef ZSTD_MULTITHREAD # ifdef ZSTD_MULTITHREAD
DISPLAYOUT(" -T# spawn # compression threads (default: 1, 0==# cores) \n"); DISPLAYOUT(" -T# Spawn # compression threads. [Default: 1; pass 0 for core count.]\n");
DISPLAYOUT(" -B# select size of each job (default: 0==automatic) \n"); DISPLAYOUT(" --single-thread Share a single thread for I/O and compression (slightly different than `-T1`).\n");
DISPLAYOUT(" --single-thread use a single thread for both I/O and compression (result slightly different than -T1) \n"); DISPLAYOUT(" --auto-threads={physical|logical}\n");
DISPLAYOUT(" --auto-threads={physical,logical} : use either physical cores or logical cores as default when specifying -T0 (default: physical)\n"); DISPLAYOUT(" Use physical/logical cores when using `-T0`. [Default: Physical]\n\n");
DISPLAYOUT(" --rsyncable compress using a rsync-friendly method (-B sets block size) \n"); DISPLAYOUT(" -B# Set job size to #. [Default: 0 (automatic)]\n");
DISPLAYOUT(" --rsyncable Compress using a rsync-friendly method (`-B` sets block size). \n");
DISPLAYOUT("\n");
# endif # endif
DISPLAYOUT(" --exclude-compressed : only compress files that are not already compressed \n"); DISPLAYOUT(" --exclude-compressed Only compress files that are not already compressed.\n\n");
DISPLAYOUT(" --stream-size=# specify size of streaming input from `stdin` \n");
DISPLAYOUT(" --size-hint=# optimize compression parameters for streaming input of approximately this size \n");
DISPLAYOUT(" --target-compressed-block-size=# : generate compressed block of approximately targeted size \n");
DISPLAYOUT(" --no-dictID don't write dictID into header (dictionary compression only)\n");
DISPLAYOUT(" --[no-]compress-literals : force (un)compressed literals\n");
DISPLAYOUT(" --[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies\n");
DISPLAYOUT(" --format=zstd compress files to the .zst format (default)\n"); DISPLAYOUT(" --stream-size=# Specify size of streaming input from STDIN.\n");
DISPLAYOUT(" --size-hint=# Optimize compression parameters for streaming input of approximately size #.\n");
DISPLAYOUT(" --target-compressed-block-size=#\n");
DISPLAYOUT(" Generate compressed blocks of approximately # size.\n\n");
DISPLAYOUT(" --no-dictID Don't write `dictID` into the header (dictionary compression only).\n");
DISPLAYOUT(" --[no-]compress-literals Force (un)compressed literals.\n");
DISPLAYOUT(" --[no-]row-match-finder Explicitly enable/disable the fast, row-based matchfinder for\n");
DISPLAYOUT(" the 'greedy', 'lazy', and 'lazy2' strategies.\n");
DISPLAYOUT("\n");
DISPLAYOUT(" --format=zstd Compress files to the `.zst` format. [Default]\n");
#ifdef ZSTD_GZCOMPRESS #ifdef ZSTD_GZCOMPRESS
DISPLAYOUT(" --format=gzip compress files to the .gz format\n"); DISPLAYOUT(" --format=gzip Compress files to the `.gz` format.\n");
#endif #endif
#ifdef ZSTD_LZMACOMPRESS #ifdef ZSTD_LZMACOMPRESS
DISPLAYOUT(" --format=xz compress files to the .xz format\n"); DISPLAYOUT(" --format=xz Compress files to the `.xz` format.\n");
DISPLAYOUT(" --format=lzma compress files to the .lzma format\n"); DISPLAYOUT(" --format=lzma Compress files to the `.lzma` format.\n");
#endif #endif
#ifdef ZSTD_LZ4COMPRESS #ifdef ZSTD_LZ4COMPRESS
DISPLAYOUT( " --format=lz4 compress files to the .lz4 format\n"); DISPLAYOUT( " --format=lz4 Compress files to the `.lz4` format.\n");
#endif #endif
#endif /* !ZSTD_NOCOMPRESS */ #endif /* !ZSTD_NOCOMPRESS */
#ifndef ZSTD_NODECOMPRESS #ifndef ZSTD_NODECOMPRESS
DISPLAYOUT("\n"); DISPLAYOUT("\n");
DISPLAYOUT("Advanced decompression options :\n"); DISPLAYOUT("Advanced decompression options:\n");
DISPLAYOUT(" -l print information about zstd compressed files\n"); DISPLAYOUT(" -l Print information about Zstandard-compressed files.\n");
DISPLAYOUT(" --test test compressed file integrity\n"); DISPLAYOUT(" --test Test compressed file integrity.\n");
DISPLAYOUT(" -M# Set a memory usage limit for decompression\n"); DISPLAYOUT(" -M# Set the memory usage limit to # megabytes.\n");
# if ZSTD_SPARSE_DEFAULT # if ZSTD_SPARSE_DEFAULT
DISPLAYOUT(" --[no-]sparse sparse mode (default: enabled on file, disabled on stdout)\n"); DISPLAYOUT(" --[no-]sparse Enable sparse mode. [Default: Enabled for files, disabled for STDOUT.]\n");
# else # else
DISPLAYOUT(" --[no-]sparse sparse mode (default: disabled)\n"); DISPLAYOUT(" --[no-]sparse Enable sparse mode. [Default: Disabled]\n");
# endif # endif
{ {
char const* passThroughDefault = "disabled"; char const* passThroughDefault = "Disabled";
if (exeNameMatch(programName, ZSTD_CAT) || if (exeNameMatch(programName, ZSTD_CAT) ||
exeNameMatch(programName, ZSTD_ZCAT) || exeNameMatch(programName, ZSTD_ZCAT) ||
exeNameMatch(programName, ZSTD_GZCAT)) { exeNameMatch(programName, ZSTD_GZCAT)) {
passThroughDefault = "enabled"; passThroughDefault = "Enabled";
} }
DISPLAYOUT(" --[no-]pass-through : passes through uncompressed files as-is (default: %s)\n", passThroughDefault); DISPLAYOUT(" --[no-]pass-through Pass through uncompressed files as-is. [Default: %s]\n", passThroughDefault);
} }
#endif /* ZSTD_NODECOMPRESS */ #endif /* ZSTD_NODECOMPRESS */
#ifndef ZSTD_NODICT #ifndef ZSTD_NODICT
DISPLAYOUT("\n"); DISPLAYOUT("\n");
DISPLAYOUT("Dictionary builder :\n"); DISPLAYOUT("Dictionary builder:\n");
DISPLAYOUT(" --train ## create a dictionary from a training set of files\n"); DISPLAYOUT(" --train Create a dictionary from a training set of files.\n\n");
DISPLAYOUT(" --train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]] : use the cover algorithm with optional args\n"); DISPLAYOUT(" --train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]]\n");
DISPLAYOUT(" --train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]] : use the fast cover algorithm with optional args\n"); DISPLAYOUT(" Use the cover algorithm (with optional arguments).\n");
DISPLAYOUT(" --train-legacy[=s=#] : use the legacy algorithm with selectivity (default: %u)\n", g_defaultSelectivityLevel); DISPLAYOUT(" --train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]]\n");
DISPLAYOUT(" -o DICT DICT is dictionary name (default: %s)\n", g_defaultDictName); DISPLAYOUT(" Use the fast cover algorithm (with optional arguments).\n\n");
DISPLAYOUT(" --maxdict=# limit dictionary to specified size (default: %u)\n", g_defaultMaxDictSize); DISPLAYOUT(" --train-legacy[=s=#] Use the legacy algorithm with selectivity #. [Default: %u]\n", g_defaultSelectivityLevel);
DISPLAYOUT(" --dictID=# force dictionary ID to specified value (default: random)\n"); DISPLAYOUT(" -o NAME Use NAME as dictionary name. [Default: %s]\n", g_defaultDictName);
DISPLAYOUT(" --maxdict=# Limit dictionary to specified size #. [Default: %u]\n", g_defaultMaxDictSize);
DISPLAYOUT(" --dictID=# Force dictionary ID to #. [Default: Random]\n");
#endif #endif
#ifndef ZSTD_NOBENCH #ifndef ZSTD_NOBENCH
DISPLAYOUT("\n"); DISPLAYOUT("\n");
DISPLAYOUT("Benchmark options : \n"); DISPLAYOUT("Benchmark options:\n");
DISPLAYOUT(" -b# benchmark file(s), using # compression level (default: %d)\n", ZSTDCLI_CLEVEL_DEFAULT); DISPLAYOUT(" -b# Perform benchmarking with compression level #. [Default: %d]\n", ZSTDCLI_CLEVEL_DEFAULT);
DISPLAYOUT(" -e# test all compression levels successively from -b# to -e# (default: 1)\n"); DISPLAYOUT(" -e# Test all compression levels up to #; starting level is `-b#`. [Default: 1]\n");
DISPLAYOUT(" -i# minimum evaluation time in seconds (default: 3s)\n"); DISPLAYOUT(" -i# Set the minimum evaluation to time # seconds. [Default: 3]\n");
DISPLAYOUT(" -B# cut file into independent chunks of size # (default: no chunking)\n"); DISPLAYOUT(" -B# Cut file into independent chunks of size #. [Default: No chunking]\n");
DISPLAYOUT(" -S output one benchmark result per input file (default: consolidated result)\n"); DISPLAYOUT(" -S Output one benchmark result per input file. [Default: Consolidated result]\n");
DISPLAYOUT(" --priority=rt set process priority to real-time\n"); DISPLAYOUT(" --priority=rt Set process priority to real-time.\n");
#endif #endif
} }
@@ -990,6 +1004,7 @@ int main(int argCount, const char* argv[])
if (!strcmp(argument, "--fake-stdin-is-console")) { UTIL_fakeStdinIsConsole(); continue; } if (!strcmp(argument, "--fake-stdin-is-console")) { UTIL_fakeStdinIsConsole(); continue; }
if (!strcmp(argument, "--fake-stdout-is-console")) { UTIL_fakeStdoutIsConsole(); continue; } if (!strcmp(argument, "--fake-stdout-is-console")) { UTIL_fakeStdoutIsConsole(); continue; }
if (!strcmp(argument, "--fake-stderr-is-console")) { UTIL_fakeStderrIsConsole(); continue; } if (!strcmp(argument, "--fake-stderr-is-console")) { UTIL_fakeStderrIsConsole(); continue; }
if (!strcmp(argument, "--trace-file-stat")) { UTIL_traceFileStat(); continue; }
/* long commands with arguments */ /* long commands with arguments */
#ifndef ZSTD_NODICT #ifndef ZSTD_NODICT
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+5 -5
View File
@@ -4,16 +4,16 @@ zstdgrep(1) -- print lines matching a pattern in zstandard-compressed files
SYNOPSIS SYNOPSIS
-------- --------
`zstdgrep` [*grep-flags*] [--] _pattern_ [_files_ ...] `zstdgrep` [<grep-flags>] [--] <pattern> [<files> ...]
DESCRIPTION DESCRIPTION
----------- -----------
`zstdgrep` runs `grep (1)` on files, or `stdin` if no files argument is given, after decompressing them with `zstdcat (1)`. `zstdgrep` runs `grep`(1) on files, or `stdin` if no files argument is given, after decompressing them with `zstdcat`(1).
The grep-flags and pattern arguments are passed on to `grep (1)`. If an `-e` flag is found in the `grep-flags`, `zstdgrep` will not look for a pattern argument. The <grep-flags> and <pattern> arguments are passed on to `grep`(1). If an `-e` flag is found in the <grep-flags>, `zstdgrep` will not look for a <pattern> argument.
Note that modern `grep` alternatives such as `ripgrep` (`rg`) support `zstd`-compressed files out of the box, Note that modern `grep` alternatives such as `ripgrep` (`rg`(1)) support `zstd`-compressed files out of the box,
and can prove better alternatives than `zstdgrep` notably for unsupported complex pattern searches. and can prove better alternatives than `zstdgrep` notably for unsupported complex pattern searches.
Note though that such alternatives may also feature some minor command line differences. Note though that such alternatives may also feature some minor command line differences.
@@ -23,7 +23,7 @@ In case of missing arguments or missing pattern, 1 will be returned, otherwise 0
SEE ALSO SEE ALSO
-------- --------
`zstd (1)` `zstd`(1)
AUTHORS AUTHORS
------- -------
+3 -3
View File
@@ -4,13 +4,13 @@ zstdless(1) -- view zstandard-compressed files
SYNOPSIS SYNOPSIS
-------- --------
`zstdless` [*flags*] [_file_ ...] `zstdless` [<flags>] [<file> ...]
DESCRIPTION DESCRIPTION
----------- -----------
`zstdless` runs `less (1)` on files or stdin, if no files argument is given, after decompressing them with `zstdcat (1)`. `zstdless` runs `less`(1) on files or stdin, if no <file> argument is given, after decompressing them with `zstdcat`(1).
SEE ALSO SEE ALSO
-------- --------
`zstd (1)` `zstd`(1)
+1 -1
View File
@@ -2,7 +2,7 @@
# THIS BENCHMARK IS BEING REPLACED BY automated-bencmarking.py # THIS BENCHMARK IS BEING REPLACED BY automated-bencmarking.py
# ################################################################ # ################################################################
# Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+2 -2
View File
@@ -1,6 +1,6 @@
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -169,7 +169,7 @@ fuzzer-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PR
$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT)
CLEAN += zstreamtest zstreamtest32 CLEAN += zstreamtest zstreamtest32
ZSTREAM_LOCAL_FILES := $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c seqgen.c zstreamtest.c ZSTREAM_LOCAL_FILES := $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c seqgen.c zstreamtest.c external_matchfinder.c
ZSTREAM_PROPER_FILES := $(ZDICT_FILES) $(ZSTREAM_LOCAL_FILES) ZSTREAM_PROPER_FILES := $(ZDICT_FILES) $(ZSTREAM_LOCAL_FILES)
ZSTREAMFILES := $(ZSTD_FILES) $(ZSTREAM_PROPER_FILES) ZSTREAMFILES := $(ZSTD_FILES) $(ZSTREAM_PROPER_FILES)
zstreamtest32 : CFLAGS += -m32 zstreamtest32 : CFLAGS += -m32
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env python3
# ################################################################
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under both the BSD-style license (found in the
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
# in the COPYING file in the root directory of this source tree).
# You may select, at your option, one of the above-listed licenses.
# ################################################################
import os
import subprocess
import sys
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} FILE SIZE_LIMIT")
sys.exit(1)
file = sys.argv[1]
limit = int(sys.argv[2])
if not os.path.exists(file):
print(f"{file} does not exist")
sys.exit(1)
size = os.path.getsize(file)
if size > limit:
print(f"file {file} is {size} bytes, which is greater than the limit of {limit} bytes")
sys.exit(1)
+10
View File
@@ -45,6 +45,16 @@ Examples:
./run.py --preserve --verbose basic/help.sh ./run.py --preserve --verbose basic/help.sh
``` ```
### Updating exact output
If a test is failing because a `.stderr.exact` or `.stdout.exact` no longer matches, you can re-run the tests with `--set-exact-output` and the correct output will be written.
Example:
```
./run.py --set-exact-output
./run.py basic/help.sh --set-exact-output
```
## Writing a test ## Writing a test
Test cases are arbitrary executables, and can be written in any language, but are generally shell scripts. Test cases are arbitrary executables, and can be written in any language, but are generally shell scripts.
+25 -16
View File
@@ -1,25 +1,34 @@
+ zstd -h + zstd -h
Usage: zstd *OPTION*... *FILE*... *-o file* Compress or decompress the INPUT file(s); reads from STDIN if INPUT is `-` or not provided.
Compress or uncompress FILEs (with no FILE or when FILE is `-`, read from standard input).
-o file result stored into `file` (only 1 output file) Usage: zstd *OPTIONS...* *INPUT... | -* *-o OUTPUT*
-1 .. -19 compression level (faster .. better; default: 3)
-d, --decompress decompression Options:
-f, --force disable input and output checks. Allows overwriting existing files, -o OUTPUT Write output to a single file, OUTPUT.
input from console, output to stdout, operating on links, -k, --keep Preserve INPUT file(s). *Default*
block devices, etc. During decompression and when the output --rm Remove INPUT file(s) after successful (de)compression.
destination is stdout, pass-through unrecognized formats as-is.
--rm remove source file(s) after successful de/compression -# Desired compression level, where `#` is a number between 1 and 19;
-k, --keep preserve source file(s) (default) lower numbers provide faster compression, higher numbers yield
-D DICT use DICT as Dictionary for compression or decompression better compression ratios. *Default: 3*
-h display usage and exit
-H,--help display long help and exit -d, --decompress Perform decompression.
-D DICT Use DICT as the dictionary for compression or decompression.
-f, --force Disable input and output checks. Allows overwriting existing files,
receiving input from the console, printing ouput to STDOUT, and
operating on links, block devices, etc. Unrecognized formats will be
passed-through through as-is.
-h Display short usage and exit.
-H, --help Display full help and exit.
-V, --version Display the program version and exit.
+ zstd -H + zstd -H
... ...
Advanced options : Advanced options:
... ...
+ zstd --help + zstd --help
... ...
Advanced options : Advanced options:
... ...
+2 -2
View File
@@ -1,2 +1,2 @@
*** zstd command line interface *-bits v1.*.*, by Yann Collet *** *** Zstandard CLI (*-bit) v1.*.*, by Yann Collet ***
*** zstd command line interface *-bits v1.*.*, by Yann Collet *** *** Zstandard CLI (*-bit) v1.*.*, by Yann Collet ***
+1 -3
View File
@@ -10,11 +10,9 @@ zstd --fast=10 file -o file-f10.zst
zstd --fast=1 file -o file-f1.zst zstd --fast=1 file -o file-f1.zst
zstd -1 file -o file-1.zst zstd -1 file -o file-1.zst
zstd -19 file -o file-19.zst zstd -19 file -o file-19.zst
zstd -22 --ultra file -o file-22.zst
zstd -t file-f10.zst file-f1.zst file-1.zst file-19.zst file-22.zst zstd -t file-f10.zst file-f1.zst file-1.zst file-19.zst
cmp_size -ne file-19.zst file-22.zst
cmp_size -lt file-19.zst file-1.zst cmp_size -lt file-19.zst file-1.zst
cmp_size -lt file-1.zst file-f1.zst cmp_size -lt file-1.zst file-f1.zst
cmp_size -lt file-f1.zst file-f10.zst cmp_size -lt file-f1.zst file-f10.zst
@@ -6,11 +6,9 @@ zstd --fast=10 file -o file-f10.zst
zstd --fast=1 file -o file-f1.zst zstd --fast=1 file -o file-f1.zst
zstd -1 file -o file-1.zst zstd -1 file -o file-1.zst
zstd -19 file -o file-19.zst zstd -19 file -o file-19.zst
zstd -22 --ultra file -o file-22.zst
zstd -t file-f10.zst file-f1.zst file-1.zst file-19.zst file-22.zst zstd -t file-f10.zst file-f1.zst file-1.zst file-19.zst
cmp_size -ne file-19.zst file-22.zst
cmp_size -lt file-19.zst file-1.zst cmp_size -lt file-19.zst file-1.zst
cmp_size -lt file-1.zst file-f1.zst cmp_size -lt file-1.zst file-f1.zst
cmp_size -lt file-f1.zst file-f10.zst cmp_size -lt file-f1.zst file-f10.zst
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -e
datagen > file
zstd file -q --trace-file-stat -o file.zst
zstd -tq file.zst
@@ -0,0 +1,36 @@
Trace:FileStat: > UTIL_isLink(file)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(2)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_getFileSize(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 65537
Trace:FileStat: > UTIL_isDirectory(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 0
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_isSameFile(file, file.zst)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file.zst)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file.zst)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: < 1
Trace:FileStat: > UTIL_getFileSize(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 65537
Trace:FileStat: > UTIL_utime(file.zst)
Trace:FileStat: < 0
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -e
datagen > file
zstd file -cq --trace-file-stat > file.zst
zstd -tq file.zst
@@ -0,0 +1,22 @@
Trace:FileStat: > UTIL_isLink(file)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(1)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_getFileSize(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 65537
Trace:FileStat: > UTIL_isDirectory(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 0
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
Trace:FileStat: > UTIL_stat(/*stdout*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_getFileSize(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 65537
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -e
datagen > file
zstd < file -q --trace-file-stat -o file.zst
zstd -tq file.zst
@@ -0,0 +1,28 @@
Trace:FileStat: > UTIL_isConsole(0)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(2)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < -1
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isSameFile(/*stdin*\, file.zst)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file.zst)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file.zst)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: < 1
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < -1
+8
View File
@@ -0,0 +1,8 @@
#!/bin/sh
set -e
datagen > file
zstd < file -cq --trace-file-stat > file.zst
zstd -tq file.zst
@@ -0,0 +1,20 @@
Trace:FileStat: > UTIL_isConsole(0)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(1)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < -1
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
Trace:FileStat: > UTIL_stat(/*stdout*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_getFileSize(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < -1
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -e
datagen | zstd -q > file.zst
zstd -dq --trace-file-stat file.zst
@@ -0,0 +1,30 @@
Trace:FileStat: > UTIL_isLink(file.zst)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(1)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(2)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isDirectory(file.zst)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: < 0
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_isSameFile(file.zst, file)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 1
Trace:FileStat: > UTIL_utime(file)
Trace:FileStat: < 0
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -e
datagen | zstd -q > file.zst
zstd -dcq --trace-file-stat file.zst > file
@@ -0,0 +1,14 @@
Trace:FileStat: > UTIL_isLink(file.zst)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(1)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isDirectory(file.zst)
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: < 0
Trace:FileStat: > UTIL_stat(file.zst)
Trace:FileStat: < 1
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
Trace:FileStat: > UTIL_stat(/*stdout*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -e
datagen | zstd -q > file.zst
zstd -dcq --trace-file-stat < file.zst -o file
@@ -0,0 +1,20 @@
Trace:FileStat: > UTIL_isConsole(0)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(2)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isSameFile(/*stdin*\, file)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(file)
Trace:FileStat: > UTIL_stat(file)
Trace:FileStat: < 1
Trace:FileStat: < 1
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -e
datagen | zstd -q > file.zst
zstd -dcq --trace-file-stat < file.zst > file
@@ -0,0 +1,12 @@
Trace:FileStat: > UTIL_isConsole(0)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isConsole(1)
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isDirectory(/*stdin*\)
Trace:FileStat: > UTIL_stat(/*stdin*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
Trace:FileStat: > UTIL_isRegularFile(/*stdout*\)
Trace:FileStat: > UTIL_stat(/*stdout*\)
Trace:FileStat: < 0
Trace:FileStat: < 0
@@ -55,36 +55,36 @@ decompress 2 files
args = --no-progress --fake-stderr-is-console -v args = --no-progress --fake-stderr-is-console -v
compress file to file compress file to file
*zstd* *Zstandard CLI*
hello*hello.zst* hello*hello.zst*
compress pipe to pipe compress pipe to pipe
*zstd* *Zstandard CLI*
*stdin*stdout* *stdin*stdout*
compress pipe to file compress pipe to file
*zstd* *Zstandard CLI*
*stdin*hello.zst* *stdin*hello.zst*
compress file to pipe compress file to pipe
*zstd* *Zstandard CLI*
*hello*stdout* *hello*stdout*
compress 2 files compress 2 files
*zstd* *Zstandard CLI*
*hello*hello.zst* *hello*hello.zst*
*world*world.zst* *world*world.zst*
2 files compressed* 2 files compressed*
decompress file to file decompress file to file
*zstd* *Zstandard CLI*
hello.zst* hello.zst*
decompress pipe to pipe decompress pipe to pipe
*zstd* *Zstandard CLI*
*stdin* *stdin*
decompress pipe to file decompress pipe to file
*zstd* *Zstandard CLI*
*stdin* *stdin*
decompress file to pipe decompress file to pipe
*zstd* *Zstandard CLI*
hello.zst* hello.zst*
decompress 2 files decompress 2 files
*zstd* *Zstandard CLI*
hello.zst* hello.zst*
world.zst* world.zst*
2 files decompressed* 2 files decompressed*
+16 -4
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -209,6 +209,7 @@ class Options:
preserve: bool, preserve: bool,
scratch_dir: str, scratch_dir: str,
test_dir: str, test_dir: str,
set_exact_output: bool,
) -> None: ) -> None:
self.env = env self.env = env
self.timeout = timeout self.timeout = timeout
@@ -216,6 +217,7 @@ class Options:
self.preserve = preserve self.preserve = preserve
self.scratch_dir = scratch_dir self.scratch_dir = scratch_dir
self.test_dir = test_dir self.test_dir = test_dir
self.set_exact_output = set_exact_output
class TestCase: class TestCase:
@@ -335,7 +337,7 @@ class TestCase:
self._test_stdin.close() self._test_stdin.close()
self._test_stdin = None self._test_stdin = None
def _check_output_exact(self, out_name: str, expected: bytes) -> None: def _check_output_exact(self, out_name: str, expected: bytes, exact_name: str) -> None:
""" """
Check the output named :out_name: for an exact match against the :expected: content. Check the output named :out_name: for an exact match against the :expected: content.
Saves the success and message. Saves the success and message.
@@ -349,6 +351,10 @@ class TestCase:
self._success[check_name] = False self._success[check_name] = False
self._message[check_name] = f"{out_name} does not match!\n> diff expected actual\n{diff(expected, actual)}" self._message[check_name] = f"{out_name} does not match!\n> diff expected actual\n{diff(expected, actual)}"
if self._opts.set_exact_output:
with open(exact_name, "wb") as f:
f.write(actual)
def _check_output_glob(self, out_name: str, expected: bytes) -> None: def _check_output_glob(self, out_name: str, expected: bytes) -> None:
""" """
Check the output named :out_name: for a glob match against the :expected: glob. Check the output named :out_name: for a glob match against the :expected: glob.
@@ -386,7 +392,7 @@ class TestCase:
ignore_name = f"{self._test_file}.{out_name}.ignore" ignore_name = f"{self._test_file}.{out_name}.ignore"
if os.path.exists(exact_name): if os.path.exists(exact_name):
return self._check_output_exact(out_name, read_file(exact_name)) return self._check_output_exact(out_name, read_file(exact_name), exact_name)
elif os.path.exists(glob_name): elif os.path.exists(glob_name):
return self._check_output_glob(out_name, read_file(glob_name)) return self._check_output_glob(out_name, read_file(glob_name))
elif os.path.exists(ignore_name): elif os.path.exists(ignore_name):
@@ -394,7 +400,7 @@ class TestCase:
self._success[check_name] = True self._success[check_name] = True
self._message[check_name] = f"{out_name} ignored!" self._message[check_name] = f"{out_name} ignored!"
else: else:
return self._check_output_exact(out_name, bytes()) return self._check_output_exact(out_name, bytes(), exact_name)
def _check_stderr(self) -> None: def _check_stderr(self) -> None:
"""Checks the stderr output against the expectation.""" """Checks the stderr output against the expectation."""
@@ -678,6 +684,11 @@ if __name__ == "__main__":
"Scratch directory located in TEST_DIR/scratch/." "Scratch directory located in TEST_DIR/scratch/."
) )
) )
parser.add_argument(
"--set-exact-output",
action="store_true",
help="Set stderr.exact and stdout.exact for all failing tests, unless .ignore or .glob already exists"
)
parser.add_argument( parser.add_argument(
"tests", "tests",
nargs="*", nargs="*",
@@ -714,6 +725,7 @@ if __name__ == "__main__":
preserve=args.preserve, preserve=args.preserve,
test_dir=args.test_dir, test_dir=args.test_dir,
scratch_dir=scratch_dir, scratch_dir=scratch_dir,
set_exact_output=args.set_exact_output,
) )
if len(args.tests) == 0: if len(args.tests) == 0:
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+4 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -136,7 +136,7 @@ static void RAND_genDist(U32* seed, BYTE* dist, double weight)
BYTE step = (BYTE) ((RAND(seed) % 256) | 1); /* force it to be odd so it's relatively prime to 256 */ BYTE step = (BYTE) ((RAND(seed) % 256) | 1); /* force it to be odd so it's relatively prime to 256 */
while (i < DISTSIZE) { while (i < DISTSIZE) {
size_t states = ((size_t)(weight * statesLeft)) + 1; size_t states = ((size_t)(weight * (double)statesLeft)) + 1;
size_t j; size_t j;
for (j = 0; j < states && i < DISTSIZE; j++, i++) { for (j = 0; j < states && i < DISTSIZE; j++, i++) {
dist[i] = symb; dist[i] = symb;
@@ -662,11 +662,11 @@ generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
* ensure nice numbers */ * ensure nice numbers */
U32 matchLen = U32 matchLen =
MIN_SEQ_LEN + MIN_SEQ_LEN +
ROUND(RAND_exp(seed, excessMatch / (double)(numSequences - i))); ROUND(RAND_exp(seed, (double)excessMatch / (double)(numSequences - i)));
U32 literalLen = U32 literalLen =
(RAND(seed) & 7) (RAND(seed) & 7)
? ROUND(RAND_exp(seed, ? ROUND(RAND_exp(seed,
literalsSize / (double)literalsSize /
(double)(numSequences - i))) (double)(numSequences - i)))
: 0; : 0;
/* actual offset, code to send, and point to copy up to when shifting /* actual offset, code to send, and point to copy up to when shifting
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright (c) Yann Collet, Meta Platforms, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
#include "external_matchfinder.h"
#include <string.h>
#include "zstd_compress_internal.h"
#define HSIZE 1024
static U32 const HLOG = 10;
static U32 const MLS = 4;
static U32 const BADIDX = 0xffffffff;
static size_t simpleExternalMatchFinder(
void* externalMatchState,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize,
const void* dict, size_t dictSize,
int compressionLevel,
size_t windowSize
) {
const BYTE* const istart = (const BYTE*)src;
const BYTE* const iend = istart + srcSize;
const BYTE* ip = istart;
const BYTE* anchor = istart;
size_t seqCount = 0;
U32 hashTable[HSIZE];
(void)externalMatchState;
(void)dict;
(void)dictSize;
(void)outSeqsCapacity;
(void)compressionLevel;
{ int i;
for (i=0; i < HSIZE; i++) {
hashTable[i] = BADIDX;
} }
while (ip + MLS < iend) {
size_t const hash = ZSTD_hashPtr(ip, HLOG, MLS);
U32 const matchIndex = hashTable[hash];
hashTable[hash] = (U32)(ip - istart);
if (matchIndex != BADIDX) {
const BYTE* const match = istart + matchIndex;
U32 const matchLen = (U32)ZSTD_count(ip, match, iend);
if (matchLen >= ZSTD_MINMATCH_MIN) {
U32 const litLen = (U32)(ip - anchor);
U32 const offset = (U32)(ip - match);
ZSTD_Sequence const seq = {
offset, litLen, matchLen, 0
};
/* Note: it's crucial to stay within the window size! */
if (offset <= windowSize) {
outSeqs[seqCount++] = seq;
ip += matchLen;
anchor = ip;
continue;
}
}
}
ip++;
}
{ ZSTD_Sequence const finalSeq = {
0, (U32)(iend - anchor), 0, 0
};
outSeqs[seqCount++] = finalSeq;
}
return seqCount;
}
size_t zstreamExternalMatchFinder(
void* externalMatchState,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize,
const void* dict, size_t dictSize,
int compressionLevel,
size_t windowSize
) {
EMF_testCase const testCase = *((EMF_testCase*)externalMatchState);
memset(outSeqs, 0, outSeqsCapacity);
switch (testCase) {
case EMF_ZERO_SEQS:
return 0;
case EMF_ONE_BIG_SEQ:
outSeqs[0].offset = 0;
outSeqs[0].matchLength = 0;
outSeqs[0].litLength = (U32)(srcSize);
return 1;
case EMF_LOTS_OF_SEQS:
return simpleExternalMatchFinder(
externalMatchState,
outSeqs, outSeqsCapacity,
src, srcSize,
dict, dictSize,
compressionLevel,
windowSize
);
case EMF_SMALL_ERROR:
return outSeqsCapacity + 1;
case EMF_BIG_ERROR:
default:
return ZSTD_EXTERNAL_MATCHFINDER_ERROR;
}
}
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) Yann Collet, Meta Platforms, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
* in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses.
*/
#ifndef EXTERNAL_MATCHFINDER
#define EXTERNAL_MATCHFINDER
#define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h"
/* See external_matchfinder.c for details on each test case */
typedef enum {
EMF_ZERO_SEQS = 0,
EMF_ONE_BIG_SEQ = 1,
EMF_LOTS_OF_SEQS = 2,
EMF_BIG_ERROR = 3,
EMF_SMALL_ERROR = 4
} EMF_testCase;
size_t zstreamExternalMatchFinder(
void* externalMatchState,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize,
const void* dict, size_t dictSize,
int compressionLevel,
size_t windowSize
);
#endif // EXTERNAL_MATCHFINDER
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/** /**
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/** /**
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+184 -86
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -82,8 +82,8 @@ static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER;
void FUZ_bug976(void); void FUZ_bug976(void);
void FUZ_bug976(void) void FUZ_bug976(void)
{ /* these constants shall not depend on MIN() macro */ { /* these constants shall not depend on MIN() macro */
assert(ZSTD_HASHLOG_MAX < 31); DEBUG_STATIC_ASSERT(ZSTD_HASHLOG_MAX < 31);
assert(ZSTD_CHAINLOG_MAX < 31); DEBUG_STATIC_ASSERT(ZSTD_CHAINLOG_MAX < 31);
} }
@@ -118,23 +118,24 @@ static U32 FUZ_highbit32(U32 v32)
/*============================================= /*=============================================
* Test macros * Test macros
=============================================*/ =============================================*/
#define CHECK_Z(f) { \ #define CHECK(fn) { if(!(fn)) { DISPLAYLEVEL(1, "Error : test (%s) failed \n", #fn); exit(1); } }
size_t const err = f; \
if (ZSTD_isError(err)) { \ #define CHECK_Z(f) { \
DISPLAY("Error => %s : %s ", \ size_t const err = f; \
#f, ZSTD_getErrorName(err)); \ if (ZSTD_isError(err)) { \
exit(1); \ DISPLAY("Error => %s : %s ", \
#f, ZSTD_getErrorName(err)); \
exit(1); \
} } } }
#define CHECK_VAR(var, fn) var = fn; if (ZSTD_isError(var)) { DISPLAYLEVEL(1, "%s : fails : %s \n", #fn, ZSTD_getErrorName(var)); goto _output_error; } #define CHECK_VAR(var, fn) var = fn; if (ZSTD_isError(var)) { DISPLAYLEVEL(1, "%s : fails : %s \n", #fn, ZSTD_getErrorName(var)); exit(1); }
#define CHECK_NEWV(var, fn) size_t const CHECK_VAR(var, fn) #define CHECK_NEWV(var, fn) size_t const CHECK_VAR(var, fn)
#define CHECK(fn) { CHECK_NEWV(__err, fn); }
#define CHECKPLUS(var, fn, more) { CHECK_NEWV(var, fn); more; } #define CHECKPLUS(var, fn, more) { CHECK_NEWV(var, fn); more; }
#define CHECK_OP(op, lhs, rhs) { \ #define CHECK_OP(op, lhs, rhs) { \
if (!((lhs) op (rhs))) { \ if (!((lhs) op (rhs))) { \
DISPLAY("Error L%u => FAILED %s %s %s ", __LINE__, #lhs, #op, #rhs); \ DISPLAY("Error L%u => FAILED %s %s %s ", __LINE__, #lhs, #op, #rhs); \
goto _output_error; \ exit(1); \
} \ } \
} }
#define CHECK_EQ(lhs, rhs) CHECK_OP(==, lhs, rhs) #define CHECK_EQ(lhs, rhs) CHECK_OP(==, lhs, rhs)
@@ -338,6 +339,7 @@ static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize,
} }
#ifdef ZSTD_MULTITHREAD #ifdef ZSTD_MULTITHREAD
typedef struct { typedef struct {
ZSTD_CCtx* cctx; ZSTD_CCtx* cctx;
ZSTD_threadPool* pool; ZSTD_threadPool* pool;
@@ -429,8 +431,8 @@ static int threadPoolTests(void) {
ZSTD_pthread_create(&t1, NULL, threadPoolTests_compressionJob, &p1); ZSTD_pthread_create(&t1, NULL, threadPoolTests_compressionJob, &p1);
ZSTD_pthread_create(&t2, NULL, threadPoolTests_compressionJob, &p2); ZSTD_pthread_create(&t2, NULL, threadPoolTests_compressionJob, &p2);
ZSTD_pthread_join(t1, NULL); ZSTD_pthread_join(t1);
ZSTD_pthread_join(t2, NULL); ZSTD_pthread_join(t2);
assert(!memcmp(decodedBuffer, decodedBuffer2, CNBuffSize)); assert(!memcmp(decodedBuffer, decodedBuffer2, CNBuffSize));
free(decodedBuffer2); free(decodedBuffer2);
@@ -461,6 +463,101 @@ _output_error:
* Unit tests * Unit tests
=============================================*/ =============================================*/
static void test_compressBound(unsigned tnb)
{
DISPLAYLEVEL(3, "test%3u : compressBound : ", tnb);
/* check ZSTD_compressBound == ZSTD_COMPRESSBOUND
* for a large range of known valid values */
DEBUG_STATIC_ASSERT(sizeof(size_t) >= 4);
{ int s;
for (s=0; s<30; s++) {
size_t const w = (size_t)1 << s;
CHECK_EQ(ZSTD_compressBound(w), ZSTD_COMPRESSBOUND(w));
} }
// Ensure error if srcSize too big
{ size_t const w = ZSTD_MAX_INPUT_SIZE + 1;
CHECK(ZSTD_isError(ZSTD_compressBound(w))); /* must fail */
CHECK_EQ(ZSTD_COMPRESSBOUND(w), 0);
}
DISPLAYLEVEL(3, "OK \n");
}
static void test_decompressBound(unsigned tnb)
{
DISPLAYLEVEL(3, "test%3u : decompressBound : ", tnb);
// Simple compression, with size : should provide size;
{ const char example[] = "abcd";
char cBuffer[ZSTD_COMPRESSBOUND(sizeof(example))];
size_t const cSize = ZSTD_compress(cBuffer, sizeof(cBuffer), example, sizeof(example), 0);
CHECK_Z(cSize);
CHECK_EQ(ZSTD_decompressBound(cBuffer, cSize), (unsigned long long)sizeof(example));
}
// Simple small compression without size : should provide 1 block size
{ char cBuffer[ZSTD_COMPRESSBOUND(0)];
ZSTD_outBuffer out = { cBuffer, sizeof(cBuffer), 0 };
ZSTD_inBuffer in = { NULL, 0, 0 };
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
assert(cctx);
CHECK_Z( ZSTD_initCStream(cctx, 0) );
CHECK_Z( ZSTD_compressStream(cctx, &out, &in) );
CHECK_EQ( ZSTD_endStream(cctx, &out), 0 );
CHECK_EQ( ZSTD_decompressBound(cBuffer, out.pos), ZSTD_BLOCKSIZE_MAX );
ZSTD_freeCCtx(cctx);
}
// Attempt to overflow 32-bit intermediate multiplication result
// This requires dBound >= 4 GB, aka 2^32.
// This requires 2^32 / 2^17 = 2^15 blocks
// => create 2^15 blocks (can be empty, or just 1 byte).
{ const char input[] = "a";
size_t const nbBlocks = (1 << 15) + 1;
size_t blockNb;
size_t const outCapacity = 1 << 18; // large margin
char* const outBuffer = malloc (outCapacity);
ZSTD_outBuffer out = { outBuffer, outCapacity, 0 };
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
assert(cctx);
assert(outBuffer);
CHECK_Z( ZSTD_initCStream(cctx, 0) );
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
ZSTD_inBuffer in = { input, sizeof(input), 0 };
CHECK_Z( ZSTD_compressStream(cctx, &out, &in) );
CHECK_EQ( ZSTD_flushStream(cctx, &out), 0 );
}
CHECK_EQ( ZSTD_endStream(cctx, &out), 0 );
CHECK( ZSTD_decompressBound(outBuffer, out.pos) > 0x100000000LLU /* 4 GB */ );
ZSTD_freeCCtx(cctx);
free(outBuffer);
}
DISPLAYLEVEL(3, "OK \n");
}
static void test_setCParams(unsigned tnb)
{
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
ZSTD_compressionParameters cparams;
assert(cctx);
DISPLAYLEVEL(3, "test%3u : ZSTD_CCtx_setCParams : ", tnb);
/* valid cparams */
cparams = ZSTD_getCParams(1, 0, 0);
CHECK_Z(ZSTD_CCtx_setCParams(cctx, cparams));
/* invalid cparams (must fail) */
cparams.windowLog = 99;
CHECK(ZSTD_isError(ZSTD_CCtx_setCParams(cctx, cparams)));
free(cctx);
DISPLAYLEVEL(3, "OK \n");
}
static int basicUnitTests(U32 const seed, double compressibility) static int basicUnitTests(U32 const seed, double compressibility)
{ {
size_t const CNBuffSize = 5 MB; size_t const CNBuffSize = 5 MB;
@@ -507,6 +604,12 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "%u (OK) \n", vn); DISPLAYLEVEL(3, "%u (OK) \n", vn);
} }
test_compressBound(testNb++);
test_decompressBound(testNb++);
test_setCParams(testNb++);
DISPLAYLEVEL(3, "test%3u : ZSTD_adjustCParams : ", testNb++); DISPLAYLEVEL(3, "test%3u : ZSTD_adjustCParams : ", testNb++);
{ {
ZSTD_compressionParameters params; ZSTD_compressionParameters params;
@@ -1579,7 +1682,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : init CCtx for small level %u (should work again) : ", testNb++, 1); DISPLAYLEVEL(3, "test%3i : init CCtx for small level %u (should work again) : ", testNb++, 1);
CHECK( ZSTD_compressBegin(staticCCtx, 1) ); CHECK_Z( ZSTD_compressBegin(staticCCtx, 1) );
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : use CStream on CCtx-sized static context (should fail) : ", testNb++); DISPLAYLEVEL(3, "test%3i : use CStream on CCtx-sized static context (should fail) : ", testNb++);
@@ -1647,8 +1750,8 @@ static int basicUnitTests(U32 const seed, double compressibility)
testResult = 1; testResult = 1;
goto _end; goto _end;
} }
CHECK( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_nbWorkers, 2) ); CHECK_Z( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_nbWorkers, 2) );
CHECK( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_compressionLevel, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_compressionLevel, 1) );
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3u : compress %u bytes with 2 threads : ", testNb++, (unsigned)CNBuffSize); DISPLAYLEVEL(3, "test%3u : compress %u bytes with 2 threads : ", testNb++, (unsigned)CNBuffSize);
@@ -1678,9 +1781,9 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : compress -T2 with checksum : ", testNb++); DISPLAYLEVEL(3, "test%3i : compress -T2 with checksum : ", testNb++);
CHECK( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_checksumFlag, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_checksumFlag, 1) );
CHECK( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_contentSizeFlag, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_contentSizeFlag, 1) );
CHECK( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_overlapLog, 3) ); CHECK_Z( ZSTD_CCtx_setParameter(mtctx, ZSTD_c_overlapLog, 3) );
CHECK_VAR(cSize, ZSTD_compress2(mtctx, CHECK_VAR(cSize, ZSTD_compress2(mtctx,
compressedBuffer, compressedBufferSize, compressedBuffer, compressedBufferSize,
CNBuffer, CNBuffSize) ); CNBuffer, CNBuffSize) );
@@ -1699,11 +1802,11 @@ static int basicUnitTests(U32 const seed, double compressibility)
ZSTD_DCtx* const dctx = ZSTD_createDCtx(); ZSTD_DCtx* const dctx = ZSTD_createDCtx();
char out[32]; char out[32];
if (cctx == NULL || dctx == NULL) goto _output_error; if (cctx == NULL || dctx == NULL) goto _output_error;
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0) );
CHECK_VAR(cSize, ZSTD_compress2(cctx, out, sizeof(out), NULL, 0) ); CHECK_VAR(cSize, ZSTD_compress2(cctx, out, sizeof(out), NULL, 0) );
DISPLAYLEVEL(3, "OK (%u bytes)\n", (unsigned)cSize); DISPLAYLEVEL(3, "OK (%u bytes)\n", (unsigned)cSize);
CHECK( ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 10) ); CHECK_Z( ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 10) );
{ char const* outPtr = out; { char const* outPtr = out;
ZSTD_inBuffer inBuffer = { outPtr, cSize, 0 }; ZSTD_inBuffer inBuffer = { outPtr, cSize, 0 };
ZSTD_outBuffer outBuffer = { NULL, 0, 0 }; ZSTD_outBuffer outBuffer = { NULL, 0, 0 };
@@ -1718,9 +1821,9 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : compress with block splitting : ", testNb++) DISPLAYLEVEL(3, "test%3i : compress with block splitting : ", testNb++)
{ ZSTD_CCtx* cctx = ZSTD_createCCtx(); { ZSTD_CCtx* cctx = ZSTD_createCCtx();
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_useBlockSplitter, ZSTD_ps_enable) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_useBlockSplitter, ZSTD_ps_enable) );
cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize);
CHECK(cSize); CHECK_Z(cSize);
ZSTD_freeCCtx(cctx); ZSTD_freeCCtx(cctx);
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
@@ -1728,13 +1831,13 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : compress -T2 with/without literals compression : ", testNb++) DISPLAYLEVEL(3, "test%3i : compress -T2 with/without literals compression : ", testNb++)
{ ZSTD_CCtx* cctx = ZSTD_createCCtx(); { ZSTD_CCtx* cctx = ZSTD_createCCtx();
size_t cSize1, cSize2; size_t cSize1, cSize2;
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 1) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 2) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 2) );
cSize1 = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); cSize1 = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize);
CHECK(cSize1); CHECK_Z(cSize1);
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_literalCompressionMode, ZSTD_ps_disable) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_literalCompressionMode, ZSTD_ps_disable) );
cSize2 = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); cSize2 = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize);
CHECK(cSize2); CHECK_Z(cSize2);
CHECK_LT(cSize1, cSize2); CHECK_LT(cSize1, cSize2);
ZSTD_freeCCtx(cctx); ZSTD_freeCCtx(cctx);
} }
@@ -1745,10 +1848,10 @@ static int basicUnitTests(U32 const seed, double compressibility)
/* Set rsyncable and don't give the ZSTD_compressBound(CNBuffSize) so /* Set rsyncable and don't give the ZSTD_compressBound(CNBuffSize) so
* ZSTDMT is forced to not take the shortcut. * ZSTDMT is forced to not take the shortcut.
*/ */
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 1) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_rsyncable, 1) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_rsyncable, 1) );
CHECK( ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize - 1, CNBuffer, CNBuffSize) ); CHECK_Z( ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize - 1, CNBuffer, CNBuffSize) );
ZSTD_freeCCtx(cctx); ZSTD_freeCCtx(cctx);
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
@@ -1758,22 +1861,22 @@ static int basicUnitTests(U32 const seed, double compressibility)
int const jobSize = 512 KB; int const jobSize = 512 KB;
int value; int value;
/* Check that the overlap log and job size are unset. */ /* Check that the overlap log and job size are unset. */
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) ); CHECK_Z( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) );
CHECK_EQ(value, 0); CHECK_EQ(value, 0);
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) ); CHECK_Z( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) );
CHECK_EQ(value, 0); CHECK_EQ(value, 0);
/* Set and check the overlap log and job size. */ /* Set and check the overlap log and job size. */
CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, 5) ); CHECK_Z( ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, 5) );
CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, jobSize) ); CHECK_Z( ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, jobSize) );
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) ); CHECK_Z( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) );
CHECK_EQ(value, 5); CHECK_EQ(value, 5);
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) ); CHECK_Z( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) );
CHECK_EQ(value, jobSize); CHECK_EQ(value, jobSize);
/* Set the number of workers and check the overlap log and job size. */ /* Set the number of workers and check the overlap log and job size. */
CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, 2) ); CHECK_Z( ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, 2) );
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) ); CHECK_Z( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) );
CHECK_EQ(value, 5); CHECK_EQ(value, 5);
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) ); CHECK_Z( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) );
CHECK_EQ(value, jobSize); CHECK_EQ(value, jobSize);
ZSTD_freeCCtxParams(params); ZSTD_freeCCtxParams(params);
} }
@@ -1884,8 +1987,8 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : load dictionary into context : ", testNb++); DISPLAYLEVEL(3, "test%3i : load dictionary into context : ", testNb++);
CHECK( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) ); CHECK_Z( ZSTD_compressBegin_usingDict(ctxOrig, CNBuffer, dictSize, 2) );
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, 0) ); /* Begin_usingDict implies unknown srcSize, so match that */ CHECK_Z( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, 0) ); /* Begin_usingDict implies unknown srcSize, so match that */
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : compress with flat dictionary : ", testNb++); DISPLAYLEVEL(3, "test%3i : compress with flat dictionary : ", testNb++);
@@ -1945,8 +2048,8 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : check content size on duplicated context : ", testNb++); DISPLAYLEVEL(3, "test%3i : check content size on duplicated context : ", testNb++);
{ size_t const testSize = CNBuffSize / 3; { size_t const testSize = CNBuffSize / 3;
CHECK( ZSTD_compressBegin(ctxOrig, ZSTD_defaultCLevel()) ); CHECK_Z( ZSTD_compressBegin(ctxOrig, ZSTD_defaultCLevel()) );
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) ); CHECK_Z( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) );
CHECK_VAR(cSize, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize), CHECK_VAR(cSize, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
(const char*)CNBuffer + dictSize, testSize) ); (const char*)CNBuffer + dictSize, testSize) );
@@ -2780,7 +2883,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
size_t const wrongSrcSize = (srcSize + 1000); size_t const wrongSrcSize = (srcSize + 1000);
ZSTD_parameters params = ZSTD_getParams(1, wrongSrcSize, 0); ZSTD_parameters params = ZSTD_getParams(1, wrongSrcSize, 0);
params.fParams.contentSizeFlag = 1; params.fParams.contentSizeFlag = 1;
CHECK( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, wrongSrcSize) ); CHECK_Z( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, wrongSrcSize) );
{ size_t const result = ZSTD_compressEnd(cctx, decodedBuffer, CNBuffSize, CNBuffer, srcSize); { size_t const result = ZSTD_compressEnd(cctx, decodedBuffer, CNBuffSize, CNBuffer, srcSize);
if (!ZSTD_isError(result)) goto _output_error; if (!ZSTD_isError(result)) goto _output_error;
if (ZSTD_getErrorCode(result) != ZSTD_error_srcSize_wrong) goto _output_error; if (ZSTD_getErrorCode(result) != ZSTD_error_srcSize_wrong) goto _output_error;
@@ -2800,7 +2903,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
CNBuffer, srcSize, compressionLevel); CNBuffer, srcSize, compressionLevel);
if (ZSTD_isError(cSize_1pass)) goto _output_error; if (ZSTD_isError(cSize_1pass)) goto _output_error;
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionLevel) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionLevel) );
{ size_t const compressionResult = ZSTD_compress2(cctx, { size_t const compressionResult = ZSTD_compress2(cctx,
compressedBuffer, compressedBufferSize, compressedBuffer, compressedBufferSize,
CNBuffer, srcSize); CNBuffer, srcSize);
@@ -2819,13 +2922,13 @@ static int basicUnitTests(U32 const seed, double compressibility)
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx(); { ZSTD_CCtx* const cctx = ZSTD_createCCtx();
DISPLAYLEVEL(3, "test%3i : parameters in order : ", testNb++); DISPLAYLEVEL(3, "test%3i : parameters in order : ", testNb++);
assert(cctx != NULL); assert(cctx != NULL);
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 2) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 2) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 18) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 18) );
{ size_t const compressedSize = ZSTD_compress2(cctx, { size_t const compressedSize = ZSTD_compress2(cctx,
compressedBuffer, ZSTD_compressBound(inputSize), compressedBuffer, ZSTD_compressBound(inputSize),
CNBuffer, inputSize); CNBuffer, inputSize);
CHECK(compressedSize); CHECK_Z(compressedSize);
cSize = compressedSize; cSize = compressedSize;
xxh64 = XXH64(compressedBuffer, compressedSize, 0); xxh64 = XXH64(compressedBuffer, compressedSize, 0);
} }
@@ -2835,13 +2938,13 @@ static int basicUnitTests(U32 const seed, double compressibility)
{ ZSTD_CCtx* cctx = ZSTD_createCCtx(); { ZSTD_CCtx* cctx = ZSTD_createCCtx();
DISPLAYLEVEL(3, "test%3i : parameters disordered : ", testNb++); DISPLAYLEVEL(3, "test%3i : parameters disordered : ", testNb++);
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 18) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 18) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable) );
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 2) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 2) );
{ size_t const result = ZSTD_compress2(cctx, { size_t const result = ZSTD_compress2(cctx,
compressedBuffer, ZSTD_compressBound(inputSize), compressedBuffer, ZSTD_compressBound(inputSize),
CNBuffer, inputSize); CNBuffer, inputSize);
CHECK(result); CHECK_Z(result);
if (result != cSize) goto _output_error; /* must result in same compressed result, hence same size */ if (result != cSize) goto _output_error; /* must result in same compressed result, hence same size */
if (XXH64(compressedBuffer, result, 0) != xxh64) goto _output_error; /* must result in exactly same content, hence same hash */ if (XXH64(compressedBuffer, result, 0) != xxh64) goto _output_error; /* must result in exactly same content, hence same hash */
DISPLAYLEVEL(3, "OK (compress : %u -> %u bytes)\n", (unsigned)inputSize, (unsigned)result); DISPLAYLEVEL(3, "OK (compress : %u -> %u bytes)\n", (unsigned)inputSize, (unsigned)result);
@@ -2856,7 +2959,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : get dParameter bounds ", testNb++); DISPLAYLEVEL(3, "test%3i : get dParameter bounds ", testNb++);
{ ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax); { ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);
CHECK(bounds.error); CHECK_Z(bounds.error);
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
@@ -2890,7 +2993,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
/* basic block compression */ /* basic block compression */
DISPLAYLEVEL(3, "test%3i : magic-less format test : ", testNb++); DISPLAYLEVEL(3, "test%3i : magic-less format test : ", testNb++);
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless) );
{ ZSTD_inBuffer in = { CNBuffer, inputSize, 0 }; { ZSTD_inBuffer in = { CNBuffer, inputSize, 0 };
ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(inputSize), 0 }; ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(inputSize), 0 };
size_t const result = ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end); size_t const result = ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
@@ -2908,7 +3011,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : decompress of magic-less frame : ", testNb++); DISPLAYLEVEL(3, "test%3i : decompress of magic-less frame : ", testNb++);
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters); ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters);
CHECK( ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless) ); CHECK_Z( ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless) );
{ ZSTD_frameHeader zfh; { ZSTD_frameHeader zfh;
size_t const zfhrt = ZSTD_getFrameHeader_advanced(&zfh, compressedBuffer, cSize, ZSTD_f_zstd1_magicless); size_t const zfhrt = ZSTD_getFrameHeader_advanced(&zfh, compressedBuffer, cSize, ZSTD_f_zstd1_magicless);
if (zfhrt != 0) goto _output_error; if (zfhrt != 0) goto _output_error;
@@ -2930,7 +3033,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
/* basic block compression */ /* basic block compression */
DISPLAYLEVEL(3, "test%3i : empty magic-less format test : ", testNb++); DISPLAYLEVEL(3, "test%3i : empty magic-less format test : ", testNb++);
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless) ); CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless) );
{ ZSTD_inBuffer in = { CNBuffer, 0, 0 }; { ZSTD_inBuffer in = { CNBuffer, 0, 0 };
ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(0), 0 }; ZSTD_outBuffer out = { compressedBuffer, ZSTD_compressBound(0), 0 };
size_t const result = ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end); size_t const result = ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end);
@@ -2942,7 +3045,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : decompress of empty magic-less frame : ", testNb++); DISPLAYLEVEL(3, "test%3i : decompress of empty magic-less frame : ", testNb++);
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters); ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters);
CHECK( ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless) ); CHECK_Z( ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless) );
/* one shot */ /* one shot */
{ size_t const result = ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize); { size_t const result = ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize);
if (result != 0) goto _output_error; if (result != 0) goto _output_error;
@@ -2977,13 +3080,13 @@ static int basicUnitTests(U32 const seed, double compressibility)
int check; int check;
if (ZSTD_isError(bounds.error)) if (ZSTD_isError(bounds.error))
continue; continue;
CHECK(ZSTD_DCtx_getParameter(dctx, dParam, &value1)); CHECK_Z(ZSTD_DCtx_getParameter(dctx, dParam, &value1));
value2 = (value1 != bounds.lowerBound) ? bounds.lowerBound : bounds.upperBound; value2 = (value1 != bounds.lowerBound) ? bounds.lowerBound : bounds.upperBound;
CHECK(ZSTD_DCtx_setParameter(dctx, dParam, value2)); CHECK_Z(ZSTD_DCtx_setParameter(dctx, dParam, value2));
CHECK(ZSTD_DCtx_getParameter(dctx, dParam, &check)); CHECK_Z(ZSTD_DCtx_getParameter(dctx, dParam, &check));
if (check != value2) goto _output_error; if (check != value2) goto _output_error;
CHECK(ZSTD_DCtx_reset(dctx, ZSTD_reset_parameters)); CHECK_Z(ZSTD_DCtx_reset(dctx, ZSTD_reset_parameters));
CHECK(ZSTD_DCtx_getParameter(dctx, dParam, &check)); CHECK_Z(ZSTD_DCtx_getParameter(dctx, dParam, &check));
if (check != value1) goto _output_error; if (check != value1) goto _output_error;
} }
ZSTD_freeDCtx(dctx); ZSTD_freeDCtx(dctx);
@@ -3000,21 +3103,21 @@ static int basicUnitTests(U32 const seed, double compressibility)
/* basic block compression */ /* basic block compression */
DISPLAYLEVEL(3, "test%3i : Block compression test : ", testNb++); DISPLAYLEVEL(3, "test%3i : Block compression test : ", testNb++);
CHECK( ZSTD_compressBegin(cctx, 5) ); CHECK_Z( ZSTD_compressBegin(cctx, 5) );
CHECK( ZSTD_getBlockSize(cctx) >= blockSize); CHECK_Z( ZSTD_getBlockSize(cctx) >= blockSize);
CHECK_VAR(cSize, ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize) ); CHECK_VAR(cSize, ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize) );
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : Block decompression test : ", testNb++); DISPLAYLEVEL(3, "test%3i : Block decompression test : ", testNb++);
CHECK( ZSTD_decompressBegin(dctx) ); CHECK_Z( ZSTD_decompressBegin(dctx) );
{ CHECK_NEWV(r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) ); { CHECK_NEWV(r, ZSTD_decompressBlock(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
if (r != blockSize) goto _output_error; } if (r != blockSize) goto _output_error; }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
/* very long stream of block compression */ /* very long stream of block compression */
DISPLAYLEVEL(3, "test%3i : Huge block streaming compression test : ", testNb++); DISPLAYLEVEL(3, "test%3i : Huge block streaming compression test : ", testNb++);
CHECK( ZSTD_compressBegin(cctx, -199) ); /* we just want to quickly overflow internal U32 index */ CHECK_Z( ZSTD_compressBegin(cctx, -199) ); /* we just want to quickly overflow internal U32 index */
CHECK( ZSTD_getBlockSize(cctx) >= blockSize); CHECK_Z( ZSTD_getBlockSize(cctx) >= blockSize);
{ U64 const toCompress = 5000000000ULL; /* > 4 GB */ { U64 const toCompress = 5000000000ULL; /* > 4 GB */
U64 compressed = 0; U64 compressed = 0;
while (compressed < toCompress) { while (compressed < toCompress) {
@@ -3027,7 +3130,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
/* dictionary block compression */ /* dictionary block compression */
DISPLAYLEVEL(3, "test%3i : Dictionary Block compression test : ", testNb++); DISPLAYLEVEL(3, "test%3i : Dictionary Block compression test : ", testNb++);
CHECK( ZSTD_compressBegin_usingDict(cctx, CNBuffer, dictSize, 5) ); CHECK_Z( ZSTD_compressBegin_usingDict(cctx, CNBuffer, dictSize, 5) );
CHECK_VAR(cSize, ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize)); CHECK_VAR(cSize, ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize));
RDG_genBuffer((char*)CNBuffer+dictSize+blockSize, blockSize, 0.0, 0.0, seed); /* create a non-compressible second block */ RDG_genBuffer((char*)CNBuffer+dictSize+blockSize, blockSize, 0.0, 0.0, seed); /* create a non-compressible second block */
{ CHECK_NEWV(r, ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize+blockSize, blockSize) ); /* for cctx history consistency */ { CHECK_NEWV(r, ZSTD_compressBlock(cctx, (char*)compressedBuffer+cSize, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize+blockSize, blockSize) ); /* for cctx history consistency */
@@ -3038,7 +3141,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : Dictionary Block decompression test : ", testNb++); DISPLAYLEVEL(3, "test%3i : Dictionary Block decompression test : ", testNb++);
CHECK( ZSTD_decompressBegin_usingDict(dctx, CNBuffer, dictSize) ); CHECK_Z( ZSTD_decompressBegin_usingDict(dctx, CNBuffer, dictSize) );
{ CHECK_NEWV( r, ZSTD_decompressBlock(dctx, decodedBuffer, blockSize, compressedBuffer, cSize) ); { CHECK_NEWV( r, ZSTD_decompressBlock(dctx, decodedBuffer, blockSize, compressedBuffer, cSize) );
if (r != blockSize) { if (r != blockSize) {
DISPLAYLEVEL(1, "ZSTD_decompressBlock() with _usingDict() fails : %u, instead of %u expected \n", (unsigned)r, (unsigned)blockSize); DISPLAYLEVEL(1, "ZSTD_decompressBlock() with _usingDict() fails : %u, instead of %u expected \n", (unsigned)r, (unsigned)blockSize);
@@ -3057,8 +3160,8 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : Block compression with CDict : ", testNb++); DISPLAYLEVEL(3, "test%3i : Block compression with CDict : ", testNb++);
{ ZSTD_CDict* const cdict = ZSTD_createCDict(CNBuffer, dictSize, 3); { ZSTD_CDict* const cdict = ZSTD_createCDict(CNBuffer, dictSize, 3);
if (cdict==NULL) goto _output_error; if (cdict==NULL) goto _output_error;
CHECK( ZSTD_compressBegin_usingCDict(cctx, cdict) ); CHECK_Z( ZSTD_compressBegin_usingCDict(cctx, cdict) );
CHECK( ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize) ); CHECK_Z( ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), (char*)CNBuffer+dictSize, blockSize) );
ZSTD_freeCDict(cdict); ZSTD_freeCDict(cdict);
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
@@ -3227,7 +3330,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
size_t const bound = ZSTD_compressBound(_3BYTESTESTLENGTH); size_t const bound = ZSTD_compressBound(_3BYTESTESTLENGTH);
size_t nbSeq = 1; size_t nbSeq = 1;
while (nbSeq <= maxNbSeq) { while (nbSeq <= maxNbSeq) {
CHECK(ZSTD_compressCCtx(cctx, compressedBuffer, bound, CNBuffer, nbSeq * 3, 19)); CHECK_Z(ZSTD_compressCCtx(cctx, compressedBuffer, bound, CNBuffer, nbSeq * 3, 19));
/* Check every sequence for the first 100, then skip more rapidly. */ /* Check every sequence for the first 100, then skip more rapidly. */
if (nbSeq < 100) { if (nbSeq < 100) {
++nbSeq; ++nbSeq;
@@ -3256,7 +3359,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
size_t const bound = ZSTD_compressBound(CNBuffSize); size_t const bound = ZSTD_compressBound(CNBuffSize);
size_t size = 1; size_t size = 1;
while (size <= CNBuffSize) { while (size <= CNBuffSize) {
CHECK(ZSTD_compressCCtx(cctx, compressedBuffer, bound, CNBuffer, size, 3)); CHECK_Z(ZSTD_compressCCtx(cctx, compressedBuffer, bound, CNBuffer, size, 3));
/* Check every size for the first 100, then skip more rapidly. */ /* Check every size for the first 100, then skip more rapidly. */
if (size < 100) { if (size < 100) {
++size; ++size;
@@ -3291,7 +3394,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
void* const outputBuffer = malloc(outputSize); void* const outputBuffer = malloc(outputSize);
ZSTD_CCtx* const cctx = ZSTD_createCCtx(); ZSTD_CCtx* const cctx = ZSTD_createCCtx();
if (!outputBuffer || !cctx) goto _output_error; if (!outputBuffer || !cctx) goto _output_error;
CHECK(ZSTD_compress_usingDict(cctx, outputBuffer, outputSize, CNBuffer, inputSize, dictBuffer, dictSize, 1)); CHECK_Z(ZSTD_compress_usingDict(cctx, outputBuffer, outputSize, CNBuffer, inputSize, dictBuffer, dictSize, 1));
free(outputBuffer); free(outputBuffer);
ZSTD_freeCCtx(cctx); ZSTD_freeCCtx(cctx);
} }
@@ -3628,7 +3731,7 @@ static int longUnitTests(U32 const seed, double compressibility)
while (approxIndex <= (maxIndex / 4) * 3) { while (approxIndex <= (maxIndex / 4) * 3) {
CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush)); CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush));
approxIndex += in.pos; approxIndex += in.pos;
CHECK(in.pos == in.size); CHECK_Z(in.pos == in.size);
in.pos = 0; in.pos = 0;
out.pos = 0; out.pos = 0;
} }
@@ -3654,7 +3757,7 @@ static int longUnitTests(U32 const seed, double compressibility)
while (approxIndex <= maxIndex) { while (approxIndex <= maxIndex) {
CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush)); CHECK_Z(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_flush));
approxIndex += in.pos; approxIndex += in.pos;
CHECK(in.pos == in.size); CHECK_Z(in.pos == in.size);
in.pos = 0; in.pos = 0;
out.pos = 0; out.pos = 0;
} }
@@ -3737,7 +3840,7 @@ static int longUnitTests(U32 const seed, double compressibility)
RDG_genBuffer(dict, dictSize, 0.5, 0.5, seed); RDG_genBuffer(dict, dictSize, 0.5, 0.5, seed);
RDG_genBuffer(CNBuffer, CNBuffSize, 0.6, 0.6, seed); RDG_genBuffer(CNBuffer, CNBuffSize, 0.6, 0.6, seed);
CHECK(cctx_params != NULL); CHECK_Z(cctx_params != NULL);
for (dictSize = CNBuffSize; dictSize; dictSize = dictSize >> 3) { for (dictSize = CNBuffSize; dictSize; dictSize = dictSize >> 3) {
DISPLAYLEVEL(3, "\n Testing with dictSize %u ", (U32)dictSize); DISPLAYLEVEL(3, "\n Testing with dictSize %u ", (U32)dictSize);
@@ -3780,11 +3883,6 @@ _end:
free(compressedBuffer); free(compressedBuffer);
free(decodedBuffer); free(decodedBuffer);
return testResult; return testResult;
_output_error:
testResult = 1;
DISPLAY("Error detected in Unit tests ! \n");
goto _end;
} }
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+18 -17
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -36,27 +36,27 @@ compress(ZSTD_CStream *ctx, ZSTD_outBuffer out, const void *data, size_t size)
int main(int argc, const char** argv) int main(int argc, const char** argv)
{ {
ZSTD_CStream* ctx; ZSTD_CStream* ctx;
ZSTD_parameters params; unsigned windowLog = 18;
size_t rc;
unsigned windowLog;
(void)argc; (void)argc;
(void)argv; (void)argv;
/* Create stream */ /* Create stream */
ctx = ZSTD_createCStream(); ctx = ZSTD_createCCtx();
if (!ctx) { return 1; } if (!ctx) { return 1; }
/* Set parameters */ /* Set parameters */
memset(&params, 0, sizeof(params)); if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, windowLog)))
params.cParams.windowLog = 18; return 2;
params.cParams.chainLog = 13; if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, 13)))
params.cParams.hashLog = 14; return 2;
params.cParams.searchLog = 1; if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, 14)))
params.cParams.minMatch = 7; return 2;
params.cParams.targetLength = 16; if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, 1)))
params.cParams.strategy = ZSTD_fast; return 2;
windowLog = params.cParams.windowLog; if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, 7)))
/* Initialize stream */ return 2;
rc = ZSTD_initCStream_advanced(ctx, NULL, 0, params, 0); if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, 16)))
if (ZSTD_isError(rc)) { return 2; } return 2;
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, ZSTD_fast)))
return 2;
{ {
U64 compressed = 0; U64 compressed = 0;
const U64 toCompress = ((U64)1) << 33; const U64 toCompress = ((U64)1) << 33;
@@ -97,5 +97,6 @@ int main(int argc, const char** argv)
free(srcBuffer); free(srcBuffer);
free(dstBuffer); free(dstBuffer);
} }
ZSTD_freeCCtx(ctx);
return 0; return 0;
} }
+20 -20
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -566,10 +566,10 @@ resultScore(const BMK_benchResult_t res, const size_t srcSize, const constraint_
double cs = 0., ds = 0., rt, cm = 0.; double cs = 0., ds = 0., rt, cm = 0.;
const double r1 = 1, r2 = 0.1, rtr = 0.5; const double r1 = 1, r2 = 0.1, rtr = 0.5;
double ret; double ret;
if(target.cSpeed) { cs = res.cSpeed / (double)target.cSpeed; } if(target.cSpeed) { cs = (double)res.cSpeed / (double)target.cSpeed; }
if(target.dSpeed) { ds = res.dSpeed / (double)target.dSpeed; } if(target.dSpeed) { ds = (double)res.dSpeed / (double)target.dSpeed; }
if(target.cMem != (U32)-1) { cm = (double)target.cMem / res.cMem; } if(target.cMem != (U32)-1) { cm = (double)target.cMem / (double)res.cMem; }
rt = ((double)srcSize / res.cSize); rt = ((double)srcSize / (double)res.cSize);
ret = (MIN(1, cs) + MIN(1, ds) + MIN(1, cm))*r1 + rt * rtr + ret = (MIN(1, cs) + MIN(1, ds) + MIN(1, cm))*r1 + rt * rtr +
(MAX(0, log(cs))+ MAX(0, log(ds))+ MAX(0, log(cm))) * r2; (MAX(0, log(cs))+ MAX(0, log(ds))+ MAX(0, log(cm))) * r2;
@@ -581,8 +581,8 @@ resultScore(const BMK_benchResult_t res, const size_t srcSize, const constraint_
static double static double
resultDistLvl(const BMK_benchResult_t result1, const BMK_benchResult_t lvlRes) resultDistLvl(const BMK_benchResult_t result1, const BMK_benchResult_t lvlRes)
{ {
double normalizedCSpeedGain1 = ((double)result1.cSpeed / lvlRes.cSpeed) - 1; double normalizedCSpeedGain1 = ((double)result1.cSpeed / (double)lvlRes.cSpeed) - 1;
double normalizedRatioGain1 = ((double)lvlRes.cSize / result1.cSize) - 1; double normalizedRatioGain1 = ((double)lvlRes.cSize / (double)result1.cSize) - 1;
if(normalizedRatioGain1 < 0 || normalizedCSpeedGain1 < 0) { if(normalizedRatioGain1 < 0 || normalizedCSpeedGain1 < 0) {
return 0.0; return 0.0;
} }
@@ -854,7 +854,7 @@ BMK_displayOneResult(FILE* f, winnerInfo_t res, const size_t srcSize)
} }
{ double const ratio = res.result.cSize ? { double const ratio = res.result.cSize ?
(double)srcSize / res.result.cSize : 0; (double)srcSize / (double)res.result.cSize : 0;
double const cSpeedMBps = (double)res.result.cSpeed / MB_UNIT; double const cSpeedMBps = (double)res.result.cSpeed / MB_UNIT;
double const dSpeedMBps = (double)res.result.dSpeed / MB_UNIT; double const dSpeedMBps = (double)res.result.dSpeed / MB_UNIT;
@@ -937,7 +937,7 @@ BMK_printWinnerOpt(FILE* f, const U32 cLevel, const BMK_benchResult_t result, co
} }
fprintf(f, "================================\n"); fprintf(f, "================================\n");
fprintf(f, "Level Bounds: R: > %.3f AND C: < %.1f MB/s \n\n", fprintf(f, "Level Bounds: R: > %.3f AND C: < %.1f MB/s \n\n",
(double)srcSize / g_lvltarget.cSize, (double)g_lvltarget.cSpeed / MB_UNIT); (double)srcSize / (double)g_lvltarget.cSize, (double)g_lvltarget.cSpeed / MB_UNIT);
fprintf(f, "Overall Winner: \n"); fprintf(f, "Overall Winner: \n");
@@ -977,7 +977,7 @@ BMK_print_cLevelEntry(FILE* f, const int cLevel,
} }
/* print comment */ /* print comment */
{ double const ratio = result.cSize ? { double const ratio = result.cSize ?
(double)srcSize / result.cSize : 0; (double)srcSize / (double)result.cSize : 0;
double const cSpeedMBps = (double)result.cSpeed / MB_UNIT; double const cSpeedMBps = (double)result.cSpeed / MB_UNIT;
double const dSpeedMBps = (double)result.dSpeed / MB_UNIT; double const dSpeedMBps = (double)result.dSpeed / MB_UNIT;
@@ -1726,19 +1726,19 @@ static int allBench(BMK_benchResult_t* resultPtr,
/* calculate uncertainty in compression / decompression runs */ /* calculate uncertainty in compression / decompression runs */
if (benchres.cSpeed) { if (benchres.cSpeed) {
U64 const loopDurationC = (((U64)buf.srcSize * TIMELOOP_NANOSEC) / benchres.cSpeed); double const loopDurationC = (double)(((U64)buf.srcSize * TIMELOOP_NANOSEC) / benchres.cSpeed);
uncertaintyConstantC = ((loopDurationC + (double)(2 * g_clockGranularity))/loopDurationC); uncertaintyConstantC = ((loopDurationC + (double)(2 * g_clockGranularity))/loopDurationC);
} }
if (benchres.dSpeed) { if (benchres.dSpeed) {
U64 const loopDurationD = (((U64)buf.srcSize * TIMELOOP_NANOSEC) / benchres.dSpeed); double const loopDurationD = (double)(((U64)buf.srcSize * TIMELOOP_NANOSEC) / benchres.dSpeed);
uncertaintyConstantD = ((loopDurationD + (double)(2 * g_clockGranularity))/loopDurationD); uncertaintyConstantD = ((loopDurationD + (double)(2 * g_clockGranularity))/loopDurationD);
} }
/* optimistic assumption of benchres */ /* optimistic assumption of benchres */
{ BMK_benchResult_t resultMax = benchres; { BMK_benchResult_t resultMax = benchres;
resultMax.cSpeed = (unsigned long long)(resultMax.cSpeed * uncertaintyConstantC * VARIANCE); resultMax.cSpeed = (unsigned long long)((double)resultMax.cSpeed * uncertaintyConstantC * VARIANCE);
resultMax.dSpeed = (unsigned long long)(resultMax.dSpeed * uncertaintyConstantD * VARIANCE); resultMax.dSpeed = (unsigned long long)((double)resultMax.dSpeed * uncertaintyConstantD * VARIANCE);
/* disregard infeasible results in feas mode */ /* disregard infeasible results in feas mode */
/* disregard if resultMax < winner in infeas mode */ /* disregard if resultMax < winner in infeas mode */
@@ -1850,8 +1850,8 @@ static int BMK_seed(winnerInfo_t* winners,
if ((double)testResult.cSize <= ((double)winners[cLevel].result.cSize * (1. + (0.02 / cLevel))) ) { if ((double)testResult.cSize <= ((double)winners[cLevel].result.cSize * (1. + (0.02 / cLevel))) ) {
/* Validate solution is "good enough" */ /* Validate solution is "good enough" */
double W_ratio = (double)buf.srcSize / testResult.cSize; double W_ratio = (double)buf.srcSize / (double)testResult.cSize;
double O_ratio = (double)buf.srcSize / winners[cLevel].result.cSize; double O_ratio = (double)buf.srcSize / (double)winners[cLevel].result.cSize;
double W_ratioNote = log (W_ratio); double W_ratioNote = log (W_ratio);
double O_ratioNote = log (O_ratio); double O_ratioNote = log (O_ratio);
size_t W_DMemUsed = (1 << params.vals[wlog_ind]) + (16 KB); size_t W_DMemUsed = (1 << params.vals[wlog_ind]) + (16 KB);
@@ -1864,11 +1864,11 @@ static int BMK_seed(winnerInfo_t* winners,
double W_CMemUsed_note = W_ratioNote * ( 50 + 13*cLevel) - log((double)W_CMemUsed); double W_CMemUsed_note = W_ratioNote * ( 50 + 13*cLevel) - log((double)W_CMemUsed);
double O_CMemUsed_note = O_ratioNote * ( 50 + 13*cLevel) - log((double)O_CMemUsed); double O_CMemUsed_note = O_ratioNote * ( 50 + 13*cLevel) - log((double)O_CMemUsed);
double W_CSpeed_note = W_ratioNote * (double)( 30 + 10*cLevel) + log(testResult.cSpeed); double W_CSpeed_note = W_ratioNote * (double)( 30 + 10*cLevel) + log((double)testResult.cSpeed);
double O_CSpeed_note = O_ratioNote * (double)( 30 + 10*cLevel) + log(winners[cLevel].result.cSpeed); double O_CSpeed_note = O_ratioNote * (double)( 30 + 10*cLevel) + log((double)winners[cLevel].result.cSpeed);
double W_DSpeed_note = W_ratioNote * (double)( 20 + 2*cLevel) + log(testResult.dSpeed); double W_DSpeed_note = W_ratioNote * (double)( 20 + 2*cLevel) + log((double)testResult.dSpeed);
double O_DSpeed_note = O_ratioNote * (double)( 20 + 2*cLevel) + log(winners[cLevel].result.dSpeed); double O_DSpeed_note = O_ratioNote * (double)( 20 + 2*cLevel) + log((double)winners[cLevel].result.dSpeed);
if (W_DMemUsed_note < O_DMemUsed_note) { if (W_DMemUsed_note < O_DMemUsed_note) {
/* uses too much Decompression memory for too little benefit */ /* uses too much Decompression memory for too little benefit */
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+95 -95
View File
@@ -11,10 +11,10 @@ silesia.tar, level 6, compress
silesia.tar, level 7, compress simple, 4576661 silesia.tar, level 7, compress simple, 4576661
silesia.tar, level 9, compress simple, 4552899 silesia.tar, level 9, compress simple, 4552899
silesia.tar, level 13, compress simple, 4502956 silesia.tar, level 13, compress simple, 4502956
silesia.tar, level 16, compress simple, 4360527 silesia.tar, level 16, compress simple, 4360546
silesia.tar, level 19, compress simple, 4266970 silesia.tar, level 19, compress simple, 4265911
silesia.tar, uncompressed literals, compress simple, 4854086 silesia.tar, uncompressed literals, compress simple, 4854086
silesia.tar, uncompressed literals optimal, compress simple, 4266970 silesia.tar, uncompressed literals optimal, compress simple, 4265911
silesia.tar, huffman literals, compress simple, 6179047 silesia.tar, huffman literals, compress simple, 6179047
github.tar, level -5, compress simple, 52115 github.tar, level -5, compress simple, 52115
github.tar, level -3, compress simple, 45678 github.tar, level -3, compress simple, 45678
@@ -28,10 +28,10 @@ github.tar, level 6, compress
github.tar, level 7, compress simple, 38110 github.tar, level 7, compress simple, 38110
github.tar, level 9, compress simple, 36760 github.tar, level 9, compress simple, 36760
github.tar, level 13, compress simple, 35501 github.tar, level 13, compress simple, 35501
github.tar, level 16, compress simple, 40471 github.tar, level 16, compress simple, 40466
github.tar, level 19, compress simple, 32149 github.tar, level 19, compress simple, 32276
github.tar, uncompressed literals, compress simple, 38831 github.tar, uncompressed literals, compress simple, 38831
github.tar, uncompressed literals optimal, compress simple, 32149 github.tar, uncompressed literals optimal, compress simple, 32276
github.tar, huffman literals, compress simple, 42560 github.tar, huffman literals, compress simple, 42560
silesia, level -5, compress cctx, 6857372 silesia, level -5, compress cctx, 6857372
silesia, level -3, compress cctx, 6503412 silesia, level -3, compress cctx, 6503412
@@ -45,8 +45,8 @@ silesia, level 6, compress
silesia, level 7, compress cctx, 4566984 silesia, level 7, compress cctx, 4566984
silesia, level 9, compress cctx, 4543018 silesia, level 9, compress cctx, 4543018
silesia, level 13, compress cctx, 4493990 silesia, level 13, compress cctx, 4493990
silesia, level 16, compress cctx, 4359864 silesia, level 16, compress cctx, 4360041
silesia, level 19, compress cctx, 4296438 silesia, level 19, compress cctx, 4296055
silesia, long distance mode, compress cctx, 4842075 silesia, long distance mode, compress cctx, 4842075
silesia, multithreaded, compress cctx, 4842075 silesia, multithreaded, compress cctx, 4842075
silesia, multithreaded long distance mode, compress cctx, 4842075 silesia, multithreaded long distance mode, compress cctx, 4842075
@@ -55,7 +55,7 @@ silesia, small hash log, compress
silesia, small chain log, compress cctx, 4912197 silesia, small chain log, compress cctx, 4912197
silesia, explicit params, compress cctx, 4794052 silesia, explicit params, compress cctx, 4794052
silesia, uncompressed literals, compress cctx, 4842075 silesia, uncompressed literals, compress cctx, 4842075
silesia, uncompressed literals optimal, compress cctx, 4296438 silesia, uncompressed literals optimal, compress cctx, 4296055
silesia, huffman literals, compress cctx, 6172202 silesia, huffman literals, compress cctx, 6172202
silesia, multithreaded with advanced params, compress cctx, 4842075 silesia, multithreaded with advanced params, compress cctx, 4842075
github, level -5, compress cctx, 204407 github, level -5, compress cctx, 204407
@@ -80,11 +80,11 @@ github, level 7, compress
github, level 7 with dict, compress cctx, 38755 github, level 7 with dict, compress cctx, 38755
github, level 9, compress cctx, 135122 github, level 9, compress cctx, 135122
github, level 9 with dict, compress cctx, 39398 github, level 9 with dict, compress cctx, 39398
github, level 13, compress cctx, 132729 github, level 13, compress cctx, 132878
github, level 13 with dict, compress cctx, 39948 github, level 13 with dict, compress cctx, 39948
github, level 16, compress cctx, 132729 github, level 16, compress cctx, 133209
github, level 16 with dict, compress cctx, 37568 github, level 16 with dict, compress cctx, 37568
github, level 19, compress cctx, 132729 github, level 19, compress cctx, 132879
github, level 19 with dict, compress cctx, 37567 github, level 19 with dict, compress cctx, 37567
github, long distance mode, compress cctx, 141069 github, long distance mode, compress cctx, 141069
github, multithreaded, compress cctx, 141069 github, multithreaded, compress cctx, 141069
@@ -94,7 +94,7 @@ github, small hash log, compress
github, small chain log, compress cctx, 139242 github, small chain log, compress cctx, 139242
github, explicit params, compress cctx, 140932 github, explicit params, compress cctx, 140932
github, uncompressed literals, compress cctx, 136332 github, uncompressed literals, compress cctx, 136332
github, uncompressed literals optimal, compress cctx, 132729 github, uncompressed literals optimal, compress cctx, 132879
github, huffman literals, compress cctx, 175468 github, huffman literals, compress cctx, 175468
github, multithreaded with advanced params, compress cctx, 141069 github, multithreaded with advanced params, compress cctx, 141069
silesia, level -5, zstdcli, 6857420 silesia, level -5, zstdcli, 6857420
@@ -109,8 +109,8 @@ silesia, level 6, zstdcli,
silesia, level 7, zstdcli, 4567032 silesia, level 7, zstdcli, 4567032
silesia, level 9, zstdcli, 4543066 silesia, level 9, zstdcli, 4543066
silesia, level 13, zstdcli, 4494038 silesia, level 13, zstdcli, 4494038
silesia, level 16, zstdcli, 4359912 silesia, level 16, zstdcli, 4360089
silesia, level 19, zstdcli, 4296486 silesia, level 19, zstdcli, 4296103
silesia, long distance mode, zstdcli, 4833785 silesia, long distance mode, zstdcli, 4833785
silesia, multithreaded, zstdcli, 4842123 silesia, multithreaded, zstdcli, 4842123
silesia, multithreaded long distance mode, zstdcli, 4833785 silesia, multithreaded long distance mode, zstdcli, 4833785
@@ -134,14 +134,14 @@ silesia.tar, level 6, zstdcli,
silesia.tar, level 7, zstdcli, 4578719 silesia.tar, level 7, zstdcli, 4578719
silesia.tar, level 9, zstdcli, 4552903 silesia.tar, level 9, zstdcli, 4552903
silesia.tar, level 13, zstdcli, 4502960 silesia.tar, level 13, zstdcli, 4502960
silesia.tar, level 16, zstdcli, 4360531 silesia.tar, level 16, zstdcli, 4360550
silesia.tar, level 19, zstdcli, 4266974 silesia.tar, level 19, zstdcli, 4265915
silesia.tar, no source size, zstdcli, 4854160 silesia.tar, no source size, zstdcli, 4854160
silesia.tar, long distance mode, zstdcli, 4845745 silesia.tar, long distance mode, zstdcli, 4845745
silesia.tar, multithreaded, zstdcli, 4854164 silesia.tar, multithreaded, zstdcli, 4854164
silesia.tar, multithreaded long distance mode, zstdcli, 4845745 silesia.tar, multithreaded long distance mode, zstdcli, 4845745
silesia.tar, small window log, zstdcli, 7100701 silesia.tar, small window log, zstdcli, 7100701
silesia.tar, small hash log, zstdcli, 6529289 silesia.tar, small hash log, zstdcli, 6529264
silesia.tar, small chain log, zstdcli, 4917022 silesia.tar, small chain log, zstdcli, 4917022
silesia.tar, explicit params, zstdcli, 4820713 silesia.tar, explicit params, zstdcli, 4820713
silesia.tar, uncompressed literals, zstdcli, 5122571 silesia.tar, uncompressed literals, zstdcli, 5122571
@@ -170,11 +170,11 @@ github, level 7, zstdcli,
github, level 7 with dict, zstdcli, 40745 github, level 7 with dict, zstdcli, 40745
github, level 9, zstdcli, 137122 github, level 9, zstdcli, 137122
github, level 9 with dict, zstdcli, 41393 github, level 9 with dict, zstdcli, 41393
github, level 13, zstdcli, 134729 github, level 13, zstdcli, 134878
github, level 13 with dict, zstdcli, 41900 github, level 13 with dict, zstdcli, 41900
github, level 16, zstdcli, 134729 github, level 16, zstdcli, 135209
github, level 16 with dict, zstdcli, 39577 github, level 16 with dict, zstdcli, 39577
github, level 19, zstdcli, 134729 github, level 19, zstdcli, 134879
github, level 19 with dict, zstdcli, 39576 github, level 19 with dict, zstdcli, 39576
github, long distance mode, zstdcli, 138332 github, long distance mode, zstdcli, 138332
github, multithreaded, zstdcli, 138332 github, multithreaded, zstdcli, 138332
@@ -184,7 +184,7 @@ github, small hash log, zstdcli,
github, small chain log, zstdcli, 138341 github, small chain log, zstdcli, 138341
github, explicit params, zstdcli, 136197 github, explicit params, zstdcli, 136197
github, uncompressed literals, zstdcli, 167911 github, uncompressed literals, zstdcli, 167911
github, uncompressed literals optimal, zstdcli, 159227 github, uncompressed literals optimal, zstdcli, 154667
github, huffman literals, zstdcli, 144365 github, huffman literals, zstdcli, 144365
github, multithreaded with advanced params, zstdcli, 167911 github, multithreaded with advanced params, zstdcli, 167911
github.tar, level -5, zstdcli, 52119 github.tar, level -5, zstdcli, 52119
@@ -211,9 +211,9 @@ github.tar, level 9, zstdcli,
github.tar, level 9 with dict, zstdcli, 36632 github.tar, level 9 with dict, zstdcli, 36632
github.tar, level 13, zstdcli, 35505 github.tar, level 13, zstdcli, 35505
github.tar, level 13 with dict, zstdcli, 37134 github.tar, level 13 with dict, zstdcli, 37134
github.tar, level 16, zstdcli, 40475 github.tar, level 16, zstdcli, 40470
github.tar, level 16 with dict, zstdcli, 33378 github.tar, level 16 with dict, zstdcli, 33378
github.tar, level 19, zstdcli, 32153 github.tar, level 19, zstdcli, 32280
github.tar, level 19 with dict, zstdcli, 32716 github.tar, level 19 with dict, zstdcli, 32716
github.tar, no source size, zstdcli, 38832 github.tar, no source size, zstdcli, 38832
github.tar, no source size with dict, zstdcli, 38004 github.tar, no source size with dict, zstdcli, 38004
@@ -248,8 +248,8 @@ silesia, level 11 row 2, advanced
silesia, level 12 row 1, advanced one pass, 4505046 silesia, level 12 row 1, advanced one pass, 4505046
silesia, level 12 row 2, advanced one pass, 4503116 silesia, level 12 row 2, advanced one pass, 4503116
silesia, level 13, advanced one pass, 4493990 silesia, level 13, advanced one pass, 4493990
silesia, level 16, advanced one pass, 4359864 silesia, level 16, advanced one pass, 4360041
silesia, level 19, advanced one pass, 4296438 silesia, level 19, advanced one pass, 4296055
silesia, no source size, advanced one pass, 4842075 silesia, no source size, advanced one pass, 4842075
silesia, long distance mode, advanced one pass, 4833710 silesia, long distance mode, advanced one pass, 4833710
silesia, multithreaded, advanced one pass, 4842075 silesia, multithreaded, advanced one pass, 4842075
@@ -282,14 +282,14 @@ silesia.tar, level 11 row 2, advanced
silesia.tar, level 12 row 1, advanced one pass, 4514049 silesia.tar, level 12 row 1, advanced one pass, 4514049
silesia.tar, level 12 row 2, advanced one pass, 4513797 silesia.tar, level 12 row 2, advanced one pass, 4513797
silesia.tar, level 13, advanced one pass, 4502956 silesia.tar, level 13, advanced one pass, 4502956
silesia.tar, level 16, advanced one pass, 4360527 silesia.tar, level 16, advanced one pass, 4360546
silesia.tar, level 19, advanced one pass, 4266970 silesia.tar, level 19, advanced one pass, 4265911
silesia.tar, no source size, advanced one pass, 4854086 silesia.tar, no source size, advanced one pass, 4854086
silesia.tar, long distance mode, advanced one pass, 4840452 silesia.tar, long distance mode, advanced one pass, 4840452
silesia.tar, multithreaded, advanced one pass, 4854160 silesia.tar, multithreaded, advanced one pass, 4854160
silesia.tar, multithreaded long distance mode, advanced one pass, 4845741 silesia.tar, multithreaded long distance mode, advanced one pass, 4845741
silesia.tar, small window log, advanced one pass, 7100655 silesia.tar, small window log, advanced one pass, 7100655
silesia.tar, small hash log, advanced one pass, 6529231 silesia.tar, small hash log, advanced one pass, 6529206
silesia.tar, small chain log, advanced one pass, 4917041 silesia.tar, small chain log, advanced one pass, 4917041
silesia.tar, explicit params, advanced one pass, 4806855 silesia.tar, explicit params, advanced one pass, 4806855
silesia.tar, uncompressed literals, advanced one pass, 5122473 silesia.tar, uncompressed literals, advanced one pass, 5122473
@@ -370,39 +370,39 @@ github, level 9 with dict dms, advanced
github, level 9 with dict dds, advanced one pass, 39393 github, level 9 with dict dds, advanced one pass, 39393
github, level 9 with dict copy, advanced one pass, 39398 github, level 9 with dict copy, advanced one pass, 39398
github, level 9 with dict load, advanced one pass, 41710 github, level 9 with dict load, advanced one pass, 41710
github, level 11 row 1, advanced one pass, 135119 github, level 11 row 1, advanced one pass, 135367
github, level 11 row 1 with dict dms, advanced one pass, 39671 github, level 11 row 1 with dict dms, advanced one pass, 39671
github, level 11 row 1 with dict dds, advanced one pass, 39671 github, level 11 row 1 with dict dds, advanced one pass, 39671
github, level 11 row 1 with dict copy, advanced one pass, 39651 github, level 11 row 1 with dict copy, advanced one pass, 39651
github, level 11 row 1 with dict load, advanced one pass, 41360 github, level 11 row 1 with dict load, advanced one pass, 41360
github, level 11 row 2, advanced one pass, 135119 github, level 11 row 2, advanced one pass, 135367
github, level 11 row 2 with dict dms, advanced one pass, 39671 github, level 11 row 2 with dict dms, advanced one pass, 39671
github, level 11 row 2 with dict dds, advanced one pass, 39671 github, level 11 row 2 with dict dds, advanced one pass, 39671
github, level 11 row 2 with dict copy, advanced one pass, 39651 github, level 11 row 2 with dict copy, advanced one pass, 39651
github, level 11 row 2 with dict load, advanced one pass, 41360 github, level 11 row 2 with dict load, advanced one pass, 41360
github, level 12 row 1, advanced one pass, 134180 github, level 12 row 1, advanced one pass, 134402
github, level 12 row 1 with dict dms, advanced one pass, 39677 github, level 12 row 1 with dict dms, advanced one pass, 39677
github, level 12 row 1 with dict dds, advanced one pass, 39677 github, level 12 row 1 with dict dds, advanced one pass, 39677
github, level 12 row 1 with dict copy, advanced one pass, 39677 github, level 12 row 1 with dict copy, advanced one pass, 39677
github, level 12 row 1 with dict load, advanced one pass, 41166 github, level 12 row 1 with dict load, advanced one pass, 41166
github, level 12 row 2, advanced one pass, 134180 github, level 12 row 2, advanced one pass, 134402
github, level 12 row 2 with dict dms, advanced one pass, 39677 github, level 12 row 2 with dict dms, advanced one pass, 39677
github, level 12 row 2 with dict dds, advanced one pass, 39677 github, level 12 row 2 with dict dds, advanced one pass, 39677
github, level 12 row 2 with dict copy, advanced one pass, 39677 github, level 12 row 2 with dict copy, advanced one pass, 39677
github, level 12 row 2 with dict load, advanced one pass, 41166 github, level 12 row 2 with dict load, advanced one pass, 41166
github, level 13, advanced one pass, 132729 github, level 13, advanced one pass, 132878
github, level 13 with dict, advanced one pass, 39900 github, level 13 with dict, advanced one pass, 39900
github, level 13 with dict dms, advanced one pass, 39900 github, level 13 with dict dms, advanced one pass, 39900
github, level 13 with dict dds, advanced one pass, 39900 github, level 13 with dict dds, advanced one pass, 39900
github, level 13 with dict copy, advanced one pass, 39948 github, level 13 with dict copy, advanced one pass, 39948
github, level 13 with dict load, advanced one pass, 42624 github, level 13 with dict load, advanced one pass, 42624
github, level 16, advanced one pass, 132729 github, level 16, advanced one pass, 133209
github, level 16 with dict, advanced one pass, 37577 github, level 16 with dict, advanced one pass, 37577
github, level 16 with dict dms, advanced one pass, 37577 github, level 16 with dict dms, advanced one pass, 37577
github, level 16 with dict dds, advanced one pass, 37577 github, level 16 with dict dds, advanced one pass, 37577
github, level 16 with dict copy, advanced one pass, 37568 github, level 16 with dict copy, advanced one pass, 37568
github, level 16 with dict load, advanced one pass, 42338 github, level 16 with dict load, advanced one pass, 42338
github, level 19, advanced one pass, 132729 github, level 19, advanced one pass, 132879
github, level 19 with dict, advanced one pass, 37576 github, level 19 with dict, advanced one pass, 37576
github, level 19 with dict dms, advanced one pass, 37576 github, level 19 with dict dms, advanced one pass, 37576
github, level 19 with dict dds, advanced one pass, 37576 github, level 19 with dict dds, advanced one pass, 37576
@@ -418,7 +418,7 @@ github, small hash log, advanced
github, small chain log, advanced one pass, 136341 github, small chain log, advanced one pass, 136341
github, explicit params, advanced one pass, 137727 github, explicit params, advanced one pass, 137727
github, uncompressed literals, advanced one pass, 165911 github, uncompressed literals, advanced one pass, 165911
github, uncompressed literals optimal, advanced one pass, 157227 github, uncompressed literals optimal, advanced one pass, 152667
github, huffman literals, advanced one pass, 142365 github, huffman literals, advanced one pass, 142365
github, multithreaded with advanced params, advanced one pass, 165911 github, multithreaded with advanced params, advanced one pass, 165911
github.tar, level -5, advanced one pass, 52115 github.tar, level -5, advanced one pass, 52115
@@ -521,13 +521,13 @@ github.tar, level 13 with dict dms, advanced
github.tar, level 13 with dict dds, advanced one pass, 37220 github.tar, level 13 with dict dds, advanced one pass, 37220
github.tar, level 13 with dict copy, advanced one pass, 37130 github.tar, level 13 with dict copy, advanced one pass, 37130
github.tar, level 13 with dict load, advanced one pass, 36010 github.tar, level 13 with dict load, advanced one pass, 36010
github.tar, level 16, advanced one pass, 40471 github.tar, level 16, advanced one pass, 40466
github.tar, level 16 with dict, advanced one pass, 33374 github.tar, level 16 with dict, advanced one pass, 33374
github.tar, level 16 with dict dms, advanced one pass, 33206 github.tar, level 16 with dict dms, advanced one pass, 33206
github.tar, level 16 with dict dds, advanced one pass, 33206 github.tar, level 16 with dict dds, advanced one pass, 33206
github.tar, level 16 with dict copy, advanced one pass, 33374 github.tar, level 16 with dict copy, advanced one pass, 33374
github.tar, level 16 with dict load, advanced one pass, 39081 github.tar, level 16 with dict load, advanced one pass, 39081
github.tar, level 19, advanced one pass, 32149 github.tar, level 19, advanced one pass, 32276
github.tar, level 19 with dict, advanced one pass, 32712 github.tar, level 19 with dict, advanced one pass, 32712
github.tar, level 19 with dict dms, advanced one pass, 32555 github.tar, level 19 with dict dms, advanced one pass, 32555
github.tar, level 19 with dict dds, advanced one pass, 32555 github.tar, level 19 with dict dds, advanced one pass, 32555
@@ -566,8 +566,8 @@ silesia, level 11 row 2, advanced
silesia, level 12 row 1, advanced one pass small out, 4505046 silesia, level 12 row 1, advanced one pass small out, 4505046
silesia, level 12 row 2, advanced one pass small out, 4503116 silesia, level 12 row 2, advanced one pass small out, 4503116
silesia, level 13, advanced one pass small out, 4493990 silesia, level 13, advanced one pass small out, 4493990
silesia, level 16, advanced one pass small out, 4359864 silesia, level 16, advanced one pass small out, 4360041
silesia, level 19, advanced one pass small out, 4296438 silesia, level 19, advanced one pass small out, 4296055
silesia, no source size, advanced one pass small out, 4842075 silesia, no source size, advanced one pass small out, 4842075
silesia, long distance mode, advanced one pass small out, 4833710 silesia, long distance mode, advanced one pass small out, 4833710
silesia, multithreaded, advanced one pass small out, 4842075 silesia, multithreaded, advanced one pass small out, 4842075
@@ -600,14 +600,14 @@ silesia.tar, level 11 row 2, advanced
silesia.tar, level 12 row 1, advanced one pass small out, 4514049 silesia.tar, level 12 row 1, advanced one pass small out, 4514049
silesia.tar, level 12 row 2, advanced one pass small out, 4513797 silesia.tar, level 12 row 2, advanced one pass small out, 4513797
silesia.tar, level 13, advanced one pass small out, 4502956 silesia.tar, level 13, advanced one pass small out, 4502956
silesia.tar, level 16, advanced one pass small out, 4360527 silesia.tar, level 16, advanced one pass small out, 4360546
silesia.tar, level 19, advanced one pass small out, 4266970 silesia.tar, level 19, advanced one pass small out, 4265911
silesia.tar, no source size, advanced one pass small out, 4854086 silesia.tar, no source size, advanced one pass small out, 4854086
silesia.tar, long distance mode, advanced one pass small out, 4840452 silesia.tar, long distance mode, advanced one pass small out, 4840452
silesia.tar, multithreaded, advanced one pass small out, 4854160 silesia.tar, multithreaded, advanced one pass small out, 4854160
silesia.tar, multithreaded long distance mode, advanced one pass small out, 4845741 silesia.tar, multithreaded long distance mode, advanced one pass small out, 4845741
silesia.tar, small window log, advanced one pass small out, 7100655 silesia.tar, small window log, advanced one pass small out, 7100655
silesia.tar, small hash log, advanced one pass small out, 6529231 silesia.tar, small hash log, advanced one pass small out, 6529206
silesia.tar, small chain log, advanced one pass small out, 4917041 silesia.tar, small chain log, advanced one pass small out, 4917041
silesia.tar, explicit params, advanced one pass small out, 4806855 silesia.tar, explicit params, advanced one pass small out, 4806855
silesia.tar, uncompressed literals, advanced one pass small out, 5122473 silesia.tar, uncompressed literals, advanced one pass small out, 5122473
@@ -688,39 +688,39 @@ github, level 9 with dict dms, advanced
github, level 9 with dict dds, advanced one pass small out, 39393 github, level 9 with dict dds, advanced one pass small out, 39393
github, level 9 with dict copy, advanced one pass small out, 39398 github, level 9 with dict copy, advanced one pass small out, 39398
github, level 9 with dict load, advanced one pass small out, 41710 github, level 9 with dict load, advanced one pass small out, 41710
github, level 11 row 1, advanced one pass small out, 135119 github, level 11 row 1, advanced one pass small out, 135367
github, level 11 row 1 with dict dms, advanced one pass small out, 39671 github, level 11 row 1 with dict dms, advanced one pass small out, 39671
github, level 11 row 1 with dict dds, advanced one pass small out, 39671 github, level 11 row 1 with dict dds, advanced one pass small out, 39671
github, level 11 row 1 with dict copy, advanced one pass small out, 39651 github, level 11 row 1 with dict copy, advanced one pass small out, 39651
github, level 11 row 1 with dict load, advanced one pass small out, 41360 github, level 11 row 1 with dict load, advanced one pass small out, 41360
github, level 11 row 2, advanced one pass small out, 135119 github, level 11 row 2, advanced one pass small out, 135367
github, level 11 row 2 with dict dms, advanced one pass small out, 39671 github, level 11 row 2 with dict dms, advanced one pass small out, 39671
github, level 11 row 2 with dict dds, advanced one pass small out, 39671 github, level 11 row 2 with dict dds, advanced one pass small out, 39671
github, level 11 row 2 with dict copy, advanced one pass small out, 39651 github, level 11 row 2 with dict copy, advanced one pass small out, 39651
github, level 11 row 2 with dict load, advanced one pass small out, 41360 github, level 11 row 2 with dict load, advanced one pass small out, 41360
github, level 12 row 1, advanced one pass small out, 134180 github, level 12 row 1, advanced one pass small out, 134402
github, level 12 row 1 with dict dms, advanced one pass small out, 39677 github, level 12 row 1 with dict dms, advanced one pass small out, 39677
github, level 12 row 1 with dict dds, advanced one pass small out, 39677 github, level 12 row 1 with dict dds, advanced one pass small out, 39677
github, level 12 row 1 with dict copy, advanced one pass small out, 39677 github, level 12 row 1 with dict copy, advanced one pass small out, 39677
github, level 12 row 1 with dict load, advanced one pass small out, 41166 github, level 12 row 1 with dict load, advanced one pass small out, 41166
github, level 12 row 2, advanced one pass small out, 134180 github, level 12 row 2, advanced one pass small out, 134402
github, level 12 row 2 with dict dms, advanced one pass small out, 39677 github, level 12 row 2 with dict dms, advanced one pass small out, 39677
github, level 12 row 2 with dict dds, advanced one pass small out, 39677 github, level 12 row 2 with dict dds, advanced one pass small out, 39677
github, level 12 row 2 with dict copy, advanced one pass small out, 39677 github, level 12 row 2 with dict copy, advanced one pass small out, 39677
github, level 12 row 2 with dict load, advanced one pass small out, 41166 github, level 12 row 2 with dict load, advanced one pass small out, 41166
github, level 13, advanced one pass small out, 132729 github, level 13, advanced one pass small out, 132878
github, level 13 with dict, advanced one pass small out, 39900 github, level 13 with dict, advanced one pass small out, 39900
github, level 13 with dict dms, advanced one pass small out, 39900 github, level 13 with dict dms, advanced one pass small out, 39900
github, level 13 with dict dds, advanced one pass small out, 39900 github, level 13 with dict dds, advanced one pass small out, 39900
github, level 13 with dict copy, advanced one pass small out, 39948 github, level 13 with dict copy, advanced one pass small out, 39948
github, level 13 with dict load, advanced one pass small out, 42624 github, level 13 with dict load, advanced one pass small out, 42624
github, level 16, advanced one pass small out, 132729 github, level 16, advanced one pass small out, 133209
github, level 16 with dict, advanced one pass small out, 37577 github, level 16 with dict, advanced one pass small out, 37577
github, level 16 with dict dms, advanced one pass small out, 37577 github, level 16 with dict dms, advanced one pass small out, 37577
github, level 16 with dict dds, advanced one pass small out, 37577 github, level 16 with dict dds, advanced one pass small out, 37577
github, level 16 with dict copy, advanced one pass small out, 37568 github, level 16 with dict copy, advanced one pass small out, 37568
github, level 16 with dict load, advanced one pass small out, 42338 github, level 16 with dict load, advanced one pass small out, 42338
github, level 19, advanced one pass small out, 132729 github, level 19, advanced one pass small out, 132879
github, level 19 with dict, advanced one pass small out, 37576 github, level 19 with dict, advanced one pass small out, 37576
github, level 19 with dict dms, advanced one pass small out, 37576 github, level 19 with dict dms, advanced one pass small out, 37576
github, level 19 with dict dds, advanced one pass small out, 37576 github, level 19 with dict dds, advanced one pass small out, 37576
@@ -736,7 +736,7 @@ github, small hash log, advanced
github, small chain log, advanced one pass small out, 136341 github, small chain log, advanced one pass small out, 136341
github, explicit params, advanced one pass small out, 137727 github, explicit params, advanced one pass small out, 137727
github, uncompressed literals, advanced one pass small out, 165911 github, uncompressed literals, advanced one pass small out, 165911
github, uncompressed literals optimal, advanced one pass small out, 157227 github, uncompressed literals optimal, advanced one pass small out, 152667
github, huffman literals, advanced one pass small out, 142365 github, huffman literals, advanced one pass small out, 142365
github, multithreaded with advanced params, advanced one pass small out, 165911 github, multithreaded with advanced params, advanced one pass small out, 165911
github.tar, level -5, advanced one pass small out, 52115 github.tar, level -5, advanced one pass small out, 52115
@@ -839,13 +839,13 @@ github.tar, level 13 with dict dms, advanced
github.tar, level 13 with dict dds, advanced one pass small out, 37220 github.tar, level 13 with dict dds, advanced one pass small out, 37220
github.tar, level 13 with dict copy, advanced one pass small out, 37130 github.tar, level 13 with dict copy, advanced one pass small out, 37130
github.tar, level 13 with dict load, advanced one pass small out, 36010 github.tar, level 13 with dict load, advanced one pass small out, 36010
github.tar, level 16, advanced one pass small out, 40471 github.tar, level 16, advanced one pass small out, 40466
github.tar, level 16 with dict, advanced one pass small out, 33374 github.tar, level 16 with dict, advanced one pass small out, 33374
github.tar, level 16 with dict dms, advanced one pass small out, 33206 github.tar, level 16 with dict dms, advanced one pass small out, 33206
github.tar, level 16 with dict dds, advanced one pass small out, 33206 github.tar, level 16 with dict dds, advanced one pass small out, 33206
github.tar, level 16 with dict copy, advanced one pass small out, 33374 github.tar, level 16 with dict copy, advanced one pass small out, 33374
github.tar, level 16 with dict load, advanced one pass small out, 39081 github.tar, level 16 with dict load, advanced one pass small out, 39081
github.tar, level 19, advanced one pass small out, 32149 github.tar, level 19, advanced one pass small out, 32276
github.tar, level 19 with dict, advanced one pass small out, 32712 github.tar, level 19 with dict, advanced one pass small out, 32712
github.tar, level 19 with dict dms, advanced one pass small out, 32555 github.tar, level 19 with dict dms, advanced one pass small out, 32555
github.tar, level 19 with dict dds, advanced one pass small out, 32555 github.tar, level 19 with dict dds, advanced one pass small out, 32555
@@ -884,8 +884,8 @@ silesia, level 11 row 2, advanced
silesia, level 12 row 1, advanced streaming, 4505046 silesia, level 12 row 1, advanced streaming, 4505046
silesia, level 12 row 2, advanced streaming, 4503116 silesia, level 12 row 2, advanced streaming, 4503116
silesia, level 13, advanced streaming, 4493990 silesia, level 13, advanced streaming, 4493990
silesia, level 16, advanced streaming, 4359864 silesia, level 16, advanced streaming, 4360041
silesia, level 19, advanced streaming, 4296438 silesia, level 19, advanced streaming, 4296055
silesia, no source size, advanced streaming, 4842039 silesia, no source size, advanced streaming, 4842039
silesia, long distance mode, advanced streaming, 4833710 silesia, long distance mode, advanced streaming, 4833710
silesia, multithreaded, advanced streaming, 4842075 silesia, multithreaded, advanced streaming, 4842075
@@ -918,14 +918,14 @@ silesia.tar, level 11 row 2, advanced
silesia.tar, level 12 row 1, advanced streaming, 4514049 silesia.tar, level 12 row 1, advanced streaming, 4514049
silesia.tar, level 12 row 2, advanced streaming, 4513797 silesia.tar, level 12 row 2, advanced streaming, 4513797
silesia.tar, level 13, advanced streaming, 4502956 silesia.tar, level 13, advanced streaming, 4502956
silesia.tar, level 16, advanced streaming, 4360527 silesia.tar, level 16, advanced streaming, 4360546
silesia.tar, level 19, advanced streaming, 4266970 silesia.tar, level 19, advanced streaming, 4265911
silesia.tar, no source size, advanced streaming, 4859267 silesia.tar, no source size, advanced streaming, 4859267
silesia.tar, long distance mode, advanced streaming, 4840452 silesia.tar, long distance mode, advanced streaming, 4840452
silesia.tar, multithreaded, advanced streaming, 4854160 silesia.tar, multithreaded, advanced streaming, 4854160
silesia.tar, multithreaded long distance mode, advanced streaming, 4845741 silesia.tar, multithreaded long distance mode, advanced streaming, 4845741
silesia.tar, small window log, advanced streaming, 7117559 silesia.tar, small window log, advanced streaming, 7117559
silesia.tar, small hash log, advanced streaming, 6529234 silesia.tar, small hash log, advanced streaming, 6529209
silesia.tar, small chain log, advanced streaming, 4917021 silesia.tar, small chain log, advanced streaming, 4917021
silesia.tar, explicit params, advanced streaming, 4806873 silesia.tar, explicit params, advanced streaming, 4806873
silesia.tar, uncompressed literals, advanced streaming, 5127423 silesia.tar, uncompressed literals, advanced streaming, 5127423
@@ -1006,39 +1006,39 @@ github, level 9 with dict dms, advanced
github, level 9 with dict dds, advanced streaming, 39393 github, level 9 with dict dds, advanced streaming, 39393
github, level 9 with dict copy, advanced streaming, 39398 github, level 9 with dict copy, advanced streaming, 39398
github, level 9 with dict load, advanced streaming, 41710 github, level 9 with dict load, advanced streaming, 41710
github, level 11 row 1, advanced streaming, 135119 github, level 11 row 1, advanced streaming, 135367
github, level 11 row 1 with dict dms, advanced streaming, 39671 github, level 11 row 1 with dict dms, advanced streaming, 39671
github, level 11 row 1 with dict dds, advanced streaming, 39671 github, level 11 row 1 with dict dds, advanced streaming, 39671
github, level 11 row 1 with dict copy, advanced streaming, 39651 github, level 11 row 1 with dict copy, advanced streaming, 39651
github, level 11 row 1 with dict load, advanced streaming, 41360 github, level 11 row 1 with dict load, advanced streaming, 41360
github, level 11 row 2, advanced streaming, 135119 github, level 11 row 2, advanced streaming, 135367
github, level 11 row 2 with dict dms, advanced streaming, 39671 github, level 11 row 2 with dict dms, advanced streaming, 39671
github, level 11 row 2 with dict dds, advanced streaming, 39671 github, level 11 row 2 with dict dds, advanced streaming, 39671
github, level 11 row 2 with dict copy, advanced streaming, 39651 github, level 11 row 2 with dict copy, advanced streaming, 39651
github, level 11 row 2 with dict load, advanced streaming, 41360 github, level 11 row 2 with dict load, advanced streaming, 41360
github, level 12 row 1, advanced streaming, 134180 github, level 12 row 1, advanced streaming, 134402
github, level 12 row 1 with dict dms, advanced streaming, 39677 github, level 12 row 1 with dict dms, advanced streaming, 39677
github, level 12 row 1 with dict dds, advanced streaming, 39677 github, level 12 row 1 with dict dds, advanced streaming, 39677
github, level 12 row 1 with dict copy, advanced streaming, 39677 github, level 12 row 1 with dict copy, advanced streaming, 39677
github, level 12 row 1 with dict load, advanced streaming, 41166 github, level 12 row 1 with dict load, advanced streaming, 41166
github, level 12 row 2, advanced streaming, 134180 github, level 12 row 2, advanced streaming, 134402
github, level 12 row 2 with dict dms, advanced streaming, 39677 github, level 12 row 2 with dict dms, advanced streaming, 39677
github, level 12 row 2 with dict dds, advanced streaming, 39677 github, level 12 row 2 with dict dds, advanced streaming, 39677
github, level 12 row 2 with dict copy, advanced streaming, 39677 github, level 12 row 2 with dict copy, advanced streaming, 39677
github, level 12 row 2 with dict load, advanced streaming, 41166 github, level 12 row 2 with dict load, advanced streaming, 41166
github, level 13, advanced streaming, 132729 github, level 13, advanced streaming, 132878
github, level 13 with dict, advanced streaming, 39900 github, level 13 with dict, advanced streaming, 39900
github, level 13 with dict dms, advanced streaming, 39900 github, level 13 with dict dms, advanced streaming, 39900
github, level 13 with dict dds, advanced streaming, 39900 github, level 13 with dict dds, advanced streaming, 39900
github, level 13 with dict copy, advanced streaming, 39948 github, level 13 with dict copy, advanced streaming, 39948
github, level 13 with dict load, advanced streaming, 42624 github, level 13 with dict load, advanced streaming, 42624
github, level 16, advanced streaming, 132729 github, level 16, advanced streaming, 133209
github, level 16 with dict, advanced streaming, 37577 github, level 16 with dict, advanced streaming, 37577
github, level 16 with dict dms, advanced streaming, 37577 github, level 16 with dict dms, advanced streaming, 37577
github, level 16 with dict dds, advanced streaming, 37577 github, level 16 with dict dds, advanced streaming, 37577
github, level 16 with dict copy, advanced streaming, 37568 github, level 16 with dict copy, advanced streaming, 37568
github, level 16 with dict load, advanced streaming, 42338 github, level 16 with dict load, advanced streaming, 42338
github, level 19, advanced streaming, 132729 github, level 19, advanced streaming, 132879
github, level 19 with dict, advanced streaming, 37576 github, level 19 with dict, advanced streaming, 37576
github, level 19 with dict dms, advanced streaming, 37576 github, level 19 with dict dms, advanced streaming, 37576
github, level 19 with dict dds, advanced streaming, 37576 github, level 19 with dict dds, advanced streaming, 37576
@@ -1054,7 +1054,7 @@ github, small hash log, advanced
github, small chain log, advanced streaming, 136341 github, small chain log, advanced streaming, 136341
github, explicit params, advanced streaming, 137727 github, explicit params, advanced streaming, 137727
github, uncompressed literals, advanced streaming, 165911 github, uncompressed literals, advanced streaming, 165911
github, uncompressed literals optimal, advanced streaming, 157227 github, uncompressed literals optimal, advanced streaming, 152667
github, huffman literals, advanced streaming, 142365 github, huffman literals, advanced streaming, 142365
github, multithreaded with advanced params, advanced streaming, 165911 github, multithreaded with advanced params, advanced streaming, 165911
github.tar, level -5, advanced streaming, 52152 github.tar, level -5, advanced streaming, 52152
@@ -1157,13 +1157,13 @@ github.tar, level 13 with dict dms, advanced
github.tar, level 13 with dict dds, advanced streaming, 37220 github.tar, level 13 with dict dds, advanced streaming, 37220
github.tar, level 13 with dict copy, advanced streaming, 37130 github.tar, level 13 with dict copy, advanced streaming, 37130
github.tar, level 13 with dict load, advanced streaming, 36010 github.tar, level 13 with dict load, advanced streaming, 36010
github.tar, level 16, advanced streaming, 40471 github.tar, level 16, advanced streaming, 40466
github.tar, level 16 with dict, advanced streaming, 33374 github.tar, level 16 with dict, advanced streaming, 33374
github.tar, level 16 with dict dms, advanced streaming, 33206 github.tar, level 16 with dict dms, advanced streaming, 33206
github.tar, level 16 with dict dds, advanced streaming, 33206 github.tar, level 16 with dict dds, advanced streaming, 33206
github.tar, level 16 with dict copy, advanced streaming, 33374 github.tar, level 16 with dict copy, advanced streaming, 33374
github.tar, level 16 with dict load, advanced streaming, 39081 github.tar, level 16 with dict load, advanced streaming, 39081
github.tar, level 19, advanced streaming, 32149 github.tar, level 19, advanced streaming, 32276
github.tar, level 19 with dict, advanced streaming, 32712 github.tar, level 19 with dict, advanced streaming, 32712
github.tar, level 19 with dict dms, advanced streaming, 32555 github.tar, level 19 with dict dms, advanced streaming, 32555
github.tar, level 19 with dict dds, advanced streaming, 32555 github.tar, level 19 with dict dds, advanced streaming, 32555
@@ -1194,11 +1194,11 @@ silesia, level 6, old stre
silesia, level 7, old streaming, 4566984 silesia, level 7, old streaming, 4566984
silesia, level 9, old streaming, 4543018 silesia, level 9, old streaming, 4543018
silesia, level 13, old streaming, 4493990 silesia, level 13, old streaming, 4493990
silesia, level 16, old streaming, 4359864 silesia, level 16, old streaming, 4360041
silesia, level 19, old streaming, 4296438 silesia, level 19, old streaming, 4296055
silesia, no source size, old streaming, 4842039 silesia, no source size, old streaming, 4842039
silesia, uncompressed literals, old streaming, 4842075 silesia, uncompressed literals, old streaming, 4842075
silesia, uncompressed literals optimal, old streaming, 4296438 silesia, uncompressed literals optimal, old streaming, 4296055
silesia, huffman literals, old streaming, 6172207 silesia, huffman literals, old streaming, 6172207
silesia.tar, level -5, old streaming, 6856523 silesia.tar, level -5, old streaming, 6856523
silesia.tar, level -3, old streaming, 6505954 silesia.tar, level -3, old streaming, 6505954
@@ -1212,11 +1212,11 @@ silesia.tar, level 6, old stre
silesia.tar, level 7, old streaming, 4576664 silesia.tar, level 7, old streaming, 4576664
silesia.tar, level 9, old streaming, 4552900 silesia.tar, level 9, old streaming, 4552900
silesia.tar, level 13, old streaming, 4502956 silesia.tar, level 13, old streaming, 4502956
silesia.tar, level 16, old streaming, 4360527 silesia.tar, level 16, old streaming, 4360546
silesia.tar, level 19, old streaming, 4266970 silesia.tar, level 19, old streaming, 4265911
silesia.tar, no source size, old streaming, 4859267 silesia.tar, no source size, old streaming, 4859267
silesia.tar, uncompressed literals, old streaming, 4859271 silesia.tar, uncompressed literals, old streaming, 4859271
silesia.tar, uncompressed literals optimal, old streaming, 4266970 silesia.tar, uncompressed literals optimal, old streaming, 4265911
silesia.tar, huffman literals, old streaming, 6179056 silesia.tar, huffman literals, old streaming, 6179056
github, level -5, old streaming, 204407 github, level -5, old streaming, 204407
github, level -5 with dict, old streaming, 46718 github, level -5 with dict, old streaming, 46718
@@ -1240,16 +1240,16 @@ github, level 7, old stre
github, level 7 with dict, old streaming, 38758 github, level 7 with dict, old streaming, 38758
github, level 9, old streaming, 135122 github, level 9, old streaming, 135122
github, level 9 with dict, old streaming, 39437 github, level 9 with dict, old streaming, 39437
github, level 13, old streaming, 132729 github, level 13, old streaming, 132878
github, level 13 with dict, old streaming, 39900 github, level 13 with dict, old streaming, 39900
github, level 16, old streaming, 132729 github, level 16, old streaming, 133209
github, level 16 with dict, old streaming, 37577 github, level 16 with dict, old streaming, 37577
github, level 19, old streaming, 132729 github, level 19, old streaming, 132879
github, level 19 with dict, old streaming, 37576 github, level 19 with dict, old streaming, 37576
github, no source size, old streaming, 140599 github, no source size, old streaming, 140599
github, no source size with dict, old streaming, 40654 github, no source size with dict, old streaming, 40654
github, uncompressed literals, old streaming, 136332 github, uncompressed literals, old streaming, 136332
github, uncompressed literals optimal, old streaming, 132729 github, uncompressed literals optimal, old streaming, 132879
github, huffman literals, old streaming, 175468 github, huffman literals, old streaming, 175468
github.tar, level -5, old streaming, 52152 github.tar, level -5, old streaming, 52152
github.tar, level -5 with dict, old streaming, 51045 github.tar, level -5 with dict, old streaming, 51045
@@ -1275,14 +1275,14 @@ github.tar, level 9, old stre
github.tar, level 9 with dict, old streaming, 36484 github.tar, level 9 with dict, old streaming, 36484
github.tar, level 13, old streaming, 35501 github.tar, level 13, old streaming, 35501
github.tar, level 13 with dict, old streaming, 37130 github.tar, level 13 with dict, old streaming, 37130
github.tar, level 16, old streaming, 40471 github.tar, level 16, old streaming, 40466
github.tar, level 16 with dict, old streaming, 33374 github.tar, level 16 with dict, old streaming, 33374
github.tar, level 19, old streaming, 32149 github.tar, level 19, old streaming, 32276
github.tar, level 19 with dict, old streaming, 32712 github.tar, level 19 with dict, old streaming, 32712
github.tar, no source size, old streaming, 38828 github.tar, no source size, old streaming, 38828
github.tar, no source size with dict, old streaming, 38000 github.tar, no source size with dict, old streaming, 38000
github.tar, uncompressed literals, old streaming, 38831 github.tar, uncompressed literals, old streaming, 38831
github.tar, uncompressed literals optimal, old streaming, 32149 github.tar, uncompressed literals optimal, old streaming, 32276
github.tar, huffman literals, old streaming, 42560 github.tar, huffman literals, old streaming, 42560
silesia, level -5, old streaming advanced, 6854744 silesia, level -5, old streaming advanced, 6854744
silesia, level -3, old streaming advanced, 6503319 silesia, level -3, old streaming advanced, 6503319
@@ -1296,8 +1296,8 @@ silesia, level 6, old stre
silesia, level 7, old streaming advanced, 4566984 silesia, level 7, old streaming advanced, 4566984
silesia, level 9, old streaming advanced, 4543018 silesia, level 9, old streaming advanced, 4543018
silesia, level 13, old streaming advanced, 4493990 silesia, level 13, old streaming advanced, 4493990
silesia, level 16, old streaming advanced, 4359864 silesia, level 16, old streaming advanced, 4360041
silesia, level 19, old streaming advanced, 4296438 silesia, level 19, old streaming advanced, 4296055
silesia, no source size, old streaming advanced, 4842039 silesia, no source size, old streaming advanced, 4842039
silesia, long distance mode, old streaming advanced, 4842075 silesia, long distance mode, old streaming advanced, 4842075
silesia, multithreaded, old streaming advanced, 4842075 silesia, multithreaded, old streaming advanced, 4842075
@@ -1307,7 +1307,7 @@ silesia, small hash log, old stre
silesia, small chain log, old streaming advanced, 4912197 silesia, small chain log, old streaming advanced, 4912197
silesia, explicit params, old streaming advanced, 4795452 silesia, explicit params, old streaming advanced, 4795452
silesia, uncompressed literals, old streaming advanced, 4842075 silesia, uncompressed literals, old streaming advanced, 4842075
silesia, uncompressed literals optimal, old streaming advanced, 4296438 silesia, uncompressed literals optimal, old streaming advanced, 4296055
silesia, huffman literals, old streaming advanced, 6172207 silesia, huffman literals, old streaming advanced, 6172207
silesia, multithreaded with advanced params, old streaming advanced, 4842075 silesia, multithreaded with advanced params, old streaming advanced, 4842075
silesia.tar, level -5, old streaming advanced, 6856523 silesia.tar, level -5, old streaming advanced, 6856523
@@ -1322,18 +1322,18 @@ silesia.tar, level 6, old stre
silesia.tar, level 7, old streaming advanced, 4576664 silesia.tar, level 7, old streaming advanced, 4576664
silesia.tar, level 9, old streaming advanced, 4552900 silesia.tar, level 9, old streaming advanced, 4552900
silesia.tar, level 13, old streaming advanced, 4502956 silesia.tar, level 13, old streaming advanced, 4502956
silesia.tar, level 16, old streaming advanced, 4360527 silesia.tar, level 16, old streaming advanced, 4360546
silesia.tar, level 19, old streaming advanced, 4266970 silesia.tar, level 19, old streaming advanced, 4265911
silesia.tar, no source size, old streaming advanced, 4859267 silesia.tar, no source size, old streaming advanced, 4859267
silesia.tar, long distance mode, old streaming advanced, 4859271 silesia.tar, long distance mode, old streaming advanced, 4859271
silesia.tar, multithreaded, old streaming advanced, 4859271 silesia.tar, multithreaded, old streaming advanced, 4859271
silesia.tar, multithreaded long distance mode, old streaming advanced, 4859271 silesia.tar, multithreaded long distance mode, old streaming advanced, 4859271
silesia.tar, small window log, old streaming advanced, 7117562 silesia.tar, small window log, old streaming advanced, 7117562
silesia.tar, small hash log, old streaming advanced, 6529234 silesia.tar, small hash log, old streaming advanced, 6529209
silesia.tar, small chain log, old streaming advanced, 4917021 silesia.tar, small chain log, old streaming advanced, 4917021
silesia.tar, explicit params, old streaming advanced, 4806873 silesia.tar, explicit params, old streaming advanced, 4806873
silesia.tar, uncompressed literals, old streaming advanced, 4859271 silesia.tar, uncompressed literals, old streaming advanced, 4859271
silesia.tar, uncompressed literals optimal, old streaming advanced, 4266970 silesia.tar, uncompressed literals optimal, old streaming advanced, 4265911
silesia.tar, huffman literals, old streaming advanced, 6179056 silesia.tar, huffman literals, old streaming advanced, 6179056
silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271
github, level -5, old streaming advanced, 213265 github, level -5, old streaming advanced, 213265
@@ -1360,9 +1360,9 @@ github, level 9, old stre
github, level 9 with dict, old streaming advanced, 38981 github, level 9 with dict, old streaming advanced, 38981
github, level 13, old streaming advanced, 138676 github, level 13, old streaming advanced, 138676
github, level 13 with dict, old streaming advanced, 39725 github, level 13 with dict, old streaming advanced, 39725
github, level 16, old streaming advanced, 138676 github, level 16, old streaming advanced, 138575
github, level 16 with dict, old streaming advanced, 40789 github, level 16 with dict, old streaming advanced, 40789
github, level 19, old streaming advanced, 132729 github, level 19, old streaming advanced, 132879
github, level 19 with dict, old streaming advanced, 37576 github, level 19 with dict, old streaming advanced, 37576
github, no source size, old streaming advanced, 140599 github, no source size, old streaming advanced, 140599
github, no source size with dict, old streaming advanced, 40608 github, no source size with dict, old streaming advanced, 40608
@@ -1374,7 +1374,7 @@ github, small hash log, old stre
github, small chain log, old streaming advanced, 139275 github, small chain log, old streaming advanced, 139275
github, explicit params, old streaming advanced, 140937 github, explicit params, old streaming advanced, 140937
github, uncompressed literals, old streaming advanced, 141104 github, uncompressed literals, old streaming advanced, 141104
github, uncompressed literals optimal, old streaming advanced, 132729 github, uncompressed literals optimal, old streaming advanced, 132879
github, huffman literals, old streaming advanced, 181107 github, huffman literals, old streaming advanced, 181107
github, multithreaded with advanced params, old streaming advanced, 141104 github, multithreaded with advanced params, old streaming advanced, 141104
github.tar, level -5, old streaming advanced, 52152 github.tar, level -5, old streaming advanced, 52152
@@ -1401,9 +1401,9 @@ github.tar, level 9, old stre
github.tar, level 9 with dict, old streaming advanced, 36312 github.tar, level 9 with dict, old streaming advanced, 36312
github.tar, level 13, old streaming advanced, 35501 github.tar, level 13, old streaming advanced, 35501
github.tar, level 13 with dict, old streaming advanced, 35807 github.tar, level 13 with dict, old streaming advanced, 35807
github.tar, level 16, old streaming advanced, 40471 github.tar, level 16, old streaming advanced, 40466
github.tar, level 16 with dict, old streaming advanced, 38578 github.tar, level 16 with dict, old streaming advanced, 38578
github.tar, level 19, old streaming advanced, 32149 github.tar, level 19, old streaming advanced, 32276
github.tar, level 19 with dict, old streaming advanced, 32704 github.tar, level 19 with dict, old streaming advanced, 32704
github.tar, no source size, old streaming advanced, 38828 github.tar, no source size, old streaming advanced, 38828
github.tar, no source size with dict, old streaming advanced, 38015 github.tar, no source size with dict, old streaming advanced, 38015
@@ -1415,7 +1415,7 @@ github.tar, small hash log, old stre
github.tar, small chain log, old streaming advanced, 41669 github.tar, small chain log, old streaming advanced, 41669
github.tar, explicit params, old streaming advanced, 41385 github.tar, explicit params, old streaming advanced, 41385
github.tar, uncompressed literals, old streaming advanced, 38831 github.tar, uncompressed literals, old streaming advanced, 38831
github.tar, uncompressed literals optimal, old streaming advanced, 32149 github.tar, uncompressed literals optimal, old streaming advanced, 32276
github.tar, huffman literals, old streaming advanced, 42560 github.tar, huffman literals, old streaming advanced, 42560
github.tar, multithreaded with advanced params, old streaming advanced, 38831 github.tar, multithreaded with advanced params, old streaming advanced, 38831
github, level -5 with dict, old streaming cdict, 46718 github, level -5 with dict, old streaming cdict, 46718
1 Data Config Method Total compressed size
11 silesia.tar level 7 compress simple 4576661
12 silesia.tar level 9 compress simple 4552899
13 silesia.tar level 13 compress simple 4502956
14 silesia.tar level 16 compress simple 4360527 4360546
15 silesia.tar level 19 compress simple 4266970 4265911
16 silesia.tar uncompressed literals compress simple 4854086
17 silesia.tar uncompressed literals optimal compress simple 4266970 4265911
18 silesia.tar huffman literals compress simple 6179047
19 github.tar level -5 compress simple 52115
20 github.tar level -3 compress simple 45678
28 github.tar level 7 compress simple 38110
29 github.tar level 9 compress simple 36760
30 github.tar level 13 compress simple 35501
31 github.tar level 16 compress simple 40471 40466
32 github.tar level 19 compress simple 32149 32276
33 github.tar uncompressed literals compress simple 38831
34 github.tar uncompressed literals optimal compress simple 32149 32276
35 github.tar huffman literals compress simple 42560
36 silesia level -5 compress cctx 6857372
37 silesia level -3 compress cctx 6503412
45 silesia level 7 compress cctx 4566984
46 silesia level 9 compress cctx 4543018
47 silesia level 13 compress cctx 4493990
48 silesia level 16 compress cctx 4359864 4360041
49 silesia level 19 compress cctx 4296438 4296055
50 silesia long distance mode compress cctx 4842075
51 silesia multithreaded compress cctx 4842075
52 silesia multithreaded long distance mode compress cctx 4842075
55 silesia small chain log compress cctx 4912197
56 silesia explicit params compress cctx 4794052
57 silesia uncompressed literals compress cctx 4842075
58 silesia uncompressed literals optimal compress cctx 4296438 4296055
59 silesia huffman literals compress cctx 6172202
60 silesia multithreaded with advanced params compress cctx 4842075
61 github level -5 compress cctx 204407
80 github level 7 with dict compress cctx 38755
81 github level 9 compress cctx 135122
82 github level 9 with dict compress cctx 39398
83 github level 13 compress cctx 132729 132878
84 github level 13 with dict compress cctx 39948
85 github level 16 compress cctx 132729 133209
86 github level 16 with dict compress cctx 37568
87 github level 19 compress cctx 132729 132879
88 github level 19 with dict compress cctx 37567
89 github long distance mode compress cctx 141069
90 github multithreaded compress cctx 141069
94 github small chain log compress cctx 139242
95 github explicit params compress cctx 140932
96 github uncompressed literals compress cctx 136332
97 github uncompressed literals optimal compress cctx 132729 132879
98 github huffman literals compress cctx 175468
99 github multithreaded with advanced params compress cctx 141069
100 silesia level -5 zstdcli 6857420
109 silesia level 7 zstdcli 4567032
110 silesia level 9 zstdcli 4543066
111 silesia level 13 zstdcli 4494038
112 silesia level 16 zstdcli 4359912 4360089
113 silesia level 19 zstdcli 4296486 4296103
114 silesia long distance mode zstdcli 4833785
115 silesia multithreaded zstdcli 4842123
116 silesia multithreaded long distance mode zstdcli 4833785
134 silesia.tar level 7 zstdcli 4578719
135 silesia.tar level 9 zstdcli 4552903
136 silesia.tar level 13 zstdcli 4502960
137 silesia.tar level 16 zstdcli 4360531 4360550
138 silesia.tar level 19 zstdcli 4266974 4265915
139 silesia.tar no source size zstdcli 4854160
140 silesia.tar long distance mode zstdcli 4845745
141 silesia.tar multithreaded zstdcli 4854164
142 silesia.tar multithreaded long distance mode zstdcli 4845745
143 silesia.tar small window log zstdcli 7100701
144 silesia.tar small hash log zstdcli 6529289 6529264
145 silesia.tar small chain log zstdcli 4917022
146 silesia.tar explicit params zstdcli 4820713
147 silesia.tar uncompressed literals zstdcli 5122571
170 github level 7 with dict zstdcli 40745
171 github level 9 zstdcli 137122
172 github level 9 with dict zstdcli 41393
173 github level 13 zstdcli 134729 134878
174 github level 13 with dict zstdcli 41900
175 github level 16 zstdcli 134729 135209
176 github level 16 with dict zstdcli 39577
177 github level 19 zstdcli 134729 134879
178 github level 19 with dict zstdcli 39576
179 github long distance mode zstdcli 138332
180 github multithreaded zstdcli 138332
184 github small chain log zstdcli 138341
185 github explicit params zstdcli 136197
186 github uncompressed literals zstdcli 167911
187 github uncompressed literals optimal zstdcli 159227 154667
188 github huffman literals zstdcli 144365
189 github multithreaded with advanced params zstdcli 167911
190 github.tar level -5 zstdcli 52119
211 github.tar level 9 with dict zstdcli 36632
212 github.tar level 13 zstdcli 35505
213 github.tar level 13 with dict zstdcli 37134
214 github.tar level 16 zstdcli 40475 40470
215 github.tar level 16 with dict zstdcli 33378
216 github.tar level 19 zstdcli 32153 32280
217 github.tar level 19 with dict zstdcli 32716
218 github.tar no source size zstdcli 38832
219 github.tar no source size with dict zstdcli 38004
248 silesia level 12 row 1 advanced one pass 4505046
249 silesia level 12 row 2 advanced one pass 4503116
250 silesia level 13 advanced one pass 4493990
251 silesia level 16 advanced one pass 4359864 4360041
252 silesia level 19 advanced one pass 4296438 4296055
253 silesia no source size advanced one pass 4842075
254 silesia long distance mode advanced one pass 4833710
255 silesia multithreaded advanced one pass 4842075
282 silesia.tar level 12 row 1 advanced one pass 4514049
283 silesia.tar level 12 row 2 advanced one pass 4513797
284 silesia.tar level 13 advanced one pass 4502956
285 silesia.tar level 16 advanced one pass 4360527 4360546
286 silesia.tar level 19 advanced one pass 4266970 4265911
287 silesia.tar no source size advanced one pass 4854086
288 silesia.tar long distance mode advanced one pass 4840452
289 silesia.tar multithreaded advanced one pass 4854160
290 silesia.tar multithreaded long distance mode advanced one pass 4845741
291 silesia.tar small window log advanced one pass 7100655
292 silesia.tar small hash log advanced one pass 6529231 6529206
293 silesia.tar small chain log advanced one pass 4917041
294 silesia.tar explicit params advanced one pass 4806855
295 silesia.tar uncompressed literals advanced one pass 5122473
370 github level 9 with dict dds advanced one pass 39393
371 github level 9 with dict copy advanced one pass 39398
372 github level 9 with dict load advanced one pass 41710
373 github level 11 row 1 advanced one pass 135119 135367
374 github level 11 row 1 with dict dms advanced one pass 39671
375 github level 11 row 1 with dict dds advanced one pass 39671
376 github level 11 row 1 with dict copy advanced one pass 39651
377 github level 11 row 1 with dict load advanced one pass 41360
378 github level 11 row 2 advanced one pass 135119 135367
379 github level 11 row 2 with dict dms advanced one pass 39671
380 github level 11 row 2 with dict dds advanced one pass 39671
381 github level 11 row 2 with dict copy advanced one pass 39651
382 github level 11 row 2 with dict load advanced one pass 41360
383 github level 12 row 1 advanced one pass 134180 134402
384 github level 12 row 1 with dict dms advanced one pass 39677
385 github level 12 row 1 with dict dds advanced one pass 39677
386 github level 12 row 1 with dict copy advanced one pass 39677
387 github level 12 row 1 with dict load advanced one pass 41166
388 github level 12 row 2 advanced one pass 134180 134402
389 github level 12 row 2 with dict dms advanced one pass 39677
390 github level 12 row 2 with dict dds advanced one pass 39677
391 github level 12 row 2 with dict copy advanced one pass 39677
392 github level 12 row 2 with dict load advanced one pass 41166
393 github level 13 advanced one pass 132729 132878
394 github level 13 with dict advanced one pass 39900
395 github level 13 with dict dms advanced one pass 39900
396 github level 13 with dict dds advanced one pass 39900
397 github level 13 with dict copy advanced one pass 39948
398 github level 13 with dict load advanced one pass 42624
399 github level 16 advanced one pass 132729 133209
400 github level 16 with dict advanced one pass 37577
401 github level 16 with dict dms advanced one pass 37577
402 github level 16 with dict dds advanced one pass 37577
403 github level 16 with dict copy advanced one pass 37568
404 github level 16 with dict load advanced one pass 42338
405 github level 19 advanced one pass 132729 132879
406 github level 19 with dict advanced one pass 37576
407 github level 19 with dict dms advanced one pass 37576
408 github level 19 with dict dds advanced one pass 37576
418 github small chain log advanced one pass 136341
419 github explicit params advanced one pass 137727
420 github uncompressed literals advanced one pass 165911
421 github uncompressed literals optimal advanced one pass 157227 152667
422 github huffman literals advanced one pass 142365
423 github multithreaded with advanced params advanced one pass 165911
424 github.tar level -5 advanced one pass 52115
521 github.tar level 13 with dict dds advanced one pass 37220
522 github.tar level 13 with dict copy advanced one pass 37130
523 github.tar level 13 with dict load advanced one pass 36010
524 github.tar level 16 advanced one pass 40471 40466
525 github.tar level 16 with dict advanced one pass 33374
526 github.tar level 16 with dict dms advanced one pass 33206
527 github.tar level 16 with dict dds advanced one pass 33206
528 github.tar level 16 with dict copy advanced one pass 33374
529 github.tar level 16 with dict load advanced one pass 39081
530 github.tar level 19 advanced one pass 32149 32276
531 github.tar level 19 with dict advanced one pass 32712
532 github.tar level 19 with dict dms advanced one pass 32555
533 github.tar level 19 with dict dds advanced one pass 32555
566 silesia level 12 row 1 advanced one pass small out 4505046
567 silesia level 12 row 2 advanced one pass small out 4503116
568 silesia level 13 advanced one pass small out 4493990
569 silesia level 16 advanced one pass small out 4359864 4360041
570 silesia level 19 advanced one pass small out 4296438 4296055
571 silesia no source size advanced one pass small out 4842075
572 silesia long distance mode advanced one pass small out 4833710
573 silesia multithreaded advanced one pass small out 4842075
600 silesia.tar level 12 row 1 advanced one pass small out 4514049
601 silesia.tar level 12 row 2 advanced one pass small out 4513797
602 silesia.tar level 13 advanced one pass small out 4502956
603 silesia.tar level 16 advanced one pass small out 4360527 4360546
604 silesia.tar level 19 advanced one pass small out 4266970 4265911
605 silesia.tar no source size advanced one pass small out 4854086
606 silesia.tar long distance mode advanced one pass small out 4840452
607 silesia.tar multithreaded advanced one pass small out 4854160
608 silesia.tar multithreaded long distance mode advanced one pass small out 4845741
609 silesia.tar small window log advanced one pass small out 7100655
610 silesia.tar small hash log advanced one pass small out 6529231 6529206
611 silesia.tar small chain log advanced one pass small out 4917041
612 silesia.tar explicit params advanced one pass small out 4806855
613 silesia.tar uncompressed literals advanced one pass small out 5122473
688 github level 9 with dict dds advanced one pass small out 39393
689 github level 9 with dict copy advanced one pass small out 39398
690 github level 9 with dict load advanced one pass small out 41710
691 github level 11 row 1 advanced one pass small out 135119 135367
692 github level 11 row 1 with dict dms advanced one pass small out 39671
693 github level 11 row 1 with dict dds advanced one pass small out 39671
694 github level 11 row 1 with dict copy advanced one pass small out 39651
695 github level 11 row 1 with dict load advanced one pass small out 41360
696 github level 11 row 2 advanced one pass small out 135119 135367
697 github level 11 row 2 with dict dms advanced one pass small out 39671
698 github level 11 row 2 with dict dds advanced one pass small out 39671
699 github level 11 row 2 with dict copy advanced one pass small out 39651
700 github level 11 row 2 with dict load advanced one pass small out 41360
701 github level 12 row 1 advanced one pass small out 134180 134402
702 github level 12 row 1 with dict dms advanced one pass small out 39677
703 github level 12 row 1 with dict dds advanced one pass small out 39677
704 github level 12 row 1 with dict copy advanced one pass small out 39677
705 github level 12 row 1 with dict load advanced one pass small out 41166
706 github level 12 row 2 advanced one pass small out 134180 134402
707 github level 12 row 2 with dict dms advanced one pass small out 39677
708 github level 12 row 2 with dict dds advanced one pass small out 39677
709 github level 12 row 2 with dict copy advanced one pass small out 39677
710 github level 12 row 2 with dict load advanced one pass small out 41166
711 github level 13 advanced one pass small out 132729 132878
712 github level 13 with dict advanced one pass small out 39900
713 github level 13 with dict dms advanced one pass small out 39900
714 github level 13 with dict dds advanced one pass small out 39900
715 github level 13 with dict copy advanced one pass small out 39948
716 github level 13 with dict load advanced one pass small out 42624
717 github level 16 advanced one pass small out 132729 133209
718 github level 16 with dict advanced one pass small out 37577
719 github level 16 with dict dms advanced one pass small out 37577
720 github level 16 with dict dds advanced one pass small out 37577
721 github level 16 with dict copy advanced one pass small out 37568
722 github level 16 with dict load advanced one pass small out 42338
723 github level 19 advanced one pass small out 132729 132879
724 github level 19 with dict advanced one pass small out 37576
725 github level 19 with dict dms advanced one pass small out 37576
726 github level 19 with dict dds advanced one pass small out 37576
736 github small chain log advanced one pass small out 136341
737 github explicit params advanced one pass small out 137727
738 github uncompressed literals advanced one pass small out 165911
739 github uncompressed literals optimal advanced one pass small out 157227 152667
740 github huffman literals advanced one pass small out 142365
741 github multithreaded with advanced params advanced one pass small out 165911
742 github.tar level -5 advanced one pass small out 52115
839 github.tar level 13 with dict dds advanced one pass small out 37220
840 github.tar level 13 with dict copy advanced one pass small out 37130
841 github.tar level 13 with dict load advanced one pass small out 36010
842 github.tar level 16 advanced one pass small out 40471 40466
843 github.tar level 16 with dict advanced one pass small out 33374
844 github.tar level 16 with dict dms advanced one pass small out 33206
845 github.tar level 16 with dict dds advanced one pass small out 33206
846 github.tar level 16 with dict copy advanced one pass small out 33374
847 github.tar level 16 with dict load advanced one pass small out 39081
848 github.tar level 19 advanced one pass small out 32149 32276
849 github.tar level 19 with dict advanced one pass small out 32712
850 github.tar level 19 with dict dms advanced one pass small out 32555
851 github.tar level 19 with dict dds advanced one pass small out 32555
884 silesia level 12 row 1 advanced streaming 4505046
885 silesia level 12 row 2 advanced streaming 4503116
886 silesia level 13 advanced streaming 4493990
887 silesia level 16 advanced streaming 4359864 4360041
888 silesia level 19 advanced streaming 4296438 4296055
889 silesia no source size advanced streaming 4842039
890 silesia long distance mode advanced streaming 4833710
891 silesia multithreaded advanced streaming 4842075
918 silesia.tar level 12 row 1 advanced streaming 4514049
919 silesia.tar level 12 row 2 advanced streaming 4513797
920 silesia.tar level 13 advanced streaming 4502956
921 silesia.tar level 16 advanced streaming 4360527 4360546
922 silesia.tar level 19 advanced streaming 4266970 4265911
923 silesia.tar no source size advanced streaming 4859267
924 silesia.tar long distance mode advanced streaming 4840452
925 silesia.tar multithreaded advanced streaming 4854160
926 silesia.tar multithreaded long distance mode advanced streaming 4845741
927 silesia.tar small window log advanced streaming 7117559
928 silesia.tar small hash log advanced streaming 6529234 6529209
929 silesia.tar small chain log advanced streaming 4917021
930 silesia.tar explicit params advanced streaming 4806873
931 silesia.tar uncompressed literals advanced streaming 5127423
1006 github level 9 with dict dds advanced streaming 39393
1007 github level 9 with dict copy advanced streaming 39398
1008 github level 9 with dict load advanced streaming 41710
1009 github level 11 row 1 advanced streaming 135119 135367
1010 github level 11 row 1 with dict dms advanced streaming 39671
1011 github level 11 row 1 with dict dds advanced streaming 39671
1012 github level 11 row 1 with dict copy advanced streaming 39651
1013 github level 11 row 1 with dict load advanced streaming 41360
1014 github level 11 row 2 advanced streaming 135119 135367
1015 github level 11 row 2 with dict dms advanced streaming 39671
1016 github level 11 row 2 with dict dds advanced streaming 39671
1017 github level 11 row 2 with dict copy advanced streaming 39651
1018 github level 11 row 2 with dict load advanced streaming 41360
1019 github level 12 row 1 advanced streaming 134180 134402
1020 github level 12 row 1 with dict dms advanced streaming 39677
1021 github level 12 row 1 with dict dds advanced streaming 39677
1022 github level 12 row 1 with dict copy advanced streaming 39677
1023 github level 12 row 1 with dict load advanced streaming 41166
1024 github level 12 row 2 advanced streaming 134180 134402
1025 github level 12 row 2 with dict dms advanced streaming 39677
1026 github level 12 row 2 with dict dds advanced streaming 39677
1027 github level 12 row 2 with dict copy advanced streaming 39677
1028 github level 12 row 2 with dict load advanced streaming 41166
1029 github level 13 advanced streaming 132729 132878
1030 github level 13 with dict advanced streaming 39900
1031 github level 13 with dict dms advanced streaming 39900
1032 github level 13 with dict dds advanced streaming 39900
1033 github level 13 with dict copy advanced streaming 39948
1034 github level 13 with dict load advanced streaming 42624
1035 github level 16 advanced streaming 132729 133209
1036 github level 16 with dict advanced streaming 37577
1037 github level 16 with dict dms advanced streaming 37577
1038 github level 16 with dict dds advanced streaming 37577
1039 github level 16 with dict copy advanced streaming 37568
1040 github level 16 with dict load advanced streaming 42338
1041 github level 19 advanced streaming 132729 132879
1042 github level 19 with dict advanced streaming 37576
1043 github level 19 with dict dms advanced streaming 37576
1044 github level 19 with dict dds advanced streaming 37576
1054 github small chain log advanced streaming 136341
1055 github explicit params advanced streaming 137727
1056 github uncompressed literals advanced streaming 165911
1057 github uncompressed literals optimal advanced streaming 157227 152667
1058 github huffman literals advanced streaming 142365
1059 github multithreaded with advanced params advanced streaming 165911
1060 github.tar level -5 advanced streaming 52152
1157 github.tar level 13 with dict dds advanced streaming 37220
1158 github.tar level 13 with dict copy advanced streaming 37130
1159 github.tar level 13 with dict load advanced streaming 36010
1160 github.tar level 16 advanced streaming 40471 40466
1161 github.tar level 16 with dict advanced streaming 33374
1162 github.tar level 16 with dict dms advanced streaming 33206
1163 github.tar level 16 with dict dds advanced streaming 33206
1164 github.tar level 16 with dict copy advanced streaming 33374
1165 github.tar level 16 with dict load advanced streaming 39081
1166 github.tar level 19 advanced streaming 32149 32276
1167 github.tar level 19 with dict advanced streaming 32712
1168 github.tar level 19 with dict dms advanced streaming 32555
1169 github.tar level 19 with dict dds advanced streaming 32555
1194 silesia level 7 old streaming 4566984
1195 silesia level 9 old streaming 4543018
1196 silesia level 13 old streaming 4493990
1197 silesia level 16 old streaming 4359864 4360041
1198 silesia level 19 old streaming 4296438 4296055
1199 silesia no source size old streaming 4842039
1200 silesia uncompressed literals old streaming 4842075
1201 silesia uncompressed literals optimal old streaming 4296438 4296055
1202 silesia huffman literals old streaming 6172207
1203 silesia.tar level -5 old streaming 6856523
1204 silesia.tar level -3 old streaming 6505954
1212 silesia.tar level 7 old streaming 4576664
1213 silesia.tar level 9 old streaming 4552900
1214 silesia.tar level 13 old streaming 4502956
1215 silesia.tar level 16 old streaming 4360527 4360546
1216 silesia.tar level 19 old streaming 4266970 4265911
1217 silesia.tar no source size old streaming 4859267
1218 silesia.tar uncompressed literals old streaming 4859271
1219 silesia.tar uncompressed literals optimal old streaming 4266970 4265911
1220 silesia.tar huffman literals old streaming 6179056
1221 github level -5 old streaming 204407
1222 github level -5 with dict old streaming 46718
1240 github level 7 with dict old streaming 38758
1241 github level 9 old streaming 135122
1242 github level 9 with dict old streaming 39437
1243 github level 13 old streaming 132729 132878
1244 github level 13 with dict old streaming 39900
1245 github level 16 old streaming 132729 133209
1246 github level 16 with dict old streaming 37577
1247 github level 19 old streaming 132729 132879
1248 github level 19 with dict old streaming 37576
1249 github no source size old streaming 140599
1250 github no source size with dict old streaming 40654
1251 github uncompressed literals old streaming 136332
1252 github uncompressed literals optimal old streaming 132729 132879
1253 github huffman literals old streaming 175468
1254 github.tar level -5 old streaming 52152
1255 github.tar level -5 with dict old streaming 51045
1275 github.tar level 9 with dict old streaming 36484
1276 github.tar level 13 old streaming 35501
1277 github.tar level 13 with dict old streaming 37130
1278 github.tar level 16 old streaming 40471 40466
1279 github.tar level 16 with dict old streaming 33374
1280 github.tar level 19 old streaming 32149 32276
1281 github.tar level 19 with dict old streaming 32712
1282 github.tar no source size old streaming 38828
1283 github.tar no source size with dict old streaming 38000
1284 github.tar uncompressed literals old streaming 38831
1285 github.tar uncompressed literals optimal old streaming 32149 32276
1286 github.tar huffman literals old streaming 42560
1287 silesia level -5 old streaming advanced 6854744
1288 silesia level -3 old streaming advanced 6503319
1296 silesia level 7 old streaming advanced 4566984
1297 silesia level 9 old streaming advanced 4543018
1298 silesia level 13 old streaming advanced 4493990
1299 silesia level 16 old streaming advanced 4359864 4360041
1300 silesia level 19 old streaming advanced 4296438 4296055
1301 silesia no source size old streaming advanced 4842039
1302 silesia long distance mode old streaming advanced 4842075
1303 silesia multithreaded old streaming advanced 4842075
1307 silesia small chain log old streaming advanced 4912197
1308 silesia explicit params old streaming advanced 4795452
1309 silesia uncompressed literals old streaming advanced 4842075
1310 silesia uncompressed literals optimal old streaming advanced 4296438 4296055
1311 silesia huffman literals old streaming advanced 6172207
1312 silesia multithreaded with advanced params old streaming advanced 4842075
1313 silesia.tar level -5 old streaming advanced 6856523
1322 silesia.tar level 7 old streaming advanced 4576664
1323 silesia.tar level 9 old streaming advanced 4552900
1324 silesia.tar level 13 old streaming advanced 4502956
1325 silesia.tar level 16 old streaming advanced 4360527 4360546
1326 silesia.tar level 19 old streaming advanced 4266970 4265911
1327 silesia.tar no source size old streaming advanced 4859267
1328 silesia.tar long distance mode old streaming advanced 4859271
1329 silesia.tar multithreaded old streaming advanced 4859271
1330 silesia.tar multithreaded long distance mode old streaming advanced 4859271
1331 silesia.tar small window log old streaming advanced 7117562
1332 silesia.tar small hash log old streaming advanced 6529234 6529209
1333 silesia.tar small chain log old streaming advanced 4917021
1334 silesia.tar explicit params old streaming advanced 4806873
1335 silesia.tar uncompressed literals old streaming advanced 4859271
1336 silesia.tar uncompressed literals optimal old streaming advanced 4266970 4265911
1337 silesia.tar huffman literals old streaming advanced 6179056
1338 silesia.tar multithreaded with advanced params old streaming advanced 4859271
1339 github level -5 old streaming advanced 213265
1360 github level 9 with dict old streaming advanced 38981
1361 github level 13 old streaming advanced 138676
1362 github level 13 with dict old streaming advanced 39725
1363 github level 16 old streaming advanced 138676 138575
1364 github level 16 with dict old streaming advanced 40789
1365 github level 19 old streaming advanced 132729 132879
1366 github level 19 with dict old streaming advanced 37576
1367 github no source size old streaming advanced 140599
1368 github no source size with dict old streaming advanced 40608
1374 github small chain log old streaming advanced 139275
1375 github explicit params old streaming advanced 140937
1376 github uncompressed literals old streaming advanced 141104
1377 github uncompressed literals optimal old streaming advanced 132729 132879
1378 github huffman literals old streaming advanced 181107
1379 github multithreaded with advanced params old streaming advanced 141104
1380 github.tar level -5 old streaming advanced 52152
1401 github.tar level 9 with dict old streaming advanced 36312
1402 github.tar level 13 old streaming advanced 35501
1403 github.tar level 13 with dict old streaming advanced 35807
1404 github.tar level 16 old streaming advanced 40471 40466
1405 github.tar level 16 with dict old streaming advanced 38578
1406 github.tar level 19 old streaming advanced 32149 32276
1407 github.tar level 19 with dict old streaming advanced 32704
1408 github.tar no source size old streaming advanced 38828
1409 github.tar no source size with dict old streaming advanced 38015
1415 github.tar small chain log old streaming advanced 41669
1416 github.tar explicit params old streaming advanced 41385
1417 github.tar uncompressed literals old streaming advanced 38831
1418 github.tar uncompressed literals optimal old streaming advanced 32149 32276
1419 github.tar huffman literals old streaming advanced 42560
1420 github.tar multithreaded with advanced params old streaming advanced 38831
1421 github level -5 with dict old streaming cdict 46718
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+3 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -83,8 +83,8 @@ def valid_copyright(lines):
continue continue
if "present" in line: if "present" in line:
return (False, f"Copyright line '{line}' contains 'present'!") return (False, f"Copyright line '{line}' contains 'present'!")
if "Facebook, Inc" not in line: if "Meta Platforms, Inc" not in line:
return (False, f"Copyright line '{line}' does not contain 'Facebook, Inc'") return (False, f"Copyright line '{line}' does not contain 'Meta Platforms, Inc'")
year = YEAR_REGEX.search(line) year = YEAR_REGEX.search(line)
if year is not None: if year is not None:
return (False, f"Copyright line '{line}' contains {year.group(0)}; it should be yearless") return (False, f"Copyright line '{line}' contains {year.group(0)}; it should be yearless")
+42 -62
View File
@@ -2,7 +2,7 @@
"""Test zstd interoperability between versions""" """Test zstd interoperability between versions"""
# ################################################################ # ################################################################
# Copyright (c) Yann Collet, Facebook, Inc. # Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved. # All rights reserved.
# #
# This source code is licensed under both the BSD-style license (found in the # This source code is licensed under both the BSD-style license (found in the
@@ -23,7 +23,7 @@ from subprocess import Popen, PIPE
repo_url = 'https://github.com/facebook/zstd.git' repo_url = 'https://github.com/facebook/zstd.git'
tmp_dir_name = 'tests/versionsTest' tmp_dir_name = 'tests/versionsTest'
make_cmd = 'make' make_cmd = 'make'
make_args = ['-j','CFLAGS=-O1'] make_args = ['-j','CFLAGS=-O0']
git_cmd = 'git' git_cmd = 'git'
test_dat_src = 'README.md' test_dat_src = 'README.md'
test_dat = 'test_dat' test_dat = 'test_dat'
@@ -86,41 +86,46 @@ def create_dict(tag, dict_source_path):
if result == 0: if result == 0:
print(dict_name + ' created') print(dict_name + ' created')
else: else:
print('ERROR: creating of ' + dict_name + ' failed') raise RuntimeError('ERROR: creating of ' + dict_name + ' failed')
else: else:
print(dict_name + ' already exists') print(dict_name + ' already exists')
def zstd(tag, args, input_file, output_file):
"""
Zstd compress input_file to output_file.
Need this helper because 0.5.0 is broken when stdout is not a TTY.
Throws an exception if the command returns non-zero.
"""
with open(input_file, "rb") as i:
with open(output_file, "wb") as o:
cmd = ['./zstd.' + tag] + args
print("Running: '{}', input={}, output={}" .format(
' '.join(cmd), input_file, output_file
))
subprocess.check_call(cmd, stdin=i, stdout=o)
def dict_compress_sample(tag, sample): def dict_compress_sample(tag, sample):
dict_name = 'dict.' + tag dict_name = 'dict.' + tag
DEVNULL = open(os.devnull, 'wb') zstd(tag, ['-D', dict_name, '-1'], sample, sample + '_01_64_' + tag + '_dictio.zst')
if subprocess.call(['./zstd.' + tag, '-D', dict_name, '-f', sample], stderr=DEVNULL) == 0: zstd(tag, ['-D', dict_name, '-3'], sample, sample + '_03_64_' + tag + '_dictio.zst')
os.rename(sample + '.zst', sample + '_01_64_' + tag + '_dictio.zst') zstd(tag, ['-D', dict_name, '-5'], sample, sample + '_05_64_' + tag + '_dictio.zst')
if subprocess.call(['./zstd.' + tag, '-D', dict_name, '-5f', sample], stderr=DEVNULL) == 0: zstd(tag, ['-D', dict_name, '-9'], sample, sample + '_09_64_' + tag + '_dictio.zst')
os.rename(sample + '.zst', sample + '_05_64_' + tag + '_dictio.zst') zstd(tag, ['-D', dict_name, '-15'], sample, sample + '_15_64_' + tag + '_dictio.zst')
if subprocess.call(['./zstd.' + tag, '-D', dict_name, '-9f', sample], stderr=DEVNULL) == 0: zstd(tag, ['-D', dict_name, '-18'], sample, sample + '_18_64_' + tag + '_dictio.zst')
os.rename(sample + '.zst', sample + '_09_64_' + tag + '_dictio.zst')
if subprocess.call(['./zstd.' + tag, '-D', dict_name, '-15f', sample], stderr=DEVNULL) == 0:
os.rename(sample + '.zst', sample + '_15_64_' + tag + '_dictio.zst')
if subprocess.call(['./zstd.' + tag, '-D', dict_name, '-18f', sample], stderr=DEVNULL) == 0:
os.rename(sample + '.zst', sample + '_18_64_' + tag + '_dictio.zst')
# zstdFiles = glob.glob("*.zst*") # zstdFiles = glob.glob("*.zst*")
# print(zstdFiles) # print(zstdFiles)
print(tag + " : dict compression completed") print(tag + " : dict compression completed")
def compress_sample(tag, sample): def compress_sample(tag, sample):
DEVNULL = open(os.devnull, 'wb') zstd(tag, ['-1'], sample, sample + '_01_64_' + tag + '_nodict.zst')
if subprocess.call(['./zstd.' + tag, '-f', sample], stderr=DEVNULL) == 0: zstd(tag, ['-3'], sample, sample + '_03_64_' + tag + '_nodict.zst')
os.rename(sample + '.zst', sample + '_01_64_' + tag + '_nodict.zst') zstd(tag, ['-5'], sample, sample + '_05_64_' + tag + '_nodict.zst')
if subprocess.call(['./zstd.' + tag, '-5f', sample], stderr=DEVNULL) == 0: zstd(tag, ['-9'], sample, sample + '_09_64_' + tag + '_nodict.zst')
os.rename(sample + '.zst', sample + '_05_64_' + tag + '_nodict.zst') zstd(tag, ['-15'], sample, sample + '_15_64_' + tag + '_nodict.zst')
if subprocess.call(['./zstd.' + tag, '-9f', sample], stderr=DEVNULL) == 0: zstd(tag, ['-18'], sample, sample + '_18_64_' + tag + '_nodict.zst')
os.rename(sample + '.zst', sample + '_09_64_' + tag + '_nodict.zst')
if subprocess.call(['./zstd.' + tag, '-15f', sample], stderr=DEVNULL) == 0:
os.rename(sample + '.zst', sample + '_15_64_' + tag + '_nodict.zst')
if subprocess.call(['./zstd.' + tag, '-18f', sample], stderr=DEVNULL) == 0:
os.rename(sample + '.zst', sample + '_18_64_' + tag + '_nodict.zst')
# zstdFiles = glob.glob("*.zst*") # zstdFiles = glob.glob("*.zst*")
# print(zstdFiles) # print(zstdFiles)
print(tag + " : compression completed") print(tag + " : compression completed")
@@ -150,23 +155,13 @@ def decompress_zst(tag):
dec_error = 0 dec_error = 0
list_zst = sorted(glob.glob('*_nodict.zst')) list_zst = sorted(glob.glob('*_nodict.zst'))
for file_zst in list_zst: for file_zst in list_zst:
print(file_zst, end=' ') print(file_zst + ' ' + tag)
print(tag, end=' ')
file_dec = file_zst + '_d64_' + tag + '.dec' file_dec = file_zst + '_d64_' + tag + '.dec'
if tag <= 'v0.5.0': zstd(tag, ['-d'], file_zst, file_dec)
params = ['./zstd.' + tag, '-df', file_zst, file_dec] if not filecmp.cmp(file_dec, test_dat):
raise RuntimeError('Decompression failed: tag={} file={}'.format(tag, file_zst))
else: else:
params = ['./zstd.' + tag, '-df', file_zst, '-o', file_dec] print('OK ')
if execute(params) == 0:
if not filecmp.cmp(file_dec, test_dat):
print('ERR !! ')
dec_error = 1
else:
print('OK ')
else:
print('command does not work')
dec_error = 1
return dec_error
def decompress_dict(tag): def decompress_dict(tag):
@@ -181,22 +176,13 @@ def decompress_dict(tag):
if tag == 'v0.6.0' and dict_tag < 'v0.6.0': if tag == 'v0.6.0' and dict_tag < 'v0.6.0':
continue continue
dict_name = 'dict.' + dict_tag dict_name = 'dict.' + dict_tag
print(file_zst + ' ' + tag + ' dict=' + dict_tag, end=' ') print(file_zst + ' ' + tag + ' dict=' + dict_tag)
file_dec = file_zst + '_d64_' + tag + '.dec' file_dec = file_zst + '_d64_' + tag + '.dec'
if tag <= 'v0.5.0': zstd(tag, ['-D', dict_name, '-d'], file_zst, file_dec)
params = ['./zstd.' + tag, '-D', dict_name, '-df', file_zst, file_dec] if not filecmp.cmp(file_dec, test_dat):
raise RuntimeError('Decompression failed: tag={} file={}'.format(tag, file_zst))
else: else:
params = ['./zstd.' + tag, '-D', dict_name, '-df', file_zst, '-o', file_dec] print('OK ')
if execute(params) == 0:
if not filecmp.cmp(file_dec, test_dat):
print('ERR !! ')
dec_error = 1
else:
print('OK ')
else:
print('command does not work')
dec_error = 1
return dec_error
if __name__ == '__main__': if __name__ == '__main__':
@@ -267,25 +253,19 @@ if __name__ == '__main__':
print('Compress test.dat by all released zstd') print('Compress test.dat by all released zstd')
print('-----------------------------------------------') print('-----------------------------------------------')
error_code = 0
for tag in tags: for tag in tags:
print(tag) print(tag)
if tag >= 'v0.5.0': if tag >= 'v0.5.0':
create_dict(tag, dict_source_path) create_dict(tag, dict_source_path)
dict_compress_sample(tag, test_dat) dict_compress_sample(tag, test_dat)
remove_duplicates() remove_duplicates()
error_code += decompress_dict(tag) decompress_dict(tag)
compress_sample(tag, test_dat) compress_sample(tag, test_dat)
remove_duplicates() remove_duplicates()
error_code += decompress_zst(tag) decompress_zst(tag)
print('') print('')
print('Enumerate different compressed files') print('Enumerate different compressed files')
zstds = sorted(glob.glob('*.zst')) zstds = sorted(glob.glob('*.zst'))
for zstd in zstds: for zstd in zstds:
print(zstd + ' : ' + repr(os.path.getsize(zstd)) + ', ' + sha1_of_file(zstd)) print(zstd + ' : ' + repr(os.path.getsize(zstd)) + ', ' + sha1_of_file(zstd))
if error_code != 0:
print('====== ERROR !!! =======')
sys.exit(error_code)
+93 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -39,7 +39,7 @@
#include "seqgen.h" #include "seqgen.h"
#include "util.h" #include "util.h"
#include "timefn.h" /* UTIL_time_t, UTIL_clockSpanMicro, UTIL_getTime */ #include "timefn.h" /* UTIL_time_t, UTIL_clockSpanMicro, UTIL_getTime */
#include "external_matchfinder.h" /* zstreamExternalMatchFinder, EMF_testCase */
/*-************************************ /*-************************************
* Constants * Constants
@@ -1834,6 +1834,97 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests)
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : External matchfinder API: ", testNb++);
{
size_t const dstBufSize = ZSTD_compressBound(CNBufferSize);
BYTE* const dstBuf = (BYTE*)malloc(ZSTD_compressBound(dstBufSize));
size_t const checkBufSize = CNBufferSize;
BYTE* const checkBuf = (BYTE*)malloc(checkBufSize);
int enableFallback;
EMF_testCase externalMatchState;
CHECK(dstBuf == NULL || checkBuf == NULL, "allocation failed");
ZSTD_CCtx_reset(zc, ZSTD_reset_session_and_parameters);
/* Reference external matchfinder outside the test loop to
* check that the reference is preserved across compressions */
ZSTD_registerExternalMatchFinder(
zc,
&externalMatchState,
zstreamExternalMatchFinder
);
for (enableFallback = 0; enableFallback < 1; enableFallback++) {
size_t testCaseId;
EMF_testCase const EMF_successCases[] = {
EMF_ONE_BIG_SEQ,
EMF_LOTS_OF_SEQS,
};
size_t const EMF_numSuccessCases = 2;
EMF_testCase const EMF_failureCases[] = {
EMF_ZERO_SEQS,
EMF_BIG_ERROR,
EMF_SMALL_ERROR,
};
size_t const EMF_numFailureCases = 3;
/* Test external matchfinder success scenarios */
for (testCaseId = 0; testCaseId < EMF_numSuccessCases; testCaseId++) {
size_t res;
externalMatchState = EMF_successCases[testCaseId];
ZSTD_CCtx_reset(zc, ZSTD_reset_session_only);
CHECK_Z(ZSTD_CCtx_setParameter(zc, ZSTD_c_enableMatchFinderFallback, enableFallback));
res = ZSTD_compress2(zc, dstBuf, dstBufSize, CNBuffer, CNBufferSize);
CHECK(ZSTD_isError(res), "EMF: Compression error: %s", ZSTD_getErrorName(res));
CHECK_Z(ZSTD_decompress(checkBuf, checkBufSize, dstBuf, res));
CHECK(memcmp(CNBuffer, checkBuf, CNBufferSize) != 0, "EMF: Corruption!");
}
/* Test external matchfinder failure scenarios */
for (testCaseId = 0; testCaseId < EMF_numFailureCases; testCaseId++) {
size_t res;
externalMatchState = EMF_failureCases[testCaseId];
ZSTD_CCtx_reset(zc, ZSTD_reset_session_only);
CHECK_Z(ZSTD_CCtx_setParameter(zc, ZSTD_c_enableMatchFinderFallback, enableFallback));
res = ZSTD_compress2(zc, dstBuf, dstBufSize, CNBuffer, CNBufferSize);
if (enableFallback) {
CHECK_Z(ZSTD_decompress(checkBuf, checkBufSize, dstBuf, res));
CHECK(memcmp(CNBuffer, checkBuf, CNBufferSize) != 0, "EMF: Corruption!");
} else {
CHECK(!ZSTD_isError(res), "EMF: Should have raised an error!");
CHECK(
ZSTD_getErrorCode(res) != ZSTD_error_externalMatchFinder_failed,
"EMF: Wrong error code: %s", ZSTD_getErrorName(res)
);
}
}
/* Test compression with external matchfinder + empty src buffer */
{
size_t res;
externalMatchState = EMF_ZERO_SEQS;
ZSTD_CCtx_reset(zc, ZSTD_reset_session_only);
CHECK_Z(ZSTD_CCtx_setParameter(zc, ZSTD_c_enableMatchFinderFallback, enableFallback));
res = ZSTD_compress2(zc, dstBuf, dstBufSize, CNBuffer, 0);
CHECK(ZSTD_isError(res), "EMF: Compression error: %s", ZSTD_getErrorName(res));
CHECK(ZSTD_decompress(checkBuf, checkBufSize, dstBuf, res) != 0, "EMF: Empty src round trip failed!");
}
}
/* Test that reset clears the external matchfinder */
ZSTD_CCtx_reset(zc, ZSTD_reset_session_and_parameters);
externalMatchState = EMF_BIG_ERROR; /* ensure zstd will fail if the matchfinder wasn't cleared */
CHECK_Z(ZSTD_CCtx_setParameter(zc, ZSTD_c_enableMatchFinderFallback, 0));
CHECK_Z(ZSTD_compress2(zc, dstBuf, dstBufSize, CNBuffer, CNBufferSize));
free(dstBuf);
free(checkBuf);
}
DISPLAYLEVEL(3, "OK \n");
_end: _end:
FUZ_freeDictionary(dictionary); FUZ_freeDictionary(dictionary);
ZSTD_freeCStream(zc); ZSTD_freeCStream(zc);
+6 -6
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
@@ -388,7 +388,7 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
markNb = (markNb+1) % NB_MARKS; markNb = (markNb+1) % NB_MARKS;
DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s\r", DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s\r",
marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratio, marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratio,
(double)srcSize / fastestC ); (double)srcSize / (double)fastestC );
(void)fastestD; (void)crcOrig; /* unused when decompression disabled */ (void)fastestD; (void)crcOrig; /* unused when decompression disabled */
#if 1 #if 1
@@ -527,8 +527,8 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
markNb = (markNb+1) % NB_MARKS; markNb = (markNb+1) % NB_MARKS;
DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s ,%6.1f MB/s\r", DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.3f),%6.1f MB/s ,%6.1f MB/s\r",
marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratio, marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratio,
(double)srcSize / fastestC, (double)srcSize / (double)fastestC,
(double)srcSize / fastestD ); (double)srcSize / (double)fastestD );
/* CRC Checking */ /* CRC Checking */
{ U64 const crcCheck = XXH64(resultBuffer, srcSize, 0); { U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
@@ -558,8 +558,8 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
} /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */ } /* for (testNb = 1; testNb <= (g_nbIterations + !g_nbIterations); testNb++) */
if (g_displayLevel == 1) { if (g_displayLevel == 1) {
double cSpeed = (double)srcSize / fastestC; double cSpeed = (double)srcSize / (double)fastestC;
double dSpeed = (double)srcSize / fastestD; double dSpeed = (double)srcSize / (double)fastestD;
if (g_additionalParam) if (g_additionalParam)
DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, g_additionalParam); DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, g_additionalParam);
else else
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc. * Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved. * All rights reserved.
* *
* This source code is licensed under both the BSD-style license (found in the * This source code is licensed under both the BSD-style license (found in the