Compare commits

..

11 Commits
dev ... v1.5.6

Author SHA1 Message Date
Yann Collet
794ea1b0af
Merge pull request #3984 from facebook/dev
v1.5.6
2024-03-21 15:05:51 -07:00
Yann Collet
63779c7982
Merge pull request #3595 from facebook/dev
v1.5.5 last changes
2023-04-04 13:13:52 -07:00
Yann Collet
d507e02940
Merge pull request #3590 from facebook/dev
v1.5.5
2023-04-03 14:38:22 -07:00
Yann Collet
73e19c4cf1
Merge pull request #3585 from facebook/dev
Preparation for release v1.5.5
2023-04-01 18:06:35 -07:00
Yann Collet
945f27758c
Merge pull request #3487 from facebook/dev
release v1.5.4
2023-02-09 16:41:50 -08:00
Felix Handte
e47e674cd0
Merge pull request #2995 from facebook/v1.5.2-rc
Zstandard v1.5.2
2022-01-20 16:17:18 -05:00
Yann Collet
791626dfb9
Merge pull request #2942 from facebook/dev
update man pages for v1.5.1
2021-12-20 14:49:18 -08:00
Yann Collet
f4a541b021
Merge pull request #2941 from facebook/dev
v1.5.1
2021-12-20 13:49:33 -08:00
sen
a488ba114e
Zstd 1.5.0 Release
Zstd 1.5.0 Release
2021-05-14 10:59:34 -04:00
Felix Handte
e4558ffd1d
Merge pull request #2515 from facebook/dev
ZStandard v1.4.9
2021-03-02 17:20:57 -05:00
Yann Collet
97a3da1df0
Merge pull request #2435 from facebook/dev
v1.4.8 hotfix
2020-12-18 16:39:42 -08:00
219 changed files with 4768 additions and 10062 deletions

123
.circleci/config.yml Normal file
View File

@ -0,0 +1,123 @@
version: 2
jobs:
# the first half of the jobs are in this test
short-tests-0:
# TODO: Create a small custom docker image with all the dependencies we need
# preinstalled to reduce installation time.
docker:
- image: fbopensource/zstd-circleci-primary:0.0.1
steps:
- checkout
- run:
name: Test
command: |
./tests/test-license.py
cc -v
CFLAGS="-O0 -Werror -pedantic" make allmost; make clean
make c99build; make clean
make c11build; make clean
make -j regressiontest; make clean
make shortest; make clean
make cxxtest; make clean
# the second half of the jobs are in this test
short-tests-1:
docker:
- image: fbopensource/zstd-circleci-primary:0.0.1
steps:
- checkout
- run:
name: Test
command: |
make gnu90build; make clean
make gnu99build; make clean
make ppc64build V=1; make clean
make ppcbuild V=1; make clean
make armbuild V=1; make clean
make aarch64build V=1; make clean
make -C tests test-legacy test-longmatch; make clean
make -C lib libzstd-nomt; make clean
# This step should only be run in a cron job
regression-test:
docker:
- image: fbopensource/zstd-circleci-primary:0.0.1
environment:
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
steps:
- checkout
# Restore the cached resources.
- restore_cache:
# We try our best to bust the cache when the data changes by hashing
# data.c. If that doesn't work, simply update the version number here
# and below. If we fail to bust the cache, the regression testing will
# still work, since it has its own stamp, but will need to redownload
# everything.
keys:
- regression-cache-{{ checksum "tests/regression/data.c" }}-v0
- run:
name: Regression Test
command: |
make -C programs zstd
make -C tests/regression test
mkdir -p $CIRCLE_ARTIFACTS
./tests/regression/test \
--cache tests/regression/cache \
--output $CIRCLE_ARTIFACTS/results.csv \
--zstd programs/zstd
echo "NOTE: The new results.csv is uploaded as an artifact to this job"
echo " If this fails, go to the Artifacts pane in CircleCI, "
echo " download /tmp/circleci-artifacts/results.csv, and if they "
echo " are still good, copy it into the repo and commit it."
echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv"
diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv
# Only save the cache on success (default), since if the failure happened
# before we stamp the data cache, we will have a bad cache for this key.
- save_cache:
key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0
paths:
- tests/regression/cache
- store_artifacts:
path: /tmp/circleci-artifacts
workflows:
version: 2
commit:
jobs:
# Run the tests in parallel
- short-tests-0
- short-tests-1
- regression-test
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- release
- dev
- master
jobs:
# Run daily regression tests
- regression-test
# Longer tests
#- make -C tests test-zstd-nolegacy && make clean
#- pyenv global 3.4.4; make -C tests versionsTest && make clean
#- make zlibwrapper && make clean
#- gcc -v; make -C tests test32 MOREFLAGS="-I/usr/include/x86_64-linux-gnu" && make clean
#- make uasan && make clean
#- make asan32 && make clean
#- make -C tests test32 CC=clang MOREFLAGS="-g -fsanitize=address -I/usr/include/x86_64-linux-gnu"
# Valgrind tests
#- CFLAGS="-O1 -g" make -C zlibWrapper valgrindTest && make clean
#- make -C tests valgrindTest && make clean
# ARM, AArch64, PowerPC, PowerPC64 tests
#- make ppctest && make clean
#- make ppc64test && make clean
#- make armtest && make clean
#- make aarch64test && make clean

View File

@ -0,0 +1,9 @@
FROM circleci/buildpack-deps@sha256:f6f10c11b7b8ccfd4f4a5b830c3256803604ce61292b60cb22e26b12f62b0e8c
RUN sudo dpkg --add-architecture i386
RUN sudo apt-get -y -qq update
RUN sudo apt-get -y install \
gcc-multilib-powerpc-linux-gnu gcc-arm-linux-gnueabi \
libc6-dev-armel-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
libc6-dev-ppc64-powerpc-cross zstd gzip coreutils \
libcurl4-openssl-dev

View File

@ -1,9 +1,10 @@
task: task:
name: FreeBSD (make check) name: FreeBSD (shortest)
freebsd_instance: freebsd_instance:
matrix: matrix:
image_family: freebsd-14-2 image_family: freebsd-14-0
image_family: freebsd-13-2
install_script: pkg install -y gmake coreutils install_script: pkg install -y gmake coreutils
script: | script: |
MOREFLAGS="-Werror" gmake -j all MOREFLAGS="-Werror" gmake -j all
gmake check gmake shortest

View File

@ -1,39 +0,0 @@
name: Android NDK Build
on:
pull_request:
branches: [ dev, release, actionsTest ]
push:
branches: [ actionsTest, '*ndk*' ]
permissions: read-all
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Set up JDK 17
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Android SDK
uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2
- name: Install Android NDK
run: |
sdkmanager --install "ndk;27.0.12077973"
echo "ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/27.0.12077973" >> $GITHUB_ENV
- name: Build with NDK
run: |
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
make CC=aarch64-linux-android21-clang \
AR=llvm-ar \
RANLIB=llvm-ranlib \
STRIP=llvm-strip

View File

@ -1,153 +0,0 @@
name: cmake-tests
# CMake-specific build and test workflows
# This workflow validates zstd builds across different CMake configurations,
# platforms, and edge cases to ensure broad compatibility.
concurrency:
group: cmake-${{ github.ref }}
cancel-in-progress: true
on:
pull_request:
branches: [ dev, release, actionsTest ]
permissions: read-all
env:
# Centralized test timeouts for consistency
QUICK_TEST_TIME: "30s"
STANDARD_TEST_TIME: "1mn"
# Common CMake flags
COMMON_CMAKE_FLAGS: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DZSTD_BUILD_TESTS=ON"
jobs:
# Ubuntu-based cmake build using make wrapper
# This test uses the make-driven cmake build to ensure compatibility
# with the existing build system integration
cmake-ubuntu-basic:
name: "CMake Ubuntu Basic Build"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Install dependencies
run: |
sudo apt install liblzma-dev # Required for compression algorithms
- name: CMake build and test via make
run: |
# Use make wrapper for cmake build with quick test timeouts
FUZZERTEST=-T${{ env.STANDARD_TEST_TIME }} ZSTREAM_TESTTIME=-T${{ env.STANDARD_TEST_TIME }} make cmakebuild V=1
# Cross-platform cmake build with edge case: source paths containing spaces
# This test ensures cmake handles filesystem paths with spaces correctly
# across different operating systems and build generators
cmake-cross-platform-spaces:
name: "CMake Cross-Platform (Spaces in Path)"
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
generator: "Unix Makefiles"
name: "Linux"
- os: windows-latest
generator: "NMake Makefiles"
name: "Windows NMake"
- os: macos-latest
generator: "Unix Makefiles"
name: "macOS"
env:
SRC_DIR: "source directory with spaces"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
with:
path: "${{ env.SRC_DIR }}"
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
if: ${{ matrix.generator == 'NMake Makefiles' }}
- name: "CMake build and install (${{ matrix.name }})"
run: |
# Test Release build with installation to verify packaging
cmake -S "${{ env.SRC_DIR }}/build/cmake" -B build -DBUILD_TESTING=ON -G "${{ matrix.generator }}" -DCMAKE_BUILD_TYPE=Release --install-prefix "${{ runner.temp }}/install"
cmake --build build --config Release
cmake --install build --config Release
# Windows-specific cmake testing with Visual Studio 2022
# Tests multiple generators and toolchains to ensure broad Windows compatibility
# including MSVC (x64, Win32, ARM64), MinGW, and Clang-CL with various architectures and optimizations
cmake-windows-comprehensive:
name: "CMake Windows VS2022 (${{ matrix.name }})"
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- generator: "Visual Studio 17 2022"
flags: "-A x64"
name: "MSVC x64"
runner: "windows-2022"
cmake_extra_flags: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DZSTD_BUILD_TESTS=ON"
- generator: "Visual Studio 17 2022"
flags: "-A Win32"
name: "MSVC Win32"
runner: "windows-2022"
cmake_extra_flags: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DZSTD_BUILD_TESTS=ON"
- generator: "Visual Studio 17 2022"
flags: "-A x64"
name: "MSVC x64 (No ZSTD_BUILD_TESTS)"
runner: "windows-2022"
# Intentionally omit ZSTD_BUILD_TESTS to reproduce the CXX language configuration bug
cmake_extra_flags: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON"
# - generator: "Visual Studio 17 2022"
# flags: "-A ARM64"
# name: "MSVC ARM64"
# runner: "windows-2022-arm64" # Disabled due to very long queue times
- generator: "MinGW Makefiles"
flags: ""
name: "MinGW"
runner: "windows-2022"
cmake_extra_flags: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DZSTD_BUILD_TESTS=ON"
- generator: "Visual Studio 17 2022"
flags: "-T ClangCL"
name: "Clang-CL"
runner: "windows-2022"
cmake_extra_flags: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DZSTD_BUILD_TESTS=ON"
- generator: "Visual Studio 17 2022"
flags: "-T ClangCL -A x64 -DCMAKE_C_FLAGS=/arch:AVX2"
name: "Clang-CL AVX2"
runner: "windows-2022"
cmake_extra_flags: "-DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DZSTD_BUILD_TESTS=ON"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0
- name: "Configure CMake (${{ matrix.name }})"
run: |
cd build\cmake
mkdir build
cd build
cmake.exe -G "${{matrix.generator}}" ${{matrix.flags}} -DCMAKE_BUILD_TYPE=Debug ${{ matrix.cmake_extra_flags }} -DZSTD_ZSTREAM_FLAGS=-T${{ env.QUICK_TEST_TIME }} -DZSTD_FUZZER_FLAGS=-T${{ env.QUICK_TEST_TIME }} -DZSTD_FULLBENCH_FLAGS=-i0 ..
- name: "Build (${{ matrix.name }})"
run: |
cd build\cmake\build
cmake.exe --build .
- name: "Test (${{ matrix.name }})"
run: |
cd build\cmake\build
ctest.exe -V -C Debug
# macOS ARM64 (Apple Silicon) specific cmake testing
# Validates zstd builds and runs correctly on Apple Silicon architecture
# Uses native ARM64 hardware for optimal performance and compatibility testing
cmake-macos-arm64:
name: "CMake macOS ARM64 (Apple Silicon)"
runs-on: macos-14 # ARM64 runner
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: "CMake build and test (ARM64)"
run: |
# Configure and build with ARM64-specific optimizations
cd build/cmake
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ${{ env.COMMON_CMAKE_FLAGS }} -DZSTD_ZSTREAM_FLAGS=-T${{ env.QUICK_TEST_TIME }} -DZSTD_FUZZER_FLAGS=-T${{ env.QUICK_TEST_TIME }} -DZSTD_FULLBENCH_FLAGS=-i1 ..
make -j$(sysctl -n hw.ncpu)
ctest -V

View File

@ -3,12 +3,7 @@ on:
push: push:
branches: branches:
- dev - dev
pull_request:
branches:
- dev
permissions: read-all permissions: read-all
jobs: jobs:
short-tests-0: short-tests-0:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -30,9 +25,8 @@ jobs:
make c99build; make clean make c99build; make clean
make c11build; make clean make c11build; make clean
make -j regressiontest; make clean make -j regressiontest; make clean
make check; make clean make shortest; make clean
make cxxtest; make clean make cxxtest; make clean
short-tests-1: short-tests-1:
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
@ -44,26 +38,17 @@ jobs:
- name: Install Dependencies - name: Install Dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install gcc-powerpc-linux-gnu gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu libc6-dev-ppc64-powerpc-cross libcurl4-gnutls-dev lib64gcc-13-dev-powerpc-cross sudo apt-get install gcc-powerpc-linux-gnu gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu libc6-dev-ppc64-powerpc-cross libcurl4-gnutls-dev lib64gcc-11-dev-powerpc-cross
- name: gnu90 build - name: Test
run: make gnu90build && make clean run: |-
- name: gnu99 build make gnu90build; make clean
run: make gnu99build && make clean make gnu99build; make clean
- name: ppc64 build make ppc64build V=1; make clean
run: make ppc64build V=1 && make clean make ppcbuild V=1; make clean
- name: ppc build make armbuild V=1; make clean
run: make ppcbuild V=1 && make clean make aarch64build V=1; make clean
- name: arm build make -C tests test-legacy test-longmatch; make clean
run: make armbuild V=1 && make clean make -C lib libzstd-nomt; make clean
- name: aarch64 build
run: make aarch64build V=1 && make clean
- name: test-legacy
run: make -C tests test-legacy V=1 && make clean
- name: test-longmatch
run: make -C tests test-longmatch V=1 && make clean
- name: libzstd-nomt build
run: make -C lib libzstd-nomt V=1 && make clean
regression-test: regression-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:

View File

@ -1,5 +1,5 @@
name: dev-long-tests name: dev-long-tests
# Tests generally longer than 10mn # Tests longer than 10mn
concurrency: concurrency:
group: long-${{ github.ref }} group: long-${{ github.ref }}
@ -12,106 +12,91 @@ on:
permissions: read-all permissions: read-all
jobs: jobs:
# lasts ~7mn
make-all: make-all:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: make all - name: make all
run: make all run: make all
# lasts ~19mn # lasts ~24mn
make-test: make-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
DEVNULLRIGHTS: 1 DEVNULLRIGHTS: 1
READFROMBLOCKDEVICE: 1 READFROMBLOCKDEVICE: 1
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: make test - name: make test
run: |
make test
make -j zstd
./tests/test_process_substitution.bash ./zstd
# lasts ~16mn
make-test-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: make test on macos
run: make test run: make test
# lasts ~10mn # lasts ~26mn
make-test-osx:
runs-on: macos-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: OS-X test
run: make test # make -c lib all doesn't work because of the fact that it's not a tty
# lasts ~24mn
make-test-32bit: make-test-32bit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
DEVNULLRIGHTS: 1 DEVNULLRIGHTS: 1
READFROMBLOCKDEVICE: 1 READFROMBLOCKDEVICE: 1
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: make test # note: `make -j test success` seems to require a clean state - name: make test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
make libc6install make libc6install
make clean CFLAGS="-m32" make test
CFLAGS="-m32 -O2" make -j test V=1
# lasts ~7mn
test-largeDictionary:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: largeDictionary
run: |
CFLAGS="-Werror -O3" make -j -C tests test-largeDictionary
# lasts ~9mn
no-intrinsics-fuzztest: no-intrinsics-fuzztest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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
# lasts ~8mn
tsan-zstreamtest: tsan-zstreamtest:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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
uasan-zstreamtest: ubsan-zstreamtest:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: ub + address sanitizer on zstreamtest - name: undefined behavior sanitizer zstreamtest
run: CC=clang make uasan-test-zstream run: CC=clang make uasan-test-zstream
# lasts ~11mn # lasts ~15mn
tsan-fuzztest: tsan-fuzztest:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: thread sanitizer fuzztest - name: thread sanitizer fuzztest
run: CC=clang make tsan-fuzztest run: CC=clang make tsan-fuzztest
big-tests-zstreamtest32: big-tests-zstreamtest32:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: zstream tests in 32bit mode, with big tests - name: zstream tests in 32bit mode, with big tests
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
make libc6install make libc6install
CC=clang make -C tests test-zstream32 FUZZER_FLAGS="--big-tests" CC=clang make -C tests test-zstream32 FUZZER_FLAGS="--big-tests"
# lasts ~13mn # lasts ~23mn
gcc-8-asan-ubsan-testzstd: gcc-8-asan-ubsan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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: |
@ -121,16 +106,16 @@ jobs:
CC=gcc-8 make -j uasan-test-zstd </dev/null V=1 CC=gcc-8 make -j uasan-test-zstd </dev/null V=1
clang-asan-ubsan-testzstd: clang-asan-ubsan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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
@ -142,9 +127,9 @@ jobs:
# so any data coming from these libraries is always considered "uninitialized" # so any data coming from these libraries is always considered "uninitialized"
gcc-8-asan-ubsan-fuzz: gcc-8-asan-ubsan-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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: |
@ -154,72 +139,57 @@ jobs:
CC=gcc-8 FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest CC=gcc-8 FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest
clang-asan-ubsan-fuzz: clang-asan-ubsan-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: ASan + UBSan + Fuzz Test 32bit - name: ASan + UBSan + Fuzz Test 32bit
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
make libc6install make libc6install
CFLAGS="-O3 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest CFLAGS="-O3 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest
clang-asan-fuzz32: clang-asan-ubsan-fuzz32:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: clang + ASan + Fuzz Test 32bit - name: clang + ASan + UBSan + Fuzz Test 32bit
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
make libc6install make libc6install
CC=clang CFLAGS="-O3 -m32" FUZZER_FLAGS="--long-tests" make asan-fuzztest CC=clang CFLAGS="-O3 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest
# The following test seems to have issues on github CI specifically,
# it does not provide the `__mulodi4` instruction emulation
# required for signed 64-bit multiplication.
# Replaced by asan-only test (above)
#
# clang-asan-ubsan-fuzz32:
# runs-on: ubuntu-20.04
# steps:
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
# - name: clang + ASan + UBSan + Fuzz Test 32bit
# run: |
# sudo apt-get -qqq update
# make libc6install
# CC=clang CFLAGS="-O3 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest
asan-ubsan-regression: asan-ubsan-regression:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: ASan + UBSan + Regression Test - name: ASan + UBSan + Regression Test
run: make -j uasanregressiontest run: make -j uasanregressiontest
clang-asan-ubsan-regression: clang-ubsan-regression:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: MSan + Regression Test - name: MSan + Regression Test
run: make -j msanregressiontest run: make -j msanregressiontest
clang-msan-fuzz-unoptimized: clang-msan-fuzz-unoptimized:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: clang + MSan + Fuzz Test - name: clang + MSan + Fuzz Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@ -227,27 +197,30 @@ jobs:
CC=clang MOREFLAGS="-O0" make clean msan-fuzztest CC=clang MOREFLAGS="-O0" make clean msan-fuzztest
clang-msan-fuzz: clang-msan-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: clang + MSan + Fuzz Test - name: clang + MSan + Fuzz Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
sudo apt-get install clang sudo apt-get install clang
CC=clang FUZZER_FLAGS="--long-tests" make clean msan-fuzztest CC=clang FUZZER_FLAGS="--long-tests" make clean msan-fuzztest
# lasts ~24mn
clang-msan-testzstd: clang-msan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: clang + MSan + Test Zstd - name: clang + MSan + Test Zstd
run: | run: |
CC=clang make -j msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0 V=1 sudo apt-get update
sudo apt-get install clang
CC=clang make msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0 V=1
armfuzz: armfuzz:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Qemu ARM emulation + Fuzz Test - name: Qemu ARM emulation + Fuzz Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@ -257,7 +230,7 @@ jobs:
valgrind-fuzz-test: valgrind-fuzz-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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: |
@ -273,8 +246,8 @@ jobs:
run: run:
shell: msys2 {0} shell: msys2 {0}
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- uses: msys2/setup-msys2@40677d36a502eb2cf0fb808cc9dec31bf6152638 # tag=v2.28.0 - uses: msys2/setup-msys2@cc11e9188b693c2b100158c3322424c4cc1dadea # tag=v2.22.0
with: with:
msystem: MINGW64 msystem: MINGW64
install: make install: make
@ -296,7 +269,7 @@ jobs:
# lasts ~20mn # lasts ~20mn
oss-fuzz: oss-fuzz:
runs-on: ubuntu-latest runs-on: ubuntu-20.04
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@ -16,40 +16,51 @@ jobs:
linux-kernel: linux-kernel:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: make check on 32-bit - name: make check on 32-bit
run: | run: |
sudo apt update sudo apt update
APT_PACKAGES="gcc-multilib" make apt-install APT_PACKAGES="gcc-multilib" make apt-install
CFLAGS="-m32 -O1 -fstack-protector" make check V=1 CFLAGS="-m32 -O1 -fstack-protector" make check V=1
CFLAGS="-m32 -O1 -fstack-protector" make V=1 -C tests test-cli-tests
check-x32:
runs-on: ubuntu-20.04 # ubuntu-latest == ubuntu-22.04 have issues currently with x32
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: make check on x32 ABI # https://en.wikipedia.org/wiki/X32_ABI
env:
CHECK_CONSTRAINED_MEM: true
run: |
sudo apt update
APT_PACKAGES="gcc-multilib" make apt-install
CFLAGS="-mx32 -O1 -fstack-protector" make check V=1
build-c89: build-c89:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: ensure zstd can be built with c89/c90 compilers (+ long long support + variadic macros) - name: ensure zstd can be build with c89/c90 compilers (+ long long support + variadic macros)
run: | run: |
make c89build V=1 make c89build V=1
build-zstd-dll: build-zstd-dll:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: build zstd bin against a dynamic lib (debuglevel for more dependencies) - name: build zstd bin against a dynamic lib (debuglevel for more dependencies)
run: | run: |
make -C lib lib-mt-release make -C lib lib-mt-release
@ -58,7 +69,7 @@ jobs:
gcc-7-libzstd: gcc-7-libzstd:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: gcc-7 + libzstdmt compilation - name: gcc-7 + libzstdmt compilation
# See https://askubuntu.com/a/1428822 # See https://askubuntu.com/a/1428822
run: | run: |
@ -72,10 +83,18 @@ jobs:
# candidate test (for discussion) : underlink test # candidate test (for discussion) : underlink test
# LDFLAGS=-Wl,--no-undefined : will make the linker fail if dll is underlinked # LDFLAGS=-Wl,--no-undefined : will make the linker fail if dll is underlinked
cmake-build-and-test-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: cmake build and test
run: |
FUZZERTEST=-T1mn ZSTREAM_TESTTIME=-T1mn make cmakebuild V=1
cpp-gnu90-c99-compatibility: cpp-gnu90-c99-compatibility:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: C++, gnu90 and c99 compatibility - name: C++, gnu90 and c99 compatibility
run: | run: |
make cxxtest make cxxtest
@ -89,7 +108,7 @@ jobs:
mingw-cross-compilation: mingw-cross-compilation:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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)
@ -100,7 +119,7 @@ jobs:
armbuild: armbuild:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: ARM Build Test - name: ARM Build Test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
@ -110,7 +129,7 @@ jobs:
bourne-shell: bourne-shell:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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
@ -120,22 +139,21 @@ jobs:
zlib-wrapper: zlib-wrapper:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: install valgrind - name: zlib wrapper test
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
make valgrindinstall V=1 make valgrindinstall
- name: zlib wrapper test make -C zlibWrapper test
run: make -C zlibWrapper test V=1 make -C zlibWrapper test-valgrind
- name: zlib wrapper test under valgrind
run: make -C zlibWrapper test-valgrind V=1
lz4-threadpool-libs: lz4-threadpool-libs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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 -C tests test-lz4 make -C tests test-lz4
make check < /dev/null | tee # mess with lz4 console detection make check < /dev/null | tee # mess with lz4 console detection
make clean make clean
@ -143,41 +161,20 @@ jobs:
make clean make clean
bash tests/libzstd_builds.sh bash tests/libzstd_builds.sh
gcc-make-all-avx2: gcc-make-tests-32bit:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Make all, with AVX2
run: |
sudo apt-get -qqq update
make libc6install
CFLAGS="-Werror -mavx2" make -j all
gcc-make-all-32bit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Make all, 32bit mode - name: Make all, 32bit mode
run: | run: |
sudo apt-get -qqq update sudo apt-get -qqq update
make libc6install make libc6install
CFLAGS="-Werror -m32" make -j all32 CFLAGS="-Werror -m32" make -j all32
gcc-make-all-32bit-avx2:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Make all, 32bit + AVX2 mode
run: |
sudo apt-get -qqq update
make libc6install
CPPFLAGS="-DSTATIC_BMI2=1" CFLAGS="-Werror -m32 -mavx2 -mbmi2" make -j all32
gcc-8-make: gcc-8-make:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: gcc-8 build - name: gcc-8 build
# See https://askubuntu.com/a/1428822 # See https://askubuntu.com/a/1428822
run: | run: |
@ -200,17 +197,15 @@ jobs:
flags: "HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=1" flags: "HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=1"
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Build with ${{matrix.name}} - name: Build with ${{matrix.name}}
run: | run: ${{matrix.flags}} make zstd
sudo apt install liblzma-dev
${{matrix.flags}} make zstd
implicit-fall-through: implicit-fall-through:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: -Wimplicit-fallthrough build - name: -Wimplicit-fallthrough build
run: | run: |
make clean make clean
@ -221,11 +216,11 @@ jobs:
meson-linux: meson-linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Install packages - name: Install packages
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get -y install build-essential python3-pip ninja-build liblz4-dev liblzma-dev sudo apt-get -y install build-essential python3-pip ninja-build liblz4-dev
pip install --pre meson pip install --pre meson
- name: Build with Meson - name: Build with Meson
run: | run: |
@ -237,59 +232,15 @@ jobs:
-Dbin_tests=true \ -Dbin_tests=true \
-Dbin_contrib=true \ -Dbin_contrib=true \
-Ddefault_library=both \ -Ddefault_library=both \
build/meson mesonBuild
ninja -C mesonBuild/
meson test -C mesonBuild/ --print-errorlogs
meson install -C mesonBuild --destdir staging/
meson-mingw-cross-compilation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Install packages
run: |
sudo apt-get -qqq update
sudo apt-get -y install build-essential python3-pip ninja-build {gcc,g++}-mingw-w64-x86-64
pip install --pre meson
- name: Build with Meson
run: |
cat > cross.ini <<EOF
[binaries]
ar = 'x86_64-w64-mingw32-ar'
c = 'x86_64-w64-mingw32-gcc'
cpp = 'x86_64-w64-mingw32-g++'
ld = 'x86_64-w64-mingw32-ld'
objcopy = 'x86_64-w64-mingw32-objcopy'
objdump = 'x86_64-w64-mingw32-objdump'
strip = 'x86_64-w64-mingw32-strip'
windres = 'x86_64-w64-mingw32-windres'
[host_machine]
system = 'windows'
endian = 'little'
cpu_family = 'x86_64'
cpu = 'x86_64'
EOF
# pzstd doesn't build; skip -Dbin_contrib=true
meson setup \
--buildtype=debugoptimized \
--cross-file=cross.ini \
-Db_lundef=false \
-Dbin_programs=true \
-Dbin_tests=true \
-Ddefault_library=both \
build/meson builddir build/meson builddir
ninja -C builddir/ ninja -C builddir/
if grep -- -pthread builddir/meson-private/libzstd.pc; then meson test -C builddir/ --print-errorlogs
echo "Error: found stray pthread dependency" meson install -C builddir --destdir staging/
exit 1
fi
meson-windows: meson-windows:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Install packages - name: Install packages
run: pip install --pre meson run: pip install --pre meson
- name: Configure with Meson - name: Configure with Meson
@ -305,6 +256,32 @@ jobs:
run: | run: |
meson install -C builddir --destdir staging/ meson install -C builddir --destdir staging/
cmake-visual-2022:
strategy:
matrix:
include:
- generator: "Visual Studio 17 2022"
flags: "-A x64"
- generator: "Visual Studio 17 2022"
flags: "-A Win32"
- generator: "MinGW Makefiles"
- generator: "Visual Studio 17 2022"
flags: "-T ClangCL"
runs-on: windows-2022
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0
- name: Build & Test
working-directory: ${{env.GITHUB_WORKSPACE}}
run: |
cd build\cmake
mkdir build
cd build
cmake.exe -G "${{matrix.generator}}" ${{matrix.flags}} -DCMAKE_BUILD_TYPE=Debug -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZSTREAM_FLAGS=-T30s -DZSTD_FUZZER_FLAGS=-T30s -DZSTD_FULLBENCH_FLAGS=-i0 ..
cmake.exe --build .
ctest.exe -V -C Debug
msbuild-visual-studio: msbuild-visual-studio:
strategy: strategy:
fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed. fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed.
@ -320,7 +297,7 @@ jobs:
] ]
runs-on: ${{matrix.runner}} runs-on: ${{matrix.runner}}
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Add MSBuild to PATH - name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0 uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0
- name: Build ${{matrix.name}} - name: Build ${{matrix.name}}
@ -345,7 +322,7 @@ jobs:
libzstd-size: libzstd-size:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: libzstd size test - name: libzstd size test
run: | run: |
make clean && make -j -C lib libzstd && ./tests/check_size.py lib/libzstd.so 1100000 make clean && make -j -C lib libzstd && ./tests/check_size.py lib/libzstd.so 1100000
@ -356,7 +333,7 @@ jobs:
minimal-decompressor-macros: minimal-decompressor-macros:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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"
@ -373,7 +350,7 @@ jobs:
dynamic-bmi2: dynamic-bmi2:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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"
@ -385,7 +362,7 @@ jobs:
test-variants: test-variants:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- 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
@ -393,13 +370,13 @@ jobs:
qemu-consistency: qemu-consistency:
name: QEMU ${{ matrix.name }} name: QEMU ${{ matrix.name }}
runs-on: ubuntu-24.04 runs-on: ubuntu-20.04
strategy: strategy:
fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed. fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed.
matrix: matrix:
include: [ include: [
{ name: ARM, xcc_pkg: gcc-arm-linux-gnueabi, xcc: arm-linux-gnueabi-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-arm-static }, { name: ARM, xcc_pkg: gcc-arm-linux-gnueabi, xcc: arm-linux-gnueabi-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-arm-static },
{ name: ARM64, xcc_pkg: gcc-aarch64-linux-gnu, xcc: aarch64-linux-gnu-gcc, xemu_pkg: qemu-system-aarch64,xemu: qemu-aarch64-static }, { name: ARM64, xcc_pkg: gcc-aarch64-linux-gnu, xcc: aarch64-linux-gnu-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-aarch64-static },
{ name: PPC, xcc_pkg: gcc-powerpc-linux-gnu, xcc: powerpc-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc-static }, { name: PPC, xcc_pkg: gcc-powerpc-linux-gnu, xcc: powerpc-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc-static },
{ name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static }, { name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static },
{ name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static }, { name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static },
@ -412,7 +389,7 @@ jobs:
XCC: ${{ matrix.xcc }} XCC: ${{ matrix.xcc }}
XEMU: ${{ matrix.xemu }} XEMU: ${{ matrix.xemu }}
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: apt update & install - name: apt update & install
run: | run: |
sudo apt-get update sudo apt-get update
@ -432,15 +409,8 @@ jobs:
- name: ARM64 - name: ARM64
if: ${{ matrix.name == 'ARM64' }} if: ${{ matrix.name == 'ARM64' }}
run: | run: |
make clean LDFLAGS="-static -z force-bti" MOREFLAGS="-mbranch-protection=standard" CC=$XCC QEMU_SYS=$XEMU make clean check
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j check LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j -C tests test-cli-tests
CFLAGS="-march=armv8.2-a+sve2" LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j check
CFLAGS="-march=armv8.2-a+sve2" LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j -C tests test-cli-tests
# This test is only compatible with standard libraries that support BTI (Branch Target Identification).
# Unfortunately, the standard library provided on Ubuntu 24.04 does not have this feature enabled.
# make clean
# LDFLAGS="-static -z force-bti" MOREFLAGS="-mbranch-protection=standard" CC=$XCC QEMU_SYS=$XEMU make check V=1
- name: PPC - name: PPC
if: ${{ matrix.name == 'PPC' }} if: ${{ matrix.name == 'PPC' }}
run: | run: |
@ -484,8 +454,8 @@ jobs:
run: run:
shell: msys2 {0} shell: msys2 {0}
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- uses: msys2/setup-msys2@40677d36a502eb2cf0fb808cc9dec31bf6152638 # tag=v2.28.0 - uses: msys2/setup-msys2@cc11e9188b693c2b100158c3322424c4cc1dadea # tag=v2.22.0
with: with:
msystem: ${{ matrix.msystem }} msystem: ${{ matrix.msystem }}
install: make diffutils install: make diffutils
@ -520,7 +490,7 @@ jobs:
platform: [x64, Win32] platform: [x64, Win32]
configuration: [Release] configuration: [Release]
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Add MSBuild to PATH - name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0 uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0
- name: Build and run tests - name: Build and run tests
@ -541,8 +511,8 @@ jobs:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- run: git config --global core.autocrlf input - run: git config --global core.autocrlf input
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- uses: cygwin/cygwin-install-action@f61179d72284ceddc397ed07ddb444d82bf9e559 # tag=v5 - uses: cygwin/cygwin-install-action@006ad0b0946ca6d0a3ea2d4437677fa767392401 # tag=master
with: with:
platform: x86_64 platform: x86_64
packages: >- packages: >-
@ -562,18 +532,13 @@ jobs:
make -j allzstd && make -j allzstd &&
make -C tests fuzzer && make -C tests fuzzer &&
./tests/fuzzer.exe -v -T1m ./tests/fuzzer.exe -v -T1m
- name: cygwin install test
shell: C:\cygwin\bin\bash.exe --noprofile --norc -eo pipefail '{0}'
run: >-
make -j &&
make install
pkg-config: pkg-config:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: debian:testing image: debian:testing
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Install dependencies - name: Install dependencies
run: | run: |
apt -y update apt -y update
@ -588,7 +553,7 @@ jobs:
versions-compatibility: versions-compatibility:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Versions Compatibility Test - name: Versions Compatibility Test
run: | run: |
make -C tests versionsTest make -C tests versionsTest
@ -596,15 +561,27 @@ jobs:
clangbuild: clangbuild:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: make clangbuild - name: make clangbuild
run: | run: |
make clangbuild make clangbuild
clang-pgo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Build PGO Zstd with Clang
env:
CC: clang-14
LLVM_PROFDATA: llvm-profdata-14
run: |
make -C programs zstd-pgo
./programs/zstd -b
gcc-pgo: gcc-pgo:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Build PGO Zstd with GCC - name: Build PGO Zstd with GCC
env: env:
CC: gcc CC: gcc
@ -612,34 +589,10 @@ jobs:
make -C programs zstd-pgo make -C programs zstd-pgo
./programs/zstd -b ./programs/zstd -b
clang-pgo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Build PGO Zstd with Clang
env:
CC: clang
run: |
sudo apt install -y llvm
llvm-profdata --version
make -C programs zstd-pgo
./programs/zstd -b
musl-build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
- name: Install musl-tools
run: |
sudo apt install -y musl-tools
- name: Compile with musl-gcc and test-zstd
run: |
CC=musl-gcc CFLAGS="-Werror -O3" CPPFLAGS=-DZDICT_QSORT=ZDICT_QSORT_C90 make -j -C tests test-zstd V=1
intel-cet-compatibility: intel-cet-compatibility:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
- name: Build Zstd - name: Build Zstd
run: | run: |
make -j zstd V=1 make -j zstd V=1
@ -655,24 +608,26 @@ jobs:
run: | run: |
sde-external-9.33.0-2024-01-07-lin/sde -cet -cet-raise 0 -cet-endbr-exe -cet-stderr -cet-abort -- ./zstd -b3 sde-external-9.33.0-2024-01-07-lin/sde -cet -cet-raise 0 -cet-endbr-exe -cet-stderr -cet-abort -- ./zstd -b3
icx:
# install instructions: https://www.intel.com/content/www/us/en/docs/oneapi/installation-guide-linux/2025-0/apt-005.html
name: icx-check
runs-on: ubuntu-latest
steps:
- name: install icx
run: |
# download the key to system keyring
wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB \
| gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null
# add signed entry to apt sources and configure the APT client to use Intel repository: # Failing tests, for reference
echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
sudo apt-get update # icc tests are currently failing on Github Actions, likely to issues during installation stage
sudo apt-get install -y intel-basekit intel-hpckit #
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 # icc:
- name: make check # name: icc-check
run: | # runs-on: ubuntu-latest
source /opt/intel/oneapi/setvars.sh # steps:
make CC=icx check # - name: install icc
make CC=icx -C tests test-cli-tests # run: |
# export DEBIAN_FRONTEND=noninteractive
# sudo apt-get -qqq update
# sudo apt-get install -y wget build-essential pkg-config cmake ca-certificates gnupg
# sudo wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
# sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
# sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main"
# sudo apt-get update
# sudo apt-get install -y intel-basekit intel-hpckit
# - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
# - name: make check
# run: |
# make CC=/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc check

View File

@ -1,24 +1,51 @@
name: facebook/zstd/nightly name: facebook/zstd/nightly
on: on:
schedule: schedule:
- cron: '0 0 * * *' - cron: 0 0 * * *
push: push:
branches: branches:
- release - release
- dev - dev
- '*nightly*' - master
permissions: read-all permissions: read-all
jobs: jobs:
regression-test: regression-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
services:
docker:
image: fbopensource/zstd-circleci-primary:0.0.1
options: --entrypoint /bin/bash
env:
CIRCLE_ARTIFACTS: "/tmp/circleci-artifacts"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install dependencies - uses: actions/cache@v4
run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev with:
key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0
path: tests/regression/cache
restore-keys: regression-cache-{{ checksum "tests/regression/data.c" }}-v0
- uses: actions/upload-artifact@v4
with:
path: "/tmp/circleci-artifacts"
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install libcurl4-gnutls-dev
- name: Regression Test - name: Regression Test
run: | run: |
make -C programs zstd make -C programs zstd
make -C tests/regression test make -C tests/regression test
mkdir -p $CIRCLE_ARTIFACTS
./tests/regression/test \
--cache tests/regression/cache \
--output $CIRCLE_ARTIFACTS/results.csv \
--zstd programs/zstd
echo "NOTE: The new results.csv is uploaded as an artifact to this job"
echo " If this fails, go to the Artifacts pane in CircleCI, "
echo " download /tmp/circleci-artifacts/results.csv, and if they "
echo " are still good, copy it into the repo and commit it."
echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv"
diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv
# Longer tests # Longer tests
#- make -C tests test-zstd-nolegacy && make clean #- make -C tests test-zstd-nolegacy && make clean

View File

@ -17,7 +17,7 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
- name: Archive - name: Archive
env: env:

View File

@ -1,64 +0,0 @@
name: release_checks
on:
push:
branches:
- release
pull_request:
branches:
- release
permissions: read-all
jobs:
verify-manual:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Save current manual
run: mv doc/zstd_manual.html doc/zstd_manual_saved.html
- name: Generate new manual
run: make manual
- name: Compare manuals
run: |
if ! cmp -s doc/zstd_manual.html doc/zstd_manual_saved.html; then
echo "The API manual was not updated before release !"
exit 1
fi
verify-man-pages:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ruby ruby-dev
sudo gem install ronn
- name: Display ronn version
run: ronn --version
- name: Save current man pages
run: |
mv programs/zstd.1 programs/zstd.1.saved
mv programs/zstdgrep.1 programs/zstdgrep.1.saved
mv programs/zstdless.1 programs/zstdless.1.saved
- name: Generate new manual pages
run: make -C programs man
- name: Compare man pages
run: |
for file in zstd.1 zstdgrep.1 zstdless.1; do
if ! cmp -s programs/$file programs/$file.saved; then
echo "The man page $file should have been updated."
exit 1
fi
done

View File

@ -27,12 +27,12 @@ jobs:
steps: steps:
- name: "Checkout code" - name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
with: with:
persist-credentials: false persist-credentials: false
- name: "Run analysis" - name: "Run analysis"
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # tag=v2.4.1 uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v2.3.1
with: with:
results_file: results.sarif results_file: results.sarif
results_format: sarif results_format: 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@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # tag=v3.28.9 uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # tag=v3.24.7
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View File

@ -2,7 +2,7 @@ name: windows-artifacts
on: on:
push: push:
branches: [ test_artifacts, win_artifacts, release ] branches: [ test_artifacts, win_artifacts ]
release: release:
types: types:
- published - published
@ -11,8 +11,6 @@ permissions: read-all
jobs: jobs:
windows-artifacts: windows-artifacts:
permissions:
contents: write # to fetch code and upload artifacts
# see https://ariya.io/2020/07/on-github-actions-with-msys2 # see https://ariya.io/2020/07/on-github-actions-with-msys2
runs-on: windows-latest runs-on: windows-latest
# see https://github.com/msys2/setup-msys2 # see https://github.com/msys2/setup-msys2
@ -25,11 +23,11 @@ jobs:
run: run:
shell: msys2 {0} shell: msys2 {0}
steps: steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
- uses: msys2/setup-msys2@40677d36a502eb2cf0fb808cc9dec31bf6152638 # tag=v2.28.0 - uses: msys2/setup-msys2@5beef6d11f48bba68b9eb503e3adc60b23c0cc36 # tag=v2
with: with:
msystem: ${{ matrix.msystem }} msystem: ${{ matrix.msystem }}
install: make p7zip git mingw-w64-${{matrix.env}}-gcc install: make zlib git p7zip mingw-w64-${{matrix.env}}-gcc
update: true update: true
- name: display versions - name: display versions
@ -39,43 +37,22 @@ jobs:
- name: Building zlib to static link - name: Building zlib to static link
run: | run: |
git clone --depth 1 --branch v1.3.1 https://github.com/madler/zlib git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib
make -C zlib -f win32/Makefile.gcc libz.a make -C zlib -f win32/Makefile.gcc libz.a
- name: Building lz4 to static link
run: |
git clone --depth 1 --branch v1.10.0 https://github.com/lz4/lz4
# ensure both libraries use the same version of libxxhash
cp lib/common/xxhash.* lz4/lib
CPPFLAGS=-DXXH_NAMESPACE=LZ4_ make -C lz4/lib liblz4.a V=1
- name: Building zstd programs - name: Building zstd programs
run: | run: |
CPPFLAGS="-I../zlib -I../lz4/lib" LDFLAGS=-static make -j allzstd V=1 HAVE_ZLIB=1 HAVE_LZ4=1 HAVE_LZMA=0 LDLIBS="../zlib/libz.a ../lz4/lib/liblz4.a" CPPFLAGS=-I../zlib LDFLAGS=../zlib/libz.a make -j allzstd MOREFLAGS=-static V=1
- name: Create artifacts - name: Create artifacts
run: | run: |
./lib/dll/example/build_package.bat || exit 1 ./lib/dll/example/build_package.bat
mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/ mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
7z a -tzip -mx9 zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
cd ..
- name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip for manual inspection - name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1 uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1
with: with:
compression-level: 9 # maximum compression path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip
if-no-files-found: error # defaults to `warn` name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip
path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}
- name: Package artifact for upload
run: |
7z a -tzip -mx9 "$(cygpath -u '${{ github.workspace }}/zstd-${{ github.ref_name }}-${{ matrix.ziparch }}.zip')" "$(cygpath -u '${{ github.workspace }}/zstd-${{ github.ref_name }}-${{ matrix.ziparch }}')"
- name: Upload release asset
if: github.event_name == 'release'
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload "${{ github.ref_name }}" "$env:GITHUB_WORKSPACE/zstd-${{ github.ref_name }}-${{ matrix.ziparch }}.zip" --clobber

2
.gitignore vendored
View File

@ -12,8 +12,6 @@
*.so *.so
*.so.* *.so.*
*.dylib *.dylib
*.framework
*.xcframework
# Executables # Executables
/zstd /zstd

View File

@ -1,35 +1,9 @@
V1.5.7 (Feb 2025)
fix: compression bug in 32-bit mode associated with long-lasting sessions
api: new method `ZSTD_compressSequencesAndLiterals()` (#4217, #4232)
api: `ZSTD_getFrameHeader()` works on skippable frames (#4228)
perf: substantial compression speed improvements (up to +30%) on small data, by @TocarIP (#4144) and @cyan4973 (#4165)
perf: improved compression speed (~+5%) for dictionary compression at low levels (#4170)
perf: much faster speed for `--patch-from` at high compression levels (#4276)
perf: higher `--patch-from` compression ratios, notably at high levels (#4288)
perf: better speed for binaries on Windows (@pps83) and when compiled with Visual Studio (@MessyHack)
perf: slight compression ratio improvement thanks to better block boundaries (#4136, #4176, #4178)
perf: slight compression ratio improvement for `dfast`, aka levels 3 and 4 (#4171)
perf: runtime bmi2 detection enabled on x86 32-bit mode (#4251)
cli: multi-threading as default CLI setting, by @daniellerozenblit
cli: new `--max` command (#4290)
build: improve `msbuild` version autodetection, support VS2022, by @ManuelBlanc
build: fix `meson` build by @artem and @Victor-C-Zhang, and on Windows by @bgilbert
build: compatibility with Apple Framework, by @Treata11
build: improve icc/icx compatibility, by @josepho0918 and @luau-project
build: improve compatibility with Android NDK, by Adenilson Cavalcanti
portability: linux kernel branch, with improved support for Sequence producers (@embg, @gcabiddu, @cyan4973)
portability: improved qnx compatibility, suggested by @rainbowball
portability: improved install script for FreeBSD, by @sunpoet
portability: fixed test suite compatibility with gnu hurd, by @diegonc
doc: clarify specification, by @elasota
misc: improved tests/decodecorpus validation tool (#4102), by antmicro
V1.5.6 (Mar 2024) V1.5.6 (Mar 2024)
api: Promote `ZSTD_c_targetCBlockSize` to Stable API by @felixhandte api: Promote `ZSTD_c_targetCBlockSize` to Stable API by @felixhandte
api: new `ZSTD_d_maxBlockSize` experimental parameter, to reduce streaming decompression memory, by @terrelln api: new `ZSTD_d_maxBlockSize` experimental parameter, to reduce streaming decompression memory, by @terrelln
perf: improve performance of param `ZSTD_c_targetCBlockSize`, by @Cyan4973 perf: improve performance of param `ZSTD_c_targetCBlockSize`, by @Cyan4973
perf: improved compression of arrays of integers at high compression, by @Cyan4973 perf: improved compression of arrays of integers at high compression, by @Cyan4973
lib: reduce binary size with selective build-time exclusion, by @felixhandte lib: reduce binary size with selective built-time exclusion, by @felixhandte
lib: improved huffman speed on small data and linux kernel, by @terrelln lib: improved huffman speed on small data and linux kernel, by @terrelln
lib: accept dictionaries with partial literal tables, by @terrelln lib: accept dictionaries with partial literal tables, by @terrelln
lib: fix CCtx size estimation with external sequence producer, by @embg lib: fix CCtx size estimation with external sequence producer, by @embg
@ -515,7 +489,7 @@ misc: added /contrib/docker script by @gyscos
v1.3.3 (Dec 21, 2017) v1.3.3 (Dec 21, 2017)
perf: faster zstd_opt strategy (levels 16-19) perf: faster zstd_opt strategy (levels 16-19)
fix : bug #944 : multithreading with shared dictionary and large data, reported by @gsliepen fix : bug #944 : multithreading with shared ditionary and large data, reported by @gsliepen
cli : fix : content size written in header by default cli : fix : content size written in header by default
cli : fix : improved LZ4 format support, by @felixhandte cli : fix : improved LZ4 format support, by @felixhandte
cli : new : hidden command `-S`, to benchmark multiple files while generating one result per file cli : new : hidden command `-S`, to benchmark multiple files while generating one result per file

View File

@ -60,7 +60,7 @@ Our contribution process works in three main stages:
* Note: run local tests to ensure that your changes didn't break existing functionality * Note: run local tests to ensure that your changes didn't break existing functionality
* Quick check * Quick check
``` ```
make check make shortest
``` ```
* Longer check * Longer check
``` ```

View File

@ -85,10 +85,14 @@ test:
$(MAKE) -C $(TESTDIR) $@ $(MAKE) -C $(TESTDIR) $@
ZSTD=../../programs/zstd $(MAKE) -C doc/educational_decoder $@ ZSTD=../../programs/zstd $(MAKE) -C doc/educational_decoder $@
## shortest: same as `make check`
.PHONY: shortest
shortest:
$(Q)$(MAKE) -C $(TESTDIR) $@
## check: run basic tests for `zstd` cli ## check: run basic tests for `zstd` cli
.PHONY: check .PHONY: check
check: check: shortest
$(Q)$(MAKE) -C $(TESTDIR) $@
.PHONY: automated_benchmarking .PHONY: automated_benchmarking
automated_benchmarking: automated_benchmarking:
@ -141,13 +145,13 @@ clean:
$(Q)$(MAKE) -C contrib/largeNbDicts $@ > $(VOID) $(Q)$(MAKE) -C contrib/largeNbDicts $@ > $(VOID)
$(Q)$(MAKE) -C contrib/externalSequenceProducer $@ > $(VOID) $(Q)$(MAKE) -C contrib/externalSequenceProducer $@ > $(VOID)
$(Q)$(RM) zstd$(EXT) zstdmt$(EXT) tmp* $(Q)$(RM) zstd$(EXT) zstdmt$(EXT) tmp*
$(Q)$(RM) -r lz4 cmakebuild mesonbuild install $(Q)$(RM) -r lz4 cmakebuild install
@echo Cleaning completed @echo Cleaning completed
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# make install is validated only for Linux, macOS, Hurd and some BSD targets # make install is validated only for Linux, macOS, Hurd and some BSD targets
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT% CYGWIN_NT% Haiku AIX,$(shell sh -c 'MSYSTEM="MSYS" uname') )) ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT CYGWIN_NT Haiku AIX))
HOST_OS = POSIX HOST_OS = POSIX
@ -196,9 +200,9 @@ travis-install:
.PHONY: clangbuild-darwin-fat .PHONY: clangbuild-darwin-fat
clangbuild-darwin-fat: clean clangbuild-darwin-fat: clean
clang -v clang -v
CXX=clang++ CC=clang CFLAGS+="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch arm64" $(MAKE) zstd-release CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch arm64" $(MAKE) zstd-release
mv programs/zstd programs/zstd_arm64 mv programs/zstd programs/zstd_arm64
CXX=clang++ CC=clang CFLAGS+="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch x86_64" $(MAKE) zstd-release CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation -arch x86_64" $(MAKE) zstd-release
mv programs/zstd programs/zstd_x64 mv programs/zstd programs/zstd_x64
lipo -create programs/zstd_x64 programs/zstd_arm64 -output programs/zstd lipo -create programs/zstd_x64 programs/zstd_arm64 -output programs/zstd
@ -289,16 +293,16 @@ regressiontest:
$(MAKE) -C $(FUZZDIR) regressiontest $(MAKE) -C $(FUZZDIR) regressiontest
uasanregressiontest: uasanregressiontest:
$(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=address,undefined -Werror" CXXFLAGS="-O3 -fsanitize=address,undefined -Werror" $(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=address,undefined" CXXFLAGS="-O3 -fsanitize=address,undefined"
msanregressiontest: msanregressiontest:
$(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=memory -Werror" CXXFLAGS="-O3 -fsanitize=memory -Werror" $(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=memory" CXXFLAGS="-O3 -fsanitize=memory"
update_regressionResults : REGRESS_RESULTS_DIR := /tmp/regress_results_dir/ update_regressionResults : REGRESS_RESULTS_DIR := /tmp/regress_results_dir/
update_regressionResults: update_regressionResults:
$(MAKE) -j -C programs zstd $(MAKE) -C programs zstd
$(MAKE) -j -C tests/regression test $(MAKE) -C tests/regression test
$(RM) -r $(REGRESS_RESULTS_DIR) $(RM) -rf $(REGRESS_RESULTS_DIR)
$(MKDIR) $(REGRESS_RESULTS_DIR) $(MKDIR) $(REGRESS_RESULTS_DIR)
./tests/regression/test \ ./tests/regression/test \
--cache tests/regression/cache \ --cache tests/regression/cache \
@ -351,7 +355,7 @@ apt-add-repo:
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update -y -qq sudo apt-get update -y -qq
.PHONY: ppcinstall arminstall valgrindinstall libc6install gcc6install gcc7install gcc8install gpp6install clang38install .PHONY: ppcinstall arminstall valgrindinstall libc6install gcc6install gcc7install gcc8install gpp6install clang38install lz4install
ppcinstall: ppcinstall:
APT_PACKAGES="qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu" $(MAKE) apt-install APT_PACKAGES="qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu" $(MAKE) apt-install
@ -379,22 +383,26 @@ gpp6install: apt-add-repo
clang38install: clang38install:
APT_PACKAGES="clang-3.8" $(MAKE) apt-install APT_PACKAGES="clang-3.8" $(MAKE) apt-install
# Ubuntu 14.04 ships a too-old lz4
lz4install:
[ -e lz4 ] || git clone https://github.com/lz4/lz4 && sudo $(MAKE) -C lz4 install
endif endif
ifneq (,$(filter MSYS%,$(shell sh -c 'MSYSTEM="MSYS" uname') )) ifneq (,$(filter MSYS%,$(shell uname)))
HOST_OS = MSYS HOST_OS = MSYS
endif endif
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# target specific tests # target specific tests
#------------------------------------------------------------------------ #------------------------------------------------------------------------
ifneq (,$(filter MSYS POSIX,$(HOST_OS))) ifneq (,$(filter $(HOST_OS),MSYS POSIX))
CMAKE ?= cmake CMAKE ?= cmake
CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON
ifneq (,$(filter MSYS%,$(shell sh -c 'MSYSTEM="MSYS" uname'))) ifneq (,$(filter MSYS%,$(shell uname)))
CMAKE_PARAMS = -G"MSYS Makefiles" -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON CMAKE_PARAMS = -G"MSYS Makefiles" -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON
endif endif
@ -407,24 +415,6 @@ cmakebuild:
$(CMAKE) --build cmakebuild --target install -- -j V=1 $(CMAKE) --build cmakebuild --target install -- -j V=1
cd cmakebuild; ctest -V -L Medium cd cmakebuild; ctest -V -L Medium
MESON ?= meson
NINJA ?= ninja
.PHONY: mesonbuild
mesonbuild:
$(MESON) setup \
--buildtype=debugoptimized \
-Db_lundef=false \
-Dauto_features=enabled \
-Dbin_programs=true \
-Dbin_tests=true \
-Dbin_contrib=true \
-Ddefault_library=both \
build/meson mesonbuild
$(NINJA) -C mesonbuild/
$(MESON) test -C mesonbuild/ --print-errorlogs
$(MESON) install -C mesonbuild --destdir staging/
.PHONY: c89build gnu90build c99build gnu99build c11build bmix64build bmix32build bmi32build staticAnalyze .PHONY: c89build gnu90build c99build gnu99build c11build bmix64build bmix32build bmi32build staticAnalyze
c89build: clean c89build: clean
$(CC) -v $(CC) -v

View File

@ -29,10 +29,10 @@ a list of known ports and bindings is provided on [Zstandard homepage](https://f
## Benchmarks ## Benchmarks
For reference, several fast compression algorithms were tested and compared For reference, several fast compression algorithms were tested and compared
on a desktop featuring a Core i7-9700K CPU @ 4.9GHz on a desktop running Ubuntu 20.04 (`Linux 5.11.0-41-generic`),
and running Ubuntu 24.04 (`Linux 6.8.0-53-generic`), with a Core i7-9700K CPU @ 4.9GHz,
using [lzbench], an open-source in-memory benchmark by @inikep using [lzbench], an open-source in-memory benchmark by @inikep
compiled with [gcc] 14.2.0, compiled with [gcc] 9.3.0,
on the [Silesia compression corpus]. on the [Silesia compression corpus].
[lzbench]: https://github.com/inikep/lzbench [lzbench]: https://github.com/inikep/lzbench
@ -41,23 +41,24 @@ on the [Silesia compression corpus].
| Compressor name | Ratio | Compression| Decompress.| | Compressor name | Ratio | Compression| Decompress.|
| --------------- | ------| -----------| ---------- | | --------------- | ------| -----------| ---------- |
| **zstd 1.5.7 -1** | 2.896 | 510 MB/s | 1550 MB/s | | **zstd 1.5.1 -1** | 2.887 | 530 MB/s | 1700 MB/s |
| brotli 1.1.0 -1 | 2.883 | 290 MB/s | 425 MB/s | | [zlib] 1.2.11 -1 | 2.743 | 95 MB/s | 400 MB/s |
| [zlib] 1.3.1 -1 | 2.743 | 105 MB/s | 390 MB/s | | brotli 1.0.9 -0 | 2.702 | 395 MB/s | 450 MB/s |
| **zstd 1.5.7 --fast=1** | 2.439 | 545 MB/s | 1850 MB/s | | **zstd 1.5.1 --fast=1** | 2.437 | 600 MB/s | 2150 MB/s |
| quicklz 1.5.0 -1 | 2.238 | 520 MB/s | 750 MB/s | | **zstd 1.5.1 --fast=3** | 2.239 | 670 MB/s | 2250 MB/s |
| **zstd 1.5.7 --fast=4** | 2.146 | 665 MB/s | 2050 MB/s | | quicklz 1.5.0 -1 | 2.238 | 540 MB/s | 760 MB/s |
| lzo1x 2.10 -1 | 2.106 | 650 MB/s | 780 MB/s | | **zstd 1.5.1 --fast=4** | 2.148 | 710 MB/s | 2300 MB/s |
| [lz4] 1.10.0 | 2.101 | 675 MB/s | 3850 MB/s | | lzo1x 2.10 -1 | 2.106 | 660 MB/s | 845 MB/s |
| snappy 1.2.1 | 2.089 | 520 MB/s | 1500 MB/s | | [lz4] 1.9.3 | 2.101 | 740 MB/s | 4500 MB/s |
| lzf 3.6 -1 | 2.077 | 410 MB/s | 820 MB/s | | lzf 3.6 -1 | 2.077 | 410 MB/s | 830 MB/s |
| snappy 1.1.9 | 2.073 | 550 MB/s | 1750 MB/s |
[zlib]: https://www.zlib.net/ [zlib]: https://www.zlib.net/
[lz4]: https://lz4.github.io/lz4/ [lz4]: https://lz4.github.io/lz4/
The negative compression levels, specified with `--fast=#`, The negative compression levels, specified with `--fast=#`,
offer faster compression and decompression speed offer faster compression and decompression speed
at the cost of compression ratio. at the cost of compression ratio (compared to level 1).
Zstd can also offer stronger compression ratios at the cost of compression speed. Zstd can also offer stronger compression ratios at the cost of compression speed.
Speed vs Compression trade-off is configurable by small increments. Speed vs Compression trade-off is configurable by small increments.
@ -184,17 +185,6 @@ You can build and install zstd [vcpkg](https://github.com/Microsoft/vcpkg/) depe
The zstd port in vcpkg is kept up to date by Microsoft team members and community contributors. The zstd port in vcpkg is kept up to date by Microsoft team members and community contributors.
If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
### Conan
You can install pre-built binaries for zstd or build it from source using [Conan](https://conan.io/). Use the following command:
```bash
conan install --requires="zstd/[*]" --build=missing
```
The zstd Conan recipe is kept up to date by Conan maintainers and community contributors.
If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the ConanCenterIndex repository.
### Visual Studio (Windows) ### Visual Studio (Windows)
Going into `build` directory, you will find additional possibilities: Going into `build` directory, you will find additional possibilities:

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>fullbench-dll</RootNamespace>
<OutDir>$(SolutionDir)bin\$(Platform)_$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)bin\obj\$(RootNamespace)_$(Platform)_$(Configuration)\</IntDir>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(IncludePath);$(SolutionDir)..\..\lib;$(SolutionDir)..\..\programs;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\common;$(UniversalCRT_IncludePath);</IncludePath>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<EnablePREfast>false</EnablePREfast>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libzstd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<EnablePREfast>false</EnablePREfast>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libzstd.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<EnablePREfast>false</EnablePREfast>
<TreatWarningAsError>false</TreatWarningAsError>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libzstd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;ZSTD_DLL_IMPORT=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>false</TreatWarningAsError>
<EnablePREfast>false</EnablePREfast>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)_$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>libzstd.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\lib\common\xxhash.c" />
<ClCompile Include="..\..\..\programs\util.c" />
<ClCompile Include="..\..\..\programs\timefn.c" />
<ClCompile Include="..\..\..\programs\datagen.c" />
<ClCompile Include="..\..\..\programs\benchfn.c" />
<ClCompile Include="..\..\..\tests\fullbench.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\lib\zstd.h" />
<ClInclude Include="..\..\..\programs\datagen.h" />
<ClInclude Include="..\..\..\programs\benchfn.h" />
<ClInclude Include="..\..\..\programs\util.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\libzstd-dll\libzstd-dll.vcxproj">
<Project>{00000000-94d5-4bf9-8a50-7bd9929a0850}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -170,7 +170,6 @@
<ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_preSplit.c" />
<ClCompile Include="..\..\..\lib\compress\zstdmt_compress.c" /> <ClCompile Include="..\..\..\lib\compress\zstdmt_compress.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" />
@ -184,7 +183,6 @@
<ClCompile Include="..\..\..\programs\util.c" /> <ClCompile Include="..\..\..\programs\util.c" />
<ClCompile Include="..\..\..\programs\timefn.c" /> <ClCompile Include="..\..\..\programs\timefn.c" />
<ClCompile Include="..\..\..\programs\datagen.c" /> <ClCompile Include="..\..\..\programs\datagen.c" />
<ClCompile Include="..\..\..\programs\lorem.c" />
<ClCompile Include="..\..\..\programs\benchfn.c" /> <ClCompile Include="..\..\..\programs\benchfn.c" />
<ClCompile Include="..\..\..\tests\fullbench.c" /> <ClCompile Include="..\..\..\tests\fullbench.c" />
</ItemGroup> </ItemGroup>

View File

@ -170,7 +170,6 @@
<ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_preSplit.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" />

View File

@ -34,7 +34,6 @@
<ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_preSplit.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" />

View File

@ -34,7 +34,6 @@
<ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_preSplit.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" />

View File

@ -7,6 +7,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fuzzer", "fuzzer\fuzzer.vcx
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench", "fullbench\fullbench.vcxproj", "{61ABD629-1CC8-4FD7-9281-6B8DBB9D3DF8}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fullbench-dll", "fullbench-dll\fullbench-dll.vcxproj", "{00000000-1CC8-4FD7-9281-6B8DBB9D3DF8}"
ProjectSection(ProjectDependencies) = postProject
{00000000-94D5-4BF9-8A50-7BD9929A0850} = {00000000-94D5-4BF9-8A50-7BD9929A0850}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "datagen", "datagen\datagen.vcxproj", "{037E781E-81A6-494B-B1B3-438AB1200523}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd", "libzstd\libzstd.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzstd", "libzstd\libzstd.vcxproj", "{8BFD8150-94D5-4BF9-8A50-7BD9929A0850}"

View File

@ -35,7 +35,6 @@
<ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_literals.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_sequences.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_compress_superblock.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_preSplit.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_double_fast.c" />
<ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" /> <ClCompile Include="..\..\..\lib\compress\zstd_lazy.c" />

View File

@ -1,7 +0,0 @@
@echo off
rem build 32-bit
call "%~p0%build.generic.cmd" preview Win32 Release v143
rem build 64-bit
call "%~p0%build.generic.cmd" preview x64 Release v143

View File

@ -2,7 +2,7 @@
IF "%1%" == "" GOTO display_help IF "%1%" == "" GOTO display_help
SETLOCAL ENABLEDELAYEDEXPANSION SETLOCAL
SET msbuild_version=%1 SET msbuild_version=%1
@ -19,34 +19,39 @@ GOTO build
:display_help :display_help
echo Syntax: build.generic.cmd msbuild_version msbuild_platform msbuild_configuration msbuild_toolset echo Syntax: build.generic.cmd msbuild_version msbuild_platform msbuild_configuration msbuild_toolset
echo msbuild_version: VS installed version (latest, VS2012, VS2013, VS2015, VS2017, VS2019, VS2022, ...) echo msbuild_version: VS installed version (VS2012, VS2013, VS2015, VS2017, VS2019, ...)
echo msbuild_platform: Platform (x64 or Win32) echo msbuild_platform: Platform (x64 or Win32)
echo msbuild_configuration: VS configuration (Release or Debug) echo msbuild_configuration: VS configuration (Release or Debug)
echo msbuild_toolset: Platform Toolset (v100, v110, v120, v140, v141, v142, v143, ...) echo msbuild_toolset: Platform Toolset (v100, v110, v120, v140, v141, v142, ...)
EXIT /B 1 EXIT /B 1
:build :build
SET msbuild="%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" SET msbuild="%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe"
SET msbuild_vs2017community="%programfiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
SET msbuild_vs2017professional="%programfiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe"
SET msbuild_vs2017enterprise="%programfiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe"
IF %msbuild_version% == VS2013 SET msbuild="%programfiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" IF %msbuild_version% == VS2013 SET msbuild="%programfiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe"
IF %msbuild_version% == VS2015 SET msbuild="%programfiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe" IF %msbuild_version% == VS2015 SET msbuild="%programfiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe"
IF %msbuild_version% == VS2017 SET vswhere_params=-version [15,16) -products * IF %msbuild_version% == VS2017Community SET msbuild=%msbuild_vs2017community%
IF %msbuild_version% == VS2017Community SET vswhere_params=-version [15,16) -products Community IF %msbuild_version% == VS2017Professional SET msbuild=%msbuild_vs2017professional%
IF %msbuild_version% == VS2017Enterprise SET vswhere_params=-version [15,16) -products Enterprise IF %msbuild_version% == VS2017Enterprise SET msbuild=%msbuild_vs2017enterprise%
IF %msbuild_version% == VS2017Professional SET vswhere_params=-version [15,16) -products Professional IF %msbuild_version% == VS2017 (
IF %msbuild_version% == VS2019 SET vswhere_params=-version [16,17) -products * IF EXIST %msbuild_vs2017community% SET msbuild=%msbuild_vs2017community%
IF %msbuild_version% == VS2022 SET vswhere_params=-version [17,18) -products * IF EXIST %msbuild_vs2017professional% SET msbuild=%msbuild_vs2017professional%
REM Add the next Visual Studio version here. IF EXIST %msbuild_vs2017enterprise% SET msbuild=%msbuild_vs2017enterprise%
IF %msbuild_version% == latest SET vswhere_params=-latest -products * )
IF %msbuild_version% == preview SET vswhere_params=-prerelease -products *
:: VS2019
IF NOT DEFINED vswhere_params GOTO skip_vswhere SET msbuild_vs2019community="%programfiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
SET vswhere="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" SET msbuild_vs2019professional="%programfiles(x86)%\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe"
FOR /F "USEBACKQ TOKENS=*" %%F IN (`%vswhere% !vswhere_params! -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe`) DO ( SET msbuild_vs2019enterprise="%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe"
SET msbuild="%%F" IF %msbuild_version% == VS2019 (
IF EXIST %msbuild_vs2019community% SET msbuild=%msbuild_vs2019community%
IF EXIST %msbuild_vs2019professional% SET msbuild=%msbuild_vs2019professional%
IF EXIST %msbuild_vs2019enterprise% SET msbuild=%msbuild_vs2019enterprise%
) )
:skip_vswhere
SET project="%~p0\..\VS2010\zstd.sln" SET project="%~p0\..\VS2010\zstd.sln"

View File

@ -7,75 +7,210 @@
# in the COPYING file in the root directory of this source tree). # in the COPYING file in the root directory of this source tree).
# ################################################################ # ################################################################
cmake_minimum_required(VERSION 3.10 FATAL_ERROR) cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# 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(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3")
set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13") #Policies never changed at PATCH level
if("${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}" EQUAL "${CMAKE_MAJOR_VERSION}" AND
"${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}" GREATER "${CMAKE_MINOR_VERSION}")
set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}")
else()
set(ZSTD_CMAKE_POLICY_VERSION "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}.${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}.0")
endif()
cmake_policy(VERSION ${ZSTD_CMAKE_POLICY_VERSION})
set(CMAKE_BUILD_WITH_INSTALL_RPATH on)
#-----------------------------------------------------------------------------
# Setup CMake environment
#-----------------------------------------------------------------------------
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
# Define project paths
set(ZSTD_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..") set(ZSTD_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib) set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib)
# Parse version
include(GetZstdLibraryVersion)
GetZstdLibraryVersion(${LIBRARY_DIR}/zstd.h zstd_VERSION_MAJOR zstd_VERSION_MINOR zstd_VERSION_PATCH)
#-----------------------------------------------------------------------------
# Configure CMake policies and version
#-----------------------------------------------------------------------------
include(ZstdVersion)
#-----------------------------------------------------------------------------
# Project declaration
#-----------------------------------------------------------------------------
project(zstd project(zstd
VERSION "${ZSTD_FULL_VERSION}" VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}"
LANGUAGES C ASM # Main library is in C and ASM LANGUAGES C # Main library is in C
HOMEPAGE_URL "${zstd_HOMEPAGE_URL}" ASM # And ASM
DESCRIPTION "${zstd_DESCRIPTION}" CXX # Testing contributed code also utilizes CXX
) )
#----------------------------------------------------------------------------- message(STATUS "ZSTD VERSION: ${zstd_VERSION}")
# Build type configuration set(zstd_HOMEPAGE_URL "https://facebook.github.io/zstd")
#----------------------------------------------------------------------------- set(zstd_DESCRIPTION "Zstandard is a real-time compression algorithm, providing high compression ratios.")
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.") message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") # Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif() endif()
#-----------------------------------------------------------------------------
# Include standard modules
#-----------------------------------------------------------------------------
include(GNUInstallDirs) include(GNUInstallDirs)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Display installation information # Add extra compilation flags
#-----------------------------------------------------------------------------
include(AddZstdCompilationFlags)
ADD_ZSTD_COMPILATION_FLAGS()
# Always hide XXHash symbols
add_definitions(-DXXH_NAMESPACE=ZSTD_)
#-----------------------------------------------------------------------------
# Installation variables
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}") message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}") message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}")
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Configure build options # Options
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
include(ZstdOptions)
# Legacy support
option(ZSTD_LEGACY_SUPPORT "LEGACY SUPPORT" ON)
if (ZSTD_LEGACY_SUPPORT)
message(STATUS "ZSTD_LEGACY_SUPPORT defined!")
set(ZSTD_LEGACY_LEVEL 5 CACHE STRING "")
add_definitions(-DZSTD_LEGACY_SUPPORT=${ZSTD_LEGACY_LEVEL})
else ()
message(STATUS "ZSTD_LEGACY_SUPPORT not defined!")
add_definitions(-DZSTD_LEGACY_SUPPORT=0)
endif ()
if (ANDROID)
set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT OFF)
else()
set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT ON)
endif()
# Multi-threading support
option(ZSTD_MULTITHREAD_SUPPORT "MULTITHREADING SUPPORT" ${ZSTD_MULTITHREAD_SUPPORT_DEFAULT})
if (ZSTD_MULTITHREAD_SUPPORT)
message(STATUS "ZSTD_MULTITHREAD_SUPPORT is enabled")
else ()
message(STATUS "ZSTD_MULTITHREAD_SUPPORT is disabled")
endif ()
option(ZSTD_BUILD_PROGRAMS "BUILD PROGRAMS" ON)
option(ZSTD_BUILD_CONTRIB "BUILD CONTRIB" OFF)
# Respect the conventional CMake option for enabling tests if it was specified on the first configure
if (BUILD_TESTING)
set(ZSTD_BUILD_TESTS_default ON)
else()
set(ZSTD_BUILD_TESTS_default OFF)
endif()
option(ZSTD_BUILD_TESTS "BUILD TESTS" ${ZSTD_BUILD_TESTS_default})
if (MSVC)
option(ZSTD_USE_STATIC_RUNTIME "LINK TO STATIC RUN-TIME LIBRARIES" OFF)
endif ()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Configure compilation flags # External dependencies
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
include(AddZstdCompilationFlags) # Define a function to handle special thread settings for HP-UX
ADD_ZSTD_COMPILATION_FLAGS(ON ZSTD_ENABLE_CXX ON) # See https://github.com/facebook/zstd/pull/3862 for details.
function(setup_hpux_threads)
find_package(Threads)
if (NOT Threads_FOUND)
set(CMAKE_USE_PTHREADS_INIT 1 PARENT_SCOPE)
set(CMAKE_THREAD_LIBS_INIT -lpthread PARENT_SCOPE)
set(CMAKE_HAVE_THREADS_LIBRARY 1 PARENT_SCOPE)
set(Threads_FOUND TRUE PARENT_SCOPE)
endif()
endfunction()
if (ZSTD_MULTITHREAD_SUPPORT AND UNIX)
if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
setup_hpux_threads()
else()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()
if (CMAKE_USE_PTHREADS_INIT)
set(THREADS_LIBS "${CMAKE_THREAD_LIBS_INIT}")
else()
message(SEND_ERROR "ZSTD currently does not support thread libraries other than pthreads")
endif()
endif ()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Configure dependencies # Add source directories
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
include(ZstdDependencies) add_subdirectory(lib)
option(ZSTD_PROGRAMS_LINK_SHARED "PROGRAMS LINK SHARED" OFF)
if (ZSTD_BUILD_PROGRAMS)
if (NOT ZSTD_BUILD_STATIC AND NOT ZSTD_PROGRAMS_LINK_SHARED)
message(SEND_ERROR "You need to build static library to build zstd CLI")
elseif(NOT ZSTD_BUILD_SHARED AND ZSTD_PROGRAMS_LINK_SHARED)
message(SEND_ERROR "You need to build shared library to build zstd CLI")
endif ()
add_subdirectory(programs)
endif ()
if (ZSTD_BUILD_TESTS)
enable_testing()
if (NOT ZSTD_BUILD_STATIC)
message(SEND_ERROR "You need to build static library to build tests")
endif ()
add_subdirectory(tests)
endif ()
if (ZSTD_BUILD_CONTRIB)
add_subdirectory(contrib)
endif ()
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Configure build targets # Add clean-all target
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
include(ZstdBuild) add_custom_target(clean-all
COMMAND ${CMAKE_BUILD_TOOL} clean
COMMAND rm -rf ${CMAKE_BINARY_DIR}/
)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Configure package generation # Generate Package Config files
#
# This section is based on the boiler plate code from:
# https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
include(ZstdPackage) include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
VERSION ${zstd_VERSION}
COMPATIBILITY SameMajorVersion
)
# A Package Config file that works from the build directory
export(EXPORT zstdExports
FILE "${CMAKE_CURRENT_BINARY_DIR}/zstdTargets.cmake"
NAMESPACE zstd::
)
# A Package Config file that works from the installation directory
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/zstd)
install(EXPORT zstdExports
FILE zstdTargets.cmake
NAMESPACE zstd::
DESTINATION ${ConfigPackageLocation}
)
configure_package_config_file(
zstdConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake"
INSTALL_DESTINATION ${ConfigPackageLocation}
)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
DESTINATION ${ConfigPackageLocation}
)

View File

@ -1,12 +1,11 @@
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
if(CMAKE_CXX_COMPILER) # VERSION_GREATER_EQUAL requires CMake 3.7 or later.
include(CheckCXXCompilerFlag) # https://cmake.org/cmake/help/latest/command/if.html#version-greater-equal
endif() if (CMAKE_VERSION VERSION_LESS 3.18)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
set(ZSTD_HAVE_CHECK_LINKER_FLAG true)
else ()
set(ZSTD_HAVE_CHECK_LINKER_FLAG false) set(ZSTD_HAVE_CHECK_LINKER_FLAG false)
else ()
set(ZSTD_HAVE_CHECK_LINKER_FLAG true)
endif () endif ()
if (ZSTD_HAVE_CHECK_LINKER_FLAG) if (ZSTD_HAVE_CHECK_LINKER_FLAG)
include(CheckLinkerFlag) include(CheckLinkerFlag)
@ -23,7 +22,7 @@ function(EnableCompilerFlag _flag _C _CXX _LD)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}" PARENT_SCOPE) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_flag}" PARENT_SCOPE)
endif () endif ()
endif () endif ()
if (_CXX AND CMAKE_CXX_COMPILER) if (_CXX)
CHECK_CXX_COMPILER_FLAG(${_flag} CXX_FLAG_${varname}) CHECK_CXX_COMPILER_FLAG(${_flag} CXX_FLAG_${varname})
if (CXX_FLAG_${varname}) if (CXX_FLAG_${varname})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE)
@ -51,65 +50,49 @@ function(EnableCompilerFlag _flag _C _CXX _LD)
endif () endif ()
endfunction() endfunction()
macro(ADD_ZSTD_COMPILATION_FLAGS _C _CXX _LD) macro(ADD_ZSTD_COMPILATION_FLAGS)
# We set ZSTD_HAS_NOEXECSTACK if we are certain we've set all the required
# compiler flags to mark the stack as non-executable.
set(ZSTD_HAS_NOEXECSTACK false)
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" OR MINGW) #Not only UNIX but also WIN32 for MinGW if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang" OR MINGW) #Not only UNIX but also WIN32 for MinGW
# It's possible to select the exact standard used for compilation. # It's possible to select the exact standard used for compilation.
# It's not necessary, but can be employed for specific purposes. # It's not necessary, but can be employed for specific purposes.
# Note that zstd source code is compatible with both C++98 and above # Note that zstd source code is compatible with both C++98 and above
# and C-gnu90 (c90 + long long + variadic macros ) and above # and C-gnu90 (c90 + long long + variadic macros ) and above
# EnableCompilerFlag("-std=c++11" false true) # Set C++ compilation to c++11 standard # EnableCompilerFlag("-std=c++11" false true) # Set C++ compilation to c++11 standard
# EnableCompilerFlag("-std=c99" true false) # Set C compilation 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" _C _CXX false) EnableCompilerFlag("/clang:-Wall" true true false)
else () else ()
EnableCompilerFlag("-Wall" _C _CXX false) EnableCompilerFlag("-Wall" true true false)
endif () endif ()
EnableCompilerFlag("-Wextra" _C _CXX false) EnableCompilerFlag("-Wextra" true true false)
EnableCompilerFlag("-Wundef" _C _CXX false) EnableCompilerFlag("-Wundef" true true false)
EnableCompilerFlag("-Wshadow" _C _CXX false) EnableCompilerFlag("-Wshadow" true true false)
EnableCompilerFlag("-Wcast-align" _C _CXX false) EnableCompilerFlag("-Wcast-align" true true false)
EnableCompilerFlag("-Wcast-qual" _C _CXX false) EnableCompilerFlag("-Wcast-qual" true true false)
EnableCompilerFlag("-Wstrict-prototypes" _C false 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" _C _CXX false) EnableCompilerFlag("-DDEBUGLEVEL=1" true true false)
endif () endif ()
# Add noexecstack flags # Add noexecstack flags
# LDFLAGS # LDFLAGS
EnableCompilerFlag("-Wl,-z,noexecstack" false false _LD) EnableCompilerFlag("-z noexecstack" false false true)
# CFLAGS & CXXFLAGS # CFLAGS & CXXFLAGS
EnableCompilerFlag("-Qunused-arguments" _C _CXX false) EnableCompilerFlag("-Qunused-arguments" true true false)
EnableCompilerFlag("-Wa,--noexecstack" _C _CXX false) EnableCompilerFlag("-Wa,--noexecstack" true true false)
# NOTE: Using 3 nested ifs because the variables are sometimes
# empty if the condition is false, and sometimes equal to false.
# This implicitly converts them to truthy values. There may be
# a better way to do this, but this reliably works.
if (${LD_FLAG_WL_Z_NOEXECSTACK})
if (${C_FLAG_WA_NOEXECSTACK})
if (${CXX_FLAG_WA_NOEXECSTACK})
# We've succeeded in marking the stack as non-executable
set(ZSTD_HAS_NOEXECSTACK true)
endif()
endif()
endif()
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" _C _CXX false) EnableCompilerFlag("/MP" true true false)
endif () endif ()
# UNICODE SUPPORT # UNICODE SUPPORT
EnableCompilerFlag("/D_UNICODE" _C _CXX false) EnableCompilerFlag("/D_UNICODE" true true false)
EnableCompilerFlag("/DUNICODE" _C _CXX false) 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" _C _CXX false) EnableCompilerFlag("/DDEBUGLEVEL=1" true true false)
endif () endif ()
endif () endif ()

View File

@ -1,42 +0,0 @@
# ################################################################
# ZSTD Build Targets Configuration
# ################################################################
# Always build the library first (this defines ZSTD_BUILD_STATIC/SHARED options)
add_subdirectory(lib)
# Validate build configuration after lib options are defined
if(ZSTD_BUILD_PROGRAMS)
if(NOT ZSTD_BUILD_STATIC AND NOT ZSTD_PROGRAMS_LINK_SHARED)
message(SEND_ERROR "Static library required to build zstd CLI programs")
elseif(NOT ZSTD_BUILD_SHARED AND ZSTD_PROGRAMS_LINK_SHARED)
message(SEND_ERROR "Shared library required to build zstd CLI programs")
endif()
endif()
if(ZSTD_BUILD_TESTS AND NOT ZSTD_BUILD_STATIC)
message(SEND_ERROR "Static library required to build test suite")
endif()
# Add programs if requested
if(ZSTD_BUILD_PROGRAMS)
add_subdirectory(programs)
endif()
# Add tests if requested
if(ZSTD_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
# Add contrib utilities if requested
if(ZSTD_BUILD_CONTRIB)
add_subdirectory(contrib)
endif()
# Clean-all target for thorough cleanup
add_custom_target(clean-all
COMMAND ${CMAKE_BUILD_TOOL} clean
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/
COMMENT "Performing complete clean including build directory"
)

View File

@ -1,30 +0,0 @@
# ################################################################
# ZSTD Dependencies Configuration
# ################################################################
# Function to handle HP-UX thread configuration
function(setup_hpux_threads)
find_package(Threads)
if(NOT Threads_FOUND)
set(CMAKE_USE_PTHREADS_INIT 1 PARENT_SCOPE)
set(CMAKE_THREAD_LIBS_INIT -lpthread PARENT_SCOPE)
set(CMAKE_HAVE_THREADS_LIBRARY 1 PARENT_SCOPE)
set(Threads_FOUND TRUE PARENT_SCOPE)
endif()
endfunction()
# Configure threading support
if(ZSTD_MULTITHREAD_SUPPORT AND UNIX)
if(CMAKE_SYSTEM_NAME MATCHES "HP-UX")
setup_hpux_threads()
else()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()
if(CMAKE_USE_PTHREADS_INIT)
set(THREADS_LIBS "${CMAKE_THREAD_LIBS_INIT}")
else()
message(SEND_ERROR "ZSTD currently does not support thread libraries other than pthreads")
endif()
endif()

View File

@ -1,68 +0,0 @@
# ################################################################
# ZSTD Build Options Configuration
# ################################################################
# Legacy support configuration
option(ZSTD_LEGACY_SUPPORT "Enable legacy format support" ON)
if(ZSTD_LEGACY_SUPPORT)
message(STATUS "ZSTD_LEGACY_SUPPORT enabled")
set(ZSTD_LEGACY_LEVEL 5 CACHE STRING "Legacy support level")
add_definitions(-DZSTD_LEGACY_SUPPORT=${ZSTD_LEGACY_LEVEL})
else()
message(STATUS "ZSTD_LEGACY_SUPPORT disabled")
add_definitions(-DZSTD_LEGACY_SUPPORT=0)
endif()
# Platform-specific options
if(APPLE)
option(ZSTD_FRAMEWORK "Build as Apple Framework" OFF)
endif()
# Android-specific configuration
if(ANDROID)
set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT OFF)
# Handle old Android API levels
if((NOT ANDROID_PLATFORM_LEVEL) OR (ANDROID_PLATFORM_LEVEL VERSION_LESS 24))
message(STATUS "Configuring for old Android API - disabling fseeko/ftello")
add_compile_definitions(LIBC_NO_FSEEKO)
endif()
else()
set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT ON)
endif()
# Multi-threading support
option(ZSTD_MULTITHREAD_SUPPORT "Enable multi-threading support" ${ZSTD_MULTITHREAD_SUPPORT_DEFAULT})
if(ZSTD_MULTITHREAD_SUPPORT)
message(STATUS "Multi-threading support enabled")
else()
message(STATUS "Multi-threading support disabled")
endif()
# Build component options
option(ZSTD_BUILD_PROGRAMS "Build command-line programs" ON)
option(ZSTD_BUILD_CONTRIB "Build contrib utilities" OFF)
option(ZSTD_PROGRAMS_LINK_SHARED "Link programs against shared library" OFF)
# Test configuration
if(BUILD_TESTING)
set(ZSTD_BUILD_TESTS_default ON)
else()
set(ZSTD_BUILD_TESTS_default OFF)
endif()
option(ZSTD_BUILD_TESTS "Build test suite" ${ZSTD_BUILD_TESTS_default})
# MSVC-specific options
if(MSVC)
option(ZSTD_USE_STATIC_RUNTIME "Link to static runtime libraries" OFF)
endif()
# C++ support (needed for tests)
set(ZSTD_ENABLE_CXX ${ZSTD_BUILD_TESTS})
if(ZSTD_ENABLE_CXX)
enable_language(CXX)
endif()
# Set global definitions
add_definitions(-DXXH_NAMESPACE=ZSTD_)

View File

@ -1,42 +0,0 @@
# ################################################################
# ZSTD Package Configuration
# ################################################################
include(CMakePackageConfigHelpers)
# Generate version file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
VERSION ${zstd_VERSION}
COMPATIBILITY SameMajorVersion
)
# Export targets for build directory
export(EXPORT zstdExports
FILE "${CMAKE_CURRENT_BINARY_DIR}/zstdTargets.cmake"
NAMESPACE zstd::
)
# Configure package for installation
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/zstd)
# Install exported targets
install(EXPORT zstdExports
FILE zstdTargets.cmake
NAMESPACE zstd::
DESTINATION ${ConfigPackageLocation}
)
# Configure and install package config file
configure_package_config_file(
zstdConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake"
INSTALL_DESTINATION ${ConfigPackageLocation}
)
# Install config files
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
DESTINATION ${ConfigPackageLocation}
)

View File

@ -1,31 +0,0 @@
# ################################################################
# ZSTD Version Configuration
# ################################################################
# Setup CMake policy version
set(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3")
set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13")
# Determine appropriate policy version
if("${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}" EQUAL "${CMAKE_MAJOR_VERSION}" AND
"${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}" GREATER "${CMAKE_MINOR_VERSION}")
set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}")
else()
set(ZSTD_CMAKE_POLICY_VERSION "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}.${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}.0")
endif()
cmake_policy(VERSION ${ZSTD_CMAKE_POLICY_VERSION})
# Parse version from header file
include(GetZstdLibraryVersion)
GetZstdLibraryVersion(${LIBRARY_DIR}/zstd.h zstd_VERSION_MAJOR zstd_VERSION_MINOR zstd_VERSION_PATCH)
# Set version variables
set(ZSTD_SHORT_VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}")
set(ZSTD_FULL_VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}")
# Project metadata
set(zstd_HOMEPAGE_URL "https://facebook.github.io/zstd")
set(zstd_DESCRIPTION "Zstandard is a real-time compression algorithm, providing high compression ratios.")
message(STATUS "ZSTD VERSION: ${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}")

View File

@ -41,16 +41,6 @@ cmake -DZSTD_BUILD_TESTS=ON -DZSTD_LEGACY_SUPPORT=OFF ..
make make
``` ```
**Apple Frameworks**
It's generally recommended to have CMake with versions higher than 3.14 for [iOS-derived platforms](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#id27).
```sh
cmake -S. -B build-cmake -DZSTD_FRAMEWORK=ON -DCMAKE_SYSTEM_NAME=iOS
```
Or you can utilize [iOS-CMake](https://github.com/leetal/ios-cmake) toolchain for CMake versions lower than 3.14
```sh
cmake -B build -G Xcode -DCMAKE_TOOLCHAIN_FILE=<Path To ios.toolchain.cmake> -DPLATFORM=OS64 -DZSTD_FRAMEWORK=ON
```
### how to use it with CMake FetchContent ### how to use it with CMake FetchContent
For all options available, you can see it on <https://github.com/facebook/zstd/blob/dev/build/cmake/lib/CMakeLists.txt> For all options available, you can see it on <https://github.com/facebook/zstd/blob/dev/build/cmake/lib/CMakeLists.txt>

View File

@ -39,7 +39,7 @@ file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c)
if (MSVC) if (MSVC)
add_compile_options(-DZSTD_DISABLE_ASM) add_compile_options(-DZSTD_DISABLE_ASM)
else () else ()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|AMD64.*|x86_64.*|X86_64.*" AND ${ZSTD_HAS_NOEXECSTACK}) if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|AMD64.*|x86_64.*|X86_64.*")
set(DecompressSources ${DecompressSources} ${LIBRARY_DIR}/decompress/huf_decompress_amd64.S) set(DecompressSources ${DecompressSources} ${LIBRARY_DIR}/decompress/huf_decompress_amd64.S)
else() else()
add_compile_options(-DZSTD_DISABLE_ASM) add_compile_options(-DZSTD_DISABLE_ASM)
@ -97,11 +97,9 @@ if (ZSTD_LEGACY_SUPPORT)
${LIBRARY_LEGACY_DIR}/zstd_v07.h) ${LIBRARY_LEGACY_DIR}/zstd_v07.h)
endif () endif ()
if (MSVC AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) if (MSVC)
set(MSVC_RESOURCE_DIR ${ZSTD_SOURCE_DIR}/build/VS2010/libzstd-dll) set(MSVC_RESOURCE_DIR ${ZSTD_SOURCE_DIR}/build/VS2010/libzstd-dll)
set(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc) set(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc)
else()
set(PlatformDependResources)
endif () endif ()
# Explicitly set the language to C for all files, including ASM files. # Explicitly set the language to C for all files, including ASM files.
@ -114,13 +112,13 @@ endif()
macro (add_definition target var) macro (add_definition target var)
if (NOT ("${${var}}" STREQUAL "")) if (NOT ("${${var}}" STREQUAL ""))
target_compile_definitions(${target} PUBLIC "${var}=__attribute__((visibility(\"${${var}}\")))") set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS "${var}=__attribute__((visibility(\"${${var}}\")))")
endif () endif ()
endmacro () endmacro ()
# Define directories containing the library's public headers # Define directories containing the library's public headers
set(PUBLIC_INCLUDE_DIRS ${LIBRARY_DIR}) set(PUBLIC_INCLUDE_DIRS ${LIBRARY_DIR})
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /I \"${LIBRARY_DIR}\"")
# 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)
@ -128,7 +126,7 @@ if (ZSTD_BUILD_SHARED)
target_include_directories(libzstd_shared INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>) target_include_directories(libzstd_shared INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>)
list(APPEND library_targets libzstd_shared) list(APPEND library_targets libzstd_shared)
if (ZSTD_MULTITHREAD_SUPPORT) if (ZSTD_MULTITHREAD_SUPPORT)
target_compile_definitions(libzstd_shared PUBLIC ZSTD_MULTITHREAD) set_property(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD")
if (UNIX) if (UNIX)
target_link_libraries(libzstd_shared ${THREADS_LIBS}) target_link_libraries(libzstd_shared ${THREADS_LIBS})
endif () endif ()
@ -142,7 +140,7 @@ if (ZSTD_BUILD_STATIC)
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>) target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>)
list(APPEND library_targets libzstd_static) list(APPEND library_targets libzstd_static)
if (ZSTD_MULTITHREAD_SUPPORT) if (ZSTD_MULTITHREAD_SUPPORT)
target_compile_definitions(libzstd_static PUBLIC ZSTD_MULTITHREAD) set_property(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD")
if (UNIX) if (UNIX)
target_link_libraries(libzstd_static ${THREADS_LIBS}) target_link_libraries(libzstd_static ${THREADS_LIBS})
endif () endif ()
@ -207,28 +205,8 @@ if (ZSTD_BUILD_SHARED)
libzstd_shared libzstd_shared
PROPERTIES PROPERTIES
OUTPUT_NAME zstd OUTPUT_NAME zstd
VERSION ${ZSTD_FULL_VERSION} VERSION ${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}.${zstd_VERSION_PATCH}
SOVERSION ${zstd_VERSION_MAJOR}) SOVERSION ${zstd_VERSION_MAJOR})
if (ZSTD_FRAMEWORK)
set_target_properties(
libzstd_shared
PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${ZSTD_FULL_VERSION}"
PRODUCT_BUNDLE_IDENTIFIER "github.com/facebook/zstd"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
PUBLIC_HEADER "${PublicHeaders}"
OUTPUT_NAME "zstd"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
MACOSX_FRAMEWORK_IDENTIFIER "github.com/facebook/zstd"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${ZSTD_FULL_VERSION}"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${ZSTD_SHORT_VERSION}"
MACOSX_RPATH TRUE
RESOURCE ${PublicHeaders})
endif ()
endif () endif ()
if (ZSTD_BUILD_STATIC) if (ZSTD_BUILD_STATIC)
@ -237,26 +215,6 @@ if (ZSTD_BUILD_STATIC)
PROPERTIES PROPERTIES
POSITION_INDEPENDENT_CODE On POSITION_INDEPENDENT_CODE On
OUTPUT_NAME ${STATIC_LIBRARY_BASE_NAME}) OUTPUT_NAME ${STATIC_LIBRARY_BASE_NAME})
if (ZSTD_FRAMEWORK)
set_target_properties(
libzstd_static
PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION "${ZSTD_FULL_VERSION}"
PRODUCT_BUNDLE_IDENTIFIER "github.com/facebook/zstd/${STATIC_LIBRARY_BASE_NAME}"
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
PUBLIC_HEADER "${PublicHeaders}"
OUTPUT_NAME "${STATIC_LIBRARY_BASE_NAME}"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
MACOSX_FRAMEWORK_IDENTIFIER "github.com/facebook/zstd/${STATIC_LIBRARY_BASE_NAME}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${ZSTD_FULL_VERSION}"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${ZSTD_SHORT_VERSION}"
MACOSX_RPATH TRUE
RESOURCE ${PublicHeaders})
endif ()
endif () endif ()
# pkg-config # pkg-config
@ -281,8 +239,6 @@ install(TARGETS ${library_targets}
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}" BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}"
FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime OPTIONAL
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
) )
# uninstall target # uninstall target

View File

@ -20,6 +20,6 @@ pzstd = executable('pzstd',
pzstd_sources, pzstd_sources,
cpp_args: pzstd_warning_flags, cpp_args: pzstd_warning_flags,
include_directories: pzstd_includes, include_directories: pzstd_includes,
dependencies: [ libzstd_internal_dep, thread_dep ], dependencies: [ libzstd_dep, thread_dep ],
override_options: ['b_ndebug=true'], override_options: ['b_ndebug=true'],
install: true) install: true)

View File

@ -30,7 +30,6 @@ libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'),
join_paths(zstd_rootdir, 'lib/compress/zstd_compress_literals.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_compress_literals.c'),
join_paths(zstd_rootdir, 'lib/compress/zstd_compress_sequences.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_compress_sequences.c'),
join_paths(zstd_rootdir, 'lib/compress/zstd_compress_superblock.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_compress_superblock.c'),
join_paths(zstd_rootdir, 'lib/compress/zstd_preSplit.c'),
join_paths(zstd_rootdir, 'lib/compress/zstdmt_compress.c'), join_paths(zstd_rootdir, 'lib/compress/zstdmt_compress.c'),
join_paths(zstd_rootdir, 'lib/compress/zstd_fast.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_fast.c'),
join_paths(zstd_rootdir, 'lib/compress/zstd_double_fast.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_double_fast.c'),
@ -125,7 +124,7 @@ libzstd = library('zstd',
version: zstd_libversion) version: zstd_libversion)
libzstd_dep = declare_dependency(link_with: libzstd, libzstd_dep = declare_dependency(link_with: libzstd,
include_directories: join_paths(zstd_rootdir,'lib')) # Do not expose private headers include_directories: libzstd_includes)
# we link to both: # we link to both:
# - the shared library (for public symbols) # - the shared library (for public symbols)
@ -135,8 +134,7 @@ libzstd_dep = declare_dependency(link_with: libzstd,
# -fvisibility=hidden means those cannot be found # -fvisibility=hidden means those cannot be found
if get_option('default_library') == 'static' if get_option('default_library') == 'static'
libzstd_static = libzstd libzstd_static = libzstd
libzstd_internal_dep = declare_dependency(link_with: libzstd, libzstd_internal_dep = libzstd_dep
include_directories: libzstd_includes)
else else
if get_option('default_library') == 'shared' if get_option('default_library') == 'shared'
libzstd_static = static_library('zstd_objlib', libzstd_static = static_library('zstd_objlib',
@ -149,13 +147,11 @@ else
if cc_id == compiler_msvc if cc_id == compiler_msvc
# msvc does not actually support linking to both, but errors out with: # msvc does not actually support linking to both, but errors out with:
# error LNK2005: ZSTD_<foo> already defined in zstd.lib(zstd-1.dll) # error LNK2005: ZSTD_<foo> already defined in zstd.lib(zstd-1.dll)
libzstd_internal_dep = declare_dependency(link_with: libzstd_static, libzstd_internal_dep = declare_dependency(link_with: libzstd_static)
include_directories: libzstd_includes)
else else
libzstd_internal_dep = declare_dependency(link_with: libzstd, libzstd_internal_dep = declare_dependency(link_with: libzstd,
# the static library must be linked after the shared one # the static library must be linked after the shared one
dependencies: declare_dependency(link_with: libzstd_static), dependencies: declare_dependency(link_with: libzstd_static))
include_directories: libzstd_includes)
endif endif
endif endif

View File

@ -10,7 +10,7 @@
project('zstd', project('zstd',
['c', 'cpp'], ['c', 'cpp'],
license: 'BSD-3-Clause OR GPL-2.0-only', license: ['BSD', 'GPLv2'],
default_options : [ default_options : [
# There shouldn't be any need to force a C standard convention for zstd # There shouldn't be any need to force a C standard convention for zstd
# but in case one would want that anyway, this can be done here. # but in case one would want that anyway, this can be done here.
@ -65,6 +65,7 @@ zstd_docdir = join_paths(zstd_datadir, 'doc', meson.project_name())
# Built-in options # Built-in options
use_debug = get_option('debug') use_debug = get_option('debug')
buildtype = get_option('buildtype')
default_library_type = get_option('default_library') default_library_type = get_option('default_library')
# Custom options # Custom options
@ -87,13 +88,8 @@ feature_lz4 = get_option('lz4')
# ============================================================================= # =============================================================================
libm_dep = cc.find_library('m', required: false) libm_dep = cc.find_library('m', required: false)
if host_machine_os == os_windows thread_dep = dependency('threads', required: feature_multi_thread)
thread_dep = dependency('', required: false) use_multi_thread = thread_dep.found()
use_multi_thread = not feature_multi_thread.disabled()
else
thread_dep = dependency('threads', required: feature_multi_thread)
use_multi_thread = thread_dep.found()
endif
# Arguments in dependency should be equivalent to those passed to pkg-config # Arguments in dependency should be equivalent to those passed to pkg-config
zlib_dep = dependency('zlib', required: feature_zlib) zlib_dep = dependency('zlib', required: feature_zlib)
use_zlib = zlib_dep.found() use_zlib = zlib_dep.found()
@ -115,16 +111,10 @@ if [compiler_gcc, compiler_clang].contains(cc_id)
if cc_id == compiler_clang if cc_id == compiler_clang
common_warning_flags += ['-Wconversion', '-Wno-sign-conversion', '-Wdocumentation'] common_warning_flags += ['-Wconversion', '-Wno-sign-conversion', '-Wdocumentation']
endif endif
noexecstack_flags = ['-Wa,--noexecstack' ] cc_compile_flags = cc.get_supported_arguments(common_warning_flags + ['-Wstrict-prototypes'])
noexecstack_link_flags = ['-Wl,-z,noexecstack'] cxx_compile_flags = cxx.get_supported_arguments(common_warning_flags)
cc_compile_flags = cc.get_supported_arguments(common_warning_flags + noexecstack_flags + ['-Wstrict-prototypes'])
cxx_compile_flags = cxx.get_supported_arguments(common_warning_flags + noexecstack_flags)
add_project_arguments(cc_compile_flags, language : 'c') add_project_arguments(cc_compile_flags, language : 'c')
add_project_arguments(cxx_compile_flags, language : 'cpp') add_project_arguments(cxx_compile_flags, language : 'cpp')
cc_link_flags = cc.get_supported_link_arguments(noexecstack_link_flags)
cxx_link_flags = cxx.get_supported_link_arguments(noexecstack_link_flags)
add_project_link_arguments(cc_link_flags, language: 'c')
add_project_link_arguments(cxx_link_flags, language: 'cpp')
elif cc_id == compiler_msvc elif cc_id == compiler_msvc
msvc_compile_flags = [ '/D_UNICODE', '/DUNICODE' ] msvc_compile_flags = [ '/D_UNICODE', '/DUNICODE' ]
if use_multi_thread if use_multi_thread

View File

@ -27,7 +27,7 @@ option('bin_contrib', type: 'boolean', value: false,
description: 'Enable contrib build') description: 'Enable contrib build')
option('multi_thread', type: 'feature', value: 'enabled', option('multi_thread', type: 'feature', value: 'enabled',
description: 'Enable multi-threading when pthread or Windows is detected') description: 'Enable multi-threading when pthread is detected')
option('zlib', type: 'feature', value: 'auto', option('zlib', type: 'feature', value: 'auto',
description: 'Enable zlib support') description: 'Enable zlib support')
option('lzma', type: 'feature', value: 'auto', option('lzma', type: 'feature', value: 'auto',

View File

@ -93,7 +93,7 @@ roundTripCrash = executable('roundTripCrash',
longmatch_sources = [join_paths(zstd_rootdir, 'tests/longmatch.c')] longmatch_sources = [join_paths(zstd_rootdir, 'tests/longmatch.c')]
longmatch = executable('longmatch', longmatch = executable('longmatch',
longmatch_sources, longmatch_sources,
dependencies: [ libzstd_internal_dep ], dependencies: [ libzstd_dep ],
install: false) install: false)
invalidDictionaries_sources = [join_paths(zstd_rootdir, 'tests/invalidDictionaries.c')] invalidDictionaries_sources = [join_paths(zstd_rootdir, 'tests/invalidDictionaries.c')]

View File

@ -4,7 +4,6 @@ zstddeclib.c
zstdenclib.c zstdenclib.c
zstd.c zstd.c
zstd.h zstd.h
zstd_errors.h
# test artifacts # test artifacts
temp* temp*

View File

@ -70,7 +70,6 @@ echo "Single file library creation script: PASSED"
# Copy the header to here (for the tests) # Copy the header to here (for the tests)
cp "$ZSTD_SRC_ROOT/zstd.h" examples/zstd.h cp "$ZSTD_SRC_ROOT/zstd.h" examples/zstd.h
cp "$ZSTD_SRC_ROOT/zstd_errors.h" examples/zstd_errors.h
# Compile the generated output # Compile the generated output
cc -Wall -Wextra -Werror -Wshadow -pthread -I. -Os -g0 -o $OUT_FILE zstd.c examples/roundtrip.c cc -Wall -Wextra -Werror -Wshadow -pthread -I. -Os -g0 -o $OUT_FILE zstd.c examples/roundtrip.c

View File

@ -69,7 +69,6 @@
#include "compress/zstd_compress_literals.c" #include "compress/zstd_compress_literals.c"
#include "compress/zstd_compress_sequences.c" #include "compress/zstd_compress_sequences.c"
#include "compress/zstd_compress_superblock.c" #include "compress/zstd_compress_superblock.c"
#include "compress/zstd_preSplit.c"
#include "compress/zstd_compress.c" #include "compress/zstd_compress.c"
#include "compress/zstd_double_fast.c" #include "compress/zstd_double_fast.c"
#include "compress/zstd_fast.c" #include "compress/zstd_fast.c"

View File

@ -27,7 +27,6 @@ do { \
} while (0) \ } while (0) \
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int retn = 0;
if (argc != 2) { if (argc != 2) {
printf("Usage: externalSequenceProducer <file>\n"); printf("Usage: externalSequenceProducer <file>\n");
return 1; return 1;
@ -97,12 +96,12 @@ int main(int argc, char *argv[]) {
break; break;
} }
} }
retn = 1; return 1;
} }
ZSTD_freeCCtx(zc); ZSTD_freeCCtx(zc);
free(src); free(src);
free(dst); free(dst);
free(val); free(val);
return retn; return 0;
} }

View File

@ -40,7 +40,7 @@ gen_html: gen_html.cpp
$(ZSTDMANUAL): gen_html $(ZSTDAPI) $(ZSTDMANUAL): gen_html $(ZSTDAPI)
echo "Update zstd manual in /doc" echo "Update zstd manual in /doc"
./gen_html$(EXT) $(LIBVER) $(ZSTDAPI) $(ZSTDMANUAL) ./gen_html $(LIBVER) $(ZSTDAPI) $(ZSTDMANUAL)
.PHONY: manual .PHONY: manual
manual: gen_html $(ZSTDMANUAL) manual: gen_html $(ZSTDMANUAL)

View File

@ -211,7 +211,6 @@ int main(int argc, char *argv[]) {
ostream << "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n<title>" << version << "</title>\n</head>\n<body>" << endl; ostream << "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">\n<title>" << version << "</title>\n</head>\n<body>" << endl;
ostream << "<h1>" << version << "</h1>\n"; ostream << "<h1>" << version << "</h1>\n";
ostream << "Note: the content of this file has been automatically generated by parsing \"zstd.h\" \n";
ostream << "<hr>\n<a name=\"Contents\"></a><h2>Contents</h2>\n<ol>\n"; ostream << "<hr>\n<a name=\"Contents\"></a><h2>Contents</h2>\n<ol>\n";
for (size_t i=0; i<chapters.size(); i++) for (size_t i=0; i<chapters.size(); i++)

View File

@ -739,8 +739,6 @@ static int benchMem(slice_collection_t dstBlocks, slice_collection_t srcBlocks,
/* BMK_benchTimedFn may not run exactly nbRounds iterations */ /* BMK_benchTimedFn may not run exactly nbRounds iterations */
double speedAggregated = double speedAggregated =
aggregateData(speedPerRound, roundNb + 1, metricAggregatePref); aggregateData(speedPerRound, roundNb + 1, metricAggregatePref);
free(speedPerRound);
if (metricAggregatePref == fastest) if (metricAggregatePref == fastest)
DISPLAY("Fastest Speed : %.1f MB/s \n", speedAggregated); DISPLAY("Fastest Speed : %.1f MB/s \n", speedAggregated);
else else
@ -1027,7 +1025,7 @@ int main (int argc, const char** argv)
unsigned nbBlocks = 0; /* determine nbBlocks automatically, from source and blockSize */ unsigned nbBlocks = 0; /* determine nbBlocks automatically, from source and blockSize */
ZSTD_dictContentType_e dictContentType = ZSTD_dct_auto; ZSTD_dictContentType_e dictContentType = ZSTD_dct_auto;
ZSTD_dictAttachPref_e dictAttachPref = ZSTD_dictDefaultAttach; ZSTD_dictAttachPref_e dictAttachPref = ZSTD_dictDefaultAttach;
ZSTD_ParamSwitch_e prefetchCDictTables = ZSTD_ps_auto; ZSTD_paramSwitch_e prefetchCDictTables = ZSTD_ps_auto;
metricAggregatePref_e metricAggregatePref = fastest; metricAggregatePref_e metricAggregatePref = fastest;
for (int argNb = 1; argNb < argc ; argNb++) { for (int argNb = 1; argNb < argc ; argNb++) {

View File

@ -26,7 +26,6 @@ zstd_compress-y := \
compress/zstd_lazy.o \ compress/zstd_lazy.o \
compress/zstd_ldm.o \ compress/zstd_ldm.o \
compress/zstd_opt.o \ compress/zstd_opt.o \
compress/zstd_preSplit.o \
zstd_decompress-y := \ zstd_decompress-y := \
zstd_decompress_module.o \ zstd_decompress_module.o \

View File

@ -77,30 +77,6 @@ int zstd_min_clevel(void);
*/ */
int zstd_max_clevel(void); int zstd_max_clevel(void);
/**
* zstd_default_clevel() - default compression level
*
* Return: Default compression level.
*/
int zstd_default_clevel(void);
/**
* struct zstd_custom_mem - custom memory allocation
*/
typedef ZSTD_customMem zstd_custom_mem;
/**
* struct zstd_dict_load_method - Dictionary load method.
* See zstd_lib.h.
*/
typedef ZSTD_dictLoadMethod_e zstd_dict_load_method;
/**
* struct zstd_dict_content_type - Dictionary context type.
* See zstd_lib.h.
*/
typedef ZSTD_dictContentType_e zstd_dict_content_type;
/* ====== Parameter Selection ====== */ /* ====== Parameter Selection ====== */
/** /**
@ -160,32 +136,9 @@ typedef ZSTD_parameters zstd_parameters;
zstd_parameters zstd_get_params(int level, zstd_parameters zstd_get_params(int level,
unsigned long long estimated_src_size); unsigned long long estimated_src_size);
/** /* ====== Single-pass Compression ====== */
* zstd_get_cparams() - returns zstd_compression_parameters for selected level
* @level: The compression level
* @estimated_src_size: The estimated source size to compress or 0
* if unknown.
* @dict_size: Dictionary size.
*
* Return: The selected zstd_compression_parameters.
*/
zstd_compression_parameters zstd_get_cparams(int level,
unsigned long long estimated_src_size, size_t dict_size);
typedef ZSTD_CCtx zstd_cctx; typedef ZSTD_CCtx zstd_cctx;
typedef ZSTD_cParameter zstd_cparameter;
/**
* zstd_cctx_set_param() - sets a compression parameter
* @cctx: The context. Must have been initialized with zstd_init_cctx().
* @param: The parameter to set.
* @value: The value to set the parameter to.
*
* Return: Zero or an error, which can be checked using zstd_is_error().
*/
size_t zstd_cctx_set_param(zstd_cctx *cctx, zstd_cparameter param, int value);
/* ====== Single-pass Compression ====== */
/** /**
* zstd_cctx_workspace_bound() - max memory needed to initialize a zstd_cctx * zstd_cctx_workspace_bound() - max memory needed to initialize a zstd_cctx
@ -200,20 +153,6 @@ size_t zstd_cctx_set_param(zstd_cctx *cctx, zstd_cparameter param, int value);
*/ */
size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *parameters); size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *parameters);
/**
* zstd_cctx_workspace_bound_with_ext_seq_prod() - max memory needed to
* initialize a zstd_cctx when using the block-level external sequence
* producer API.
* @parameters: The compression parameters to be used.
*
* If multiple compression parameters might be used, the caller must call
* this function for each set of parameters and use the maximum size.
*
* Return: A lower bound on the size of the workspace that is passed to
* zstd_init_cctx().
*/
size_t zstd_cctx_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *parameters);
/** /**
* zstd_init_cctx() - initialize a zstd compression context * zstd_init_cctx() - initialize a zstd compression context
* @workspace: The workspace to emplace the context into. It must outlive * @workspace: The workspace to emplace the context into. It must outlive
@ -241,71 +180,6 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size);
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size, const zstd_parameters *parameters); const void *src, size_t src_size, const zstd_parameters *parameters);
/**
* zstd_create_cctx_advanced() - Create compression context
* @custom_mem: Custom allocator.
*
* Return: NULL on error, pointer to compression context otherwise.
*/
zstd_cctx *zstd_create_cctx_advanced(zstd_custom_mem custom_mem);
/**
* zstd_free_cctx() - Free compression context
* @cdict: Pointer to compression context.
*
* Return: Always 0.
*/
size_t zstd_free_cctx(zstd_cctx* cctx);
/**
* struct zstd_cdict - Compression dictionary.
* See zstd_lib.h.
*/
typedef ZSTD_CDict zstd_cdict;
/**
* zstd_create_cdict_byreference() - Create compression dictionary
* @dict: Pointer to dictionary buffer.
* @dict_size: Size of the dictionary buffer.
* @dict_load_method: Dictionary load method.
* @dict_content_type: Dictionary content type.
* @custom_mem: Memory allocator.
*
* Note, this uses @dict by reference (ZSTD_dlm_byRef), so it should be
* free before zstd_cdict is destroyed.
*
* Return: NULL on error, pointer to compression dictionary
* otherwise.
*/
zstd_cdict *zstd_create_cdict_byreference(const void *dict, size_t dict_size,
zstd_compression_parameters cparams,
zstd_custom_mem custom_mem);
/**
* zstd_free_cdict() - Free compression dictionary
* @cdict: Pointer to compression dictionary.
*
* Return: Always 0.
*/
size_t zstd_free_cdict(zstd_cdict* cdict);
/**
* zstd_compress_using_cdict() - compress src into dst using a dictionary
* @cctx: The context. Must have been initialized with zstd_init_cctx().
* @dst: The buffer to compress src into.
* @dst_capacity: The size of the destination buffer. May be any size, but
* ZSTD_compressBound(srcSize) is guaranteed to be large enough.
* @src: The data to compress.
* @src_size: The size of the data to compress.
* @cdict: The dictionary to be used.
*
* Return: The compressed size or an error, which can be checked using
* zstd_is_error().
*/
size_t zstd_compress_using_cdict(zstd_cctx *cctx, void *dst,
size_t dst_capacity, const void *src, size_t src_size,
const zstd_cdict *cdict);
/* ====== Single-pass Decompression ====== */ /* ====== Single-pass Decompression ====== */
typedef ZSTD_DCtx zstd_dctx; typedef ZSTD_DCtx zstd_dctx;
@ -346,71 +220,6 @@ zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size);
size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity, size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size); const void *src, size_t src_size);
/**
* struct zstd_ddict - Decompression dictionary.
* See zstd_lib.h.
*/
typedef ZSTD_DDict zstd_ddict;
/**
* zstd_create_ddict_byreference() - Create decompression dictionary
* @dict: Pointer to dictionary buffer.
* @dict_size: Size of the dictionary buffer.
* @dict_load_method: Dictionary load method.
* @dict_content_type: Dictionary content type.
* @custom_mem: Memory allocator.
*
* Note, this uses @dict by reference (ZSTD_dlm_byRef), so it should be
* free before zstd_ddict is destroyed.
*
* Return: NULL on error, pointer to decompression dictionary
* otherwise.
*/
zstd_ddict *zstd_create_ddict_byreference(const void *dict, size_t dict_size,
zstd_custom_mem custom_mem);
/**
* zstd_free_ddict() - Free decompression dictionary
* @dict: Pointer to the dictionary.
*
* Return: Always 0.
*/
size_t zstd_free_ddict(zstd_ddict *ddict);
/**
* zstd_create_dctx_advanced() - Create decompression context
* @custom_mem: Custom allocator.
*
* Return: NULL on error, pointer to decompression context otherwise.
*/
zstd_dctx *zstd_create_dctx_advanced(zstd_custom_mem custom_mem);
/**
* zstd_free_dctx() -- Free decompression context
* @dctx: Pointer to decompression context.
* Return: Always 0.
*/
size_t zstd_free_dctx(zstd_dctx *dctx);
/**
* zstd_decompress_using_ddict() - decompress src into dst using a dictionary
* @dctx: The decompression context.
* @dst: The buffer to decompress src into.
* @dst_capacity: The size of the destination buffer. Must be at least as large
* as the decompressed size. If the caller cannot upper bound the
* decompressed size, then it's better to use the streaming API.
* @src: The zstd compressed data to decompress. Multiple concatenated
* frames and skippable frames are allowed.
* @src_size: The exact size of the data to decompress.
* @ddict: The dictionary to be used.
*
* Return: The decompressed size or an error, which can be checked using
* zstd_is_error().
*/
size_t zstd_decompress_using_ddict(zstd_dctx *dctx,
void *dst, size_t dst_capacity, const void *src, size_t src_size,
const zstd_ddict *ddict);
/* ====== Streaming Buffers ====== */ /* ====== Streaming Buffers ====== */
/** /**
@ -448,16 +257,6 @@ typedef ZSTD_CStream zstd_cstream;
*/ */
size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams); size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams);
/**
* zstd_cstream_workspace_bound_with_ext_seq_prod() - memory needed to initialize
* a zstd_cstream when using the block-level external sequence producer API.
* @cparams: The compression parameters to be used for compression.
*
* Return: A lower bound on the size of the workspace that is passed to
* zstd_init_cstream().
*/
size_t zstd_cstream_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *cparams);
/** /**
* zstd_init_cstream() - initialize a zstd streaming compression context * zstd_init_cstream() - initialize a zstd streaming compression context
* @parameters The zstd parameters to use for compression. * @parameters The zstd parameters to use for compression.
@ -617,18 +416,6 @@ size_t zstd_decompress_stream(zstd_dstream *dstream, zstd_out_buffer *output,
*/ */
size_t zstd_find_frame_compressed_size(const void *src, size_t src_size); size_t zstd_find_frame_compressed_size(const void *src, size_t src_size);
/**
* zstd_register_sequence_producer() - exposes the zstd library function
* ZSTD_registerSequenceProducer(). This is used for the block-level external
* sequence producer API. See upstream zstd.h for detailed documentation.
*/
typedef ZSTD_sequenceProducer_F zstd_sequence_producer_f;
void zstd_register_sequence_producer(
zstd_cctx *cctx,
void* sequence_producer_state,
zstd_sequence_producer_f sequence_producer
);
/** /**
* struct zstd_frame_params - zstd frame parameters stored in the frame header * struct zstd_frame_params - zstd frame parameters stored in the frame header
* @frameContentSize: The frame content size, or ZSTD_CONTENTSIZE_UNKNOWN if not * @frameContentSize: The frame content size, or ZSTD_CONTENTSIZE_UNKNOWN if not
@ -642,7 +429,7 @@ void zstd_register_sequence_producer(
* *
* See zstd_lib.h. * See zstd_lib.h.
*/ */
typedef ZSTD_FrameHeader zstd_frame_header; typedef ZSTD_frameHeader zstd_frame_header;
/** /**
* zstd_get_frame_header() - extracts parameters from a zstd or skippable frame * zstd_get_frame_header() - extracts parameters from a zstd or skippable frame
@ -657,35 +444,4 @@ typedef ZSTD_FrameHeader zstd_frame_header;
size_t zstd_get_frame_header(zstd_frame_header *params, const void *src, size_t zstd_get_frame_header(zstd_frame_header *params, const void *src,
size_t src_size); size_t src_size);
/**
* struct zstd_sequence - a sequence of literals or a match
*
* @offset: The offset of the match
* @litLength: The literal length of the sequence
* @matchLength: The match length of the sequence
* @rep: Represents which repeat offset is used
*/
typedef ZSTD_Sequence zstd_sequence;
/**
* zstd_compress_sequences_and_literals() - compress an array of zstd_sequence and literals
*
* @cctx: The zstd compression context.
* @dst: The buffer to compress the data into.
* @dst_capacity: The size of the destination buffer.
* @in_seqs: The array of zstd_sequence to compress.
* @in_seqs_size: The number of sequences in in_seqs.
* @literals: The literals associated to the sequences to be compressed.
* @lit_size: The size of the literals in the literals buffer.
* @lit_capacity: The size of the literals buffer.
* @decompressed_size: The size of the input data
*
* Return: The compressed size or an error, which can be checked using
* zstd_is_error().
*/
size_t zstd_compress_sequences_and_literals(zstd_cctx *cctx, void* dst, size_t dst_capacity,
const zstd_sequence *in_seqs, size_t in_seqs_size,
const void* literals, size_t lit_size, size_t lit_capacity,
size_t decompressed_size);
#endif /* LINUX_ZSTD_H */ #endif /* LINUX_ZSTD_H */

View File

@ -15,7 +15,7 @@
/*-**************************************** /*-****************************************
* Dependencies * Dependencies
******************************************/ ******************************************/
#include <linux/unaligned.h> /* get_unaligned, put_unaligned* */ #include <asm/unaligned.h> /* get_unaligned, put_unaligned* */
#include <linux/compiler.h> /* inline */ #include <linux/compiler.h> /* inline */
#include <linux/swab.h> /* swab32, swab64 */ #include <linux/swab.h> /* swab32, swab64 */
#include <linux/types.h> /* size_t, ptrdiff_t */ #include <linux/types.h> /* size_t, ptrdiff_t */

View File

@ -296,7 +296,7 @@ XXH_API void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state
* - xxHash source repository: https://github.com/Cyan4973/xxHash * - xxHash source repository: https://github.com/Cyan4973/xxHash
*/ */
#include <linux/unaligned.h> #include <asm/unaligned.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>

View File

@ -16,7 +16,6 @@
#include "common/zstd_deps.h" #include "common/zstd_deps.h"
#include "common/zstd_internal.h" #include "common/zstd_internal.h"
#include "compress/zstd_compress_internal.h"
#define ZSTD_FORWARD_IF_ERR(ret) \ #define ZSTD_FORWARD_IF_ERR(ret) \
do { \ do { \
@ -67,12 +66,6 @@ int zstd_max_clevel(void)
} }
EXPORT_SYMBOL(zstd_max_clevel); EXPORT_SYMBOL(zstd_max_clevel);
int zstd_default_clevel(void)
{
return ZSTD_defaultCLevel();
}
EXPORT_SYMBOL(zstd_default_clevel);
size_t zstd_compress_bound(size_t src_size) size_t zstd_compress_bound(size_t src_size)
{ {
return ZSTD_compressBound(src_size); return ZSTD_compressBound(src_size);
@ -86,71 +79,12 @@ zstd_parameters zstd_get_params(int level,
} }
EXPORT_SYMBOL(zstd_get_params); EXPORT_SYMBOL(zstd_get_params);
zstd_compression_parameters zstd_get_cparams(int level,
unsigned long long estimated_src_size, size_t dict_size)
{
return ZSTD_getCParams(level, estimated_src_size, dict_size);
}
EXPORT_SYMBOL(zstd_get_cparams);
size_t zstd_cctx_set_param(zstd_cctx *cctx, ZSTD_cParameter param, int value)
{
return ZSTD_CCtx_setParameter(cctx, param, value);
}
EXPORT_SYMBOL(zstd_cctx_set_param);
size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *cparams) size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *cparams)
{ {
return ZSTD_estimateCCtxSize_usingCParams(*cparams); return ZSTD_estimateCCtxSize_usingCParams(*cparams);
} }
EXPORT_SYMBOL(zstd_cctx_workspace_bound); EXPORT_SYMBOL(zstd_cctx_workspace_bound);
// Used by zstd_cctx_workspace_bound_with_ext_seq_prod()
static size_t dummy_external_sequence_producer(
void *sequenceProducerState,
ZSTD_Sequence *outSeqs, size_t outSeqsCapacity,
const void *src, size_t srcSize,
const void *dict, size_t dictSize,
int compressionLevel,
size_t windowSize)
{
(void)sequenceProducerState;
(void)outSeqs; (void)outSeqsCapacity;
(void)src; (void)srcSize;
(void)dict; (void)dictSize;
(void)compressionLevel;
(void)windowSize;
return ZSTD_SEQUENCE_PRODUCER_ERROR;
}
static void init_cctx_params_from_compress_params(
ZSTD_CCtx_params *cctx_params,
const zstd_compression_parameters *compress_params)
{
ZSTD_parameters zstd_params;
memset(&zstd_params, 0, sizeof(zstd_params));
zstd_params.cParams = *compress_params;
ZSTD_CCtxParams_init_advanced(cctx_params, zstd_params);
}
size_t zstd_cctx_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *compress_params)
{
ZSTD_CCtx_params cctx_params;
init_cctx_params_from_compress_params(&cctx_params, compress_params);
ZSTD_CCtxParams_registerSequenceProducer(&cctx_params, NULL, dummy_external_sequence_producer);
return ZSTD_estimateCCtxSize_usingCCtxParams(&cctx_params);
}
EXPORT_SYMBOL(zstd_cctx_workspace_bound_with_ext_seq_prod);
size_t zstd_cstream_workspace_bound_with_ext_seq_prod(const zstd_compression_parameters *compress_params)
{
ZSTD_CCtx_params cctx_params;
init_cctx_params_from_compress_params(&cctx_params, compress_params);
ZSTD_CCtxParams_registerSequenceProducer(&cctx_params, NULL, dummy_external_sequence_producer);
return ZSTD_estimateCStreamSize_usingCCtxParams(&cctx_params);
}
EXPORT_SYMBOL(zstd_cstream_workspace_bound_with_ext_seq_prod);
zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size) zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size)
{ {
if (workspace == NULL) if (workspace == NULL)
@ -159,33 +93,6 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size)
} }
EXPORT_SYMBOL(zstd_init_cctx); EXPORT_SYMBOL(zstd_init_cctx);
zstd_cctx *zstd_create_cctx_advanced(zstd_custom_mem custom_mem)
{
return ZSTD_createCCtx_advanced(custom_mem);
}
EXPORT_SYMBOL(zstd_create_cctx_advanced);
size_t zstd_free_cctx(zstd_cctx *cctx)
{
return ZSTD_freeCCtx(cctx);
}
EXPORT_SYMBOL(zstd_free_cctx);
zstd_cdict *zstd_create_cdict_byreference(const void *dict, size_t dict_size,
zstd_compression_parameters cparams,
zstd_custom_mem custom_mem)
{
return ZSTD_createCDict_advanced(dict, dict_size, ZSTD_dlm_byRef,
ZSTD_dct_auto, cparams, custom_mem);
}
EXPORT_SYMBOL(zstd_create_cdict_byreference);
size_t zstd_free_cdict(zstd_cdict *cdict)
{
return ZSTD_freeCDict(cdict);
}
EXPORT_SYMBOL(zstd_free_cdict);
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size, const zstd_parameters *parameters) const void *src, size_t src_size, const zstd_parameters *parameters)
{ {
@ -194,15 +101,6 @@ size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
} }
EXPORT_SYMBOL(zstd_compress_cctx); EXPORT_SYMBOL(zstd_compress_cctx);
size_t zstd_compress_using_cdict(zstd_cctx *cctx, void *dst,
size_t dst_capacity, const void *src, size_t src_size,
const ZSTD_CDict *cdict)
{
return ZSTD_compress_usingCDict(cctx, dst, dst_capacity,
src, src_size, cdict);
}
EXPORT_SYMBOL(zstd_compress_using_cdict);
size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams) size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams)
{ {
return ZSTD_estimateCStreamSize_usingCParams(*cparams); return ZSTD_estimateCStreamSize_usingCParams(*cparams);
@ -262,25 +160,5 @@ size_t zstd_end_stream(zstd_cstream *cstream, zstd_out_buffer *output)
} }
EXPORT_SYMBOL(zstd_end_stream); EXPORT_SYMBOL(zstd_end_stream);
void zstd_register_sequence_producer(
zstd_cctx *cctx,
void* sequence_producer_state,
zstd_sequence_producer_f sequence_producer
) {
ZSTD_registerSequenceProducer(cctx, sequence_producer_state, sequence_producer);
}
EXPORT_SYMBOL(zstd_register_sequence_producer);
size_t zstd_compress_sequences_and_literals(zstd_cctx *cctx, void* dst, size_t dst_capacity,
const zstd_sequence *in_seqs, size_t in_seqs_size,
const void* literals, size_t lit_size, size_t lit_capacity,
size_t decompressed_size)
{
return ZSTD_compressSequencesAndLiterals(cctx, dst, dst_capacity, in_seqs,
in_seqs_size, literals, lit_size,
lit_capacity, decompressed_size);
}
EXPORT_SYMBOL(zstd_compress_sequences_and_literals);
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Zstd Compressor"); MODULE_DESCRIPTION("Zstd Compressor");

View File

@ -44,33 +44,6 @@ size_t zstd_dctx_workspace_bound(void)
} }
EXPORT_SYMBOL(zstd_dctx_workspace_bound); EXPORT_SYMBOL(zstd_dctx_workspace_bound);
zstd_dctx *zstd_create_dctx_advanced(zstd_custom_mem custom_mem)
{
return ZSTD_createDCtx_advanced(custom_mem);
}
EXPORT_SYMBOL(zstd_create_dctx_advanced);
size_t zstd_free_dctx(zstd_dctx *dctx)
{
return ZSTD_freeDCtx(dctx);
}
EXPORT_SYMBOL(zstd_free_dctx);
zstd_ddict *zstd_create_ddict_byreference(const void *dict, size_t dict_size,
zstd_custom_mem custom_mem)
{
return ZSTD_createDDict_advanced(dict, dict_size, ZSTD_dlm_byRef,
ZSTD_dct_auto, custom_mem);
}
EXPORT_SYMBOL(zstd_create_ddict_byreference);
size_t zstd_free_ddict(zstd_ddict *ddict)
{
return ZSTD_freeDDict(ddict);
}
EXPORT_SYMBOL(zstd_free_ddict);
zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size) zstd_dctx *zstd_init_dctx(void *workspace, size_t workspace_size)
{ {
if (workspace == NULL) if (workspace == NULL)
@ -86,15 +59,6 @@ size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity,
} }
EXPORT_SYMBOL(zstd_decompress_dctx); EXPORT_SYMBOL(zstd_decompress_dctx);
size_t zstd_decompress_using_ddict(zstd_dctx *dctx,
void *dst, size_t dst_capacity, const void* src, size_t src_size,
const zstd_ddict* ddict)
{
return ZSTD_decompress_usingDDict(dctx, dst, dst_capacity, src,
src_size, ddict);
}
EXPORT_SYMBOL(zstd_decompress_using_ddict);
size_t zstd_dstream_workspace_bound(size_t max_window_size) size_t zstd_dstream_workspace_bound(size_t max_window_size)
{ {
return ZSTD_estimateDStreamSize(max_window_size); return ZSTD_estimateDStreamSize(max_window_size);

View File

@ -10,7 +10,6 @@
#include <cstdio> #include <cstdio>
#include <mutex> #include <mutex>
#include <chrono>
namespace pzstd { namespace pzstd {

View File

@ -322,7 +322,7 @@ Options::Status Options::parse(int argc, const char **argv) {
g_utilDisplayLevel = verbosity; g_utilDisplayLevel = verbosity;
// Remove local input files that are symbolic links // Remove local input files that are symbolic links
if (!followLinks) { if (!followLinks) {
localInputFiles.erase(std::remove_if(localInputFiles.begin(), localInputFiles.end(), std::remove_if(localInputFiles.begin(), localInputFiles.end(),
[&](const char *path) { [&](const char *path) {
bool isLink = UTIL_isLink(path); bool isLink = UTIL_isLink(path);
if (isLink && verbosity >= 2) { if (isLink && verbosity >= 2) {
@ -332,7 +332,7 @@ Options::Status Options::parse(int argc, const char **argv) {
path); path);
} }
return isLink; return isLink;
}), localInputFiles.end()); });
} }
// Translate input files/directories into files to (de)compress // Translate input files/directories into files to (de)compress

View File

@ -269,10 +269,7 @@ static void compress(
std::shared_ptr<BufferWorkQueue> out, std::shared_ptr<BufferWorkQueue> out,
size_t maxInputSize) { size_t maxInputSize) {
auto& errorHolder = state.errorHolder; auto& errorHolder = state.errorHolder;
auto guard = makeScopeGuard([&] { auto guard = makeScopeGuard([&] { out->finish(); });
in->finish();
out->finish();
});
// Initialize the CCtx // Initialize the CCtx
auto ctx = state.cStreamPool->get(); auto ctx = state.cStreamPool->get();
if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_CStream")) { if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_CStream")) {
@ -434,10 +431,7 @@ static void decompress(
std::shared_ptr<BufferWorkQueue> in, std::shared_ptr<BufferWorkQueue> in,
std::shared_ptr<BufferWorkQueue> out) { std::shared_ptr<BufferWorkQueue> out) {
auto& errorHolder = state.errorHolder; auto& errorHolder = state.errorHolder;
auto guard = makeScopeGuard([&] { auto guard = makeScopeGuard([&] { out->finish(); });
in->finish();
out->finish();
});
// Initialize the DCtx // Initialize the DCtx
auto ctx = state.dStreamPool->get(); auto ctx = state.dStreamPool->get();
if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_DStream")) { if (!errorHolder.check(ctx != nullptr, "Failed to allocate ZSTD_DStream")) {
@ -584,7 +578,6 @@ std::uint64_t writeFile(
FILE* outputFd, FILE* outputFd,
bool decompress) { bool decompress) {
auto& errorHolder = state.errorHolder; auto& errorHolder = state.errorHolder;
auto outsFinishGuard = makeScopeGuard([&outs] { outs.finish(); });
auto lineClearGuard = makeScopeGuard([&state] { auto lineClearGuard = makeScopeGuard([&state] {
state.log.clear(kLogInfo); state.log.clear(kLogInfo);
}); });
@ -592,7 +585,6 @@ std::uint64_t writeFile(
std::shared_ptr<BufferWorkQueue> out; std::shared_ptr<BufferWorkQueue> out;
// Grab the output queue for each decompression job (in order). // Grab the output queue for each decompression job (in order).
while (outs.pop(out)) { while (outs.pop(out)) {
auto outFinishGuard = makeScopeGuard([&out] { out->finish(); });
if (errorHolder.hasError()) { if (errorHolder.hasError()) {
continue; continue;
} }

View File

@ -7,7 +7,9 @@
* in the COPYING file in the root directory of this source tree). * in the COPYING file in the root directory of this source tree).
*/ */
#include "Pzstd.h" #include "Pzstd.h"
extern "C" {
#include "datagen.h" #include "datagen.h"
}
#include "test/RoundTrip.h" #include "test/RoundTrip.h"
#include "utils/ScopeGuard.h" #include "utils/ScopeGuard.h"

View File

@ -6,7 +6,9 @@
* LICENSE file in the root directory of this source tree) and the GPLv2 (found * 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). * in the COPYING file in the root directory of this source tree).
*/ */
extern "C" {
#include "datagen.h" #include "datagen.h"
}
#include "Options.h" #include "Options.h"
#include "test/RoundTrip.h" #include "test/RoundTrip.h"
#include "utils/ScopeGuard.h" #include "utils/ScopeGuard.h"

View File

@ -115,14 +115,13 @@ class WorkQueue {
} }
/** /**
* Promise that either the reader side or the writer side is done. * Promise that `push()` won't be called again, so once the queue is empty
* If the writer is done, `push()` won't be called again, so once the queue * there will never any more work.
* is empty there will never be any more work. If the reader is done, `pop()`
* won't be called again, so further items pushed will just be ignored.
*/ */
void finish() { void finish() {
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
assert(!done_);
done_ = true; done_ = true;
} }
readerCv_.notify_all(); readerCv_.notify_all();

View File

@ -11,8 +11,6 @@
ZSTDLIB_PATH = ../../../lib ZSTDLIB_PATH = ../../../lib
ZSTDLIB_NAME = libzstd.a ZSTDLIB_NAME = libzstd.a
# Parallel tools only make sense against multi-threaded libzstd
ZSTDLIB_TARGET = $(ZSTDLIB_NAME)-mt
ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME) ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME)
CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I../../../lib -I../../../lib/common CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I../../../lib -I../../../lib/common
@ -30,7 +28,7 @@ all: seekable_compression seekable_decompression seekable_decompression_mem \
parallel_processing parallel_processing
$(ZSTDLIB): $(ZSTDLIB):
$(MAKE) -C $(ZSTDLIB_PATH) $(ZSTDLIB_TARGET) make -C $(ZSTDLIB_PATH) $(ZSTDLIB_NAME)
seekable_compression : seekable_compression.c $(SEEKABLE_OBJS) seekable_compression : seekable_compression.c $(SEEKABLE_OBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@

View File

@ -23,8 +23,6 @@
#include "xxhash.h" #include "xxhash.h"
#define ZSTD_MULTITHREAD 1
#include "threading.h"
#include "pool.h" // use zstd thread pool for demo #include "pool.h" // use zstd thread pool for demo
#include "../zstd_seekable.h" #include "../zstd_seekable.h"
@ -74,87 +72,114 @@ static size_t fclose_orDie(FILE* file)
exit(6); exit(6);
} }
struct state { static void fseek_orDie(FILE* file, long int offset, int origin)
FILE* fout; {
ZSTD_pthread_mutex_t mutex; if (!fseek(file, offset, origin)) {
size_t nextID; if (!fflush(file)) return;
struct job* pending; }
ZSTD_frameLog* frameLog; /* error */
const int compressionLevel; perror("fseek");
}; exit(7);
}
static long int ftell_orDie(FILE* file)
{
long int off = ftell(file);
if (off != -1) return off;
/* error */
perror("ftell");
exit(8);
}
struct job { struct job {
size_t id; const void* src;
struct job* next;
struct state* state;
void* src;
size_t srcSize; size_t srcSize;
void* dst; void* dst;
size_t dstSize; size_t dstSize;
unsigned checksum; unsigned checksum;
int compressionLevel;
int done;
}; };
static void addPending_inmutex(struct state* state, struct job* job)
{
struct job** p = &state->pending;
while (*p && (*p)->id < job->id)
p = &(*p)->next;
job->next = *p;
*p = job;
}
static void flushFrame(struct state* state, struct job* job)
{
fwrite_orDie(job->dst, job->dstSize, state->fout);
free(job->dst);
size_t ret = ZSTD_seekable_logFrame(state->frameLog, (unsigned)job->dstSize, (unsigned)job->srcSize, job->checksum);
if (ZSTD_isError(ret)) {
fprintf(stderr, "ZSTD_seekable_logFrame() error : %s \n", ZSTD_getErrorName(ret));
exit(12);
}
}
static void flushPending_inmutex(struct state* state)
{
while (state->pending && state->pending->id == state->nextID) {
struct job* p = state->pending;
state->pending = p->next;
flushFrame(state, p);
free(p);
state->nextID++;
}
}
static void finishFrame(struct job* job)
{
struct state *state = job->state;
ZSTD_pthread_mutex_lock(&state->mutex);
addPending_inmutex(state, job);
flushPending_inmutex(state);
ZSTD_pthread_mutex_unlock(&state->mutex);
}
static void compressFrame(void* opaque) static void compressFrame(void* opaque)
{ {
struct job* job = opaque; struct job* job = opaque;
job->checksum = (unsigned)XXH64(job->src, job->srcSize, 0); job->checksum = XXH64(job->src, job->srcSize, 0);
size_t ret = ZSTD_compress(job->dst, job->dstSize, job->src, job->srcSize, job->state->compressionLevel); size_t ret = ZSTD_compress(job->dst, job->dstSize, job->src, job->srcSize, job->compressionLevel);
if (ZSTD_isError(ret)) { if (ZSTD_isError(ret)) {
fprintf(stderr, "ZSTD_compress() error : %s \n", ZSTD_getErrorName(ret)); fprintf(stderr, "ZSTD_compress() error : %s \n", ZSTD_getErrorName(ret));
exit(20); exit(20);
} }
job->dstSize = ret; job->dstSize = ret;
job->done = 1;
}
// No longer need static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize, int nbThreads)
free(job->src); {
job->src = NULL; POOL_ctx* pool = POOL_create(nbThreads, nbThreads);
if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); }
finishFrame(job); FILE* const fin = fopen_orDie(fname, "rb");
FILE* const fout = fopen_orDie(outName, "wb");
if (ZSTD_compressBound(frameSize) > 0xFFFFFFFFU) { fprintf(stderr, "Frame size too large \n"); exit(10); }
unsigned dstSize = ZSTD_compressBound(frameSize);
fseek_orDie(fin, 0, SEEK_END);
long int length = ftell_orDie(fin);
fseek_orDie(fin, 0, SEEK_SET);
size_t numFrames = (length + frameSize - 1) / frameSize;
struct job* jobs = malloc_orDie(sizeof(struct job) * numFrames);
size_t i;
for(i = 0; i < numFrames; i++) {
void* in = malloc_orDie(frameSize);
void* out = malloc_orDie(dstSize);
size_t inSize = fread_orDie(in, frameSize, fin);
jobs[i].src = in;
jobs[i].srcSize = inSize;
jobs[i].dst = out;
jobs[i].dstSize = dstSize;
jobs[i].compressionLevel = cLevel;
jobs[i].done = 0;
POOL_add(pool, compressFrame, &jobs[i]);
}
ZSTD_frameLog* fl = ZSTD_seekable_createFrameLog(1);
if (fl == NULL) { fprintf(stderr, "ZSTD_seekable_createFrameLog() failed \n"); exit(11); }
for (i = 0; i < numFrames; i++) {
while (!jobs[i].done) SLEEP(5); /* wake up every 5 milliseconds to check */
fwrite_orDie(jobs[i].dst, jobs[i].dstSize, fout);
free((void*)jobs[i].src);
free(jobs[i].dst);
size_t ret = ZSTD_seekable_logFrame(fl, jobs[i].dstSize, jobs[i].srcSize, jobs[i].checksum);
if (ZSTD_isError(ret)) { fprintf(stderr, "ZSTD_seekable_logFrame() error : %s \n", ZSTD_getErrorName(ret)); }
}
{ unsigned char seekTableBuff[1024];
ZSTD_outBuffer out = {seekTableBuff, 1024, 0};
while (ZSTD_seekable_writeSeekTable(fl, &out) != 0) {
fwrite_orDie(seekTableBuff, out.pos, fout);
out.pos = 0;
}
fwrite_orDie(seekTableBuff, out.pos, fout);
}
ZSTD_seekable_freeFrameLog(fl);
free(jobs);
fclose_orDie(fout);
fclose_orDie(fin);
} }
static const char* createOutFilename_orDie(const char* filename) static const char* createOutFilename_orDie(const char* filename)
@ -168,72 +193,6 @@ static const char* createOutFilename_orDie(const char* filename)
return (const char*)outSpace; return (const char*)outSpace;
} }
static void openInOut_orDie(const char* fname, FILE** fin, FILE** fout) {
if (strcmp(fname, "-") == 0) {
*fin = stdin;
*fout = stdout;
} else {
*fin = fopen_orDie(fname, "rb");
const char* outName = createOutFilename_orDie(fname);
*fout = fopen_orDie(outName, "wb");
}
}
static void compressFile_orDie(const char* fname, int cLevel, unsigned frameSize, size_t nbThreads)
{
struct state state = {
.nextID = 0,
.pending = NULL,
.compressionLevel = cLevel,
};
ZSTD_pthread_mutex_init(&state.mutex, NULL);
state.frameLog = ZSTD_seekable_createFrameLog(1);
if (state.frameLog == NULL) { fprintf(stderr, "ZSTD_seekable_createFrameLog() failed \n"); exit(11); }
POOL_ctx* pool = POOL_create(nbThreads, nbThreads);
if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); }
FILE* fin;
openInOut_orDie(fname, &fin, &state.fout);
if (ZSTD_compressBound(frameSize) > 0xFFFFFFFFU) { fprintf(stderr, "Frame size too large \n"); exit(10); }
size_t dstSize = ZSTD_compressBound(frameSize);
for (size_t id = 0; 1; id++) {
struct job* job = malloc_orDie(sizeof(struct job));
job->id = id;
job->next = NULL;
job->state = &state;
job->src = malloc_orDie(frameSize);
job->dst = malloc_orDie(dstSize);
job->srcSize = fread_orDie(job->src, frameSize, fin);
job->dstSize = dstSize;
POOL_add(pool, compressFrame, job);
if (feof(fin))
break;
}
POOL_joinJobs(pool);
POOL_free(pool);
if (state.pending) {
fprintf(stderr, "Unexpected leftover output blocks!\n");
exit(13);
}
{ unsigned char seekTableBuff[1024];
ZSTD_outBuffer out = {seekTableBuff, 1024, 0};
while (ZSTD_seekable_writeSeekTable(state.frameLog, &out) != 0) {
fwrite_orDie(seekTableBuff, out.pos, state.fout);
out.pos = 0;
}
fwrite_orDie(seekTableBuff, out.pos, state.fout);
}
ZSTD_seekable_freeFrameLog(state.frameLog);
fclose_orDie(state.fout);
fclose_orDie(fin);
}
int main(int argc, const char** argv) { int main(int argc, const char** argv) {
const char* const exeName = argv[0]; const char* const exeName = argv[0];
if (argc!=4) { if (argc!=4) {
@ -245,9 +204,10 @@ int main(int argc, const char** argv) {
{ const char* const inFileName = argv[1]; { const char* const inFileName = argv[1];
unsigned const frameSize = (unsigned)atoi(argv[2]); unsigned const frameSize = (unsigned)atoi(argv[2]);
size_t const nbThreads = (size_t)atoi(argv[3]); int const nbThreads = atoi(argv[3]);
compressFile_orDie(inFileName, 5, frameSize, nbThreads); const char* const outFileName = createOutFilename_orDie(inFileName);
compressFile_orDie(inFileName, outFileName, 5, frameSize, nbThreads);
} }
return 0; return 0;

View File

@ -100,11 +100,13 @@ struct sum_job {
const char* fname; const char* fname;
unsigned long long sum; unsigned long long sum;
unsigned frameNb; unsigned frameNb;
int done;
}; };
static void sumFrame(void* opaque) static void sumFrame(void* opaque)
{ {
struct sum_job* job = (struct sum_job*)opaque; struct sum_job* job = (struct sum_job*)opaque;
job->done = 0;
FILE* const fin = fopen_orDie(job->fname, "rb"); FILE* const fin = fopen_orDie(job->fname, "rb");
@ -126,6 +128,7 @@ static void sumFrame(void* opaque)
sum += data[i]; sum += data[i];
} }
job->sum = sum; job->sum = sum;
job->done = 1;
fclose(fin); fclose(fin);
ZSTD_seekable_free(seekable); ZSTD_seekable_free(seekable);
@ -150,14 +153,14 @@ static void sumFile_orDie(const char* fname, int nbThreads)
unsigned fnb; unsigned fnb;
for (fnb = 0; fnb < numFrames; fnb++) { for (fnb = 0; fnb < numFrames; fnb++) {
jobs[fnb] = (struct sum_job){ fname, 0, fnb }; jobs[fnb] = (struct sum_job){ fname, 0, fnb, 0 };
POOL_add(pool, sumFrame, &jobs[fnb]); POOL_add(pool, sumFrame, &jobs[fnb]);
} }
POOL_joinJobs(pool);
unsigned long long total = 0; unsigned long long total = 0;
for (fnb = 0; fnb < numFrames; fnb++) { for (fnb = 0; fnb < numFrames; fnb++) {
while (!jobs[fnb].done) SLEEP(5); /* wake up every 5 milliseconds to check */
total += jobs[fnb].sum; total += jobs[fnb].sum;
} }

View File

@ -1,2 +1 @@
seekable_tests seekable_tests
data.txt

View File

@ -24,7 +24,7 @@ SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c $(ZSTDLIB)
.PHONY: default clean test .PHONY: default clean test
default: test default: test
test: seekable_tests parallel_compression_test test: seekable_tests
./seekable_tests ./seekable_tests
$(ZSTDLIB): $(ZSTDLIB):
@ -32,27 +32,7 @@ $(ZSTDLIB):
seekable_tests : $(SEEKABLE_OBJS) seekable_tests : $(SEEKABLE_OBJS)
EXAMPLES_PATH = ../examples
PARALLEL_COMPRESSION = $(EXAMPLES_PATH)/parallel_compression
DATAGEN_PATH = ../../../tests
DATAGEN = $(DATAGEN_PATH)/datagen
$(PARALLEL_COMPRESSION):
$(MAKE) -C $(EXAMPLES_PATH) parallel_compression
$(DATAGEN):
$(MAKE) -C $(DATAGEN_PATH) datagen
data.txt: $(DATAGEN)
$(DATAGEN) -g100M > $@
parallel_compression_test: $(PARALLEL_COMPRESSION) data.txt
ulimit -Sv 102400; $(PARALLEL_COMPRESSION) data.txt 1048576 2
.PHONY: parallel_compression_test parallel_comp
clean: clean:
@$(RM) core *.o tmp* result* *.zst \ @$(RM) core *.o tmp* result* *.zst \
seekable_tests data.txt seekable_tests
@echo Cleaning completed @echo Cleaning completed

View File

@ -316,10 +316,6 @@ int main(int argc, const char** argv)
for (pos = 0; pos < inSize; pos += 2) { for (pos = 0; pos < inSize; pos += 2) {
size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, 1, pos); size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, 1, pos);
if (decStatus != 1 || outBuffer[0] != inBuffer[pos]) { if (decStatus != 1 || outBuffer[0] != inBuffer[pos]) {
free(seekBuffer);
free(outBuffer);
ZSTD_seekable_freeCStream(zscs);
ZSTD_seekable_free(stream);
goto _test_error; goto _test_error;
} }
} }
@ -327,10 +323,6 @@ int main(int argc, const char** argv)
/* We read more than the compressed size, meaning there were some rereads. /* We read more than the compressed size, meaning there were some rereads.
This is unneeded because we only seeked forward. */ This is unneeded because we only seeked forward. */
printf("Too much data read: %zu read, with compressed size %zu\n", buffWrapper.totalRead, seekSize); printf("Too much data read: %zu read, with compressed size %zu\n", buffWrapper.totalRead, seekSize);
free(seekBuffer);
free(outBuffer);
ZSTD_seekable_freeCStream(zscs);
ZSTD_seekable_free(stream);
goto _test_error; goto _test_error;
} }
@ -350,10 +342,6 @@ int main(int argc, const char** argv)
for (idx = 0; idx < sizeof(tests) / sizeof(tests[0]); idx++) { for (idx = 0; idx < sizeof(tests) / sizeof(tests[0]); idx++) {
size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, tests[idx].size, tests[idx].offset); size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, tests[idx].size, tests[idx].offset);
if (decStatus != tests[idx].size || memcmp(outBuffer, inBuffer + tests[idx].offset, tests[idx].size) != 0) { if (decStatus != tests[idx].size || memcmp(outBuffer, inBuffer + tests[idx].offset, tests[idx].size) != 0) {
free(seekBuffer);
free(outBuffer);
ZSTD_seekable_freeCStream(zscs);
ZSTD_seekable_free(stream);
goto _test_error; goto _test_error;
} }
} }

View File

@ -1,13 +1,13 @@
#ifndef SEEKABLE_H #ifndef SEEKABLE_H
#define SEEKABLE_H #define SEEKABLE_H
#include <stdio.h>
#include "zstd.h" /* ZSTDLIB_API */
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
#include <stdio.h>
#include "zstd.h" /* ZSTDLIB_API */
#define ZSTD_seekTableFooterSize 9 #define ZSTD_seekTableFooterSize 9

View File

@ -77,10 +77,7 @@
/* ************************************************************ /* ************************************************************
* Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW * Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW
***************************************************************/ ***************************************************************/
#if defined(LIBC_NO_FSEEKO) #if defined(_MSC_VER) && _MSC_VER >= 1400
/* Some older libc implementations don't include these functions (e.g. Bionic < 24) */
# define LONG_SEEK fseek
#elif defined(_MSC_VER) && _MSC_VER >= 1400
# define LONG_SEEK _fseeki64 # define LONG_SEEK _fseeki64
#elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */ #elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
# define LONG_SEEK fseeko # define LONG_SEEK fseeko
@ -255,8 +252,6 @@ size_t ZSTD_seekable_free(ZSTD_seekable* zs)
ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs) ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs)
{ {
assert(zs != NULL);
if (zs->seekTable.entries == NULL) return NULL;
ZSTD_seekTable* const st = (ZSTD_seekTable*)malloc(sizeof(ZSTD_seekTable)); ZSTD_seekTable* const st = (ZSTD_seekTable*)malloc(sizeof(ZSTD_seekTable));
if (st==NULL) return NULL; if (st==NULL) return NULL;

View File

@ -18,26 +18,6 @@ This document lists a few known cases where invalid data was formerly accepted
by the decoder, and what has changed since. by the decoder, and what has changed since.
Truncated Huffman states
------------------------
**Last affected version**: v1.5.6
**Produced by the reference compressor**: No
**Example Frame**: `28b5 2ffd 0000 5500 0072 8001 0420 7e1f 02aa 00`
When using FSE-compressed Huffman weights, the compressed weight bitstream
could contain fewer bits than necessary to decode the initial states.
The reference decompressor up to v1.5.6 will decode truncated or missing
initial states as zero, which can result in a valid Huffman tree if only
the second state is truncated.
In newer versions, truncated initial states are reported as a corruption
error by the decoder.
Offset == 0 Offset == 0
----------- -----------

View File

@ -10,7 +10,7 @@
ZSTD ?= zstd # note: requires zstd installation on local system ZSTD ?= zstd # note: requires zstd installation on local system
UNAME?= $(shell sh -c 'MSYSTEM="MSYS" uname') UNAME?= $(shell uname)
ifeq ($(UNAME), SunOS) ifeq ($(UNAME), SunOS)
DIFF ?= gdiff DIFF ?= gdiff
else else

View File

@ -16,7 +16,7 @@ Distribution of this document is unlimited.
### Version ### Version
0.4.4 (2025-03-22) 0.4.0 (2023-06-05)
Introduction Introduction
@ -390,7 +390,7 @@ __`Block_Content`__ and __`Block_Maximum_Size`__
The size of `Block_Content` is limited by `Block_Maximum_Size`, The size of `Block_Content` is limited by `Block_Maximum_Size`,
which is the smallest of: which is the smallest of:
- `Window_Size` - `Window_Size`
- 128 KiB (131.072 bytes) - 128 KB
`Block_Maximum_Size` is constant for a given frame. `Block_Maximum_Size` is constant for a given frame.
This maximum is applicable to both the decompressed size This maximum is applicable to both the decompressed size
@ -1038,54 +1038,53 @@ and to compress Huffman headers.
FSE FSE
--- ---
FSE, short for Finite State Entropy, is an entropy codec based on [ANS]. FSE, short for Finite State Entropy, is an entropy codec based on [ANS].
FSE encoding/decoding involves a state that is carried over between symbols. FSE encoding/decoding involves a state that is carried over between symbols,
Decoding must be done in the opposite direction as encoding. so decoding must be done in the opposite direction as encoding.
Therefore, all FSE bitstreams are read from end to beginning. Therefore, all FSE bitstreams are read from end to beginning.
Note that the order of the bits in the stream is not reversed, Note that the order of the bits in the stream is not reversed,
we just read each multi-bits element in the reverse order they are encoded. we just read the elements in the reverse order they are written.
For additional details on FSE, see [Finite State Entropy]. For additional details on FSE, see [Finite State Entropy].
[Finite State Entropy]:https://github.com/Cyan4973/FiniteStateEntropy/ [Finite State Entropy]:https://github.com/Cyan4973/FiniteStateEntropy/
FSE decoding is directed by a decoding table with a power of 2 size, each row containing three elements: FSE decoding involves a decoding table which has a power of 2 size, and contain three elements:
`Symbol`, `Num_Bits`, and `Baseline`. `Symbol`, `Num_Bits`, and `Baseline`.
The `log2` of the table size is its `Accuracy_Log`. The `log2` of the table size is its `Accuracy_Log`.
An FSE state value represents an index in this table. An FSE state value represents an index in this table.
To obtain the initial state value, consume `Accuracy_Log` bits from the stream as a __little-endian__ value. To obtain the initial state value, consume `Accuracy_Log` bits from the stream as a __little-endian__ value.
The first symbol in the stream is the `Symbol` indicated in the table for that state. The next symbol in the stream is the `Symbol` indicated in the table for that state.
To obtain the next state value, To obtain the next state value,
the decoder should consume `Num_Bits` bits from the stream as a __little-endian__ value and add it to `Baseline`. the decoder should consume `Num_Bits` bits from the stream as a __little-endian__ value and add it to `Baseline`.
[ANS]: https://en.wikipedia.org/wiki/Asymmetric_Numeral_Systems [ANS]: https://en.wikipedia.org/wiki/Asymmetric_Numeral_Systems
### FSE Table Description ### FSE Table Description
To decode an FSE bitstream, it is necessary to build its FSE decoding table. To decode FSE streams, it is necessary to construct the decoding table.
The decoding table is derived from a distribution of Probabilities. The Zstandard format encodes FSE table descriptions as follows:
The Zstandard format encodes distributions of Probabilities as follows:
The distribution of probabilities is described in a bitstream which is read forward, An FSE distribution table describes the probabilities of all symbols
in __little-endian__ fashion. from `0` to the last present one (included)
The amount of bytes consumed from the bitstream to describe the distribution on a normalized scale of `1 << Accuracy_Log` .
is discovered at the end of the decoding process. Note that there must be two or more symbols with nonzero probability.
The bitstream starts by reporting on which scale the distribution operates. It's a bitstream which is read forward, in __little-endian__ fashion.
It's not necessary to know bitstream exact size,
it will be discovered and reported by the decoding process.
The bitstream starts by reporting on which scale it operates.
Let's `low4Bits` designate the lowest 4 bits of the first byte : Let's `low4Bits` designate the lowest 4 bits of the first byte :
`Accuracy_Log = low4bits + 5`. `Accuracy_Log = low4bits + 5`.
An FSE distribution table describes the probabilities of all symbols Then follows each symbol value, from `0` to last present one.
from `0` to the last present one (included) in natural order. The number of bits used by each field is variable.
The sum of probabilities is normalized to reach a power of 2 total of `1 << Accuracy_Log` .
There must be two or more symbols with non-zero probabilities.
The number of bits used to decode each probability is variable.
It depends on : It depends on :
- Remaining probabilities + 1 : - Remaining probabilities + 1 :
__example__ : __example__ :
Presuming an `Accuracy_Log` of 8, Presuming an `Accuracy_Log` of 8,
and presuming 100 probability points have already been distributed, and presuming 100 probabilities points have already been distributed,
the decoder may read any value from `0` to `256 - 100 + 1 == 157` (inclusive). the decoder may read any value from `0` to `256 - 100 + 1 == 157` (inclusive).
Therefore, it may read up to `log2sup(157) == 8` bits, where `log2sup(N)` Therefore, it may read up to `log2sup(157) == 8` bits, where `log2sup(N)`
is the smallest integer `T` that satisfies `(1 << T) > N`. is the smallest integer `T` that satisfies `(1 << T) > N`.
@ -1099,133 +1098,114 @@ It depends on :
values from 98 to 157 use 8 bits. values from 98 to 157 use 8 bits.
This is achieved through this scheme : This is achieved through this scheme :
| 8-bit field read | Value decoded | Nb of bits consumed | | Value read | Value decoded | Number of bits used |
| ---------------- | ------------- | ------------------- | | ---------- | ------------- | ------------------- |
| 0 - 97 | 0 - 97 | 7 | | 0 - 97 | 0 - 97 | 7 |
| 98 - 127 | 98 - 127 | 8 | | 98 - 127 | 98 - 127 | 8 |
| 128 - 225 | 0 - 97 | 7 | | 128 - 225 | 0 - 97 | 7 |
| 226 - 255 | 128 - 157 | 8 | | 226 - 255 | 128 - 157 | 8 |
Probability is derived from Value decoded using the following formula: Symbols probabilities are read one by one, in order.
`Probality = Value - 1`
Consequently, a Probability of `0` is described by a Value `1`. Probability is obtained from Value decoded by following formula :
`Proba = value - 1`
A Value `0` is used to signal a special case, named "Probability `-1`". It means value `0` becomes negative probability `-1`.
It describes a probability which should have been "less than 1". `-1` is a special probability, which means "less than 1".
Its effect on the decoding table building process is described in the [next section]. Its effect on distribution table is described in the [next section].
For the purpose of counting total allocated probability points, it counts as one. For the purpose of calculating total allocated probability points, it counts as one.
[next section]:#from-normalized-distribution-to-decoding-tables [next section]:#from-normalized-distribution-to-decoding-tables
Symbols probabilities are read one by one, in order. When a symbol has a __probability__ of `zero`,
After each probability is decoded, the total nb of probability points is updated.
This is used to determine how many bits must be read to decode the probability of next symbol.
When a symbol has a __probability__ of `zero` (decoded from reading a Value `1`),
it is followed by a 2-bits repeat flag. it is followed by a 2-bits repeat flag.
This repeat flag tells how many probabilities of zeroes follow the current one. This repeat flag tells how many probabilities of zeroes follow the current one.
It provides a number ranging from 0 to 3. It provides a number ranging from 0 to 3.
If it is a 3, another 2-bits repeat flag follows, and so on. If it is a 3, another 2-bits repeat flag follows, and so on.
When the Probability for a symbol makes cumulated total reach `1 << Accuracy_Log`, When last symbol reaches cumulated total of `1 << Accuracy_Log`,
then it's the last symbol, and decoding is complete. decoding is complete.
If the last symbol makes cumulated total go above `1 << Accuracy_Log`,
distribution is considered corrupted.
If this process results in a non-zero probability for a value outside of the
valid range of values that the FSE table is defined for, even if that value is
not used, then the data is considered corrupted.
Then the decoder can tell how many bytes were used in this process, Then the decoder can tell how many bytes were used in this process,
and how many symbols are present. and how many symbols are present.
The bitstream consumes a round number of bytes. The bitstream consumes a round number of bytes.
Any remaining bit within the last byte is just unused. Any remaining bit within the last byte is just unused.
If this process results in a non-zero probability for a symbol outside of the
valid range of symbols that the FSE table is defined for, even if that symbol is
not used, then the data is considered corrupted.
For the specific case of offset codes,
a decoder implementation may reject a frame containing a non-zero probability
for an offset code larger than the largest offset code supported by the decoder
implementation.
#### From normalized distribution to decoding tables #### From normalized distribution to decoding tables
The normalized distribution of probabilities is enough The distribution of normalized probabilities is enough
to create a unique decoding table. to create a unique decoding table.
It is generated using the following build rule :
It follows the following build rule :
The table has a size of `Table_Size = 1 << Accuracy_Log`. The table has a size of `Table_Size = 1 << Accuracy_Log`.
Each row specifies the decoded symbol, Each cell describes the symbol decoded,
and instructions to reach the next state (`Number_of_Bits` and `Baseline`). and instructions to get the next state (`Number_of_Bits` and `Baseline`).
Symbols are first scanned in their natural order for "less than 1" probabilities Symbols are scanned in their natural order for "less than 1" probabilities.
(previously decoded from a Value of `0`). Symbols with this probability are being attributed a single cell,
Symbols with this special probability are being attributed a single row,
starting from the end of the table and retreating. starting from the end of the table and retreating.
These symbols define a full state reset, reading `Accuracy_Log` bits. These symbols define a full state reset, reading `Accuracy_Log` bits.
Then, all remaining symbols, sorted in natural order, are allocated rows. Then, all remaining symbols, sorted in natural order, are allocated cells.
Starting from smallest present symbol, and table position `0`, Starting from symbol `0` (if it exists), and table position `0`,
each symbol gets allocated as many rows as its probability. each symbol gets allocated as many cells as its probability.
Cell allocation is spread, not linear :
each successor position follows this rule :
Row allocation is not linear, it follows this order, in modular arithmetic:
``` ```
position += (tableSize>>1) + (tableSize>>3) + 3; position += (tableSize>>1) + (tableSize>>3) + 3;
position &= tableSize-1; position &= tableSize-1;
``` ```
Using above ordering rule, each symbol gets allocated as many rows as its probability. A position is skipped if already occupied by a "less than 1" probability symbol.
If a position is already occupied by a "less than 1" probability symbol, `position` does not reset between symbols, it simply iterates through
it is simply skipped, and the next position is allocated instead. each position in the table, switching to the next symbol when enough
Once enough rows have been allocated for the current symbol, states have been allocated to the current one.
the allocation process continues, using the next symbol, in natural order.
This process guarantees that the table is entirely and exactly filled.
Each row specifies a decoded symbol, and is accessed by current state value. The process guarantees that the table is entirely filled.
It also specifies `Number_of_Bits` and `Baseline`, which are required to determine next state value. Each cell corresponds to a state value, which contains the symbol being decoded.
To correctly set these fields, it's necessary to sort all occurrences of each symbol in state value order, To add the `Number_of_Bits` and `Baseline` required to retrieve next state,
and then attribute N+1 bits to lower rows, and N bits to higher rows, it's first necessary to sort all occurrences of each symbol in state order.
following the process described below (using an example): Lower states will need 1 more bit than higher ones.
The process is repeated for each symbol.
__Example__ : __Example__ :
Presuming an `Accuracy_Log` of 7, Presuming a symbol has a probability of 5,
let's imagine a symbol with a Probability of 5: it receives 5 cells, corresponding to 5 state values.
it receives 5 rows, corresponding to 5 state values between `0` and `127`. These state values are then sorted in natural order.
In this example, the first state value happens to be `1` (after unspecified previous symbols). Next power of 2 after 5 is 8.
The next 4 states are then determined using above modular arithmetic rule, Space of probabilities must be divided into 8 equal parts.
which specifies to add `64+16+3 = 83` modulo `128` to jump to next position, Presuming the `Accuracy_Log` is 7, it defines a space of 128 states.
producing the following series: `1`, `84`, `39`, `122`, `77` (modular arithmetic). Divided by 8, each share is 16 large.
(note: the next symbol will then start at `32`).
These state values are then sorted in natural order, In order to reach 8 shares, 8-5=3 lowest states will count "double",
resulting in the following series: `1`, `39`, `77`, `84`, `122`.
The next power of 2 after 5 is 8.
Therefore, the probability space will be divided into 8 equal parts.
Since the probability space is `1<<7 = 128` large, each share is `128/8 = 16` large.
In order to reach 8 shares, the `8-5 = 3` lowest states will count "double",
doubling their shares (32 in width), hence requiring one more bit. doubling their shares (32 in width), hence requiring one more bit.
Baseline is assigned starting from the lowest state using fewer bits, Baseline is assigned starting from the higher states using fewer bits,
continuing in natural state order, looping back at the beginning. increasing at each state, then resuming at the first state,
Each state takes its allocated range from Baseline, sized by its `Number_of_Bits`. each state takes its allocated width from Baseline.
| state order | 0 | 1 | 2 | 3 | 4 | | state order | 0 | 1 | 2 | 3 | 4 |
| ---------------- | ----- | ----- | ------ | ---- | ------ | | ---------------- | ----- | ----- | ------ | ---- | ------ |
| state value | 1 | 39 | 77 | 84 | 122 | | state value | 1 | 39 | 77 | 84 | 122 |
| width | 32 | 32 | 32 | 16 | 16 | | width | 32 | 32 | 32 | 16 | 16 |
| `Number_of_Bits` | 5 | 5 | 5 | 4 | 4 | | `Number_of_Bits` | 5 | 5 | 5 | 4 | 4 |
| allocation order | 3 | 4 | 5 | 1 | 2 | | range number | 2 | 4 | 6 | 0 | 1 |
| `Baseline` | 32 | 64 | 96 | 0 | 16 | | `Baseline` | 32 | 64 | 96 | 0 | 16 |
| range | 32-63 | 64-95 | 96-127 | 0-15 | 16-31 | | range | 32-63 | 64-95 | 96-127 | 0-15 | 16-31 |
During decoding, the next state value is determined by using current state value as row number, During decoding, the next state value is determined from current state value,
then reading the required `Number_of_Bits` from the bitstream, and adding the specified `Baseline`. by reading the required `Number_of_Bits`, and adding the specified `Baseline`.
Note: See [Appendix A] for the results of this process applied to the default distributions.
as a trivial example, it follows that, for a symbol with a Probability of `1`,
`Baseline` is necessarily `0`, and `Number_of_Bits` is necessarily `Accuracy_Log`.
See [Appendix A] to see the outcome of this process applied to the default distributions.
[Appendix A]: #appendix-a---decoding-tables-for-predefined-codes [Appendix A]: #appendix-a---decoding-tables-for-predefined-codes
@ -1270,13 +1250,13 @@ This specification limits maximum code length to 11 bits.
#### Representation #### Representation
All literal symbols from zero (included) to last present one (excluded) All literal values from zero (included) to last present one (excluded)
are represented by `Weight` with values from `0` to `Max_Number_of_Bits`. are represented by `Weight` with values from `0` to `Max_Number_of_Bits`.
Transformation from `Weight` to `Number_of_Bits` follows this formula : Transformation from `Weight` to `Number_of_Bits` follows this formula :
``` ```
Number_of_Bits = Weight ? (Max_Number_of_Bits + 1 - Weight) : 0 Number_of_Bits = Weight ? (Max_Number_of_Bits + 1 - Weight) : 0
``` ```
When a literal symbol is not present, it receives a `Weight` of 0. When a literal value is not present, it receives a `Weight` of 0.
The least frequent symbol receives a `Weight` of 1. The least frequent symbol receives a `Weight` of 1.
If no literal has a `Weight` of 1, then the data is considered corrupted. If no literal has a `Weight` of 1, then the data is considered corrupted.
If there are not at least two literals with non-zero `Weight`, then the data If there are not at least two literals with non-zero `Weight`, then the data
@ -1293,38 +1273,33 @@ otherwise the representation is considered corrupted.
__Example__ : __Example__ :
Let's presume the following Huffman tree must be described : Let's presume the following Huffman tree must be described :
| literal symbol | A | B | C | D | E | F | | literal value | 0 | 1 | 2 | 3 | 4 | 5 |
| ---------------- | --- | --- | --- | --- | --- | --- | | ---------------- | --- | --- | --- | --- | --- | --- |
| `Number_of_Bits` | 1 | 2 | 3 | 0 | 4 | 4 | | `Number_of_Bits` | 1 | 2 | 3 | 0 | 4 | 4 |
The tree depth is 4, since its longest elements uses 4 bits The tree depth is 4, since its longest elements uses 4 bits
(longest elements are the ones with smallest frequency). (longest elements are the one with smallest frequency).
Literal value `5` will not be listed, as it can be determined from previous values 0-4,
All symbols will now receive a `Weight` instead of `Number_of_Bits`. nor will values above `5` as they are all 0.
Values from `0` to `4` will be listed using `Weight` instead of `Number_of_Bits`.
Weight formula is : Weight formula is :
``` ```
Weight = Number_of_Bits ? (Max_Number_of_Bits + 1 - Number_of_Bits) : 0 Weight = Number_of_Bits ? (Max_Number_of_Bits + 1 - Number_of_Bits) : 0
``` ```
It gives the following series of Weights : It gives the following series of weights :
| literal symbol | A | B | C | D | E | F | | literal value | 0 | 1 | 2 | 3 | 4 |
| -------------- | --- | --- | --- | --- | --- | --- | | ------------- | --- | --- | --- | --- | --- |
| `Weight` | 4 | 3 | 2 | 0 | 1 | 1 | | `Weight` | 4 | 3 | 2 | 0 | 1 |
This list will be sent to the decoder, with the following modifications:
- `F` will not be listed, because it can be determined from previous symbols
- nor will symbols above `F` as they are all 0
- on the other hand, all symbols before `A`, starting with `\0`, will be listed, with a Weight of 0.
The decoder will do the inverse operation : The decoder will do the inverse operation :
having collected weights of literal symbols from `A` to `E`, having collected weights of literal symbols from `0` to `4`,
it knows the last literal, `F`, is present with a non-zero `Weight`. it knows the last literal, `5`, is present with a non-zero `Weight`.
The `Weight` of `F` can be determined by advancing to the next power of 2. The `Weight` of `5` can be determined by advancing to the next power of 2.
The sum of `2^(Weight-1)` (excluding 0's) is : The sum of `2^(Weight-1)` (excluding 0's) is :
`8 + 4 + 2 + 0 + 1 = 15`. `8 + 4 + 2 + 0 + 1 = 15`.
Nearest larger power of 2 value is 16. Nearest larger power of 2 value is 16.
Therefore, `Max_Number_of_Bits = log2(16) = 4` and `Weight[F] = log_2(16 - 15) + 1 = 1`. Therefore, `Max_Number_of_Bits = 4` and `Weight[5] = log_2(16 - 15) + 1 = 1`.
#### Huffman Tree header #### Huffman Tree header
@ -1364,7 +1339,7 @@ sharing a single distribution table.
To decode an FSE bitstream, it is necessary to know its compressed size. To decode an FSE bitstream, it is necessary to know its compressed size.
Compressed size is provided by `headerByte`. Compressed size is provided by `headerByte`.
It's also necessary to know its _maximum possible_ decompressed size, It's also necessary to know its _maximum possible_ decompressed size,
which is `255`, since literal symbols span from `0` to `255`, which is `255`, since literal values span from `0` to `255`,
and last symbol's `Weight` is not represented. and last symbol's `Weight` is not represented.
An FSE bitstream starts by a header, describing probabilities distribution. An FSE bitstream starts by a header, describing probabilities distribution.
@ -1389,10 +1364,6 @@ symbols for each of the final states are decoded and the process is complete.
If this process would produce more weights than the maximum number of decoded If this process would produce more weights than the maximum number of decoded
weights (255), then the data is considered corrupted. weights (255), then the data is considered corrupted.
If either of the 2 initial states are absent or truncated, then the data is
considered corrupted. Consequently, it is not possible to encode fewer than
2 weights using this mode.
#### Conversion from weights to Huffman prefix codes #### Conversion from weights to Huffman prefix codes
All present symbols shall now have a `Weight` value. All present symbols shall now have a `Weight` value.
@ -1400,28 +1371,26 @@ It is possible to transform weights into `Number_of_Bits`, using this formula:
``` ```
Number_of_Bits = (Weight>0) ? Max_Number_of_Bits + 1 - Weight : 0 Number_of_Bits = (Weight>0) ? Max_Number_of_Bits + 1 - Weight : 0
``` ```
In order to determine which prefix code is assigned to each Symbol, Symbols are sorted by `Weight`.
Symbols are first sorted by `Weight`, then by natural sequential order. Within same `Weight`, symbols keep natural sequential order.
Symbols with a `Weight` of zero are removed. Symbols with a `Weight` of zero are removed.
Then, starting from lowest `Weight` (hence highest `Number_of_Bits`), Then, starting from lowest `Weight`, prefix codes are distributed in sequential order.
prefix codes are assigned in ascending order.
__Example__ : __Example__ :
Let's assume the following list of weights has been decoded: Let's presume the following list of weights has been decoded :
| Literal | A | B | C | D | E | F | | Literal | 0 | 1 | 2 | 3 | 4 | 5 |
| -------- | --- | --- | --- | --- | --- | --- | | -------- | --- | --- | --- | --- | --- | --- |
| `Weight` | 4 | 3 | 2 | 0 | 1 | 1 | | `Weight` | 4 | 3 | 2 | 0 | 1 | 1 |
Sorted by weight and then natural sequential order, Sorted by weight and then natural sequential order,
it gives the following prefix codes distribution: it gives the following distribution :
| Literal | D | E | F | C | B | A | | Literal | 3 | 4 | 5 | 2 | 1 | 0 |
| ---------------- | --- | ---- | ---- | ---- | ---- | ---- | | ---------------- | --- | --- | --- | --- | --- | ---- |
| `Weight` | 0 | 1 | 1 | 2 | 3 | 4 | | `Weight` | 0 | 1 | 1 | 2 | 3 | 4 |
| `Number_of_Bits` | 0 | 4 | 4 | 3 | 2 | 1 | | `Number_of_Bits` | 0 | 4 | 4 | 3 | 2 | 1 |
| prefix code | N/A | 0000 | 0001 | 001 | 01 | 1 | | prefix codes | N/A | 0000| 0001| 001 | 01 | 1 |
| ascending order | N/A | 0000 | 0001 | 001x | 01xx | 1xxx |
### Huffman-coded Streams ### Huffman-coded Streams
@ -1444,10 +1413,10 @@ it's possible to read the bitstream in a __little-endian__ fashion,
keeping track of already used bits. Since the bitstream is encoded in reverse keeping track of already used bits. Since the bitstream is encoded in reverse
order, starting from the end read symbols in forward order. order, starting from the end read symbols in forward order.
For example, if the literal sequence `ABEF` was encoded using above prefix code, For example, if the literal sequence "0145" was encoded using above prefix code,
it would be encoded (in reverse order) as: it would be encoded (in reverse order) as:
|Symbol | F | E | B | A | Padding | |Symbol | 5 | 4 | 1 | 0 | Padding |
|--------|------|------|----|---|---------| |--------|------|------|----|---|---------|
|Encoding|`0000`|`0001`|`01`|`1`| `00001` | |Encoding|`0000`|`0001`|`01`|`1`| `00001` |
@ -1742,10 +1711,6 @@ or at least provide a meaningful error code explaining for which reason it canno
Version changes Version changes
--------------- ---------------
- 0.4.4 : minor clarification for block size
- 0.4.3 : clarifications for Huffman prefix code assignment example
- 0.4.2 : refactor FSE table construction process, inspired by Donald Pian
- 0.4.1 : clarifications on a few error scenarios, by Eric Lasota
- 0.4.0 : fixed imprecise behavior for nbSeq==0, detected by Igor Pavlov - 0.4.0 : fixed imprecise behavior for nbSeq==0, detected by Igor Pavlov
- 0.3.9 : clarifications for Huffman-compressed literal sizes. - 0.3.9 : clarifications for Huffman-compressed literal sizes.
- 0.3.8 : clarifications for Huffman Blocks and Huffman Tree descriptions. - 0.3.8 : clarifications for Huffman Blocks and Huffman Tree descriptions.

View File

@ -1,17 +1,16 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>zstd 1.5.7 Manual</title> <title>zstd 1.5.6 Manual</title>
</head> </head>
<body> <body>
<h1>zstd 1.5.7 Manual</h1> <h1>zstd 1.5.6 Manual</h1>
Note: the content of this file has been automatically generated by parsing "zstd.h"
<hr> <hr>
<a name="Contents"></a><h2>Contents</h2> <a name="Contents"></a><h2>Contents</h2>
<ol> <ol>
<li><a href="#Chapter1">Introduction</a></li> <li><a href="#Chapter1">Introduction</a></li>
<li><a href="#Chapter2">Version</a></li> <li><a href="#Chapter2">Version</a></li>
<li><a href="#Chapter3">Simple Core API</a></li> <li><a href="#Chapter3">Simple API</a></li>
<li><a href="#Chapter4">Explicit context</a></li> <li><a href="#Chapter4">Explicit context</a></li>
<li><a href="#Chapter5">Advanced compression API (Requires v1.4.0+)</a></li> <li><a href="#Chapter5">Advanced compression API (Requires v1.4.0+)</a></li>
<li><a href="#Chapter6">Advanced decompression API (Requires v1.4.0+)</a></li> <li><a href="#Chapter6">Advanced decompression API (Requires v1.4.0+)</a></li>
@ -75,7 +74,7 @@ Note: the content of this file has been automatically generated by parsing "zstd
</b><p> Return runtime library version, like "1.4.5". Requires v1.3.0+. </b><p> Return runtime library version, like "1.4.5". Requires v1.3.0+.
</p></pre><BR> </p></pre><BR>
<a name="Chapter3"></a><h2>Simple Core API</h2><pre></pre> <a name="Chapter3"></a><h2>Simple API</h2><pre></pre>
<pre><b>size_t ZSTD_compress( void* dst, size_t dstCapacity, <pre><b>size_t ZSTD_compress( void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
@ -89,48 +88,44 @@ Note: the content of this file has been automatically generated by parsing "zstd
<pre><b>size_t ZSTD_decompress( void* dst, size_t dstCapacity, <pre><b>size_t ZSTD_decompress( void* dst, size_t dstCapacity,
const void* src, size_t compressedSize); const void* src, size_t compressedSize);
</b><p> `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames. </b><p> `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.
Multiple compressed frames can be decompressed at once with this method. `dstCapacity` is an upper bound of originalSize to regenerate.
The result will be the concatenation of all decompressed frames, back to back. If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
`dstCapacity` is an upper bound of originalSize to regenerate. @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
First frame's decompressed size can be extracted using ZSTD_getFrameContentSize(). or an errorCode if it fails (which can be tested using ZSTD_isError()).
If maximum upper bound isn't known, prefer using streaming mode to decompress data.
@return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
or an errorCode if it fails (which can be tested using ZSTD_isError()).
</p></pre><BR> </p></pre><BR>
<h3>Decompression helper functions</h3><pre></pre><b><pre></pre></b><BR>
<pre><b>#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) <pre><b>#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) #define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
</b><p> `src` should point to the start of a ZSTD encoded frame. </b><p> `src` should point to the start of a ZSTD encoded frame.
`srcSize` must be at least as large as the frame header. `srcSize` must be at least as large as the frame header.
hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. hint : any size >= `ZSTD_frameHeaderSize_max` is large enough.
@return : - decompressed size of `src` frame content, if known @return : - decompressed size of `src` frame content, if known
- ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
- ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small)
note 1 : a 0 return value means the frame is valid but "empty". note 1 : a 0 return value means the frame is valid but "empty".
When invoking this method on a skippable frame, it will return 0. note 2 : decompressed size is an optional field, it may not be present, typically in streaming mode.
note 2 : decompressed size is an optional field, it may not be present (typically in streaming mode). When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.
When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. In which case, it's necessary to use streaming mode to decompress data.
In which case, it's necessary to use streaming mode to decompress data. Optionally, application can rely on some implicit limit,
Optionally, application can rely on some implicit limit, as ZSTD_decompress() only needs an upper bound of decompressed size.
as ZSTD_decompress() only needs an upper bound of decompressed size. (For example, data could be necessarily cut into blocks <= 16 KB).
(For example, data could be necessarily cut into blocks <= 16 KB). note 3 : decompressed size is always present when compression is completed using single-pass functions,
note 3 : decompressed size is always present when compression is completed using single-pass functions, such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict().
such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict(). note 4 : decompressed size can be very large (64-bits value),
note 4 : decompressed size can be very large (64-bits value), potentially larger than what local system can handle as a single memory segment.
potentially larger than what local system can handle as a single memory segment. In which case, it's necessary to use streaming mode to decompress data.
In which case, it's necessary to use streaming mode to decompress data. note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified.
note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. Always ensure return value fits within application's authorized limits.
Always ensure return value fits within application's authorized limits. Each application can set its own limits.
Each application can set its own limits. note 6 : This function replaces ZSTD_getDecompressedSize()
note 6 : This function replaces ZSTD_getDecompressedSize()
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("Replaced by ZSTD_getFrameContentSize") <pre><b>ZSTD_DEPRECATED("Replaced by ZSTD_getFrameContentSize")
ZSTDLIB_API
unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
</b><p> This function is now obsolete, in favor of ZSTD_getFrameContentSize(). </b><p> NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize().
Both functions work the same way, but ZSTD_getDecompressedSize() blends Both functions work the same way, but ZSTD_getDecompressedSize() blends
"empty", "unknown" and "error" results to the same return value (0), "empty", "unknown" and "error" results to the same return value (0),
while ZSTD_getFrameContentSize() gives them separate return values. while ZSTD_getFrameContentSize() gives them separate return values.
@ -142,61 +137,53 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
`srcSize` must be >= first frame size `srcSize` must be >= first frame size
@return : the compressed size of the first frame starting at `src`, @return : the compressed size of the first frame starting at `src`,
suitable to pass as `srcSize` to `ZSTD_decompress` or similar, suitable to pass as `srcSize` to `ZSTD_decompress` or similar,
or an error code if input is invalid or an error code if input is invalid
Note 1: this method is called _find*() because it's not enough to read the header,
it may have to scan through the frame's content, to reach its end.
Note 2: this method also works with Skippable Frames. In which case,
it returns the size of the complete skippable frame,
which is always equal to its content size + 8 bytes for headers.
</p></pre><BR> </p></pre><BR>
<h3>Compression helper functions</h3><pre></pre><b><pre></pre></b><BR> <h3>Helper functions</h3><pre></pre><b><pre></b>/* ZSTD_compressBound() :<b>
<pre><b>#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U) * 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) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U)
#define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) </b>/* 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 */<b> #define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) </b>/* 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 */<b>
size_t ZSTD_compressBound(size_t srcSize); </b>/*!< maximum compressed size in worst case single-pass scenario */<b> size_t ZSTD_compressBound(size_t srcSize); </b>/*!< maximum compressed size in worst case single-pass scenario */<b>
</b><p> maximum compressed size in worst case single-pass scenario. </b>/* ZSTD_isError() :<b>
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 is too large.
</p></pre><BR>
<h3>Error helper functions</h3><pre></pre><b><pre></b>/* ZSTD_isError() :<b>
* Most ZSTD_* functions returning a size_t value can be tested for error, * Most ZSTD_* functions returning a size_t value can be tested for error,
* using ZSTD_isError(). * using ZSTD_isError().
* @return 1 if error, 0 otherwise * @return 1 if error, 0 otherwise
*/ */
unsigned ZSTD_isError(size_t result); </b>/*!< tells if a `size_t` function result is an error code */<b> unsigned ZSTD_isError(size_t code); </b>/*!< tells if a `size_t` function result is an error code */<b>
ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); </b>/* convert a result into an error code, which can be compared to error enum list */<b> const char* ZSTD_getErrorName(size_t code); </b>/*!< provides readable string from an error code */<b>
const char* ZSTD_getErrorName(size_t result); </b>/*!< provides readable string from a function result */<b> int ZSTD_minCLevel(void); </b>/*!< minimum negative compression level allowed, requires v1.4.0+ */<b>
int ZSTD_minCLevel(void); </b>/*!< minimum negative compression level allowed, requires v1.4.0+ */<b> int ZSTD_maxCLevel(void); </b>/*!< maximum compression level available */<b>
int ZSTD_maxCLevel(void); </b>/*!< maximum compression level available */<b> int ZSTD_defaultCLevel(void); </b>/*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */<b>
int ZSTD_defaultCLevel(void); </b>/*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */<b>
</pre></b><BR> </pre></b><BR>
<a name="Chapter4"></a><h2>Explicit context</h2><pre></pre> <a name="Chapter4"></a><h2>Explicit context</h2><pre></pre>
<h3>Compression context</h3><pre> When compressing many times, <h3>Compression context</h3><pre> When compressing many times,
it is recommended to allocate a compression context just once, it is recommended to allocate a context just once,
and reuse it for each successive compression operation. and reuse it for each successive compression operation.
This will make the workload easier for system's memory. This will make workload friendlier for system's memory.
Note : re-using context is just a speed / resource optimization. Note : re-using context is just a speed / resource optimization.
It doesn't change the compression ratio, which remains identical. It doesn't change the compression ratio, which remains identical.
Note 2: For parallel execution in multi-threaded environments, Note 2 : In multi-threaded environments,
use one different context per thread . use one different context per thread for parallel execution.
</pre><b><pre>typedef struct ZSTD_CCtx_s ZSTD_CCtx; </pre><b><pre>typedef struct ZSTD_CCtx_s ZSTD_CCtx;
ZSTD_CCtx* ZSTD_createCCtx(void); ZSTD_CCtx* ZSTD_createCCtx(void);
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); </b>/* compatible with NULL pointer */<b> size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); </b>/* accept NULL pointer */<b>
</pre></b><BR> </pre></b><BR>
<pre><b>size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, <pre><b>size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
@ -207,7 +194,7 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); </b>/* compatible with NULL pointer
this function compresses at the requested compression level, this function compresses at the requested compression level,
__ignoring any other advanced parameter__ . __ignoring any other advanced parameter__ .
If any advanced parameter was set using the advanced API, If any advanced parameter was set using the advanced API,
they will all be reset. Only @compressionLevel remains. they will all be reset. Only `compressionLevel` remains.
</p></pre><BR> </p></pre><BR>
@ -311,7 +298,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
* Special: value 0 means "use default strategy". */ * Special: value 0 means "use default strategy". */
ZSTD_c_targetCBlockSize=130, </b>/* v1.5.6+<b> ZSTD_c_targetCBlockSize=130, </b>/* v1.5.6+<b>
* Attempts to fit compressed block size into approximately targetCBlockSize. * Attempts to fit compressed block size into approximatively targetCBlockSize.
* Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX. * Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX.
* Note that it's not a guarantee, just a convergence target (default:0). * Note that it's not a guarantee, just a convergence target (default:0).
* No target when targetCBlockSize == 0. * No target when targetCBlockSize == 0.
@ -407,8 +394,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
* ZSTD_c_stableOutBuffer * ZSTD_c_stableOutBuffer
* ZSTD_c_blockDelimiters * ZSTD_c_blockDelimiters
* ZSTD_c_validateSequences * ZSTD_c_validateSequences
* ZSTD_c_blockSplitterLevel * ZSTD_c_useBlockSplitter
* ZSTD_c_splitAfterSequences
* ZSTD_c_useRowMatchFinder * ZSTD_c_useRowMatchFinder
* ZSTD_c_prefetchCDictTables * ZSTD_c_prefetchCDictTables
* ZSTD_c_enableSeqProducerFallback * ZSTD_c_enableSeqProducerFallback
@ -435,8 +421,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
ZSTD_c_experimentalParam16=1013, ZSTD_c_experimentalParam16=1013,
ZSTD_c_experimentalParam17=1014, ZSTD_c_experimentalParam17=1014,
ZSTD_c_experimentalParam18=1015, ZSTD_c_experimentalParam18=1015,
ZSTD_c_experimentalParam19=1016, ZSTD_c_experimentalParam19=1016
ZSTD_c_experimentalParam20=1017
} ZSTD_cParameter; } ZSTD_cParameter;
</b></pre><BR> </b></pre><BR>
<pre><b>typedef struct { <pre><b>typedef struct {
@ -733,7 +718,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
<a name="Chapter9"></a><h2>Streaming decompression - HowTo</h2><pre> <a name="Chapter9"></a><h2>Streaming decompression - HowTo</h2><pre>
A ZSTD_DStream object is required to track streaming operations. A ZSTD_DStream object is required to track streaming operations.
Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources. Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
ZSTD_DStream objects can be re-employed multiple times. ZSTD_DStream objects can be reused multiple times.
Use ZSTD_initDStream() to start a new decompression operation. Use ZSTD_initDStream() to start a new decompression operation.
@return : recommended first input size @return : recommended first input size
@ -743,21 +728,16 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
The function will update both `pos` fields. The function will update both `pos` fields.
If `input.pos < input.size`, some input has not been consumed. If `input.pos < input.size`, some input has not been consumed.
It's up to the caller to present again remaining data. It's up to the caller to present again remaining data.
The function tries to flush all data decoded immediately, respecting output buffer size. The function tries to flush all data decoded immediately, respecting output buffer size.
If `output.pos < output.size`, decoder has flushed everything it could. If `output.pos < output.size`, decoder has flushed everything it could.
But if `output.pos == output.size`, there might be some data left within internal buffers.,
However, when `output.pos == output.size`, it's more difficult to know.
If @return > 0, the frame is not complete, meaning
either there is still some data left to flush within internal buffers,
or there is more input to read to complete the frame (or both).
In which case, call ZSTD_decompressStream() again to flush whatever remains in the buffer. In which case, call ZSTD_decompressStream() again to flush whatever remains in the buffer.
Note : with no additional input provided, amount of data flushed is necessarily <= ZSTD_BLOCKSIZE_MAX. Note : with no additional input provided, amount of data flushed is necessarily <= ZSTD_BLOCKSIZE_MAX.
@return : 0 when a frame is completely decoded and fully flushed, @return : 0 when a frame is completely decoded and fully flushed,
or an error code, which can be tested using ZSTD_isError(), or an error code, which can be tested using ZSTD_isError(),
or any other value > 0, which means there is still some decoding or flushing to do to complete current frame : or any other value > 0, which means there is still some decoding or flushing to do to complete current frame :
the return value is a suggested next input size (just a hint for better latency) the return value is a suggested next input size (just a hint for better latency)
that will never request more than the remaining content of the compressed frame. that will never request more than the remaining frame size.
<BR></pre> <BR></pre>
@ -783,10 +763,9 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b>
Function will update both input and output `pos` fields exposing current state via these fields: Function will update both input and output `pos` fields exposing current state via these fields:
- `input.pos < input.size`, some input remaining and caller should provide remaining input - `input.pos < input.size`, some input remaining and caller should provide remaining input
on the next call. on the next call.
- `output.pos < output.size`, decoder flushed internal output buffer. - `output.pos < output.size`, decoder finished and flushed all remaining buffers.
- `output.pos == output.size`, unflushed data potentially present in the internal buffers, - `output.pos == output.size`, potentially uncflushed data present in the internal buffers,
check ZSTD_decompressStream() @return value, call ZSTD_decompressStream() again to flush remaining data to output.
if > 0, invoke it again to flush remaining data to output.
Note : with no additional input, amount of data flushed <= ZSTD_BLOCKSIZE_MAX. Note : with no additional input, amount of data flushed <= ZSTD_BLOCKSIZE_MAX.
@return : 0 when a frame is completely decoded and fully flushed, @return : 0 when a frame is completely decoded and fully flushed,
@ -1088,7 +1067,7 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* *
* Note: This field is optional. ZSTD_generateSequences() will calculate the value of * Note: This field is optional. ZSTD_generateSequences() will calculate the value of
* 'rep', but repeat offsets do not necessarily need to be calculated from an external * 'rep', but repeat offsets do not necessarily need to be calculated from an external
* sequence provider perspective. For example, ZSTD_compressSequences() does not * sequence provider's perspective. For example, ZSTD_compressSequences() does not
* use this 'rep' field at all (as of now). * use this 'rep' field at all (as of now).
*/ */
} ZSTD_Sequence; } ZSTD_Sequence;
@ -1193,14 +1172,14 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
} ZSTD_literalCompressionMode_e; } ZSTD_literalCompressionMode_e;
</b></pre><BR> </b></pre><BR>
<pre><b>typedef enum { <pre><b>typedef enum {
</b>/* Note: This enum controls features which are conditionally beneficial.<b> </b>/* Note: This enum controls features which are conditionally beneficial. Zstd typically will make a final<b>
* Zstd can take a decision on whether or not to enable the feature (ZSTD_ps_auto), * decision on whether or not to enable the feature (ZSTD_ps_auto), but setting the switch to ZSTD_ps_enable
* but setting the switch to ZSTD_ps_enable or ZSTD_ps_disable force enable/disable the feature. * or ZSTD_ps_disable allow for a force enable/disable the feature.
*/ */
ZSTD_ps_auto = 0, </b>/* Let the library automatically determine whether the feature shall be enabled */<b> ZSTD_ps_auto = 0, </b>/* Let the library automatically determine whether the feature shall be enabled */<b>
ZSTD_ps_enable = 1, </b>/* Force-enable the feature */<b> ZSTD_ps_enable = 1, </b>/* Force-enable the feature */<b>
ZSTD_ps_disable = 2 </b>/* Do not use the feature */<b> ZSTD_ps_disable = 2 </b>/* Do not use the feature */<b>
} ZSTD_ParamSwitch_e; } ZSTD_paramSwitch_e;
</b></pre><BR> </b></pre><BR>
<a name="Chapter15"></a><h2>Frame header and size functions</h2><pre></pre> <a name="Chapter15"></a><h2>Frame header and size functions</h2><pre></pre>
@ -1243,33 +1222,33 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); <pre><b>ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
</b><p> srcSize must be large enough, aka >= ZSTD_FRAMEHEADERSIZE_PREFIX. </b><p> srcSize must be >= ZSTD_FRAMEHEADERSIZE_PREFIX.
@return : size of the Frame Header, @return : size of the Frame Header,
or an error code (if srcSize is too small) or an error code (if srcSize is too small)
</p></pre><BR> </p></pre><BR>
<pre><b>typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_FrameType_e; <pre><b>typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e;
</b></pre><BR> </b></pre><BR>
<pre><b>typedef struct { <pre><b>typedef struct {
unsigned long long frameContentSize; </b>/* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */<b> unsigned long long frameContentSize; </b>/* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */<b>
unsigned long long windowSize; </b>/* can be very large, up to <= frameContentSize */<b> unsigned long long windowSize; </b>/* can be very large, up to <= frameContentSize */<b>
unsigned blockSizeMax; unsigned blockSizeMax;
ZSTD_FrameType_e frameType; </b>/* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */<b> ZSTD_frameType_e frameType; </b>/* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */<b>
unsigned headerSize; unsigned headerSize;
unsigned dictID; </b>/* for ZSTD_skippableFrame, contains the skippable magic variant [0-15] */<b> unsigned dictID;
unsigned checksumFlag; unsigned checksumFlag;
unsigned _reserved1; unsigned _reserved1;
unsigned _reserved2; unsigned _reserved2;
} ZSTD_FrameHeader; } ZSTD_frameHeader;
</b></pre><BR> </b></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize); <pre><b>ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); </b>/**< doesn't consume input */<b>
</b>/*! ZSTD_getFrameHeader_advanced() :<b> </b>/*! ZSTD_getFrameHeader_advanced() :<b>
* same as ZSTD_getFrameHeader(), * same as ZSTD_getFrameHeader(),
* with added capability to select a format (like ZSTD_f_zstd1_magicless) */ * with added capability to select a format (like ZSTD_f_zstd1_magicless) */
ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
</b><p> decode Frame Header into `zfhPtr`, or requires larger `srcSize`. </b><p> decode Frame Header, or requires larger `srcSize`.
@return : 0 => header is complete, `zfhPtr` is correctly filled, @return : 0, `zfhPtr` is correctly filled,
>0 => `srcSize` is too small, @return value is the wanted `srcSize` amount, `zfhPtr` is not filled, >0, `srcSize` is too small, value is wanted `srcSize` amount,
or an error code, which can be tested using ZSTD_isError() or an error code, which can be tested using ZSTD_isError()
</p></pre><BR> </p></pre><BR>
@ -1319,9 +1298,9 @@ ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr,
</p></pre><BR> </p></pre><BR>
<pre><b>typedef enum { <pre><b>typedef enum {
ZSTD_sf_noBlockDelimiters = 0, </b>/* ZSTD_Sequence[] has no block delimiters, just sequences */<b> ZSTD_sf_noBlockDelimiters = 0, </b>/* Representation of ZSTD_Sequence has no block delimiters, sequences only */<b>
ZSTD_sf_explicitBlockDelimiters = 1 </b>/* ZSTD_Sequence[] contains explicit block delimiters */<b> ZSTD_sf_explicitBlockDelimiters = 1 </b>/* Representation of ZSTD_Sequence contains explicit block delimiters */<b>
} ZSTD_SequenceFormat_e; } ZSTD_sequenceFormat_e;
</b></pre><BR> </b></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_sequenceBound(size_t srcSize); <pre><b>ZSTDLIB_STATIC_API size_t ZSTD_sequenceBound(size_t srcSize);
</b><p> `srcSize` : size of the input buffer </b><p> `srcSize` : size of the input buffer
@ -1332,37 +1311,19 @@ ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr,
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("For debugging only, will be replaced by ZSTD_extractSequences()") <pre><b></b><p> Generate sequences using ZSTD_compress2(), given a source buffer.
ZSTDLIB_STATIC_API size_t
ZSTD_generateSequences(ZSTD_CCtx* zc,
ZSTD_Sequence* outSeqs, size_t outSeqsCapacity,
const void* src, size_t srcSize);
</b><p> WARNING: This function is meant for debugging and informational purposes ONLY!
Its implementation is flawed, and it will be deleted in a future version.
It is not guaranteed to succeed, as there are several cases where it will give
up and fail. You should NOT use this function in production code.
This function is deprecated, and will be removed in a future version.
Generate sequences using ZSTD_compress2(), given a source buffer.
@param zc The compression context to be used for ZSTD_compress2(). Set any
compression parameters you need on this context.
@param outSeqs The output sequences buffer of size @p outSeqsSize
@param outSeqsCapacity The size of the output sequences buffer.
ZSTD_sequenceBound(srcSize) is an upper bound on the number
of sequences that can be generated.
@param src The source buffer to generate sequences from of size @p srcSize.
@param srcSize The size of the source buffer.
Each block will end with a dummy sequence Each block will end with a dummy sequence
with offset == 0, matchLength == 0, and litLength == length of last literals. with offset == 0, matchLength == 0, and litLength == length of last literals.
litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0) litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0)
simply acts as a block delimiter. simply acts as a block delimiter.
@returns The number of sequences generated, necessarily less than @zc can be used to insert custom compression params.
ZSTD_sequenceBound(srcSize), or an error code that can be checked This function invokes ZSTD_compress2().
with ZSTD_isError().
The output of this function can be fed into ZSTD_compressSequences() with CCtx
setting of ZSTD_c_blockDelimiters as ZSTD_sf_explicitBlockDelimiters
@return : number of sequences generated
</p></pre><BR> </p></pre><BR>
@ -1380,14 +1341,13 @@ ZSTD_generateSequences(ZSTD_CCtx* zc,
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t <pre><b>ZSTDLIB_STATIC_API size_t
ZSTD_compressSequences(ZSTD_CCtx* cctx, ZSTD_compressSequences( ZSTD_CCtx* cctx, void* dst, size_t dstSize,
void* dst, size_t dstCapacity, const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
const ZSTD_Sequence* inSeqs, size_t inSeqsSize, const void* src, size_t srcSize);
const void* src, size_t srcSize);
</b><p> Compress an array of ZSTD_Sequence, associated with @src buffer, into dst. </b><p> Compress an array of ZSTD_Sequence, associated with @src buffer, into dst.
@src contains the entire input (not just the literals). @src contains the entire input (not just the literals).
If @srcSize > sum(sequence.length), the remaining bytes are considered all literals If @srcSize > sum(sequence.length), the remaining bytes are considered all literals
If a dictionary is included, then the cctx should reference the dict (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.). If a dictionary is included, then the cctx should reference the dict. (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.)
The entire source is compressed into a single frame. The entire source is compressed into a single frame.
The compression behavior changes based on cctx params. In particular: The compression behavior changes based on cctx params. In particular:
@ -1396,17 +1356,11 @@ ZSTD_compressSequences(ZSTD_CCtx* cctx,
the block size derived from the cctx, and sequences may be split. This is the default setting. the block size derived from the cctx, and sequences may be split. This is the default setting.
If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain
valid block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided. block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided.
When ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, it's possible to decide generating repcodes If ZSTD_c_validateSequences == 0, this function will blindly accept the sequences provided. Invalid sequences cause undefined
using the advanced parameter ZSTD_c_repcodeResolution. Repcodes will improve compression ratio, though the benefit behavior. If ZSTD_c_validateSequences == 1, then if sequence is invalid (see doc/zstd_compression_format.md for
can vary greatly depending on Sequences. On the other hand, repcode resolution is an expensive operation. specifics regarding offset/matchlength requirements) then the function will bail out and return an error.
By default, it's disabled at low (<10) compression levels, and enabled above the threshold (>=10).
ZSTD_c_repcodeResolution makes it possible to directly manage this processing in either direction.
If ZSTD_c_validateSequences == 0, this function blindly accepts the Sequences provided. Invalid Sequences cause undefined
behavior. If ZSTD_c_validateSequences == 1, then the function will detect invalid Sequences (see doc/zstd_compression_format.md for
specifics regarding offset/matchlength requirements) and then bail out and return an error.
In addition to the two adjustable experimental params, there are other important cctx params. In addition to the two adjustable experimental params, there are other important cctx params.
- ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN. - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN.
@ -1414,47 +1368,21 @@ ZSTD_compressSequences(ZSTD_CCtx* cctx,
- ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset
is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md
Note: Repcodes are, as of now, always re-calculated within this function, ZSTD_Sequence.rep is effectively unused. Note: Repcodes are, as of now, always re-calculated within this function, so ZSTD_Sequence::rep is unused.
Dev Note: Once ability to ingest repcodes become available, the explicit block delims mode must respect those repcodes exactly, Note 2: Once we integrate ability to ingest repcodes, the explicit block delims mode must respect those repcodes exactly,
and cannot emit an RLE block that disagrees with the repcode history. and cannot emit an RLE block that disagrees with the repcode history
@return : final compressed size, or a ZSTD error code.
</p></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t
ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const ZSTD_Sequence* inSeqs, size_t nbSequences,
const void* literals, size_t litSize, size_t litBufCapacity,
size_t decompressedSize);
</b><p> This is a variant of ZSTD_compressSequences() which,
instead of receiving (src,srcSize) as input parameter, receives (literals,litSize),
aka all the literals, already extracted and laid out into a single continuous buffer.
This can be useful if the process generating the sequences also happens to generate the buffer of literals,
thus skipping an extraction + caching stage.
It's a speed optimization, useful when the right conditions are met,
but it also features the following limitations:
- Only supports explicit delimiter mode
- Currently does not support Sequences validation (so input Sequences are trusted)
- Not compatible with frame checksum, which must be disabled
- If any block is incompressible, will fail and return an error
- @litSize must be == sum of all @.litLength fields in @inSeqs. Any discrepancy will generate an error.
- @litBufCapacity is the size of the underlying buffer into which literals are written, starting at address @literals.
@litBufCapacity must be at least 8 bytes larger than @litSize.
- @decompressedSize must be correct, and correspond to the sum of all Sequences. Any discrepancy will generate an error.
@return : final compressed size, or a ZSTD error code. @return : final compressed size, or a ZSTD error code.
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, <pre><b>ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize, unsigned magicVariant);
unsigned magicVariant);
</b><p> Generates a zstd skippable frame containing data given by src, and writes it to dst buffer. </b><p> Generates a zstd skippable frame containing data given by src, and writes it to dst buffer.
Skippable frames begin with a 4-byte magic number. There are 16 possible choices of magic number, Skippable frames begin with a 4-byte magic number. There are 16 possible choices of magic number,
ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15. ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15.
As such, the parameter magicVariant controls the exact skippable frame magic number variant used, As such, the parameter magicVariant controls the exact skippable frame magic number variant used, so
so the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant. the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant.
Returns an error if destination buffer is not large enough, if the source size is not representable Returns an error if destination buffer is not large enough, if the source size is not representable
with a 4-byte unsigned int, or if the parameter magicVariant is greater than 15 (and therefore invalid). with a 4-byte unsigned int, or if the parameter magicVariant is greater than 15 (and therefore invalid).
@ -1463,14 +1391,13 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, <pre><b>size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
unsigned* magicVariant, const void* src, size_t srcSize);
const void* src, size_t srcSize); </b><p> Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
</b><p> Retrieves the content of a zstd skippable frame starting at @src, and writes it to @dst buffer.
The parameter @magicVariant will receive the magicVariant that was supplied when the frame was written, The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
This can be NULL if the caller is not interested in the magicVariant. in the magicVariant.
Returns an error if destination buffer is not large enough, or if the frame is not skippable. Returns an error if destination buffer is not large enough, or if the frame is not skippable.
@ -1478,7 +1405,7 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTDLIB_STATIC_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size); <pre><b>unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
</b><p> Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. </b><p> Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame.
</p></pre><BR> </p></pre><BR>
@ -1585,14 +1512,13 @@ static
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__((__unused__)) __attribute__((__unused__))
#endif #endif
ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; </b>/**< this constant defers to stdlib's functions */<b>
</b><p> These prototypes make it possible to pass your own allocation/free functions. </b><p> These prototypes make it possible to pass your own allocation/free functions.
ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below. ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below.
All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones. All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; </b>/**< this constant defers to stdlib's functions */<b>
</b></pre><BR>
<pre><b>typedef struct POOL_ctx_s ZSTD_threadPool; <pre><b>typedef struct POOL_ctx_s ZSTD_threadPool;
ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads); ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); </b>/* accept NULL pointer */<b> ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); </b>/* accept NULL pointer */<b>
@ -2131,7 +2057,7 @@ ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const Z
>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,
such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`).
Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information.
As a consequence, check that values remain within valid application range. As a consequence, check that values remain within valid application range.

View File

@ -63,8 +63,6 @@ CPPFLAGS_DYNLIB += -DZSTD_MULTITHREAD # dynamic library build defaults to multi
LDFLAGS_DYNLIB += -pthread LDFLAGS_DYNLIB += -pthread
CPPFLAGS_STATICLIB += # static library build defaults to single-threaded CPPFLAGS_STATICLIB += # static library build defaults to single-threaded
# pkg-config Libs.private points to LDFLAGS_DYNLIB
PCLIB := $(LDFLAGS_DYNLIB)
ifeq ($(findstring GCC,$(CCVER)),GCC) ifeq ($(findstring GCC,$(CCVER)),GCC)
decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize
@ -73,15 +71,13 @@ endif
# macOS linker doesn't support -soname, and use different extension # macOS linker doesn't support -soname, and use different extension
# see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html # see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
UNAME_TARGET_SYSTEM ?= $(UNAME) ifeq ($(UNAME), Darwin)
ifeq ($(UNAME_TARGET_SYSTEM), Darwin)
SHARED_EXT = dylib SHARED_EXT = dylib
SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT) SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT)
SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER)
else else
ifeq ($(UNAME_TARGET_SYSTEM), AIX) ifeq ($(UNAME), AIX)
SONAME_FLAGS = SONAME_FLAGS =
else else
SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR)
@ -166,7 +162,7 @@ $(ZSTD_DYNLIB): $(ZSTD_DYNLIB_OBJ)
$(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\ $(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\
@echo compiling multi-threaded dynamic library $(LIBVER),\ @echo compiling multi-threaded dynamic library $(LIBVER),\
@echo compiling single-threaded dynamic library $(LIBVER)) @echo compiling single-threaded dynamic library $(LIBVER))
$(CC) $(FLAGS) $^ $(SONAME_FLAGS) -o $@ $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
@echo creating versioned links @echo creating versioned links
ln -sf $@ libzstd.$(SHARED_EXT_MAJOR) ln -sf $@ libzstd.$(SHARED_EXT_MAJOR)
ln -sf $@ libzstd.$(SHARED_EXT) ln -sf $@ libzstd.$(SHARED_EXT)
@ -190,15 +186,12 @@ lib : libzstd.a libzstd
%-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD %-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD
%-mt : CPPFLAGS_STATICLIB := -DZSTD_MULTITHREAD %-mt : CPPFLAGS_STATICLIB := -DZSTD_MULTITHREAD
%-mt : LDFLAGS_DYNLIB := -pthread %-mt : LDFLAGS_DYNLIB := -pthread
%-mt : PCLIB :=
%-mt : PCMTLIB := $(LDFLAGS_DYNLIB)
%-mt : % %-mt : %
@echo multi-threaded build completed @echo multi-threaded build completed
%-nomt : CPPFLAGS_DYNLIB := %-nomt : CPPFLAGS_DYNLIB :=
%-nomt : LDFLAGS_DYNLIB := %-nomt : LDFLAGS_DYNLIB :=
%-nomt : CPPFLAGS_STATICLIB := %-nomt : CPPFLAGS_STATICLIB :=
%-nomt : PCLIB :=
%-nomt : % %-nomt : %
@echo single-threaded build completed @echo single-threaded build completed
@ -255,7 +248,7 @@ libzstd-nomt: $(ZSTD_NOMT_FILES)
echo "Error: Found zstdmt in list."; \ echo "Error: Found zstdmt in list."; \
exit 1; \ exit 1; \
fi fi
$(CC) $(FLAGS) $^ $(SONAME_FLAGS) -o $@ $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
.PHONY: clean .PHONY: clean
clean: clean:
@ -268,7 +261,7 @@ clean:
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# make install is validated only for below listed environments # make install is validated only for below listed environments
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT% CYGWIN_NT%,$(UNAME))) ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT CYGWIN_NT))
lib: libzstd.pc lib: libzstd.pc
@ -299,21 +292,13 @@ PCLIBPREFIX := $(if $(findstring $(LIBDIR),$(PCLIBDIR)),,$${exec_prefix})
# to PREFIX, rather than as a resolved value. # to PREFIX, rather than as a resolved value.
PCEXEC_PREFIX := $(if $(HAS_EXPLICIT_EXEC_PREFIX),$(EXEC_PREFIX),$${prefix}) PCEXEC_PREFIX := $(if $(HAS_EXPLICIT_EXEC_PREFIX),$(EXEC_PREFIX),$${prefix})
ifneq (,$(filter $(UNAME),FreeBSD NetBSD DragonFly))
ifneq ($(MT),)
PCLIB :=
PCMTLIB := $(LDFLAGS_DYNLIB)
else
PCLIB := $(LDFLAGS_DYNLIB)
endif
ifneq (,$(filter FreeBSD NetBSD DragonFly,$(UNAME)))
PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig PKGCONFIGDIR ?= $(PREFIX)/libdata/pkgconfig
else else
PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
endif endif
ifneq (,$(filter SunOS,$(UNAME))) ifneq (,$(filter $(UNAME),SunOS))
INSTALL ?= ginstall INSTALL ?= ginstall
else else
INSTALL ?= install INSTALL ?= install
@ -323,10 +308,6 @@ INSTALL_PROGRAM ?= $(INSTALL)
INSTALL_DATA ?= $(INSTALL) -m 644 INSTALL_DATA ?= $(INSTALL) -m 644
# pkg-config library define.
# For static single-threaded library declare -pthread in Libs.private
# For static multi-threaded library declare -pthread in Libs and Cflags
.PHONY: libzstd.pc
libzstd.pc: libzstd.pc.in libzstd.pc: libzstd.pc.in
@echo creating pkgconfig @echo creating pkgconfig
@sed \ @sed \
@ -335,8 +316,7 @@ libzstd.pc: libzstd.pc.in
-e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \
-e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \
-e 's|@VERSION@|$(VERSION)|' \ -e 's|@VERSION@|$(VERSION)|' \
-e 's|@LIBS_MT@|$(PCMTLIB)|' \ -e 's|@LIBS_PRIVATE@|$(LDFLAGS_DYNLIB)|' \
-e 's|@LIBS_PRIVATE@|$(PCLIB)|' \
$< >$@ $< >$@
.PHONY: install .PHONY: install

View File

@ -27,16 +27,12 @@ Enabling multithreading requires 2 conditions :
For convenience, we provide a build target to generate multi and single threaded libraries: For convenience, we provide a build target to generate multi and single threaded libraries:
- Force enable multithreading on both dynamic and static libraries by appending `-mt` to the target, e.g. `make lib-mt`. - Force enable multithreading on both dynamic and static libraries by appending `-mt` to the target, e.g. `make lib-mt`.
Note that the `.pc` generated on calling `make lib-mt` will already include the require Libs and Cflags.
- Force disable multithreading on both dynamic and static libraries by appending `-nomt` to the target, e.g. `make lib-nomt`. - Force disable multithreading on both dynamic and static libraries by appending `-nomt` to the target, e.g. `make lib-nomt`.
- By default, as mentioned before, dynamic library is multithreaded, and static library is single-threaded, e.g. `make lib`. - By default, as mentioned before, dynamic library is multithreaded, and static library is single-threaded, e.g. `make lib`.
When linking a POSIX program with a multithreaded version of `libzstd`, When linking a POSIX program with a multithreaded version of `libzstd`,
note that it's necessary to invoke the `-pthread` flag during link stage. note that it's necessary to invoke the `-pthread` flag during link stage.
The `.pc` generated from `make install` or `make install-pc` always assume a single-threaded static library
is compiled. To correctly generate a `.pc` for the multi-threaded static library, set `MT=1` as ENV variable.
Multithreading capabilities are exposed Multithreading capabilities are exposed
via the [advanced API defined in `lib/zstd.h`](https://github.com/facebook/zstd/blob/v1.4.3/lib/zstd.h#L351). via the [advanced API defined in `lib/zstd.h`](https://github.com/facebook/zstd/blob/v1.4.3/lib/zstd.h#L351).
@ -149,13 +145,6 @@ The file structure is designed to make this selection manually achievable for an
will expose the deprecated `ZSTDMT` API exposed by `zstdmt_compress.h` in will expose the deprecated `ZSTDMT` API exposed by `zstdmt_compress.h` in
the shared library, which is now hidden by default. the shared library, which is now hidden by default.
- The build macro `STATIC_BMI2` can be set to 1 to force usage of `bmi2` instructions.
It is generally not necessary to set this build macro,
because `STATIC_BMI2` will be automatically set to 1
on detecting the presence of the corresponding instruction set in the compilation target.
It's nonetheless available as an optional manual toggle for better control,
and can also be used to forcefully disable `bmi2` instructions by setting it to 0.
- The build macro `DYNAMIC_BMI2` can be set to 1 or 0 in order to generate binaries - The build macro `DYNAMIC_BMI2` can be set to 1 or 0 in order to generate binaries
which can detect at runtime the presence of BMI2 instructions, and use them only if present. which can detect at runtime the presence of BMI2 instructions, and use them only if present.
These instructions contribute to better performance, notably on the decoder side. These instructions contribute to better performance, notably on the decoder side.
@ -193,11 +182,6 @@ The file structure is designed to make this selection manually achievable for an
and assembly decoding loops. You may want to use this macro if these loops are and assembly decoding loops. You may want to use this macro if these loops are
slower on your platform. slower on your platform.
- The macro `ZDICT_QSORT` can enforce selection of a specific sorting variant,
which is useful when autodetection fails, for example with older versions of `musl`.
For this scenario, it can be set as `ZDICT_QSORT=ZDICT_QSORT_C90`.
Other selectable suffixes are `_GNU`, `_APPLE`, `_MSVC` and `_C11`.
#### Windows : using MinGW+MSYS to create DLL #### Windows : using MinGW+MSYS to create DLL
DLL can be created using MinGW+MSYS with the `make libzstd` command. DLL can be created using MinGW+MSYS with the `make libzstd` command.

View File

@ -21,36 +21,34 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
30, 22, 20, 15, 25, 17, 4, 8, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 31, 27, 13, 23, 21, 19, 16, 7,
26, 12, 18, 6, 11, 5, 10, 9}; 26, 12, 18, 6, 11, 5, 10, 9};
return DeBruijnBytePos[((U32) ((val & (0-val)) * 0x077CB531U)) >> 27]; return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27];
} }
} }
MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val) MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val)
{ {
assert(val != 0); assert(val != 0);
#if defined(_MSC_VER) # if defined(_MSC_VER)
# if STATIC_BMI2 # if STATIC_BMI2 == 1
return (unsigned)_tzcnt_u32(val); return (unsigned)_tzcnt_u32(val);
# else # else
if (val != 0) { if (val != 0) {
unsigned long r; unsigned long r;
_BitScanForward(&r, val); _BitScanForward(&r, val);
return (unsigned)r; return (unsigned)r;
} else { } else {
__assume(0); /* Should not reach this code path */ /* Should not reach this code path */
} __assume(0);
# endif }
#elif defined(__GNUC__) && (__GNUC__ >= 4) # endif
return (unsigned)__builtin_ctz(val); # elif defined(__GNUC__) && (__GNUC__ >= 4)
#elif defined(__ICCARM__) return (unsigned)__builtin_ctz(val);
return (unsigned)__builtin_ctz(val); # else
#else return ZSTD_countTrailingZeros32_fallback(val);
return ZSTD_countTrailingZeros32_fallback(val); # endif
#endif
} }
MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) {
{
assert(val != 0); assert(val != 0);
{ {
static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29, static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
@ -69,89 +67,86 @@ MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val)
MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val) MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
{ {
assert(val != 0); assert(val != 0);
#if defined(_MSC_VER) # if defined(_MSC_VER)
# if STATIC_BMI2 # if STATIC_BMI2 == 1
return (unsigned)_lzcnt_u32(val); return (unsigned)_lzcnt_u32(val);
# else # else
if (val != 0) { if (val != 0) {
unsigned long r; unsigned long r;
_BitScanReverse(&r, val); _BitScanReverse(&r, val);
return (unsigned)(31 - r); return (unsigned)(31 - r);
} else { } else {
__assume(0); /* Should not reach this code path */ /* Should not reach this code path */
} __assume(0);
# endif }
#elif defined(__GNUC__) && (__GNUC__ >= 4) # endif
return (unsigned)__builtin_clz(val); # elif defined(__GNUC__) && (__GNUC__ >= 4)
#elif defined(__ICCARM__) return (unsigned)__builtin_clz(val);
return (unsigned)__builtin_clz(val); # else
#else return ZSTD_countLeadingZeros32_fallback(val);
return ZSTD_countLeadingZeros32_fallback(val); # endif
#endif
} }
MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val) MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
{ {
assert(val != 0); assert(val != 0);
#if defined(_MSC_VER) && defined(_WIN64) # if defined(_MSC_VER) && defined(_WIN64)
# if STATIC_BMI2 # if STATIC_BMI2 == 1
return (unsigned)_tzcnt_u64(val); return (unsigned)_tzcnt_u64(val);
# else # else
if (val != 0) { if (val != 0) {
unsigned long r; unsigned long r;
_BitScanForward64(&r, val); _BitScanForward64(&r, val);
return (unsigned)r; return (unsigned)r;
} else { } else {
__assume(0); /* Should not reach this code path */ /* Should not reach this code path */
} __assume(0);
# endif }
#elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__) # endif
return (unsigned)__builtin_ctzll(val); # elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
#elif defined(__ICCARM__) return (unsigned)__builtin_ctzll(val);
return (unsigned)__builtin_ctzll(val); # else
#else {
{ U32 mostSignificantWord = (U32)(val >> 32);
U32 mostSignificantWord = (U32)(val >> 32); U32 leastSignificantWord = (U32)val;
U32 leastSignificantWord = (U32)val; if (leastSignificantWord == 0) {
if (leastSignificantWord == 0) { return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
return 32 + ZSTD_countTrailingZeros32(mostSignificantWord); } else {
} else { return ZSTD_countTrailingZeros32(leastSignificantWord);
return ZSTD_countTrailingZeros32(leastSignificantWord); }
} }
} # endif
#endif
} }
MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val) MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
{ {
assert(val != 0); assert(val != 0);
#if defined(_MSC_VER) && defined(_WIN64) # if defined(_MSC_VER) && defined(_WIN64)
# if STATIC_BMI2 # if STATIC_BMI2 == 1
return (unsigned)_lzcnt_u64(val); return (unsigned)_lzcnt_u64(val);
# else # else
if (val != 0) { if (val != 0) {
unsigned long r; unsigned long r;
_BitScanReverse64(&r, val); _BitScanReverse64(&r, val);
return (unsigned)(63 - r); return (unsigned)(63 - r);
} else { } else {
__assume(0); /* Should not reach this code path */ /* Should not reach this code path */
} __assume(0);
# endif }
#elif defined(__GNUC__) && (__GNUC__ >= 4) # endif
return (unsigned)(__builtin_clzll(val)); # elif defined(__GNUC__) && (__GNUC__ >= 4)
#elif defined(__ICCARM__) return (unsigned)(__builtin_clzll(val));
return (unsigned)(__builtin_clzll(val)); # else
#else {
{ U32 mostSignificantWord = (U32)(val >> 32);
U32 mostSignificantWord = (U32)(val >> 32); U32 leastSignificantWord = (U32)val;
U32 leastSignificantWord = (U32)val; if (mostSignificantWord == 0) {
if (mostSignificantWord == 0) { return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
return 32 + ZSTD_countLeadingZeros32(leastSignificantWord); } else {
} else { return ZSTD_countLeadingZeros32(mostSignificantWord);
return ZSTD_countLeadingZeros32(mostSignificantWord); }
} }
} # endif
#endif
} }
MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val) MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)

View File

@ -14,6 +14,9 @@
#ifndef BITSTREAM_H_MODULE #ifndef BITSTREAM_H_MODULE
#define BITSTREAM_H_MODULE #define BITSTREAM_H_MODULE
#if defined (__cplusplus)
extern "C" {
#endif
/* /*
* This API consists of small unitary functions, which must be inlined for best performance. * This API consists of small unitary functions, which must be inlined for best performance.
* Since link-time-optimization is not available for all compilers, * Since link-time-optimization is not available for all compilers,
@ -29,6 +32,7 @@
#include "error_private.h" /* error codes and messages */ #include "error_private.h" /* error codes and messages */
#include "bits.h" /* ZSTD_highbit32 */ #include "bits.h" /* ZSTD_highbit32 */
/*========================================= /*=========================================
* Target specific * Target specific
=========================================*/ =========================================*/
@ -48,13 +52,12 @@
/*-****************************************** /*-******************************************
* bitStream encoding API (write forward) * bitStream encoding API (write forward)
********************************************/ ********************************************/
typedef size_t BitContainerType;
/* bitStream can mix input from multiple sources. /* bitStream can mix input from multiple sources.
* A critical property of these streams is that they encode and decode in **reverse** direction. * A critical property of these streams is that they encode and decode in **reverse** direction.
* So the first bit sequence you add will be the last to be read, like a LIFO stack. * So the first bit sequence you add will be the last to be read, like a LIFO stack.
*/ */
typedef struct { typedef struct {
BitContainerType bitContainer; size_t bitContainer;
unsigned bitPos; unsigned bitPos;
char* startPtr; char* startPtr;
char* ptr; char* ptr;
@ -62,7 +65,7 @@ typedef struct {
} BIT_CStream_t; } BIT_CStream_t;
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC);
MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
@ -71,7 +74,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. * `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
* *
* bits are first added to a local register. * bits are first added to a local register.
* Local register is BitContainerType, 64-bits on 64-bits systems, or 32-bits on 32-bits systems. * Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
* Writing data into memory is an explicit operation, performed by the flushBits function. * Writing data into memory is an explicit operation, performed by the flushBits function.
* Hence keep track how many bits are potentially stored into local register to avoid register overflow. * Hence keep track how many bits are potentially stored into local register to avoid register overflow.
* After a flushBits, a maximum of 7 bits might still be stored into local register. * After a flushBits, a maximum of 7 bits might still be stored into local register.
@ -87,6 +90,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
/*-******************************************** /*-********************************************
* bitStream decoding API (read backward) * bitStream decoding API (read backward)
**********************************************/ **********************************************/
typedef size_t BitContainerType;
typedef struct { typedef struct {
BitContainerType bitContainer; BitContainerType bitContainer;
unsigned bitsConsumed; unsigned bitsConsumed;
@ -102,7 +106,7 @@ typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */
} BIT_DStream_status; /* result of BIT_reloadDStream() */ } BIT_DStream_status; /* result of BIT_reloadDStream() */
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
MEM_STATIC BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
@ -121,7 +125,7 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
/*-**************************************** /*-****************************************
* unsafe API * unsafe API
******************************************/ ******************************************/
MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ /* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
@ -159,15 +163,10 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
return 0; return 0;
} }
FORCE_INLINE_TEMPLATE BitContainerType BIT_getLowerBits(BitContainerType bitContainer, U32 const nbBits) FORCE_INLINE_TEMPLATE size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
{ {
#if STATIC_BMI2 && !defined(ZSTD_NO_INTRINSICS) #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
# if (defined(__x86_64__) || defined(_M_X64)) && !defined(__ILP32__) return _bzhi_u64(bitContainer, nbBits);
return _bzhi_u64(bitContainer, nbBits);
# else
DEBUG_STATIC_ASSERT(sizeof(bitContainer) == sizeof(U32));
return _bzhi_u32(bitContainer, nbBits);
# endif
#else #else
assert(nbBits < BIT_MASK_SIZE); assert(nbBits < BIT_MASK_SIZE);
return bitContainer & BIT_mask[nbBits]; return bitContainer & BIT_mask[nbBits];
@ -178,7 +177,7 @@ FORCE_INLINE_TEMPLATE BitContainerType BIT_getLowerBits(BitContainerType bitCont
* can add up to 31 bits into `bitC`. * can add up to 31 bits into `bitC`.
* Note : does not check for register overflow ! */ * Note : does not check for register overflow ! */
MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
BitContainerType value, unsigned nbBits) size_t value, unsigned nbBits)
{ {
DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32); DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
assert(nbBits < BIT_MASK_SIZE); assert(nbBits < BIT_MASK_SIZE);
@ -191,7 +190,7 @@ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
* works only if `value` is _clean_, * works only if `value` is _clean_,
* meaning all high bits above nbBits are 0 */ * meaning all high bits above nbBits are 0 */
MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
BitContainerType value, unsigned nbBits) size_t value, unsigned nbBits)
{ {
assert((value>>nbBits) == 0); assert((value>>nbBits) == 0);
assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
@ -238,7 +237,7 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
BIT_addBitsFast(bitC, 1, 1); /* endMark */ BIT_addBitsFast(bitC, 1, 1); /* endMark */
BIT_flushBits(bitC); BIT_flushBits(bitC);
if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
return (size_t)(bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
} }
@ -299,12 +298,12 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
return srcSize; return srcSize;
} }
FORCE_INLINE_TEMPLATE BitContainerType BIT_getUpperBits(BitContainerType bitContainer, U32 const start) FORCE_INLINE_TEMPLATE size_t BIT_getUpperBits(BitContainerType bitContainer, U32 const start)
{ {
return bitContainer >> start; return bitContainer >> start;
} }
FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits) FORCE_INLINE_TEMPLATE size_t BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits)
{ {
U32 const regMask = sizeof(bitContainer)*8 - 1; U32 const regMask = sizeof(bitContainer)*8 - 1;
/* if start > regMask, bitstream is corrupted, and result is undefined */ /* if start > regMask, bitstream is corrupted, and result is undefined */
@ -314,7 +313,7 @@ FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitCon
* such cpus old (pre-Haswell, 2013) and their performance is not of that * such cpus old (pre-Haswell, 2013) and their performance is not of that
* importance. * importance.
*/ */
#if defined(__x86_64__) || defined(_M_X64) #if defined(__x86_64__) || defined(_M_X86)
return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1); return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
#else #else
return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
@ -327,7 +326,7 @@ FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitCon
* On 32-bits, maxNbBits==24. * On 32-bits, maxNbBits==24.
* On 64-bits, maxNbBits==56. * On 64-bits, maxNbBits==56.
* @return : value extracted */ * @return : value extracted */
FORCE_INLINE_TEMPLATE BitContainerType BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) FORCE_INLINE_TEMPLATE size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
{ {
/* arbitrate between double-shift and shift+mask */ /* arbitrate between double-shift and shift+mask */
#if 1 #if 1
@ -343,7 +342,7 @@ FORCE_INLINE_TEMPLATE BitContainerType BIT_lookBits(const BIT_DStream_t* bitD,
/*! BIT_lookBitsFast() : /*! BIT_lookBitsFast() :
* unsafe version; only works if nbBits >= 1 */ * unsafe version; only works if nbBits >= 1 */
MEM_STATIC BitContainerType BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
{ {
U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
assert(nbBits >= 1); assert(nbBits >= 1);
@ -359,18 +358,18 @@ FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
* Read (consume) next n bits from local register and update. * Read (consume) next n bits from local register and update.
* Pay attention to not read more than nbBits contained into local register. * Pay attention to not read more than nbBits contained into local register.
* @return : extracted value. */ * @return : extracted value. */
FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) FORCE_INLINE_TEMPLATE size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
{ {
BitContainerType const value = BIT_lookBits(bitD, nbBits); size_t const value = BIT_lookBits(bitD, nbBits);
BIT_skipBits(bitD, nbBits); BIT_skipBits(bitD, nbBits);
return value; return value;
} }
/*! BIT_readBitsFast() : /*! BIT_readBitsFast() :
* unsafe version; only works if nbBits >= 1 */ * unsafe version; only works if nbBits >= 1 */
MEM_STATIC BitContainerType BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits) MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
{ {
BitContainerType const value = BIT_lookBitsFast(bitD, nbBits); size_t const value = BIT_lookBitsFast(bitD, nbBits);
assert(nbBits >= 1); assert(nbBits >= 1);
BIT_skipBits(bitD, nbBits); BIT_skipBits(bitD, nbBits);
return value; return value;
@ -451,4 +450,8 @@ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
} }
#if defined (__cplusplus)
}
#endif
#endif /* BITSTREAM_H_MODULE */ #endif /* BITSTREAM_H_MODULE */

View File

@ -27,7 +27,7 @@
# define INLINE_KEYWORD # define INLINE_KEYWORD
#endif #endif
#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) #if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_INLINE_ATTR __attribute__((always_inline)) # define FORCE_INLINE_ATTR __attribute__((always_inline))
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# define FORCE_INLINE_ATTR __forceinline # define FORCE_INLINE_ATTR __forceinline
@ -54,7 +54,7 @@
#endif #endif
/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ /* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) #if defined(__GNUC__)
# define UNUSED_ATTR __attribute__((unused)) # define UNUSED_ATTR __attribute__((unused))
#else #else
# define UNUSED_ATTR # define UNUSED_ATTR
@ -95,8 +95,6 @@
#ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */ #ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */
#if defined(__GNUC__) #if defined(__GNUC__)
# define MEM_STATIC static __inline UNUSED_ATTR # define MEM_STATIC static __inline UNUSED_ATTR
#elif defined(__IAR_SYSTEMS_ICC__)
# define MEM_STATIC static inline UNUSED_ATTR
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# define MEM_STATIC static inline # define MEM_STATIC static inline
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
@ -110,7 +108,7 @@
#ifdef _MSC_VER #ifdef _MSC_VER
# define FORCE_NOINLINE static __declspec(noinline) # define FORCE_NOINLINE static __declspec(noinline)
#else #else
# if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) # if defined(__GNUC__) || defined(__ICCARM__)
# define FORCE_NOINLINE static __attribute__((__noinline__)) # define FORCE_NOINLINE static __attribute__((__noinline__))
# else # else
# define FORCE_NOINLINE static # define FORCE_NOINLINE static
@ -119,7 +117,7 @@
/* target attribute */ /* target attribute */
#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) #if defined(__GNUC__) || defined(__ICCARM__)
# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) # define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
#else #else
# define TARGET_ATTRIBUTE(target) # define TARGET_ATTRIBUTE(target)
@ -207,41 +205,35 @@
# pragma warning(disable : 4324) /* disable: C4324: padded structure */ # pragma warning(disable : 4324) /* disable: C4324: padded structure */
#endif #endif
/*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/
#ifndef STATIC_BMI2
# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86))
# ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
# define STATIC_BMI2 1
# endif
# elif defined(__BMI2__) && defined(__x86_64__) && defined(__GNUC__)
# define STATIC_BMI2 1
# endif
#endif
#ifndef STATIC_BMI2
#define STATIC_BMI2 0
#endif
/* compile time determination of SIMD support */ /* compile time determination of SIMD support */
#if !defined(ZSTD_NO_INTRINSICS) #if !defined(ZSTD_NO_INTRINSICS)
# if defined(__AVX2__) # if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
# define ZSTD_ARCH_X86_AVX2
# endif
# if defined(__SSE2__) || defined(_M_X64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
# define ZSTD_ARCH_X86_SSE2 # define ZSTD_ARCH_X86_SSE2
# endif # endif
# if defined(__ARM_NEON) || defined(_M_ARM64) # if defined(__ARM_NEON) || defined(_M_ARM64)
# define ZSTD_ARCH_ARM_NEON # define ZSTD_ARCH_ARM_NEON
# endif # endif
# if defined(__ARM_FEATURE_SVE)
# define ZSTD_ARCH_ARM_SVE
# endif
# if defined(__ARM_FEATURE_SVE2)
# define ZSTD_ARCH_ARM_SVE2
# endif
# if defined(__riscv) && defined(__riscv_vector)
# define ZSTD_ARCH_RISCV_RVV
# endif
# #
# if defined(ZSTD_ARCH_X86_AVX2)
# include <immintrin.h>
# endif
# if defined(ZSTD_ARCH_X86_SSE2) # if defined(ZSTD_ARCH_X86_SSE2)
# include <emmintrin.h> # include <emmintrin.h>
# elif defined(ZSTD_ARCH_ARM_NEON) # elif defined(ZSTD_ARCH_ARM_NEON)
# include <arm_neon.h> # include <arm_neon.h>
# endif # endif
# if defined(ZSTD_ARCH_ARM_SVE) || defined(ZSTD_ARCH_ARM_SVE2)
# include <arm_sve.h>
# endif
# if defined(ZSTD_ARCH_RISCV_RVV)
# include <riscv_vector.h>
# endif
#endif #endif
/* C-language Attributes are added in C23. */ /* C-language Attributes are added in C23. */
@ -281,15 +273,9 @@
#endif #endif
/*-************************************************************** /*-**************************************************************
* Alignment * Alignment check
*****************************************************************/ *****************************************************************/
/* @return 1 if @u is a 2^n value, 0 otherwise
* useful to check a value is valid for alignment restrictions */
MEM_STATIC int ZSTD_isPower2(size_t u) {
return (u & (u-1)) == 0;
}
/* this test was initially positioned in mem.h, /* this test was initially positioned in mem.h,
* but this file is removed (or replaced) for linux kernel * but this file is removed (or replaced) for linux kernel
* so it's now hosted in compiler.h, * so it's now hosted in compiler.h,
@ -315,21 +301,6 @@ MEM_STATIC int ZSTD_isPower2(size_t u) {
# endif # endif
#endif /* ZSTD_ALIGNOF */ #endif /* ZSTD_ALIGNOF */
#ifndef ZSTD_ALIGNED
/* C90-compatible alignment macro (GCC/Clang). Adjust for other compilers if needed. */
# if defined(__GNUC__) || defined(__clang__)
# define ZSTD_ALIGNED(a) __attribute__((aligned(a)))
# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
# define ZSTD_ALIGNED(a) _Alignas(a)
#elif defined(_MSC_VER)
# define ZSTD_ALIGNED(n) __declspec(align(n))
# else
/* this compiler will require its own alignment instruction */
# define ZSTD_ALIGNED(...)
# endif
#endif /* ZSTD_ALIGNED */
/*-************************************************************** /*-**************************************************************
* Sanitizer * Sanitizer
*****************************************************************/ *****************************************************************/
@ -353,7 +324,7 @@ MEM_STATIC int ZSTD_isPower2(size_t u) {
#endif #endif
/** /**
* Helper function to perform a wrapped pointer difference without triggering * Helper function to perform a wrapped pointer difference without trigging
* UBSAN. * UBSAN.
* *
* @returns lhs - rhs with wrapping * @returns lhs - rhs with wrapping
@ -372,9 +343,9 @@ ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs
*/ */
MEM_STATIC MEM_STATIC
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
const void* ZSTD_wrappedPtrAdd(const void* ptr, ptrdiff_t add) unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add)
{ {
return (const char*)ptr + add; return ptr + add;
} }
/** /**
@ -385,9 +356,9 @@ const void* ZSTD_wrappedPtrAdd(const void* ptr, ptrdiff_t add)
*/ */
MEM_STATIC MEM_STATIC
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
const void* ZSTD_wrappedPtrSub(const void* ptr, ptrdiff_t sub) unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub)
{ {
return (const char*)ptr - sub; return ptr - sub;
} }
/** /**
@ -397,9 +368,9 @@ const void* ZSTD_wrappedPtrSub(const void* ptr, ptrdiff_t sub)
* @returns `ptr + add` except it defines `NULL + 0 == NULL`. * @returns `ptr + add` except it defines `NULL + 0 == NULL`.
*/ */
MEM_STATIC MEM_STATIC
void* ZSTD_maybeNullPtrAdd(void* ptr, ptrdiff_t add) unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add)
{ {
return add > 0 ? (char*)ptr + add : ptr; return add > 0 ? ptr + add : ptr;
} }
/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an

View File

@ -35,7 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
U32 f7b = 0; U32 f7b = 0;
U32 f7c = 0; U32 f7c = 0;
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
#if !defined(_M_X64) || !defined(__clang__) || __clang_major__ >= 16 #if !defined(__clang__)
int reg[4]; int reg[4];
__cpuid((int*)reg, 0); __cpuid((int*)reg, 0);
{ {

View File

@ -32,6 +32,10 @@
#ifndef DEBUG_H_12987983217 #ifndef DEBUG_H_12987983217
#define DEBUG_H_12987983217 #define DEBUG_H_12987983217
#if defined (__cplusplus)
extern "C" {
#endif
/* static assert is triggered at compile time, leaving no runtime artefact. /* static assert is triggered at compile time, leaving no runtime artefact.
* static assert only works with compile-time constants. * static assert only works with compile-time constants.
@ -104,4 +108,9 @@ extern int g_debuglevel; /* the variable is only declared,
# define DEBUGLOG(l, ...) do { } while (0) /* disabled */ # define DEBUGLOG(l, ...) do { } while (0) /* disabled */
#endif #endif
#if defined (__cplusplus)
}
#endif
#endif /* DEBUG_H_12987983217 */ #endif /* DEBUG_H_12987983217 */

View File

@ -40,7 +40,6 @@ const char* ERR_getErrorString(ERR_enum code)
case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
case PREFIX(cannotProduce_uncompressedBlock): return "This mode cannot generate an uncompressed block";
case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected"; case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected";
case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
case PREFIX(dictionary_wrong): return "Dictionary mismatch"; case PREFIX(dictionary_wrong): return "Dictionary mismatch";

View File

@ -13,6 +13,11 @@
#ifndef ERROR_H_MODULE #ifndef ERROR_H_MODULE
#define ERROR_H_MODULE #define ERROR_H_MODULE
#if defined (__cplusplus)
extern "C" {
#endif
/* **************************************** /* ****************************************
* Dependencies * Dependencies
******************************************/ ******************************************/
@ -21,6 +26,7 @@
#include "debug.h" #include "debug.h"
#include "zstd_deps.h" /* size_t */ #include "zstd_deps.h" /* size_t */
/* **************************************** /* ****************************************
* Compiler-specific * Compiler-specific
******************************************/ ******************************************/
@ -155,4 +161,8 @@ void _force_has_format_string(const char *format, ...) {
} \ } \
} while(0) } while(0)
#if defined (__cplusplus)
}
#endif
#endif /* ERROR_H_MODULE */ #endif /* ERROR_H_MODULE */

View File

@ -11,6 +11,11 @@
* in the COPYING file in the root directory of this source tree). * in the COPYING file in the root directory of this source tree).
* You may select, at your option, one of the above-listed licenses. * You may select, at your option, one of the above-listed licenses.
****************************************************************** */ ****************************************************************** */
#if defined (__cplusplus)
extern "C" {
#endif
#ifndef FSE_H #ifndef FSE_H
#define FSE_H #define FSE_H
@ -20,6 +25,7 @@
******************************************/ ******************************************/
#include "zstd_deps.h" /* size_t, ptrdiff_t */ #include "zstd_deps.h" /* size_t, ptrdiff_t */
/*-***************************************** /*-*****************************************
* FSE_PUBLIC_API : control library symbols visibility * FSE_PUBLIC_API : control library symbols visibility
******************************************/ ******************************************/
@ -226,8 +232,11 @@ If there is an error, the function will return an error code, which can be teste
#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) #if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
#define FSE_H_FSE_STATIC_LINKING_ONLY #define FSE_H_FSE_STATIC_LINKING_ONLY
/* *** Dependency *** */
#include "bitstream.h" #include "bitstream.h"
/* ***************************************** /* *****************************************
* Static allocation * Static allocation
*******************************************/ *******************************************/
@ -456,13 +465,13 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, un
FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
const U16* const stateTable = (const U16*)(statePtr->stateTable); const U16* const stateTable = (const U16*)(statePtr->stateTable);
U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
BIT_addBits(bitC, (BitContainerType)statePtr->value, nbBitsOut); BIT_addBits(bitC, (size_t)statePtr->value, nbBitsOut);
statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
} }
MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
{ {
BIT_addBits(bitC, (BitContainerType)statePtr->value, statePtr->stateLog); BIT_addBits(bitC, (size_t)statePtr->value, statePtr->stateLog);
BIT_flushBits(bitC); BIT_flushBits(bitC);
} }
@ -622,4 +631,10 @@ MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) #define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3)
#endif /* FSE_STATIC_LINKING_ONLY */ #endif /* FSE_STATIC_LINKING_ONLY */
#if defined (__cplusplus)
}
#endif

View File

@ -190,8 +190,6 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
FSE_initDState(&state1, &bitD, dt); FSE_initDState(&state1, &bitD, dt);
FSE_initDState(&state2, &bitD, dt); FSE_initDState(&state2, &bitD, dt);
RETURN_ERROR_IF(BIT_reloadDStream(&bitD)==BIT_DStream_overflow, corruption_detected, "");
#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD) #define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
/* 4 symbols per loop */ /* 4 symbols per loop */

View File

@ -12,6 +12,10 @@
* You may select, at your option, one of the above-listed licenses. * You may select, at your option, one of the above-listed licenses.
****************************************************************** */ ****************************************************************** */
#if defined (__cplusplus)
extern "C" {
#endif
#ifndef HUF_H_298734234 #ifndef HUF_H_298734234
#define HUF_H_298734234 #define HUF_H_298734234
@ -21,6 +25,7 @@
#define FSE_STATIC_LINKING_ONLY #define FSE_STATIC_LINKING_ONLY
#include "fse.h" #include "fse.h"
/* *** Tool functions *** */ /* *** Tool functions *** */
#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ #define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */
size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
@ -275,3 +280,7 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize
#endif #endif
#endif /* HUF_H_298734234 */ #endif /* HUF_H_298734234 */
#if defined (__cplusplus)
}
#endif

View File

@ -11,6 +11,10 @@
#ifndef MEM_H_MODULE #ifndef MEM_H_MODULE
#define MEM_H_MODULE #define MEM_H_MODULE
#if defined (__cplusplus)
extern "C" {
#endif
/*-**************************************** /*-****************************************
* Dependencies * Dependencies
******************************************/ ******************************************/
@ -26,8 +30,6 @@
#if defined(_MSC_VER) /* Visual Studio */ #if defined(_MSC_VER) /* Visual Studio */
# include <stdlib.h> /* _byteswap_ulong */ # include <stdlib.h> /* _byteswap_ulong */
# include <intrin.h> /* _byteswap_* */ # include <intrin.h> /* _byteswap_* */
#elif defined(__ICCARM__)
# include <intrinsics.h>
#endif #endif
/*-************************************************************** /*-**************************************************************
@ -72,6 +74,7 @@
typedef signed long long S64; typedef signed long long S64;
#endif #endif
/*-************************************************************** /*-**************************************************************
* Memory I/O API * Memory I/O API
*****************************************************************/ *****************************************************************/
@ -147,12 +150,10 @@ MEM_STATIC unsigned MEM_isLittleEndian(void)
return 1; return 1;
#elif defined(__clang__) && __BIG_ENDIAN__ #elif defined(__clang__) && __BIG_ENDIAN__
return 0; return 0;
#elif defined(_MSC_VER) && (_M_X64 || _M_IX86) #elif defined(_MSC_VER) && (_M_AMD64 || _M_IX86)
return 1; return 1;
#elif defined(__DMC__) && defined(_M_IX86) #elif defined(__DMC__) && defined(_M_IX86)
return 1; return 1;
#elif defined(__IAR_SYSTEMS_ICC__) && __LITTLE_ENDIAN__
return 1;
#else #else
const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
return one.c[0]; return one.c[0];
@ -245,8 +246,6 @@ MEM_STATIC U32 MEM_swap32(U32 in)
#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
|| (defined(__clang__) && __has_builtin(__builtin_bswap32)) || (defined(__clang__) && __has_builtin(__builtin_bswap32))
return __builtin_bswap32(in); return __builtin_bswap32(in);
#elif defined(__ICCARM__)
return __REV(in);
#else #else
return MEM_swap32_fallback(in); return MEM_swap32_fallback(in);
#endif #endif
@ -419,4 +418,9 @@ MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
/* code only tested on 32 and 64 bits systems */ /* code only tested on 32 and 64 bits systems */
MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
#if defined (__cplusplus)
}
#endif
#endif /* MEM_H_MODULE */ #endif /* MEM_H_MODULE */

View File

@ -11,6 +11,10 @@
#ifndef POOL_H #ifndef POOL_H
#define POOL_H #define POOL_H
#if defined (__cplusplus)
extern "C" {
#endif
#include "zstd_deps.h" #include "zstd_deps.h"
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */
@ -78,4 +82,9 @@ void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque);
*/ */
int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque); int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque);
#if defined (__cplusplus)
}
#endif
#endif #endif

View File

@ -74,39 +74,26 @@
# define ZSTD_HIDE_ASM_FUNCTION(func) # define ZSTD_HIDE_ASM_FUNCTION(func)
#endif #endif
/* Compile time determination of BMI2 support */
#ifndef STATIC_BMI2
# if defined(__BMI2__)
# define STATIC_BMI2 1
# elif defined(_MSC_VER) && defined(__AVX2__)
# define STATIC_BMI2 1 /* MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2 */
# endif
#endif
#ifndef STATIC_BMI2
# define STATIC_BMI2 0
#endif
/* Enable runtime BMI2 dispatch based on the CPU. /* Enable runtime BMI2 dispatch based on the CPU.
* Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
*/ */
#ifndef DYNAMIC_BMI2 #ifndef DYNAMIC_BMI2
# if ((defined(__clang__) && __has_attribute(__target__)) \ #if ((defined(__clang__) && __has_attribute(__target__)) \
|| (defined(__GNUC__) \ || (defined(__GNUC__) \
&& (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
&& (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) \ && (defined(__x86_64__) || defined(_M_X64)) \
&& !defined(__BMI2__) && !defined(__BMI2__)
# define DYNAMIC_BMI2 1 # define DYNAMIC_BMI2 1
# else #else
# define DYNAMIC_BMI2 0 # define DYNAMIC_BMI2 0
# endif #endif
#endif #endif
/** /**
* Only enable assembly for GNU C compatible compilers, * Only enable assembly for GNUC compatible compilers,
* because other platforms may not support GAS assembly syntax. * because other platforms may not support GAS assembly syntax.
* *
* Only enable assembly for Linux / MacOS / Win32, other platforms may * Only enable assembly for Linux / MacOS, other platforms may
* work, but they haven't been tested. This could likely be * work, but they haven't been tested. This could likely be
* extended to BSD systems. * extended to BSD systems.
* *
@ -114,7 +101,7 @@
* 100% of code to be instrumented to work. * 100% of code to be instrumented to work.
*/ */
#if defined(__GNUC__) #if defined(__GNUC__)
# if defined(__linux__) || defined(__linux) || defined(__APPLE__) || defined(_WIN32) # if defined(__linux__) || defined(__linux) || defined(__APPLE__)
# if ZSTD_MEMORY_SANITIZER # if ZSTD_MEMORY_SANITIZER
# define ZSTD_ASM_SUPPORTED 0 # define ZSTD_ASM_SUPPORTED 0
# elif ZSTD_DATAFLOW_SANITIZER # elif ZSTD_DATAFLOW_SANITIZER
@ -168,23 +155,4 @@
# define ZSTD_CET_ENDBRANCH # define ZSTD_CET_ENDBRANCH
#endif #endif
/**
* ZSTD_IS_DETERMINISTIC_BUILD must be set to 0 if any compilation macro is
* active that impacts the compressed output.
*
* NOTE: ZSTD_MULTITHREAD is allowed to be set or unset.
*/
#if defined(ZSTD_CLEVEL_DEFAULT) \
|| defined(ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR) \
|| defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \
|| defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \
|| defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \
|| defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \
|| defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \
|| defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR)
# define ZSTD_IS_DETERMINISTIC_BUILD 0
#else
# define ZSTD_IS_DETERMINISTIC_BUILD 1
#endif
#endif /* ZSTD_PORTABILITY_MACROS_H */ #endif /* ZSTD_PORTABILITY_MACROS_H */

View File

@ -16,6 +16,10 @@
#include "debug.h" #include "debug.h"
#if defined (__cplusplus)
extern "C" {
#endif
#if defined(ZSTD_MULTITHREAD) && defined(_WIN32) #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
/** /**
@ -68,6 +72,7 @@ int ZSTD_pthread_join(ZSTD_pthread_t thread);
* add here more wrappers as required * add here more wrappers as required
*/ */
#elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */ #elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
/* === POSIX Systems === */ /* === POSIX Systems === */
# include <pthread.h> # include <pthread.h>
@ -138,5 +143,8 @@ typedef int ZSTD_pthread_cond_t;
#endif /* ZSTD_MULTITHREAD */ #endif /* ZSTD_MULTITHREAD */
#if defined (__cplusplus)
}
#endif
#endif /* THREADING_H_938743 */ #endif /* THREADING_H_938743 */

View File

@ -227,6 +227,10 @@
* xxHash prototypes and implementation * xxHash prototypes and implementation
*/ */
#if defined (__cplusplus)
extern "C" {
#endif
/* **************************** /* ****************************
* INLINE mode * INLINE mode
******************************/ ******************************/
@ -533,9 +537,6 @@
/*! @brief Version number, encoded as two digits each */ /*! @brief Version number, encoded as two digits each */
#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* @brief Obtains the xxHash version. * @brief Obtains the xxHash version.
* *
@ -546,9 +547,6 @@ extern "C" {
*/ */
XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber (void); XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber (void);
#if defined (__cplusplus)
}
#endif
/* **************************** /* ****************************
* Common basic types * Common basic types
@ -595,10 +593,6 @@ typedef uint32_t XXH32_hash_t;
# endif # endif
#endif #endif
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* @} * @}
* *
@ -827,9 +821,6 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni
#endif #endif
/*! @endcond */ /*! @endcond */
#if defined (__cplusplus)
} /* end of extern "C" */
#endif
/*! /*!
* @} * @}
@ -868,9 +859,6 @@ typedef uint64_t XXH64_hash_t;
# endif # endif
#endif #endif
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* @} * @}
* *
@ -1574,11 +1562,6 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con
#endif /* !XXH_NO_XXH3 */ #endif /* !XXH_NO_XXH3 */
#if defined (__cplusplus)
} /* extern "C" */
#endif
#endif /* XXH_NO_LONG_LONG */ #endif /* XXH_NO_LONG_LONG */
/*! /*!
@ -1765,10 +1748,6 @@ struct XXH3_state_s {
} while(0) } while(0)
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* @brief Calculates the 128-bit hash of @p data using XXH3. * @brief Calculates the 128-bit hash of @p data using XXH3.
* *
@ -1984,13 +1963,8 @@ XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr,
XXH64_hash_t seed64); XXH64_hash_t seed64);
#endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_STREAM */
#if defined (__cplusplus)
} /* extern "C" */
#endif
#endif /* !XXH_NO_XXH3 */ #endif /* !XXH_NO_XXH3 */
#endif /* XXH_NO_LONG_LONG */ #endif /* XXH_NO_LONG_LONG */
#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
# define XXH_IMPLEMENTATION # define XXH_IMPLEMENTATION
#endif #endif
@ -2289,12 +2263,10 @@ XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr,
* @{ * @{
*/ */
/* ************************************* /* *************************************
* Includes & Memory related functions * Includes & Memory related functions
***************************************/ ***************************************/
#include <string.h> /* memcmp, memcpy */
#include <limits.h> /* ULLONG_MAX */
#if defined(XXH_NO_STREAM) #if defined(XXH_NO_STREAM)
/* nothing */ /* nothing */
#elif defined(XXH_NO_STDLIB) #elif defined(XXH_NO_STDLIB)
@ -2308,17 +2280,9 @@ XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr,
* without access to dynamic allocation. * without access to dynamic allocation.
*/ */
#if defined (__cplusplus)
extern "C" {
#endif
static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; } static XXH_CONSTF void* XXH_malloc(size_t s) { (void)s; return NULL; }
static void XXH_free(void* p) { (void)p; } static void XXH_free(void* p) { (void)p; }
#if defined (__cplusplus)
} /* extern "C" */
#endif
#else #else
/* /*
@ -2327,9 +2291,6 @@ static void XXH_free(void* p) { (void)p; }
*/ */
#include <stdlib.h> #include <stdlib.h>
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* @internal * @internal
* @brief Modify this function to use a different routine than malloc(). * @brief Modify this function to use a different routine than malloc().
@ -2342,15 +2303,10 @@ static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); }
*/ */
static void XXH_free(void* p) { free(p); } static void XXH_free(void* p) { free(p); }
#if defined (__cplusplus)
} /* extern "C" */
#endif
#endif /* XXH_NO_STDLIB */ #endif /* XXH_NO_STDLIB */
#if defined (__cplusplus) #include <string.h>
extern "C" {
#endif
/*! /*!
* @internal * @internal
* @brief Modify this function to use a different routine than memcpy(). * @brief Modify this function to use a different routine than memcpy().
@ -2360,9 +2316,8 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size)
return memcpy(dest,src,size); return memcpy(dest,src,size);
} }
#if defined (__cplusplus) #include <limits.h> /* ULLONG_MAX */
} /* extern "C" */
#endif
/* ************************************* /* *************************************
* Compiler Specific Options * Compiler Specific Options
@ -2497,10 +2452,6 @@ typedef XXH32_hash_t xxh_u32;
# define U32 xxh_u32 # define U32 xxh_u32
#endif #endif
#if defined (__cplusplus)
extern "C" {
#endif
/* *** Memory access *** */ /* *** Memory access *** */
/*! /*!
@ -3657,10 +3608,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can
return XXH_readBE64(src); return XXH_readBE64(src);
} }
#if defined (__cplusplus)
}
#endif
#ifndef XXH_NO_XXH3 #ifndef XXH_NO_XXH3
/* ********************************************************************* /* *********************************************************************
@ -3892,7 +3839,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
# define XXH_VECTOR XXH_AVX512 # define XXH_VECTOR XXH_AVX512
# elif defined(__AVX2__) # elif defined(__AVX2__)
# define XXH_VECTOR XXH_AVX2 # define XXH_VECTOR XXH_AVX2
# elif defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) # elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
# define XXH_VECTOR XXH_SSE2 # define XXH_VECTOR XXH_SSE2
# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ # elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
|| (defined(__s390x__) && defined(__VEC__)) \ || (defined(__s390x__) && defined(__VEC__)) \
@ -3981,10 +3928,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ {
# pragma GCC optimize("-O2") # pragma GCC optimize("-O2")
#endif #endif
#if defined (__cplusplus)
extern "C" {
#endif
#if XXH_VECTOR == XXH_NEON #if XXH_VECTOR == XXH_NEON
/* /*
@ -4107,10 +4050,6 @@ XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs)
# endif # endif
#endif /* XXH_VECTOR == XXH_NEON */ #endif /* XXH_VECTOR == XXH_NEON */
#if defined (__cplusplus)
} /* extern "C" */
#endif
/* /*
* VSX and Z Vector helpers. * VSX and Z Vector helpers.
* *
@ -4172,9 +4111,6 @@ typedef xxh_u64x2 xxh_aliasing_u64x2 XXH_ALIASING;
# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__)) # if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__))
# define XXH_vec_revb vec_revb # define XXH_vec_revb vec_revb
# else # else
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* A polyfill for POWER9's vec_revb(). * A polyfill for POWER9's vec_revb().
*/ */
@ -4184,15 +4120,9 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
return vec_perm(val, val, vByteSwap); return vec_perm(val, val, vByteSwap);
} }
#if defined (__cplusplus)
} /* extern "C" */
#endif
# endif # endif
# endif /* XXH_VSX_BE */ # endif /* XXH_VSX_BE */
#if defined (__cplusplus)
extern "C" {
#endif
/*! /*!
* Performs an unaligned vector load and byte swaps it on big endian. * Performs an unaligned vector load and byte swaps it on big endian.
*/ */
@ -4237,11 +4167,6 @@ XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
return result; return result;
} }
# endif /* XXH_vec_mulo, XXH_vec_mule */ # endif /* XXH_vec_mulo, XXH_vec_mule */
#if defined (__cplusplus)
} /* extern "C" */
#endif
#endif /* XXH_VECTOR == XXH_VSX */ #endif /* XXH_VECTOR == XXH_VSX */
#if XXH_VECTOR == XXH_SVE #if XXH_VECTOR == XXH_SVE
@ -4275,9 +4200,7 @@ do { \
# endif # endif
#endif /* XXH_NO_PREFETCH */ #endif /* XXH_NO_PREFETCH */
#if defined (__cplusplus)
extern "C" {
#endif
/* ========================================== /* ==========================================
* XXH3 default settings * XXH3 default settings
* ========================================== */ * ========================================== */
@ -6954,6 +6877,8 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_
#endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_STREAM */
/* 128-bit utility functions */ /* 128-bit utility functions */
#include <string.h> /* memcmp, memcpy */
/* return : 1 is equal, 0 if different */ /* return : 1 is equal, 0 if different */
/*! @ingroup XXH3_family */ /*! @ingroup XXH3_family */
XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
@ -7080,15 +7005,16 @@ XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed)
# pragma GCC pop_options # pragma GCC pop_options
#endif #endif
#if defined (__cplusplus)
} /* extern "C" */
#endif
#endif /* XXH_NO_LONG_LONG */ #endif /* XXH_NO_LONG_LONG */
#endif /* XXH_NO_XXH3 */ #endif /* XXH_NO_XXH3 */
/*! /*!
* @} * @}
*/ */
#endif /* XXH_IMPLEMENTATION */ #endif /* XXH_IMPLEMENTATION */
#if defined (__cplusplus)
} /* extern "C" */
#endif

View File

@ -46,12 +46,3 @@ ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
/*! ZSTD_getErrorString() : /*! ZSTD_getErrorString() :
* provides error code string from enum */ * provides error code string from enum */
const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); }
int ZSTD_isDeterministicBuild(void)
{
#if ZSTD_IS_DETERMINISTIC_BUILD
return 1;
#else
return 0;
#endif
}

View File

@ -24,18 +24,6 @@
#ifndef ZSTD_DEPS_COMMON #ifndef ZSTD_DEPS_COMMON
#define ZSTD_DEPS_COMMON #define ZSTD_DEPS_COMMON
/* Even though we use qsort_r only for the dictionary builder, the macro
* _GNU_SOURCE has to be declared *before* the inclusion of any standard
* header and the script 'combine.sh' combines the whole zstd source code
* in a single file.
*/
#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \
defined(__CYGWIN__) || defined(__MSYS__)
#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */
#define _GNU_SOURCE
#endif
#endif
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>

View File

@ -39,6 +39,10 @@
# define ZSTD_TRACE 0 # define ZSTD_TRACE 0
#endif #endif
#if defined (__cplusplus)
extern "C" {
#endif
/* ---- static assert (debug) --- */ /* ---- static assert (debug) --- */
#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
#define ZSTD_isError ERR_isError /* for inlining */ #define ZSTD_isError ERR_isError /* for inlining */
@ -91,7 +95,7 @@ typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
#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 #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;
#define LONGNBSEQ 0x7F00 #define LONGNBSEQ 0x7F00
@ -168,7 +172,7 @@ static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
* Shared functions to include for inlining * Shared functions to include for inlining
*********************************************/ *********************************************/
static void ZSTD_copy8(void* dst, const void* src) { static void ZSTD_copy8(void* dst, const void* src) {
#if defined(ZSTD_ARCH_ARM_NEON) && !defined(__aarch64__) #if defined(ZSTD_ARCH_ARM_NEON)
vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src)); vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
#else #else
ZSTD_memcpy(dst, src, 8); ZSTD_memcpy(dst, src, 8);
@ -213,7 +217,7 @@ typedef enum {
* The src buffer must be before the dst buffer. * The src buffer must be before the dst buffer.
*/ */
MEM_STATIC FORCE_INLINE_ATTR MEM_STATIC FORCE_INLINE_ATTR
void ZSTD_wildcopy(void* dst, const void* src, size_t length, ZSTD_overlap_e const ovtype) void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
{ {
ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src; ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
const BYTE* ip = (const BYTE*)src; const BYTE* ip = (const BYTE*)src;
@ -274,6 +278,62 @@ typedef enum {
/*-******************************************* /*-*******************************************
* Private declarations * Private declarations
*********************************************/ *********************************************/
typedef struct seqDef_s {
U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
U16 litLength;
U16 mlBase; /* mlBase == matchLength - MINMATCH */
} seqDef;
/* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */
typedef enum {
ZSTD_llt_none = 0, /* no longLengthType */
ZSTD_llt_literalLength = 1, /* represents a long literal */
ZSTD_llt_matchLength = 2 /* represents a long match */
} ZSTD_longLengthType_e;
typedef struct {
seqDef* sequencesStart;
seqDef* sequences; /* ptr to end of sequences */
BYTE* litStart;
BYTE* lit; /* ptr to end of literals */
BYTE* llCode;
BYTE* mlCode;
BYTE* ofCode;
size_t maxNbSeq;
size_t maxNbLit;
/* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength
* in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
* the existing value of the litLength or matchLength by 0x10000.
*/
ZSTD_longLengthType_e longLengthType;
U32 longLengthPos; /* Index of the sequence to apply long length modification to */
} seqStore_t;
typedef struct {
U32 litLength;
U32 matchLength;
} ZSTD_sequenceLength;
/**
* Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
* indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength.
*/
MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
{
ZSTD_sequenceLength seqLen;
seqLen.litLength = seq->litLength;
seqLen.matchLength = seq->mlBase + MINMATCH;
if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
if (seqStore->longLengthType == ZSTD_llt_literalLength) {
seqLen.litLength += 0x10000;
}
if (seqStore->longLengthType == ZSTD_llt_matchLength) {
seqLen.matchLength += 0x10000;
}
}
return seqLen;
}
/** /**
* Contains the compressed frame size and an upper-bound for the decompressed frame size. * Contains the compressed frame size and an upper-bound for the decompressed frame size.
@ -287,6 +347,10 @@ typedef struct {
unsigned long long decompressedBound; unsigned long long decompressedBound;
} ZSTD_frameSizeInfo; /* decompress & legacy */ } ZSTD_frameSizeInfo; /* decompress & legacy */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
int ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
/* ZSTD_invalidateRepCodes() : /* ZSTD_invalidateRepCodes() :
* ensures next compression will not use repcodes from previous block. * ensures next compression will not use repcodes from previous block.
* Note : only works with regular variant; * Note : only works with regular variant;
@ -321,4 +385,8 @@ MEM_STATIC int ZSTD_cpuSupportsBmi2(void)
return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid); return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid);
} }
#if defined (__cplusplus)
}
#endif
#endif /* ZSTD_CCOMMON_H_MODULE */ #endif /* ZSTD_CCOMMON_H_MODULE */

View File

@ -11,20 +11,23 @@
#ifndef ZSTD_TRACE_H #ifndef ZSTD_TRACE_H
#define ZSTD_TRACE_H #define ZSTD_TRACE_H
#if defined (__cplusplus)
extern "C" {
#endif
#include <stddef.h> #include <stddef.h>
/* weak symbol support /* weak symbol support
* For now, enable conservatively: * For now, enable conservatively:
* - Only GNUC * - Only GNUC
* - Only ELF * - Only ELF
* - Only x86-64, i386, aarch64 and risc-v. * - Only x86-64, i386 and aarch64
* Also, explicitly disable on platforms known not to work so they aren't * Also, explicitly disable on platforms known not to work so they aren't
* forgotten in the future. * forgotten in the future.
*/ */
#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \ #if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \
defined(__GNUC__) && defined(__ELF__) && \ defined(__GNUC__) && defined(__ELF__) && \
(defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) || defined(__aarch64__)) && \
defined(_M_IX86) || defined(__aarch64__) || defined(__riscv)) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \
!defined(__CYGWIN__) && !defined(_AIX) !defined(__CYGWIN__) && !defined(_AIX)
# define ZSTD_HAVE_WEAK_SYMBOLS 1 # define ZSTD_HAVE_WEAK_SYMBOLS 1
@ -61,7 +64,7 @@ typedef struct {
/** /**
* Non-zero if streaming (de)compression is used. * Non-zero if streaming (de)compression is used.
*/ */
int streaming; unsigned streaming;
/** /**
* The dictionary ID. * The dictionary ID.
*/ */
@ -70,7 +73,7 @@ typedef struct {
* Is the dictionary cold? * Is the dictionary cold?
* Only set on decompression. * Only set on decompression.
*/ */
int dictionaryIsCold; unsigned dictionaryIsCold;
/** /**
* The dictionary size or zero if no dictionary. * The dictionary size or zero if no dictionary.
*/ */
@ -153,4 +156,8 @@ ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end(
#endif /* ZSTD_TRACE */ #endif /* ZSTD_TRACE */
#if defined (__cplusplus)
}
#endif
#endif /* ZSTD_TRACE_H */ #endif /* ZSTD_TRACE_H */

View File

@ -19,12 +19,6 @@
#include "../common/error_private.h" /* ERROR */ #include "../common/error_private.h" /* ERROR */
#include "hist.h" #include "hist.h"
#if defined(ZSTD_ARCH_ARM_SVE2)
#define HIST_FAST_THRESHOLD 500
#else
#define HIST_FAST_THRESHOLD 1500
#endif
/* --- Error management --- */ /* --- Error management --- */
unsigned HIST_isError(size_t code) { return ERR_isError(code); } unsigned HIST_isError(size_t code) { return ERR_isError(code); }
@ -32,16 +26,6 @@ unsigned HIST_isError(size_t code) { return ERR_isError(code); }
/*-************************************************************** /*-**************************************************************
* Histogram functions * Histogram functions
****************************************************************/ ****************************************************************/
void HIST_add(unsigned* count, const void* src, size_t srcSize)
{
const BYTE* ip = (const BYTE*)src;
const BYTE* const end = ip + srcSize;
while (ip<end) {
count[*ip++]++;
}
}
unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize) const void* src, size_t srcSize)
{ {
@ -71,244 +55,6 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e; typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
#if defined(ZSTD_ARCH_ARM_SVE2)
FORCE_INLINE_TEMPLATE size_t min_size(size_t a, size_t b) { return a < b ? a : b; }
static
svuint16_t HIST_count_6_sve2(const BYTE* const src, size_t size, U32* const dst,
const svuint8_t c0, const svuint8_t c1,
const svuint8_t c2, const svuint8_t c3,
const svuint8_t c4, const svuint8_t c5,
const svuint16_t histmax, size_t maxCount)
{
const svbool_t vl128 = svptrue_pat_b8(SV_VL16);
svuint16_t hh0 = svdup_n_u16(0);
svuint16_t hh1 = svdup_n_u16(0);
svuint16_t hh2 = svdup_n_u16(0);
svuint16_t hh3 = svdup_n_u16(0);
svuint16_t hh4 = svdup_n_u16(0);
svuint16_t hh5 = svdup_n_u16(0);
svuint16_t hh6 = svdup_n_u16(0);
svuint16_t hh7 = svdup_n_u16(0);
svuint16_t hh8 = svdup_n_u16(0);
svuint16_t hh9 = svdup_n_u16(0);
svuint16_t hha = svdup_n_u16(0);
svuint16_t hhb = svdup_n_u16(0);
size_t i = 0;
while (i < size) {
/* We can only accumulate 15 (15 * 16 <= 255) iterations of histogram
* in 8-bit accumulators! */
const size_t size240 = min_size(i + 240, size);
svbool_t pred = svwhilelt_b8_u64(i, size);
svuint8_t c = svld1rq_u8(pred, src + i);
svuint8_t h0 = svhistseg_u8(c0, c);
svuint8_t h1 = svhistseg_u8(c1, c);
svuint8_t h2 = svhistseg_u8(c2, c);
svuint8_t h3 = svhistseg_u8(c3, c);
svuint8_t h4 = svhistseg_u8(c4, c);
svuint8_t h5 = svhistseg_u8(c5, c);
for (i += 16; i < size240; i += 16) {
pred = svwhilelt_b8_u64(i, size);
c = svld1rq_u8(pred, src + i);
h0 = svadd_u8_x(vl128, h0, svhistseg_u8(c0, c));
h1 = svadd_u8_x(vl128, h1, svhistseg_u8(c1, c));
h2 = svadd_u8_x(vl128, h2, svhistseg_u8(c2, c));
h3 = svadd_u8_x(vl128, h3, svhistseg_u8(c3, c));
h4 = svadd_u8_x(vl128, h4, svhistseg_u8(c4, c));
h5 = svadd_u8_x(vl128, h5, svhistseg_u8(c5, c));
}
hh0 = svaddwb_u16(hh0, h0);
hh1 = svaddwt_u16(hh1, h0);
hh2 = svaddwb_u16(hh2, h1);
hh3 = svaddwt_u16(hh3, h1);
hh4 = svaddwb_u16(hh4, h2);
hh5 = svaddwt_u16(hh5, h2);
hh6 = svaddwb_u16(hh6, h3);
hh7 = svaddwt_u16(hh7, h3);
hh8 = svaddwb_u16(hh8, h4);
hh9 = svaddwt_u16(hh9, h4);
hha = svaddwb_u16(hha, h5);
hhb = svaddwt_u16(hhb, h5);
}
svst1_u32(svwhilelt_b32_u64( 0, maxCount), dst + 0, svshllb_n_u32(hh0, 0));
svst1_u32(svwhilelt_b32_u64( 4, maxCount), dst + 4, svshllt_n_u32(hh0, 0));
svst1_u32(svwhilelt_b32_u64( 8, maxCount), dst + 8, svshllb_n_u32(hh1, 0));
svst1_u32(svwhilelt_b32_u64(12, maxCount), dst + 12, svshllt_n_u32(hh1, 0));
svst1_u32(svwhilelt_b32_u64(16, maxCount), dst + 16, svshllb_n_u32(hh2, 0));
svst1_u32(svwhilelt_b32_u64(20, maxCount), dst + 20, svshllt_n_u32(hh2, 0));
svst1_u32(svwhilelt_b32_u64(24, maxCount), dst + 24, svshllb_n_u32(hh3, 0));
svst1_u32(svwhilelt_b32_u64(28, maxCount), dst + 28, svshllt_n_u32(hh3, 0));
svst1_u32(svwhilelt_b32_u64(32, maxCount), dst + 32, svshllb_n_u32(hh4, 0));
svst1_u32(svwhilelt_b32_u64(36, maxCount), dst + 36, svshllt_n_u32(hh4, 0));
svst1_u32(svwhilelt_b32_u64(40, maxCount), dst + 40, svshllb_n_u32(hh5, 0));
svst1_u32(svwhilelt_b32_u64(44, maxCount), dst + 44, svshllt_n_u32(hh5, 0));
svst1_u32(svwhilelt_b32_u64(48, maxCount), dst + 48, svshllb_n_u32(hh6, 0));
svst1_u32(svwhilelt_b32_u64(52, maxCount), dst + 52, svshllt_n_u32(hh6, 0));
svst1_u32(svwhilelt_b32_u64(56, maxCount), dst + 56, svshllb_n_u32(hh7, 0));
svst1_u32(svwhilelt_b32_u64(60, maxCount), dst + 60, svshllt_n_u32(hh7, 0));
svst1_u32(svwhilelt_b32_u64(64, maxCount), dst + 64, svshllb_n_u32(hh8, 0));
svst1_u32(svwhilelt_b32_u64(68, maxCount), dst + 68, svshllt_n_u32(hh8, 0));
svst1_u32(svwhilelt_b32_u64(72, maxCount), dst + 72, svshllb_n_u32(hh9, 0));
svst1_u32(svwhilelt_b32_u64(76, maxCount), dst + 76, svshllt_n_u32(hh9, 0));
svst1_u32(svwhilelt_b32_u64(80, maxCount), dst + 80, svshllb_n_u32(hha, 0));
svst1_u32(svwhilelt_b32_u64(84, maxCount), dst + 84, svshllt_n_u32(hha, 0));
svst1_u32(svwhilelt_b32_u64(88, maxCount), dst + 88, svshllb_n_u32(hhb, 0));
svst1_u32(svwhilelt_b32_u64(92, maxCount), dst + 92, svshllt_n_u32(hhb, 0));
hh0 = svmax_u16_x(vl128, hh0, hh1);
hh2 = svmax_u16_x(vl128, hh2, hh3);
hh4 = svmax_u16_x(vl128, hh4, hh5);
hh6 = svmax_u16_x(vl128, hh6, hh7);
hh8 = svmax_u16_x(vl128, hh8, hh9);
hha = svmax_u16_x(vl128, hha, hhb);
hh0 = svmax_u16_x(vl128, hh0, hh2);
hh4 = svmax_u16_x(vl128, hh4, hh6);
hh8 = svmax_u16_x(vl128, hh8, hha);
hh0 = svmax_u16_x(vl128, hh0, hh4);
hh8 = svmax_u16_x(vl128, hh8, histmax);
return svmax_u16_x(vl128, hh0, hh8);
}
static size_t HIST_count_sve2(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize,
HIST_checkInput_e check)
{
const BYTE* ip = (const BYTE*)source;
const size_t maxCount = *maxSymbolValuePtr + 1;
assert(*maxSymbolValuePtr <= 255);
if (!sourceSize) {
ZSTD_memset(count, 0, maxCount * sizeof(*count));
*maxSymbolValuePtr = 0;
return 0;
}
{ const svbool_t vl128 = svptrue_pat_b8(SV_VL16);
const svuint8_t c0 = svreinterpret_u8(svindex_u32(0x0C040800, 0x01010101));
const svuint8_t c1 = svadd_n_u8_x(vl128, c0, 16);
const svuint8_t c2 = svadd_n_u8_x(vl128, c0, 32);
const svuint8_t c3 = svadd_n_u8_x(vl128, c1, 32);
svuint8_t symbolMax = svdup_n_u8(0);
svuint16_t hh0 = svdup_n_u16(0);
svuint16_t hh1 = svdup_n_u16(0);
svuint16_t hh2 = svdup_n_u16(0);
svuint16_t hh3 = svdup_n_u16(0);
svuint16_t hh4 = svdup_n_u16(0);
svuint16_t hh5 = svdup_n_u16(0);
svuint16_t hh6 = svdup_n_u16(0);
svuint16_t hh7 = svdup_n_u16(0);
svuint16_t max;
size_t maxSymbolValue;
size_t i = 0;
while (i < sourceSize) {
/* We can only accumulate 15 (15 * 16 <= 255) iterations of
* histogram in 8-bit accumulators! */
const size_t size240 = min_size(i + 240, sourceSize);
svbool_t pred = svwhilelt_b8_u64(i, sourceSize);
svuint8_t c = svld1rq_u8(pred, ip + i);
svuint8_t h0 = svhistseg_u8(c0, c);
svuint8_t h1 = svhistseg_u8(c1, c);
svuint8_t h2 = svhistseg_u8(c2, c);
svuint8_t h3 = svhistseg_u8(c3, c);
symbolMax = svmax_u8_x(vl128, symbolMax, c);
for (i += 16; i < size240; i += 16) {
pred = svwhilelt_b8_u64(i, sourceSize);
c = svld1rq_u8(pred, ip + i);
h0 = svadd_u8_x(vl128, h0, svhistseg_u8(c0, c));
h1 = svadd_u8_x(vl128, h1, svhistseg_u8(c1, c));
h2 = svadd_u8_x(vl128, h2, svhistseg_u8(c2, c));
h3 = svadd_u8_x(vl128, h3, svhistseg_u8(c3, c));
symbolMax = svmax_u8_x(vl128, symbolMax, c);
}
hh0 = svaddwb_u16(hh0, h0);
hh1 = svaddwt_u16(hh1, h0);
hh2 = svaddwb_u16(hh2, h1);
hh3 = svaddwt_u16(hh3, h1);
hh4 = svaddwb_u16(hh4, h2);
hh5 = svaddwt_u16(hh5, h2);
hh6 = svaddwb_u16(hh6, h3);
hh7 = svaddwt_u16(hh7, h3);
}
maxSymbolValue = svmaxv_u8(vl128, symbolMax);
if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall);
*maxSymbolValuePtr = maxSymbolValue;
/* If the buffer size is not divisible by 16, the last elements of the final
* vector register read will be zeros, and these elements must be subtracted
* from the histogram.
*/
hh0 = svsub_n_u16_m(svptrue_pat_b32(SV_VL1), hh0, -sourceSize & 15);
svst1_u32(svwhilelt_b32_u64( 0, maxCount), count + 0, svshllb_n_u32(hh0, 0));
svst1_u32(svwhilelt_b32_u64( 4, maxCount), count + 4, svshllt_n_u32(hh0, 0));
svst1_u32(svwhilelt_b32_u64( 8, maxCount), count + 8, svshllb_n_u32(hh1, 0));
svst1_u32(svwhilelt_b32_u64(12, maxCount), count + 12, svshllt_n_u32(hh1, 0));
svst1_u32(svwhilelt_b32_u64(16, maxCount), count + 16, svshllb_n_u32(hh2, 0));
svst1_u32(svwhilelt_b32_u64(20, maxCount), count + 20, svshllt_n_u32(hh2, 0));
svst1_u32(svwhilelt_b32_u64(24, maxCount), count + 24, svshllb_n_u32(hh3, 0));
svst1_u32(svwhilelt_b32_u64(28, maxCount), count + 28, svshllt_n_u32(hh3, 0));
svst1_u32(svwhilelt_b32_u64(32, maxCount), count + 32, svshllb_n_u32(hh4, 0));
svst1_u32(svwhilelt_b32_u64(36, maxCount), count + 36, svshllt_n_u32(hh4, 0));
svst1_u32(svwhilelt_b32_u64(40, maxCount), count + 40, svshllb_n_u32(hh5, 0));
svst1_u32(svwhilelt_b32_u64(44, maxCount), count + 44, svshllt_n_u32(hh5, 0));
svst1_u32(svwhilelt_b32_u64(48, maxCount), count + 48, svshllb_n_u32(hh6, 0));
svst1_u32(svwhilelt_b32_u64(52, maxCount), count + 52, svshllt_n_u32(hh6, 0));
svst1_u32(svwhilelt_b32_u64(56, maxCount), count + 56, svshllb_n_u32(hh7, 0));
svst1_u32(svwhilelt_b32_u64(60, maxCount), count + 60, svshllt_n_u32(hh7, 0));
hh0 = svmax_u16_x(vl128, hh0, hh1);
hh2 = svmax_u16_x(vl128, hh2, hh3);
hh4 = svmax_u16_x(vl128, hh4, hh5);
hh6 = svmax_u16_x(vl128, hh6, hh7);
hh0 = svmax_u16_x(vl128, hh0, hh2);
hh4 = svmax_u16_x(vl128, hh4, hh6);
max = svmax_u16_x(vl128, hh0, hh4);
maxSymbolValue = min_size(maxSymbolValue, maxCount);
if (maxSymbolValue >= 64) {
const svuint8_t c4 = svadd_n_u8_x(vl128, c0, 64);
const svuint8_t c5 = svadd_n_u8_x(vl128, c1, 64);
const svuint8_t c6 = svadd_n_u8_x(vl128, c2, 64);
const svuint8_t c7 = svadd_n_u8_x(vl128, c3, 64);
const svuint8_t c8 = svadd_n_u8_x(vl128, c0, 128);
const svuint8_t c9 = svadd_n_u8_x(vl128, c1, 128);
max = HIST_count_6_sve2(ip, sourceSize, count + 64, c4, c5, c6, c7,
c8, c9, max, maxCount - 64);
if (maxSymbolValue >= 160) {
const svuint8_t ca = svadd_n_u8_x(vl128, c2, 128);
const svuint8_t cb = svadd_n_u8_x(vl128, c3, 128);
const svuint8_t cc = svadd_n_u8_x(vl128, c4, 128);
const svuint8_t cd = svadd_n_u8_x(vl128, c5, 128);
const svuint8_t ce = svadd_n_u8_x(vl128, c6, 128);
const svuint8_t cf = svadd_n_u8_x(vl128, c7, 128);
max = HIST_count_6_sve2(ip, sourceSize, count + 160, ca, cb, cc,
cd, ce, cf, max, maxCount - 160);
} else if (maxCount > 160) {
ZSTD_memset(count + 160, 0, (maxCount - 160) * sizeof(*count));
}
} else if (maxCount > 64) {
ZSTD_memset(count + 64, 0, (maxCount - 64) * sizeof(*count));
}
return svmaxv_u16(vl128, max);
}
}
#endif
/* HIST_count_parallel_wksp() : /* HIST_count_parallel_wksp() :
* store histogram into 4 intermediate tables, recombined at the end. * store histogram into 4 intermediate tables, recombined at the end.
* this design makes better use of OoO cpus, * this design makes better use of OoO cpus,
@ -317,8 +63,8 @@ static size_t HIST_count_sve2(unsigned* count, unsigned* maxSymbolValuePtr,
* `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32. * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32.
* @return : largest histogram frequency, * @return : largest histogram frequency,
* or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */ * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */
static UNUSED_ATTR static size_t HIST_count_parallel_wksp(
size_t HIST_count_parallel_wksp(unsigned* count, unsigned* maxSymbolValuePtr, unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, const void* source, size_t sourceSize,
HIST_checkInput_e check, HIST_checkInput_e check,
U32* const workSpace) U32* const workSpace)
@ -395,17 +141,11 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, const void* source, size_t sourceSize,
void* workSpace, size_t workSpaceSize) void* workSpace, size_t workSpaceSize)
{ {
if (sourceSize < HIST_FAST_THRESHOLD) /* heuristic threshold */ if (sourceSize < 1500) /* heuristic threshold */
return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize);
#if defined(ZSTD_ARCH_ARM_SVE2)
(void)workSpace;
(void)workSpaceSize;
return HIST_count_sve2(count, maxSymbolValuePtr, source, sourceSize, trustInput);
#else
if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace); return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
#endif
} }
/* HIST_count_wksp() : /* HIST_count_wksp() :
@ -415,15 +155,10 @@ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, const void* source, size_t sourceSize,
void* workSpace, size_t workSpaceSize) void* workSpace, size_t workSpaceSize)
{ {
#if defined(ZSTD_ARCH_ARM_SVE2)
if (*maxSymbolValuePtr < 255)
return HIST_count_sve2(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue);
#else
if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
if (*maxSymbolValuePtr < 255) if (*maxSymbolValuePtr < 255)
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace); return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace);
#endif
*maxSymbolValuePtr = 255; *maxSymbolValuePtr = 255;
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize); return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
} }

View File

@ -35,11 +35,7 @@ unsigned HIST_isError(size_t code); /**< tells if a return value is an error co
/* --- advanced histogram functions --- */ /* --- advanced histogram functions --- */
#if defined(__ARM_FEATURE_SVE2)
#define HIST_WKSP_SIZE_U32 0
#else
#define HIST_WKSP_SIZE_U32 1024 #define HIST_WKSP_SIZE_U32 1024
#endif
#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned)) #define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned))
/** HIST_count_wksp() : /** HIST_count_wksp() :
* Same as HIST_count(), but using an externally provided scratch buffer. * Same as HIST_count(), but using an externally provided scratch buffer.
@ -77,10 +73,3 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
*/ */
unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize); const void* src, size_t srcSize);
/*! HIST_add() :
* Lowest level: just add nb of occurrences of characters from @src into @count.
* @count is not reset. @count array is presumed large enough (i.e. 1 KB).
@ This function does not need any additional stack memory.
*/
void HIST_add(unsigned* count, const void* src, size_t srcSize);

View File

@ -425,7 +425,6 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits
* gain back half the rank. * gain back half the rank.
*/ */
U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1; U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1;
assert(nBitsToDecrease <= HUF_TABLELOG_MAX+1);
for ( ; nBitsToDecrease > 1; nBitsToDecrease--) { for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
U32 const highPos = rankLast[nBitsToDecrease]; U32 const highPos = rankLast[nBitsToDecrease];
U32 const lowPos = rankLast[nBitsToDecrease-1]; U32 const lowPos = rankLast[nBitsToDecrease-1];

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,10 @@
# include "zstdmt_compress.h" # include "zstdmt_compress.h"
#endif #endif
#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_NbCommonBytes */ #include "../common/bits.h" /* ZSTD_highbit32, ZSTD_NbCommonBytes */
#include "zstd_preSplit.h" /* ZSTD_SLIPBLOCK_WORKSPACESIZE */
#if defined (__cplusplus)
extern "C" {
#endif
/*-************************************* /*-*************************************
* Constants * Constants
@ -79,70 +82,6 @@ typedef struct {
ZSTD_fseCTables_t fse; ZSTD_fseCTables_t fse;
} ZSTD_entropyCTables_t; } ZSTD_entropyCTables_t;
/***********************************************
* Sequences *
***********************************************/
typedef struct SeqDef_s {
U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
U16 litLength;
U16 mlBase; /* mlBase == matchLength - MINMATCH */
} SeqDef;
/* Controls whether seqStore has a single "long" litLength or matchLength. See SeqStore_t. */
typedef enum {
ZSTD_llt_none = 0, /* no longLengthType */
ZSTD_llt_literalLength = 1, /* represents a long literal */
ZSTD_llt_matchLength = 2 /* represents a long match */
} ZSTD_longLengthType_e;
typedef struct {
SeqDef* sequencesStart;
SeqDef* sequences; /* ptr to end of sequences */
BYTE* litStart;
BYTE* lit; /* ptr to end of literals */
BYTE* llCode;
BYTE* mlCode;
BYTE* ofCode;
size_t maxNbSeq;
size_t maxNbLit;
/* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength
* in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
* the existing value of the litLength or matchLength by 0x10000.
*/
ZSTD_longLengthType_e longLengthType;
U32 longLengthPos; /* Index of the sequence to apply long length modification to */
} SeqStore_t;
typedef struct {
U32 litLength;
U32 matchLength;
} ZSTD_SequenceLength;
/**
* Returns the ZSTD_SequenceLength for the given sequences. It handles the decoding of long sequences
* indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength.
*/
MEM_STATIC ZSTD_SequenceLength ZSTD_getSequenceLength(SeqStore_t const* seqStore, SeqDef const* seq)
{
ZSTD_SequenceLength seqLen;
seqLen.litLength = seq->litLength;
seqLen.matchLength = seq->mlBase + MINMATCH;
if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
if (seqStore->longLengthType == ZSTD_llt_literalLength) {
seqLen.litLength += 0x10000;
}
if (seqStore->longLengthType == ZSTD_llt_matchLength) {
seqLen.matchLength += 0x10000;
}
}
return seqLen;
}
const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
/*********************************************** /***********************************************
* Entropy buffer statistics structs and funcs * * Entropy buffer statistics structs and funcs *
***********************************************/ ***********************************************/
@ -152,7 +91,7 @@ int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr); /* compress, dictBuilder,
* hufDesSize refers to the size of huffman tree description in bytes. * hufDesSize refers to the size of huffman tree description in bytes.
* This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */ * This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */
typedef struct { typedef struct {
SymbolEncodingType_e hType; symbolEncodingType_e hType;
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE]; BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
size_t hufDesSize; size_t hufDesSize;
} ZSTD_hufCTablesMetadata_t; } ZSTD_hufCTablesMetadata_t;
@ -163,9 +102,9 @@ typedef struct {
* fseTablesSize refers to the size of fse tables in bytes. * fseTablesSize refers to the size of fse tables in bytes.
* This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */ * This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */
typedef struct { typedef struct {
SymbolEncodingType_e llType; symbolEncodingType_e llType;
SymbolEncodingType_e ofType; symbolEncodingType_e ofType;
SymbolEncodingType_e mlType; symbolEncodingType_e mlType;
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE]; BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
size_t fseTablesSize; size_t fseTablesSize;
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
@ -180,7 +119,7 @@ typedef struct {
* 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( size_t ZSTD_buildBlockEntropyStats(
const SeqStore_t* seqStorePtr, const seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy, const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy, ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams, const ZSTD_CCtx_params* cctxParams,
@ -209,9 +148,15 @@ typedef struct {
stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */ stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
size_t size; /* The number of sequences. <= capacity. */ size_t size; /* The number of sequences. <= capacity. */
size_t capacity; /* The capacity starting from `seq` pointer */ size_t capacity; /* The capacity starting from `seq` pointer */
} RawSeqStore_t; } rawSeqStore_t;
UNUSED_ATTR static const RawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; 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};
typedef struct { typedef struct {
int price; /* price from beginning of segment to this position */ int price; /* price from beginning of segment to this position */
@ -243,7 +188,7 @@ typedef struct {
U32 offCodeSumBasePrice; /* to compare to log2(offreq) */ U32 offCodeSumBasePrice; /* to compare to log2(offreq) */
ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */ ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */
const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */ const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */
ZSTD_ParamSwitch_e literalCompressionMode; ZSTD_paramSwitch_e literalCompressionMode;
} optState_t; } optState_t;
typedef struct { typedef struct {
@ -265,11 +210,11 @@ typedef struct {
#define ZSTD_WINDOW_START_INDEX 2 #define ZSTD_WINDOW_START_INDEX 2
typedef struct ZSTD_MatchState_t ZSTD_MatchState_t; typedef struct ZSTD_matchState_t ZSTD_matchState_t;
#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */ #define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
struct ZSTD_MatchState_t { struct ZSTD_matchState_t {
ZSTD_window_t window; /* State for window round buffer management */ ZSTD_window_t window; /* State for window round buffer management */
U32 loadedDictEnd; /* index of end of dictionary, within context's referential. U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
* When loadedDictEnd != 0, a dictionary is in use, and still valid. * When loadedDictEnd != 0, a dictionary is in use, and still valid.
@ -291,15 +236,15 @@ struct ZSTD_MatchState_t {
U32* hashTable3; U32* hashTable3;
U32* chainTable; U32* chainTable;
int forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */ U32 forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */
int dedicatedDictSearch; /* Indicates whether this matchState is using the int dedicatedDictSearch; /* Indicates whether this matchState is using the
* dedicated dictionary search structure. * dedicated dictionary search structure.
*/ */
optState_t opt; /* optimal parser state */ optState_t opt; /* optimal parser state */
const ZSTD_MatchState_t* dictMatchState; const ZSTD_matchState_t* dictMatchState;
ZSTD_compressionParameters cParams; ZSTD_compressionParameters cParams;
const RawSeqStore_t* ldmSeqStore; const rawSeqStore_t* ldmSeqStore;
/* Controls prefetching in some dictMatchState matchfinders. /* Controls prefetching in some dictMatchState matchfinders.
* This behavior is controlled from the cctx ms. * This behavior is controlled from the cctx ms.
@ -317,7 +262,7 @@ struct ZSTD_MatchState_t {
typedef struct { typedef struct {
ZSTD_compressedBlockState_t* prevCBlock; ZSTD_compressedBlockState_t* prevCBlock;
ZSTD_compressedBlockState_t* nextCBlock; ZSTD_compressedBlockState_t* nextCBlock;
ZSTD_MatchState_t matchState; ZSTD_matchState_t matchState;
} ZSTD_blockState_t; } ZSTD_blockState_t;
typedef struct { typedef struct {
@ -344,7 +289,7 @@ typedef struct {
} ldmState_t; } ldmState_t;
typedef struct { typedef struct {
ZSTD_ParamSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */ ZSTD_paramSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */
U32 hashLog; /* Log size of hashTable */ U32 hashLog; /* Log size of hashTable */
U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */ U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */
U32 minMatchLength; /* Minimum match length */ U32 minMatchLength; /* Minimum match length */
@ -375,7 +320,7 @@ struct ZSTD_CCtx_params_s {
* There is no guarantee that hint is close to actual source size */ * There is no guarantee that hint is close to actual source size */
ZSTD_dictAttachPref_e attachDictPref; ZSTD_dictAttachPref_e attachDictPref;
ZSTD_ParamSwitch_e literalCompressionMode; ZSTD_paramSwitch_e literalCompressionMode;
/* Multithreading: used to pass parameters to mtctx */ /* Multithreading: used to pass parameters to mtctx */
int nbWorkers; int nbWorkers;
@ -394,27 +339,14 @@ struct ZSTD_CCtx_params_s {
ZSTD_bufferMode_e outBufferMode; ZSTD_bufferMode_e outBufferMode;
/* Sequence compression API */ /* Sequence compression API */
ZSTD_SequenceFormat_e blockDelimiters; ZSTD_sequenceFormat_e blockDelimiters;
int validateSequences; int validateSequences;
/* Block splitting /* Block splitting */
* @postBlockSplitter executes split analysis after sequences are produced, ZSTD_paramSwitch_e useBlockSplitter;
* it's more accurate but consumes more resources.
* @preBlockSplitter_level splits before knowing sequences,
* it's more approximative but also cheaper.
* Valid @preBlockSplitter_level values range from 0 to 6 (included).
* 0 means auto, 1 means do not split,
* then levels are sorted in increasing cpu budget, from 2 (fastest) to 6 (slowest).
* Highest @preBlockSplitter_level combines well with @postBlockSplitter.
*/
ZSTD_ParamSwitch_e postBlockSplitter;
int preBlockSplitter_level;
/* Adjust the max block size*/
size_t maxBlockSize;
/* Param for deciding whether to use row-based matchfinder */ /* Param for deciding whether to use row-based matchfinder */
ZSTD_ParamSwitch_e useRowMatchFinder; ZSTD_paramSwitch_e useRowMatchFinder;
/* Always load a dictionary in ext-dict mode (not prefix mode)? */ /* Always load a dictionary in ext-dict mode (not prefix mode)? */
int deterministicRefPrefix; int deterministicRefPrefix;
@ -423,7 +355,7 @@ struct ZSTD_CCtx_params_s {
ZSTD_customMem customMem; ZSTD_customMem customMem;
/* 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 /* Controls whether zstd will fall back to an internal matchfinder
* if the external matchfinder returns an error code. */ * if the external matchfinder returns an error code. */
@ -435,13 +367,15 @@ struct ZSTD_CCtx_params_s {
void* extSeqProdState; void* extSeqProdState;
ZSTD_sequenceProducer_F extSeqProdFunc; ZSTD_sequenceProducer_F extSeqProdFunc;
/* Adjust the max block size*/
size_t maxBlockSize;
/* Controls repcode search in external sequence parsing */ /* Controls repcode search in external sequence parsing */
ZSTD_ParamSwitch_e searchForExternalRepcodes; ZSTD_paramSwitch_e searchForExternalRepcodes;
}; /* 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))
#define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE) #define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
#define TMP_WORKSPACE_SIZE (MAX(ENTROPY_WORKSPACE_SIZE, ZSTD_SLIPBLOCK_WORKSPACESIZE))
/** /**
* Indicates whether this compression proceeds directly from user-provided * Indicates whether this compression proceeds directly from user-provided
@ -459,11 +393,11 @@ typedef enum {
*/ */
#define ZSTD_MAX_NB_BLOCK_SPLITS 196 #define ZSTD_MAX_NB_BLOCK_SPLITS 196
typedef struct { typedef struct {
SeqStore_t fullSeqStoreChunk; seqStore_t fullSeqStoreChunk;
SeqStore_t firstHalfSeqStore; seqStore_t firstHalfSeqStore;
SeqStore_t secondHalfSeqStore; seqStore_t secondHalfSeqStore;
SeqStore_t currSeqStore; seqStore_t currSeqStore;
SeqStore_t nextSeqStore; seqStore_t nextSeqStore;
U32 partitions[ZSTD_MAX_NB_BLOCK_SPLITS]; U32 partitions[ZSTD_MAX_NB_BLOCK_SPLITS];
ZSTD_entropyCTablesMetadata_t entropyMetadata; ZSTD_entropyCTablesMetadata_t entropyMetadata;
@ -480,7 +414,7 @@ struct ZSTD_CCtx_s {
size_t dictContentSize; size_t dictContentSize;
ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */ ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */
size_t blockSizeMax; size_t blockSize;
unsigned long long pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */ unsigned long long pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */
unsigned long long consumedSrcSize; unsigned long long consumedSrcSize;
unsigned long long producedCSize; unsigned long long producedCSize;
@ -492,14 +426,13 @@ struct ZSTD_CCtx_s {
int isFirstBlock; int isFirstBlock;
int initialized; int initialized;
SeqStore_t seqStore; /* sequences storage ptrs */ seqStore_t seqStore; /* sequences storage ptrs */
ldmState_t ldmState; /* long distance matching state */ ldmState_t ldmState; /* long distance matching state */
rawSeq* ldmSequences; /* Storage for the ldm output sequences */ rawSeq* ldmSequences; /* Storage for the ldm output sequences */
size_t maxNbLdmSequences; size_t maxNbLdmSequences;
RawSeqStore_t externSeqStore; /* Mutable reference to external sequences */ rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
ZSTD_blockState_t blockState; ZSTD_blockState_t blockState;
void* tmpWorkspace; /* used as substitute of stack space - must be aligned for S64 type */ U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
size_t tmpWkspSize;
/* Whether we are streaming or not */ /* Whether we are streaming or not */
ZSTD_buffered_policy_e bufferedPolicy; ZSTD_buffered_policy_e bufferedPolicy;
@ -573,12 +506,12 @@ typedef enum {
* behavior of taking both the source size and the dict size into account * behavior of taking both the source size and the dict size into account
* when selecting and adjusting parameters. * when selecting and adjusting parameters.
*/ */
} ZSTD_CParamMode_e; } ZSTD_cParamMode_e;
typedef size_t (*ZSTD_BlockCompressor_f) ( typedef size_t (*ZSTD_blockCompressor) (
ZSTD_MatchState_t* bs, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode); ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
MEM_STATIC U32 ZSTD_LLcode(U32 litLength) MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
@ -624,25 +557,6 @@ MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
return 1; return 1;
} }
/* ZSTD_selectAddr:
* @return index >= lowLimit ? candidate : backup,
* tries to force branchless codegen. */
MEM_STATIC const BYTE*
ZSTD_selectAddr(U32 index, U32 lowLimit, const BYTE* candidate, const BYTE* backup)
{
#if defined(__GNUC__) && defined(__x86_64__)
__asm__ (
"cmp %1, %2\n"
"cmova %3, %0\n"
: "+r"(candidate)
: "r"(index), "r"(lowLimit), "r"(backup)
);
return candidate;
#else
return index >= lowLimit ? candidate : backup;
#endif
}
/* ZSTD_noCompressBlock() : /* ZSTD_noCompressBlock() :
* Writes uncompressed block to dst buffer from given src. * Writes uncompressed block to dst buffer from given src.
* Returns the size of the block */ * Returns the size of the block */
@ -707,7 +621,7 @@ ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE con
{ {
assert(iend > ilimit_w); assert(iend > ilimit_w);
if (ip <= ilimit_w) { if (ip <= ilimit_w) {
ZSTD_wildcopy(op, ip, (size_t)(ilimit_w - ip), ZSTD_no_overlap); ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap);
op += ilimit_w - ip; op += ilimit_w - ip;
ip = ilimit_w; ip = ilimit_w;
} }
@ -725,55 +639,14 @@ ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE con
#define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM) #define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM)
#define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */ #define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */
/*! ZSTD_storeSeqOnly() :
* Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t.
* Literals themselves are not copied, but @litPtr is updated.
* @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE().
* @matchLength : must be >= MINMATCH
*/
HINT_INLINE UNUSED_ATTR void
ZSTD_storeSeqOnly(SeqStore_t* seqStorePtr,
size_t litLength,
U32 offBase,
size_t matchLength)
{
assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
/* literal Length */
assert(litLength <= ZSTD_BLOCKSIZE_MAX);
if (UNLIKELY(litLength>0xFFFF)) {
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
seqStorePtr->longLengthType = ZSTD_llt_literalLength;
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
}
seqStorePtr->sequences[0].litLength = (U16)litLength;
/* match offset */
seqStorePtr->sequences[0].offBase = offBase;
/* match Length */
assert(matchLength <= ZSTD_BLOCKSIZE_MAX);
assert(matchLength >= MINMATCH);
{ size_t const mlBase = matchLength - MINMATCH;
if (UNLIKELY(mlBase>0xFFFF)) {
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
seqStorePtr->longLengthType = ZSTD_llt_matchLength;
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
}
seqStorePtr->sequences[0].mlBase = (U16)mlBase;
}
seqStorePtr->sequences++;
}
/*! ZSTD_storeSeq() : /*! ZSTD_storeSeq() :
* Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. * Store a sequence (litlen, litPtr, offBase and matchLength) into seqStore_t.
* @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE().
* @matchLength : must be >= MINMATCH * @matchLength : must be >= MINMATCH
* Allowed to over-read literals up to litLimit. * Allowed to over-read literals up to litLimit.
*/ */
HINT_INLINE UNUSED_ATTR void HINT_INLINE UNUSED_ATTR void
ZSTD_storeSeq(SeqStore_t* seqStorePtr, ZSTD_storeSeq(seqStore_t* seqStorePtr,
size_t litLength, const BYTE* literals, const BYTE* litLimit, size_t litLength, const BYTE* literals, const BYTE* litLimit,
U32 offBase, U32 offBase,
size_t matchLength) size_t matchLength)
@ -800,14 +673,36 @@ ZSTD_storeSeq(SeqStore_t* seqStorePtr,
ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16); ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16);
ZSTD_copy16(seqStorePtr->lit, literals); ZSTD_copy16(seqStorePtr->lit, literals);
if (litLength > 16) { if (litLength > 16) {
ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, litLength-16, ZSTD_no_overlap); ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap);
} }
} else { } else {
ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w); ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);
} }
seqStorePtr->lit += litLength; seqStorePtr->lit += litLength;
ZSTD_storeSeqOnly(seqStorePtr, litLength, offBase, matchLength); /* literal Length */
if (litLength>0xFFFF) {
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
seqStorePtr->longLengthType = ZSTD_llt_literalLength;
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
}
seqStorePtr->sequences[0].litLength = (U16)litLength;
/* match offset */
seqStorePtr->sequences[0].offBase = offBase;
/* match Length */
assert(matchLength >= MINMATCH);
{ size_t const mlBase = matchLength - MINMATCH;
if (mlBase>0xFFFF) {
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
seqStorePtr->longLengthType = ZSTD_llt_matchLength;
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
}
seqStorePtr->sequences[0].mlBase = (U16)mlBase;
}
seqStorePtr->sequences++;
} }
/* ZSTD_updateRep() : /* ZSTD_updateRep() :
@ -836,12 +731,12 @@ ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
typedef struct repcodes_s { typedef struct repcodes_s {
U32 rep[3]; U32 rep[3];
} Repcodes_t; } repcodes_t;
MEM_STATIC Repcodes_t MEM_STATIC repcodes_t
ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
{ {
Repcodes_t newReps; repcodes_t newReps;
ZSTD_memcpy(&newReps, rep, sizeof(newReps)); ZSTD_memcpy(&newReps, rep, sizeof(newReps));
ZSTD_updateRep(newReps.rep, offBase, ll0); ZSTD_updateRep(newReps.rep, offBase, ll0);
return newReps; return newReps;
@ -884,8 +779,8 @@ ZSTD_count_2segments(const BYTE* ip, const BYTE* match,
size_t const matchLength = ZSTD_count(ip, match, vEnd); size_t const matchLength = ZSTD_count(ip, match, vEnd);
if (match + matchLength != mEnd) return matchLength; if (match + matchLength != mEnd) return matchLength;
DEBUGLOG(7, "ZSTD_count_2segments: found a 2-parts match (current length==%zu)", matchLength); DEBUGLOG(7, "ZSTD_count_2segments: found a 2-parts match (current length==%zu)", matchLength);
DEBUGLOG(7, "distance from match beginning to end dictionary = %i", (int)(mEnd - match)); DEBUGLOG(7, "distance from match beginning to end dictionary = %zi", mEnd - match);
DEBUGLOG(7, "distance from current pos to end buffer = %i", (int)(iEnd - ip)); DEBUGLOG(7, "distance from current pos to end buffer = %zi", iEnd - ip);
DEBUGLOG(7, "next byte : ip==%02X, istart==%02X", ip[matchLength], *iStart); DEBUGLOG(7, "next byte : ip==%02X, istart==%02X", ip[matchLength], *iStart);
DEBUGLOG(7, "final match length = %zu", matchLength + ZSTD_count(ip+matchLength, iStart, iEnd)); DEBUGLOG(7, "final match length = %zu", matchLength + ZSTD_count(ip+matchLength, iStart, iEnd));
return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd); return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
@ -1023,12 +918,11 @@ MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64
/*-************************************* /*-*************************************
* Round buffer management * Round buffer management
***************************************/ ***************************************/
/* Max @current value allowed: #if (ZSTD_WINDOWLOG_MAX_64 > 31)
* In 32-bit mode: we want to avoid crossing the 2 GB limit, # error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
* reducing risks of side effects in case of signed operations on indexes. #endif
* In 64-bit mode: we want to ensure that adding the maximum job size (512 MB) /* Max current allowed */
* doesn't overflow U32 index capacity (4 GB) */ #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
#define ZSTD_CURRENT_MAX (MEM_64bits() ? 3500U MB : 2000U MB)
/* Maximum chunk size before overflow correction needs to be called again */ /* Maximum chunk size before overflow correction needs to be called again */
#define ZSTD_CHUNKSIZE_MAX \ #define ZSTD_CHUNKSIZE_MAX \
( ((U32)-1) /* Maximum ending current index */ \ ( ((U32)-1) /* Maximum ending current index */ \
@ -1068,7 +962,7 @@ MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window)
* Inspects the provided matchState and figures out what dictMode should be * Inspects the provided matchState and figures out what dictMode should be
* passed to the compressor. * passed to the compressor.
*/ */
MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_MatchState_t *ms) MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
{ {
return ZSTD_window_hasExtDict(ms->window) ? return ZSTD_window_hasExtDict(ms->window) ?
ZSTD_extDict : ZSTD_extDict :
@ -1257,7 +1151,7 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
const void* blockEnd, const void* blockEnd,
U32 maxDist, U32 maxDist,
U32* loadedDictEndPtr, U32* loadedDictEndPtr,
const ZSTD_MatchState_t** dictMatchStatePtr) const ZSTD_matchState_t** dictMatchStatePtr)
{ {
U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0; U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
@ -1302,7 +1196,7 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
const void* blockEnd, const void* blockEnd,
U32 maxDist, U32 maxDist,
U32* loadedDictEndPtr, U32* loadedDictEndPtr,
const ZSTD_MatchState_t** dictMatchStatePtr) const ZSTD_matchState_t** dictMatchStatePtr)
{ {
assert(loadedDictEndPtr != NULL); assert(loadedDictEndPtr != NULL);
assert(dictMatchStatePtr != NULL); assert(dictMatchStatePtr != NULL);
@ -1352,8 +1246,8 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
MEM_STATIC MEM_STATIC
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
U32 ZSTD_window_update(ZSTD_window_t* window, U32 ZSTD_window_update(ZSTD_window_t* window,
const void* src, size_t srcSize, void const* src, size_t srcSize,
int forceNonContiguous) int forceNonContiguous)
{ {
BYTE const* const ip = (BYTE const*)src; BYTE const* const ip = (BYTE const*)src;
U32 contiguous = 1; U32 contiguous = 1;
@ -1380,9 +1274,8 @@ U32 ZSTD_window_update(ZSTD_window_t* window,
/* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
if ( (ip+srcSize > window->dictBase + window->lowLimit) if ( (ip+srcSize > window->dictBase + window->lowLimit)
& (ip < window->dictBase + window->dictLimit)) { & (ip < window->dictBase + window->dictLimit)) {
size_t const highInputIdx = (size_t)((ip + srcSize) - window->dictBase); ptrdiff_t const highInputIdx = (ip + srcSize) - window->dictBase;
U32 const lowLimitMax = (highInputIdx > (size_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx; U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx;
assert(highInputIdx < UINT_MAX);
window->lowLimit = lowLimitMax; window->lowLimit = lowLimitMax;
DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit); DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit);
} }
@ -1392,7 +1285,7 @@ U32 ZSTD_window_update(ZSTD_window_t* window,
/** /**
* Returns the lowest allowed match index. It may either be in the ext-dict or the prefix. * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
*/ */
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
{ {
U32 const maxDistance = 1U << windowLog; U32 const maxDistance = 1U << windowLog;
U32 const lowestValid = ms->window.lowLimit; U32 const lowestValid = ms->window.lowLimit;
@ -1409,7 +1302,7 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_MatchState_t* ms, U32 curr, u
/** /**
* Returns the lowest allowed match index in the prefix. * Returns the lowest allowed match index in the prefix.
*/ */
MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
{ {
U32 const maxDistance = 1U << windowLog; U32 const maxDistance = 1U << windowLog;
U32 const lowestValid = ms->window.dictLimit; U32 const lowestValid = ms->window.dictLimit;
@ -1422,13 +1315,6 @@ MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_MatchState_t* ms, U32 curr,
return matchLowest; return matchLowest;
} }
/* index_safety_check:
* intentional underflow : ensure repIndex isn't overlapping dict + prefix
* @return 1 if values are not overlapping,
* 0 otherwise */
MEM_STATIC int ZSTD_index_overlap_check(const U32 prefixLowestIndex, const U32 repIndex) {
return ((U32)((prefixLowestIndex-1) - repIndex) >= 3);
}
/* debug functions */ /* debug functions */
@ -1499,6 +1385,10 @@ MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2) {
return tag1 == tag2; return tag1 == tag2;
} }
#if defined (__cplusplus)
}
#endif
/* =============================================================== /* ===============================================================
* Shared internal declarations * Shared internal declarations
* These prototypes may be called from sources not in lib/compress * These prototypes may be called from sources not in lib/compress
@ -1514,25 +1404,6 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs); void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
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;
/* for benchmark */
size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
const ZSTD_Sequence* const inSeqs, size_t nbSequences,
int repcodeResolution);
typedef struct {
size_t nbSequences;
size_t blockSize;
size_t litSize;
} BlockSummary;
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs);
/* ============================================================== /* ==============================================================
* Private declarations * Private declarations
* These prototypes shall only be called from within lib/compress * These prototypes shall only be called from within lib/compress
@ -1544,7 +1415,7 @@ BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs);
* Note: srcSizeHint == 0 means 0! * Note: srcSizeHint == 0 means 0!
*/ */
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
/*! ZSTD_initCStream_internal() : /*! ZSTD_initCStream_internal() :
* Private use only. Init streaming operation. * Private use only. Init streaming operation.
@ -1556,7 +1427,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
const ZSTD_CDict* cdict, const ZSTD_CDict* cdict,
const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize); const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize);
void ZSTD_resetSeqStore(SeqStore_t* ssPtr); void ZSTD_resetSeqStore(seqStore_t* ssPtr);
/*! ZSTD_getCParamsFromCDict() : /*! ZSTD_getCParamsFromCDict() :
* as the name implies */ * as the name implies */
@ -1609,6 +1480,33 @@ 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, ZSTD_paramSwitch_e externalRepSearch);
/* 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, ZSTD_paramSwitch_e externalRepSearch);
/* Returns 1 if an external sequence producer is registered, otherwise returns 0. */ /* Returns 1 if an external sequence producer is registered, otherwise returns 0. */
MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) { MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) {
return params->extSeqProdFunc != NULL; return params->extSeqProdFunc != NULL;

View File

@ -140,7 +140,7 @@ size_t ZSTD_compressLiterals (
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;
SymbolEncodingType_e hType = set_compressed; symbolEncodingType_e hType = set_compressed;
size_t cLitSize; size_t cLitSize;
DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i, srcSize=%u, dstCapacity=%zu)", DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i, srcSize=%u, dstCapacity=%zu)",

Some files were not shown because too many files have changed in this diff Show More