Compare commits
361
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c7b7bad26 | ||
|
|
b1796e4580 | ||
|
|
61b9912eec | ||
|
|
a20ab7436f | ||
|
|
5233c58e6c | ||
|
|
c367e0c149 | ||
|
|
885c79ba4a | ||
|
|
cb6b844cb5 | ||
|
|
c770d993fb | ||
|
|
0cdce55f2f | ||
|
|
44ebbde6a3 | ||
|
|
48c0ed7362 | ||
|
|
b3a648a204 | ||
|
|
6d6eff1008 | ||
|
|
c0ec909bde | ||
|
|
0d815ad877 | ||
|
|
a23bf84362 | ||
|
|
497a433e01 | ||
|
|
5fc4931c04 | ||
|
|
3ae099b48d | ||
|
|
cef5a5611a | ||
|
|
e56865641e | ||
|
|
c84c8fb47f | ||
|
|
ff25783fcb | ||
|
|
155046f3ac | ||
|
|
ee0af93e1c | ||
|
|
e374fc76fe | ||
|
|
3f565b731e | ||
|
|
3041c8e539 | ||
|
|
488b3a7e37 | ||
|
|
2293e9601f | ||
|
|
13ea076d3b | ||
|
|
043426b3e2 | ||
|
|
3f8f9b3f89 | ||
|
|
f1e77ab2ba | ||
|
|
7b04e6dd1e | ||
|
|
d7ee3207cc | ||
|
|
1bd8e55363 | ||
|
|
6a8715f8d4 | ||
|
|
6e1e545916 | ||
|
|
0532fe3e8a | ||
|
|
9468cace38 | ||
|
|
1c140a86a1 | ||
|
|
d9b10820f8 | ||
|
|
bb1eedcf86 | ||
|
|
2107c8f189 | ||
|
|
bce1ec6b07 | ||
|
|
81cf153bce | ||
|
|
117b0edfae | ||
|
|
a90d7e7689 | ||
|
|
1168da0e56 | ||
|
|
a380d30b20 | ||
|
|
4b8d87a8c3 | ||
|
|
deb898b541 | ||
|
|
a46bec0fba | ||
|
|
a8319c39de | ||
|
|
ae9f20ca27 | ||
|
|
e00ddf63b2 | ||
|
|
1dae4f0188 | ||
|
|
3a3c506b51 | ||
|
|
a87d0cc476 | ||
|
|
8ba2f20a90 | ||
|
|
f818f97be6 | ||
|
|
6c3e805e50 | ||
|
|
073c7fb6ea | ||
|
|
b79e86291b | ||
|
|
38cce02684 | ||
|
|
ebc93b0c91 | ||
|
|
85c5fa09fd | ||
|
|
af850cd44e | ||
|
|
5b51447734 | ||
|
|
9873a01368 | ||
|
|
de9b0810ec | ||
|
|
c26db2d0e8 | ||
|
|
1e06c42eec | ||
|
|
bfd8ad886f | ||
|
|
c7c29693c9 | ||
|
|
f28b1173df | ||
|
|
94117e39ca | ||
|
|
757f1bf465 | ||
|
|
92505deb29 | ||
|
|
f567f38b73 | ||
|
|
9e23edcf1e | ||
|
|
88ff5c2769 | ||
|
|
d462f691ba | ||
|
|
e23477ce3e | ||
|
|
448cd34087 | ||
|
|
71146f5b6d | ||
|
|
273ab1bbdf | ||
|
|
a25c1fc96f | ||
|
|
129769d04c | ||
|
|
711e17da98 | ||
|
|
57d4949098 | ||
|
|
7a3c940e7f | ||
|
|
41f2673acd | ||
|
|
ccadc33a59 | ||
|
|
d1dd7e1481 | ||
|
|
44cd3c8451 | ||
|
|
4944d2c461 | ||
|
|
c72eea13bf | ||
|
|
442fa2f2d5 | ||
|
|
5539fcfb6a | ||
|
|
6e58e9a2c4 | ||
|
|
0dffae42e3 | ||
|
|
33618c89e5 | ||
|
|
23dae4bf49 | ||
|
|
f94a01de74 | ||
|
|
b8d6101fba | ||
|
|
87cc127705 | ||
|
|
7758cc3e7a | ||
|
|
c9d3af9ed0 | ||
|
|
f42dee27b6 | ||
|
|
17888b3fbe | ||
|
|
a8f732e50f | ||
|
|
c15fa3cd40 | ||
|
|
89d685e42d | ||
|
|
4c1f86c777 | ||
|
|
eb062bc339 | ||
|
|
ee9b5f4371 | ||
|
|
0c6d32df9a | ||
|
|
f9b0c4fd0d | ||
|
|
be072c708e | ||
|
|
085cc9319a | ||
|
|
e6e5a95c15 | ||
|
|
d190b38863 | ||
|
|
236e44f00f | ||
|
|
85f4a7e84e | ||
|
|
96fdb9bd16 | ||
|
|
c59812e558 | ||
|
|
fb7a86f20f | ||
|
|
c9d2cbd5ba | ||
|
|
98d2b90e82 | ||
|
|
683c91fca8 | ||
|
|
ef4bab9079 | ||
|
|
d3536643a9 | ||
|
|
3580aa28e6 | ||
|
|
6936bc84e7 | ||
|
|
249e4a07d5 | ||
|
|
725a152c7b | ||
|
|
c41fc1aa01 | ||
|
|
6551db3459 | ||
|
|
1c5d45fc11 | ||
|
|
fc551317fb | ||
|
|
64c4288e92 | ||
|
|
ba59aeb674 | ||
|
|
22b4483163 | ||
|
|
0ee187c540 | ||
|
|
b5c294ea01 | ||
|
|
2849f3a5d1 | ||
|
|
290e692ef8 | ||
|
|
b3f134bfd4 | ||
|
|
076283fa88 | ||
|
|
002c227596 | ||
|
|
42243c3d46 | ||
|
|
0551eaa851 | ||
|
|
ae64545c6b | ||
|
|
0d1f8de9ad | ||
|
|
40c285e0ba | ||
|
|
cfeb29e397 | ||
|
|
0e69452a30 | ||
|
|
3991e8ac84 | ||
|
|
1e1db47323 | ||
|
|
e128976193 | ||
|
|
8bca04ba9f | ||
|
|
5b89189741 | ||
|
|
96f316a246 | ||
|
|
9bf5d340ae | ||
|
|
34f3a0ab11 | ||
|
|
6f1cb87ade | ||
|
|
3b23f0c673 | ||
|
|
0055ce7a02 | ||
|
|
f9e26bb42b | ||
|
|
8c651868ff | ||
|
|
a1e11db08a | ||
|
|
afa96bbf25 | ||
|
|
c768d7b94b | ||
|
|
3ce4d1cba3 | ||
|
|
9a41990883 | ||
|
|
534860c90b | ||
|
|
7325384a68 | ||
|
|
703f855734 | ||
|
|
07cd78d366 | ||
|
|
8e4400463a | ||
|
|
d04e7944dd | ||
|
|
2c3f23b018 | ||
|
|
40f64f3493 | ||
|
|
1dbc2e0908 | ||
|
|
4efbd56749 | ||
|
|
50f169411b | ||
|
|
a28e8182b1 | ||
|
|
bd38fc2c5f | ||
|
|
3c3b8274c5 | ||
|
|
7b1b6a0d2d | ||
|
|
bdceb81271 | ||
|
|
2e8ec28b30 | ||
|
|
2295826266 | ||
|
|
d77a7b6895 | ||
|
|
528132e9a0 | ||
|
|
878be1c8f0 | ||
|
|
16e13ebdeb | ||
|
|
a74f7fcabd | ||
|
|
a4b9ebcbeb | ||
|
|
1e9d2006ae | ||
|
|
7eefc22169 | ||
|
|
354cede369 | ||
|
|
e315155cc2 | ||
|
|
429dc891b2 | ||
|
|
2082749775 | ||
|
|
4255c5ea89 | ||
|
|
57bd0eb6a7 | ||
|
|
d28a737750 | ||
|
|
cad0b72ad8 | ||
|
|
7e4937bc75 | ||
|
|
5e6bdf5e3d | ||
|
|
9a6fe9a428 | ||
|
|
88bea95d11 | ||
|
|
39c091bc9e | ||
|
|
de8d9e8914 | ||
|
|
472acf5d83 | ||
|
|
7e0324e124 | ||
|
|
b6dc2924f8 | ||
|
|
49fe2ec793 | ||
|
|
75abb8bc1c | ||
|
|
c826c572cf | ||
|
|
a168ae7232 | ||
|
|
b922774602 | ||
|
|
a2dba85fd1 | ||
|
|
ec8ad2e552 | ||
|
|
5b6fbf5f96 | ||
|
|
e23d0a9616 | ||
|
|
a480191f9e | ||
|
|
80cac404c7 | ||
|
|
4be08ba122 | ||
|
|
a81ffe11d4 | ||
|
|
bd894054c0 | ||
|
|
dd4cee9190 | ||
|
|
d95123f2e6 | ||
|
|
4bd5654e72 | ||
|
|
4618b255ea | ||
|
|
f9938c217d | ||
|
|
448a09ff78 | ||
|
|
13cb7a10ae | ||
|
|
01c973de8d | ||
|
|
6fc8455a72 | ||
|
|
2d4cff69c4 | ||
|
|
f5b6531902 | ||
|
|
6b0039abcf | ||
|
|
769723aee2 | ||
|
|
2d224dc745 | ||
|
|
e26dde3dcf | ||
|
|
453e252015 | ||
|
|
7f907d5c23 | ||
|
|
8929d3b09f | ||
|
|
d654fca786 | ||
|
|
28ffb100ab | ||
|
|
f5d4da09f5 | ||
|
|
2a12bbaf90 | ||
|
|
3bd5aa3404 | ||
|
|
c5926fbab8 | ||
|
|
2f9627863f | ||
|
|
0bdeb1d204 | ||
|
|
8626da73b6 | ||
|
|
a293cdcb85 | ||
|
|
0bde39a9b3 | ||
|
|
94cfa0b5a0 | ||
|
|
76c2fdc7b7 | ||
|
|
7630870b47 | ||
|
|
165e52ce62 | ||
|
|
7f0519dcfd | ||
|
|
23e8812f5b | ||
|
|
eb168a0afc | ||
|
|
12ea5f6e30 | ||
|
|
ec40252066 | ||
|
|
64dc08f47f | ||
|
|
334af72280 | ||
|
|
c59f7ac51e | ||
|
|
33f4d40d1e | ||
|
|
bea1e942f7 | ||
|
|
2fec3989c1 | ||
|
|
6775af5b2e | ||
|
|
cd8ca9d92e | ||
|
|
eca205fc78 | ||
|
|
4d53e27144 | ||
|
|
ddcb41a282 | ||
|
|
a9b8fef2e8 | ||
|
|
dcf675886b | ||
|
|
51b6e79f65 | ||
|
|
9a57bdc0bd | ||
|
|
68dfd14a8c | ||
|
|
b27ba56a6d | ||
|
|
19541b4d1a | ||
|
|
c583c2c39e | ||
|
|
f9a6031963 | ||
|
|
3c4096c83e | ||
|
|
2ff87aefac | ||
|
|
c18374bb16 | ||
|
|
56e2ebf5c3 | ||
|
|
d5986f235f | ||
|
|
b16d193512 | ||
|
|
0de4991942 | ||
|
|
99cf130cfc | ||
|
|
190a620974 | ||
|
|
d5b84f5a27 | ||
|
|
5e7d721235 | ||
|
|
5ae1cb9fa1 | ||
|
|
f5a0e047cb | ||
|
|
0b40c513fd | ||
|
|
0298df50f9 | ||
|
|
9b8b414833 | ||
|
|
19ffcf81b8 | ||
|
|
fcfb3160dc | ||
|
|
d5dbdd6ece | ||
|
|
bceb8f2dbc | ||
|
|
9ec1a7c0ac | ||
|
|
7df457a51d | ||
|
|
cab2a29c36 | ||
|
|
3c6c472f01 | ||
|
|
46b2e05a33 | ||
|
|
83db5376d7 | ||
|
|
0727fc5ff9 | ||
|
|
a9337e6739 | ||
|
|
e99be473a6 | ||
|
|
bbbb2379ed | ||
|
|
a6d232dcad | ||
|
|
88100bc62f | ||
|
|
4e1723a7e4 | ||
|
|
7340657c6f | ||
|
|
77e58994d2 | ||
|
|
e94e09dd7b | ||
|
|
017ada44b5 | ||
|
|
bbf2801ddd | ||
|
|
a1a5154b69 | ||
|
|
22b2fd2517 | ||
|
|
d6fbaaac99 | ||
|
|
0ac659fb00 | ||
|
|
dca9791862 | ||
|
|
4d81b0000d | ||
|
|
f0d3173203 | ||
|
|
97bc43cc68 | ||
|
|
db2d205ada | ||
|
|
2413f17322 | ||
|
|
8ffa27d93b | ||
|
|
e635221f1b | ||
|
|
30281d889f | ||
|
|
2840631dc1 | ||
|
|
76779f52c2 | ||
|
|
3ff0d794b8 | ||
|
|
5743da491b | ||
|
|
e1e2f3873d | ||
|
|
b40dabeda2 | ||
|
|
fd5498a179 | ||
|
|
ebfa660b82 | ||
|
|
8ff47f3df0 | ||
|
|
0c3345d6ec | ||
|
|
c2ab0f9c4e | ||
|
|
4690d66c7e | ||
|
|
1bef87857b | ||
|
|
6af3842118 | ||
|
|
d157156bb8 | ||
|
|
37077c859b | ||
|
|
eb6608869f |
+1
-1
@@ -2,7 +2,7 @@ task:
|
|||||||
name: FreeBSD (make check)
|
name: FreeBSD (make check)
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
matrix:
|
matrix:
|
||||||
image_family: freebsd-14-2
|
image_family: freebsd-15-0-amd64-zfs
|
||||||
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
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ updates:
|
|||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
directory: "/"
|
directory: "/"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "monthly"
|
||||||
|
|||||||
@@ -13,16 +13,16 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
|
|
||||||
- name: Setup Android SDK
|
- name: Setup Android SDK
|
||||||
uses: android-actions/setup-android@9fc6c4e9069bf8d3d10b2204b1fb8f6ef7065407 # v3.2.2
|
uses: android-actions/setup-android@651bceb6f9ca583f16b8d75b62c36ded2ae6fc9c # v4.0.0
|
||||||
|
|
||||||
- name: Install Android NDK
|
- name: Install Android NDK
|
||||||
run: |
|
run: |
|
||||||
@@ -37,3 +37,14 @@ jobs:
|
|||||||
RANLIB=llvm-ranlib \
|
RANLIB=llvm-ranlib \
|
||||||
STRIP=llvm-strip
|
STRIP=llvm-strip
|
||||||
|
|
||||||
|
- name: Build with CMake and NDK
|
||||||
|
run: |
|
||||||
|
mkdir -p build-android
|
||||||
|
cd build-android
|
||||||
|
cmake --version
|
||||||
|
cmake ../build/cmake \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \
|
||||||
|
-DANDROID_ABI=arm64-v8a \
|
||||||
|
-DANDROID_PLATFORM=android-21 \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
|
cmake --build . --parallel
|
||||||
|
|||||||
@@ -0,0 +1,168 @@
|
|||||||
|
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:
|
||||||
|
# Basic cmake build using the root CMakeLists.txt
|
||||||
|
# Provides a lightweight sanity check that the top-level project config builds
|
||||||
|
# with the default Unix Makefiles generator driven purely through cmake commands
|
||||||
|
cmake-root-basic:
|
||||||
|
name: "CMake Root Build"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
|
- name: Configure (Root)
|
||||||
|
run: |
|
||||||
|
cmake -S . -B cmake-build -DCMAKE_BUILD_TYPE=Release ${{ env.COMMON_CMAKE_FLAGS }}
|
||||||
|
- name: Build (Root)
|
||||||
|
run: |
|
||||||
|
cmake --build cmake-build --config Release
|
||||||
|
|
||||||
|
# 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 build using make wrapper"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.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-11-arm" # githuh runner for WOA instance
|
||||||
|
- 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
|
- name: Add MSBuild to PATH
|
||||||
|
uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # tag=v3.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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.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
|
||||||
@@ -17,7 +17,7 @@ jobs:
|
|||||||
image: fbopensource/zstd-circleci-primary:0.0.1
|
image: fbopensource/zstd-circleci-primary:0.0.1
|
||||||
options: --entrypoint /bin/bash
|
options: --entrypoint /bin/bash
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6.0.2
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
image: fbopensource/zstd-circleci-primary:0.0.1
|
image: fbopensource/zstd-circleci-primary:0.0.1
|
||||||
options: --entrypoint /bin/bash
|
options: --entrypoint /bin/bash
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6.0.2
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -73,9 +73,9 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CIRCLE_ARTIFACTS: "/tmp/circleci-artifacts"
|
CIRCLE_ARTIFACTS: "/tmp/circleci-artifacts"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6.0.2
|
||||||
- name: restore_cache
|
- name: restore_cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0
|
key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0
|
||||||
path: tests/regression/cache
|
path: tests/regression/cache
|
||||||
@@ -99,6 +99,6 @@ jobs:
|
|||||||
echo " are still good, copy it into the repo and commit it."
|
echo " are still good, copy it into the repo and commit it."
|
||||||
echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv"
|
echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv"
|
||||||
diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv
|
diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v7.0.1
|
||||||
with:
|
with:
|
||||||
path: "/tmp/circleci-artifacts"
|
path: "/tmp/circleci-artifacts"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: dev-long-tests
|
name: dev-long-tests
|
||||||
# Tests longer than 10mn
|
# Tests generally longer than 10mn
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: long-${{ github.ref }}
|
group: long-${{ github.ref }}
|
||||||
@@ -12,40 +12,44 @@ 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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: make all
|
- name: make all
|
||||||
run: make all
|
run: make all
|
||||||
|
|
||||||
# lasts ~24mn
|
# lasts ~19mn
|
||||||
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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: make test
|
- name: make test
|
||||||
run: make test
|
run: |
|
||||||
|
make test
|
||||||
|
make -j zstd
|
||||||
|
./tests/test_process_substitution.bash ./zstd
|
||||||
|
|
||||||
# lasts ~26mn
|
# lasts ~16mn
|
||||||
make-test-macos:
|
make-test-macos:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: make test on macos
|
- name: make test on macos
|
||||||
run: make test
|
run: make test
|
||||||
|
|
||||||
# lasts ~24mn
|
# lasts ~10mn
|
||||||
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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: make test # note: `make -j test success` seems to require a clean state
|
- name: make test # note: `make -j test success` seems to require a clean state
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -53,51 +57,61 @@ jobs:
|
|||||||
make clean
|
make clean
|
||||||
CFLAGS="-m32 -O2" make -j test V=1
|
CFLAGS="-m32 -O2" make -j test V=1
|
||||||
|
|
||||||
|
# lasts ~7mn
|
||||||
|
test-largeDictionary:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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:
|
uasan-zstreamtest:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: ub + address sanitizer on zstreamtest
|
- name: ub + address sanitizer on zstreamtest
|
||||||
run: CC=clang make uasan-test-zstream
|
run: CC=clang make uasan-test-zstream
|
||||||
|
|
||||||
# lasts ~15mn
|
# lasts ~11mn
|
||||||
tsan-fuzztest:
|
tsan-fuzztest:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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 ~23mn
|
# lasts ~13mn
|
||||||
gcc-8-asan-ubsan-testzstd:
|
gcc-8-asan-ubsan-testzstd:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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: |
|
||||||
@@ -109,14 +123,14 @@ jobs:
|
|||||||
clang-asan-ubsan-testzstd:
|
clang-asan-ubsan-testzstd:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: clang + ASan + UBSan + Test Zstd
|
- name: clang + ASan + UBSan + Test Zstd
|
||||||
run: CC=clang make -j uasan-test-zstd </dev/null V=1
|
run: CC=clang make -j uasan-test-zstd </dev/null V=1
|
||||||
|
|
||||||
gcc-asan-ubsan-testzstd-32bit:
|
gcc-asan-ubsan-testzstd-32bit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
@@ -130,7 +144,7 @@ jobs:
|
|||||||
gcc-8-asan-ubsan-fuzz:
|
gcc-8-asan-ubsan-fuzz:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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: |
|
||||||
@@ -142,14 +156,14 @@ jobs:
|
|||||||
clang-asan-ubsan-fuzz:
|
clang-asan-ubsan-fuzz:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: clang + ASan + UBSan + Fuzz Test
|
- name: clang + ASan + UBSan + Fuzz Test
|
||||||
run: CC=clang FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest
|
run: CC=clang FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest
|
||||||
|
|
||||||
gcc-asan-ubsan-fuzz32:
|
gcc-asan-ubsan-fuzz32:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: ASan + UBSan + Fuzz Test 32bit
|
- name: ASan + UBSan + Fuzz Test 32bit
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -159,7 +173,7 @@ jobs:
|
|||||||
clang-asan-fuzz32:
|
clang-asan-fuzz32:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: clang + ASan + Fuzz Test 32bit
|
- name: clang + ASan + Fuzz Test 32bit
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -174,7 +188,7 @@ jobs:
|
|||||||
# clang-asan-ubsan-fuzz32:
|
# clang-asan-ubsan-fuzz32:
|
||||||
# runs-on: ubuntu-20.04
|
# runs-on: ubuntu-20.04
|
||||||
# steps:
|
# steps:
|
||||||
# - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
# - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
# - name: clang + ASan + UBSan + Fuzz Test 32bit
|
# - name: clang + ASan + UBSan + Fuzz Test 32bit
|
||||||
# run: |
|
# run: |
|
||||||
# sudo apt-get -qqq update
|
# sudo apt-get -qqq update
|
||||||
@@ -184,28 +198,28 @@ jobs:
|
|||||||
asan-ubsan-regression:
|
asan-ubsan-regression:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: ASan + UBSan + Regression Test
|
- name: ASan + UBSan + Regression Test
|
||||||
run: make -j uasanregressiontest
|
run: make -j uasanregressiontest
|
||||||
|
|
||||||
clang-asan-ubsan-regression:
|
clang-asan-ubsan-regression:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: clang + ASan + UBSan + Regression Test
|
- name: clang + ASan + UBSan + Regression Test
|
||||||
run: CC=clang make -j uasanregressiontest
|
run: CC=clang make -j uasanregressiontest
|
||||||
|
|
||||||
msan-regression:
|
msan-regression:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: clang + MSan + Fuzz Test
|
- name: clang + MSan + Fuzz Test
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -215,28 +229,25 @@ jobs:
|
|||||||
clang-msan-fuzz:
|
clang-msan-fuzz:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: clang + MSan + Test Zstd
|
- name: clang + MSan + Test Zstd
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
CC=clang make -j msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0 V=1
|
||||||
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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Qemu ARM emulation + Fuzz Test
|
- name: Qemu ARM emulation + Fuzz Test
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -246,7 +257,7 @@ jobs:
|
|||||||
valgrind-fuzz-test:
|
valgrind-fuzz-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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: |
|
||||||
@@ -262,8 +273,8 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0
|
- uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # tag=v2.31.1
|
||||||
with:
|
with:
|
||||||
msystem: MINGW64
|
msystem: MINGW64
|
||||||
install: make
|
install: make
|
||||||
@@ -306,7 +317,7 @@ jobs:
|
|||||||
dry-run: false
|
dry-run: false
|
||||||
sanitizer: ${{ matrix.sanitizer }}
|
sanitizer: ${{ matrix.sanitizer }}
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v7.0.1
|
||||||
if: failure() && steps.build.outcome == 'success'
|
if: failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.sanitizer }}-artifacts
|
name: ${{ matrix.sanitizer }}-artifacts
|
||||||
|
|||||||
@@ -16,39 +16,40 @@ jobs:
|
|||||||
linux-kernel:
|
linux-kernel:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
|
|
||||||
build-c89:
|
build-c89:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: ensure zstd can be build with c89/c90 compilers (+ long long support + variadic macros)
|
- name: ensure zstd can be built 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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
@@ -57,7 +58,7 @@ jobs:
|
|||||||
gcc-7-libzstd:
|
gcc-7-libzstd:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: gcc-7 + libzstdmt compilation
|
- name: gcc-7 + libzstdmt compilation
|
||||||
# See https://askubuntu.com/a/1428822
|
# See https://askubuntu.com/a/1428822
|
||||||
run: |
|
run: |
|
||||||
@@ -71,44 +72,10 @@ 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: |
|
|
||||||
sudo apt install liblzma-dev
|
|
||||||
FUZZERTEST=-T1mn ZSTREAM_TESTTIME=-T1mn make cmakebuild V=1
|
|
||||||
|
|
||||||
cmake-source-directory-with-spaces:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- os: ubuntu-latest
|
|
||||||
generator: "Unix Makefiles"
|
|
||||||
- os: windows-latest
|
|
||||||
generator: "NMake Makefiles"
|
|
||||||
- os: macos-latest
|
|
||||||
generator: "Unix Makefiles"
|
|
||||||
env:
|
|
||||||
SRC_DIR: "source directory with spaces"
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
|
||||||
with:
|
|
||||||
path: "${{ env.SRC_DIR }}"
|
|
||||||
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
|
|
||||||
if: ${{ matrix.generator == 'NMake Makefiles' }}
|
|
||||||
- name: cmake build on a source directory with spaces
|
|
||||||
run: |
|
|
||||||
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
|
|
||||||
|
|
||||||
cpp-gnu90-c99-compatibility:
|
cpp-gnu90-c99-compatibility:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: C++, gnu90 and c99 compatibility
|
- name: C++, gnu90 and c99 compatibility
|
||||||
run: |
|
run: |
|
||||||
make cxxtest
|
make cxxtest
|
||||||
@@ -122,7 +89,7 @@ jobs:
|
|||||||
mingw-cross-compilation:
|
mingw-cross-compilation:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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)
|
||||||
@@ -133,7 +100,7 @@ jobs:
|
|||||||
armbuild:
|
armbuild:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: ARM Build Test
|
- name: ARM Build Test
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -143,7 +110,7 @@ jobs:
|
|||||||
bourne-shell:
|
bourne-shell:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
@@ -153,7 +120,7 @@ jobs:
|
|||||||
zlib-wrapper:
|
zlib-wrapper:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: install valgrind
|
- name: install valgrind
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -166,10 +133,9 @@ jobs:
|
|||||||
lz4-threadpool-libs:
|
lz4-threadpool-libs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
@@ -180,7 +146,7 @@ jobs:
|
|||||||
gcc-make-all-avx2:
|
gcc-make-all-avx2:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Make all, with AVX2
|
- name: Make all, with AVX2
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -190,7 +156,7 @@ jobs:
|
|||||||
gcc-make-all-32bit:
|
gcc-make-all-32bit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Make all, 32bit mode
|
- name: Make all, 32bit mode
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -200,7 +166,7 @@ jobs:
|
|||||||
gcc-make-all-32bit-avx2:
|
gcc-make-all-32bit-avx2:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Make all, 32bit + AVX2 mode
|
- name: Make all, 32bit + AVX2 mode
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -211,7 +177,7 @@ jobs:
|
|||||||
gcc-8-make:
|
gcc-8-make:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: gcc-8 build
|
- name: gcc-8 build
|
||||||
# See https://askubuntu.com/a/1428822
|
# See https://askubuntu.com/a/1428822
|
||||||
run: |
|
run: |
|
||||||
@@ -234,7 +200,7 @@ 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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Build with ${{matrix.name}}
|
- name: Build with ${{matrix.name}}
|
||||||
run: |
|
run: |
|
||||||
sudo apt install liblzma-dev
|
sudo apt install liblzma-dev
|
||||||
@@ -244,7 +210,7 @@ jobs:
|
|||||||
implicit-fall-through:
|
implicit-fall-through:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: -Wimplicit-fallthrough build
|
- name: -Wimplicit-fallthrough build
|
||||||
run: |
|
run: |
|
||||||
make clean
|
make clean
|
||||||
@@ -255,7 +221,7 @@ jobs:
|
|||||||
meson-linux:
|
meson-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -279,7 +245,7 @@ jobs:
|
|||||||
meson-mingw-cross-compilation:
|
meson-mingw-cross-compilation:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get -qqq update
|
sudo apt-get -qqq update
|
||||||
@@ -323,7 +289,7 @@ jobs:
|
|||||||
meson-windows:
|
meson-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Install packages
|
- name: Install packages
|
||||||
run: pip install --pre meson
|
run: pip install --pre meson
|
||||||
- name: Configure with Meson
|
- name: Configure with Meson
|
||||||
@@ -339,34 +305,6 @@ 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"
|
|
||||||
- generator: "Visual Studio 17 2022"
|
|
||||||
flags: "-T ClangCL -A x64 -DCMAKE_C_FLAGS=/arch:AVX2"
|
|
||||||
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 -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -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.
|
||||||
@@ -376,15 +314,14 @@ jobs:
|
|||||||
{ name: "VS 2022 Win32 Debug", platform: Win32, configuration: Debug, toolset: v143, runner: "windows-2022", arch: "" },
|
{ name: "VS 2022 Win32 Debug", platform: Win32, configuration: Debug, toolset: v143, runner: "windows-2022", arch: "" },
|
||||||
{ name: "VS 2022 x64 Release", platform: x64, configuration: Release, toolset: v143, runner: "windows-2022", arch: ""},
|
{ name: "VS 2022 x64 Release", platform: x64, configuration: Release, toolset: v143, runner: "windows-2022", arch: ""},
|
||||||
{ name: "VS 2022 Win32 Release", platform: Win32, configuration: Release, toolset: v143, runner: "windows-2022", arch: ""},
|
{ name: "VS 2022 Win32 Release", platform: Win32, configuration: Release, toolset: v143, runner: "windows-2022", arch: ""},
|
||||||
{ name: "VS 2019 x64 Release", platform: Win32, configuration: Release, toolset: v142, runner: "windows-2019", arch: ""},
|
{ name: "VS 2025 x64 Debug", platform: x64, configuration: Debug, toolset: v143, runner: "windows-2025", arch: ""},
|
||||||
{ name: "VS 2019 Win32 Release", platform: x64, configuration: Release, toolset: v142, runner: "windows-2019", arch: ""},
|
|
||||||
{ name: "VS 2022 x64 Release AVX2", platform: x64, configuration: Release, toolset: v143, runner: "windows-2022", arch: "AdvancedVectorExtensions2" },
|
{ name: "VS 2022 x64 Release AVX2", platform: x64, configuration: Release, toolset: v143, runner: "windows-2022", arch: "AdvancedVectorExtensions2" },
|
||||||
]
|
]
|
||||||
runs-on: ${{matrix.runner}}
|
runs-on: ${{matrix.runner}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Add MSBuild to PATH
|
- name: Add MSBuild to PATH
|
||||||
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0
|
uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # tag=v3.0.0
|
||||||
- name: Build ${{matrix.name}}
|
- name: Build ${{matrix.name}}
|
||||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||||
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
|
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
|
||||||
@@ -407,7 +344,7 @@ jobs:
|
|||||||
libzstd-size:
|
libzstd-size:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
@@ -418,7 +355,7 @@ jobs:
|
|||||||
minimal-decompressor-macros:
|
minimal-decompressor-macros:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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"
|
||||||
@@ -435,7 +372,7 @@ jobs:
|
|||||||
dynamic-bmi2:
|
dynamic-bmi2:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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"
|
||||||
@@ -447,7 +384,7 @@ jobs:
|
|||||||
test-variants:
|
test-variants:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- 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
|
||||||
@@ -466,7 +403,7 @@ jobs:
|
|||||||
{ 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 },
|
||||||
{ name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static },
|
{ name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static },
|
||||||
{ name: RISC-V, xcc_pkg: gcc-riscv64-linux-gnu, xcc: riscv64-linux-gnu-gcc, xemu_pkg: qemu-system-riscv64,xemu: qemu-riscv64-static },
|
{ name: RISC-V, xcc_pkg: gcc-14-riscv64-linux-gnu, xcc: riscv64-linux-gnu-gcc-14, xemu_pkg: qemu-system-riscv64,xemu: qemu-riscv64-static },
|
||||||
{ name: M68K, xcc_pkg: gcc-m68k-linux-gnu, xcc: m68k-linux-gnu-gcc, xemu_pkg: qemu-system-m68k, xemu: qemu-m68k-static },
|
{ name: M68K, xcc_pkg: gcc-m68k-linux-gnu, xcc: m68k-linux-gnu-gcc, xemu_pkg: qemu-system-m68k, xemu: qemu-m68k-static },
|
||||||
{ name: SPARC, xcc_pkg: gcc-sparc64-linux-gnu, xcc: sparc64-linux-gnu-gcc, xemu_pkg: qemu-system-sparc, xemu: qemu-sparc64-static },
|
{ name: SPARC, xcc_pkg: gcc-sparc64-linux-gnu, xcc: sparc64-linux-gnu-gcc, xemu_pkg: qemu-system-sparc, xemu: qemu-sparc64-static },
|
||||||
]
|
]
|
||||||
@@ -474,7 +411,7 @@ jobs:
|
|||||||
XCC: ${{ matrix.xcc }}
|
XCC: ${{ matrix.xcc }}
|
||||||
XEMU: ${{ matrix.xemu }}
|
XEMU: ${{ matrix.xemu }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: apt update & install
|
- name: apt update & install
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -496,6 +433,9 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
make clean
|
make clean
|
||||||
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j check
|
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j check
|
||||||
|
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j -C tests test-cli-tests
|
||||||
|
CFLAGS="-O3 -march=armv8.2-a+sve2" LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make -j check
|
||||||
|
CFLAGS="-O3 -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).
|
# 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.
|
# Unfortunately, the standard library provided on Ubuntu 24.04 does not have this feature enabled.
|
||||||
# make clean
|
# make clean
|
||||||
@@ -520,6 +460,9 @@ jobs:
|
|||||||
if: ${{ matrix.name == 'RISC-V' }}
|
if: ${{ matrix.name == 'RISC-V' }}
|
||||||
run: |
|
run: |
|
||||||
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check
|
LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check
|
||||||
|
CFLAGS="-march=rv64gcv -O3" LDFLAGS="-static -DMEM_FORCE_MEMORY_ACCESS=0" CC=$XCC QEMU_SYS="$XEMU -cpu rv64,v=true,vlen=128" make clean check
|
||||||
|
CFLAGS="-march=rv64gcv -O3" LDFLAGS="-static -DMEM_FORCE_MEMORY_ACCESS=0" CC=$XCC QEMU_SYS="$XEMU -cpu rv64,v=true,vlen=256" make clean check
|
||||||
|
CFLAGS="-march=rv64gcv -O3" LDFLAGS="-static -DMEM_FORCE_MEMORY_ACCESS=0" CC=$XCC QEMU_SYS="$XEMU -cpu rv64,v=true,vlen=512" make clean check
|
||||||
- name: M68K
|
- name: M68K
|
||||||
if: ${{ matrix.name == 'M68K' }}
|
if: ${{ matrix.name == 'M68K' }}
|
||||||
run: |
|
run: |
|
||||||
@@ -543,8 +486,8 @@ jobs:
|
|||||||
run:
|
run:
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0
|
- uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # tag=v2.31.1
|
||||||
with:
|
with:
|
||||||
msystem: ${{ matrix.msystem }}
|
msystem: ${{ matrix.msystem }}
|
||||||
install: make diffutils
|
install: make diffutils
|
||||||
@@ -579,9 +522,9 @@ jobs:
|
|||||||
platform: [x64, Win32]
|
platform: [x64, Win32]
|
||||||
configuration: [Release]
|
configuration: [Release]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Add MSBuild to PATH
|
- name: Add MSBuild to PATH
|
||||||
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # tag=v2.0.0
|
uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # tag=v3.0.0
|
||||||
- name: Build and run tests
|
- name: Build and run tests
|
||||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||||
env:
|
env:
|
||||||
@@ -600,8 +543,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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- uses: cygwin/cygwin-install-action@f61179d72284ceddc397ed07ddb444d82bf9e559 # tag=v5
|
- uses: cygwin/cygwin-install-action@3f0a3f9f988f7e96b8c18098ae05eaec175f5b52 # tag=v6
|
||||||
with:
|
with:
|
||||||
platform: x86_64
|
platform: x86_64
|
||||||
packages: >-
|
packages: >-
|
||||||
@@ -632,7 +575,7 @@ jobs:
|
|||||||
container:
|
container:
|
||||||
image: debian:testing
|
image: debian:testing
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
apt -y update
|
apt -y update
|
||||||
@@ -647,7 +590,7 @@ jobs:
|
|||||||
versions-compatibility:
|
versions-compatibility:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Versions Compatibility Test
|
- name: Versions Compatibility Test
|
||||||
run: |
|
run: |
|
||||||
make -C tests versionsTest
|
make -C tests versionsTest
|
||||||
@@ -655,7 +598,7 @@ jobs:
|
|||||||
clangbuild:
|
clangbuild:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: make clangbuild
|
- name: make clangbuild
|
||||||
run: |
|
run: |
|
||||||
make clangbuild
|
make clangbuild
|
||||||
@@ -663,7 +606,7 @@ jobs:
|
|||||||
gcc-pgo:
|
gcc-pgo:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Build PGO Zstd with GCC
|
- name: Build PGO Zstd with GCC
|
||||||
env:
|
env:
|
||||||
CC: gcc
|
CC: gcc
|
||||||
@@ -674,7 +617,7 @@ jobs:
|
|||||||
clang-pgo:
|
clang-pgo:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Build PGO Zstd with Clang
|
- name: Build PGO Zstd with Clang
|
||||||
env:
|
env:
|
||||||
CC: clang
|
CC: clang
|
||||||
@@ -684,10 +627,21 @@ jobs:
|
|||||||
make -C programs zstd-pgo
|
make -C programs zstd-pgo
|
||||||
./programs/zstd -b
|
./programs/zstd -b
|
||||||
|
|
||||||
|
musl-build:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.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@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: Build Zstd
|
- name: Build Zstd
|
||||||
run: |
|
run: |
|
||||||
make -j zstd V=1
|
make -j zstd V=1
|
||||||
@@ -718,8 +672,9 @@ jobs:
|
|||||||
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
|
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
|
sudo apt-get update
|
||||||
sudo apt-get install -y intel-basekit intel-hpckit
|
sudo apt-get install -y intel-basekit intel-hpckit
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- name: make check
|
- name: make check
|
||||||
run: |
|
run: |
|
||||||
source /opt/intel/oneapi/setvars.sh
|
source /opt/intel/oneapi/setvars.sh
|
||||||
make CC=icx check
|
make CC=icx check
|
||||||
|
make CC=icx -C tests test-cli-tests
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
regression-test:
|
regression-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6.0.2
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev
|
run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev
|
||||||
- name: Regression Test
|
- name: Regression Test
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
|
|
||||||
- name: Archive
|
- name: Archive
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
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@v6.0.2
|
||||||
|
|
||||||
|
- 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@v6.0.2
|
||||||
|
|
||||||
|
- 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
|
||||||
@@ -27,12 +27,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: "Run analysis"
|
- name: "Run analysis"
|
||||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0
|
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # tag=v2.4.1
|
||||||
with:
|
with:
|
||||||
results_file: results.sarif
|
results_file: results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
@@ -51,7 +51,7 @@ jobs:
|
|||||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||||
# format to the repository Actions tab.
|
# format to the repository Actions tab.
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v7.0.1
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
@@ -59,6 +59,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # tag=v3.28.9
|
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # tag=v4.36.2
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: windows-artifacts
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ test_artifacts, win_artifacts ]
|
branches: [ test_artifacts, win_artifacts, release ]
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
- published
|
- published
|
||||||
@@ -11,48 +11,109 @@ permissions: read-all
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
windows-artifacts:
|
windows-artifacts:
|
||||||
# see https://ariya.io/2020/07/on-github-actions-with-msys2
|
permissions:
|
||||||
runs-on: windows-latest
|
contents: write # to fetch code and upload artifacts
|
||||||
# see https://github.com/msys2/setup-msys2
|
# For msys2, see https://ariya.io/2020/07/on-github-actions-with-msys2
|
||||||
|
runs-on: ${{ matrix.shell == 'cmake' && 'windows-11-arm' || 'windows-latest' }}
|
||||||
strategy:
|
strategy:
|
||||||
|
# For msys2, see https://github.com/msys2/setup-msys2
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- { msystem: mingw64, env: x86_64, ziparch: win64 }
|
- { msystem: mingw64, env: x86_64, ziparch: win64, shell: msys2 }
|
||||||
- { msystem: mingw32, env: i686, ziparch: win32 }
|
- { msystem: mingw32, env: i686, ziparch: win32, shell: msys2 }
|
||||||
|
- { msystem: null, env: arm64, ziparch: win-arm64, shell: cmake }
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: msys2 {0}
|
shell: ${{ matrix.shell == 'cmake' && 'pwsh' || 'msys2 {0}' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||||
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0
|
|
||||||
with:
|
|
||||||
msystem: ${{ matrix.msystem }}
|
|
||||||
install: make zlib git p7zip mingw-w64-${{matrix.env}}-gcc
|
|
||||||
update: true
|
|
||||||
|
|
||||||
- name: display versions
|
# MSYS2 setup
|
||||||
run: |
|
- uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # tag=v2.31.1
|
||||||
make -v
|
if: matrix.shell == 'msys2'
|
||||||
cc -v
|
with:
|
||||||
|
msystem: ${{ matrix.msystem }}
|
||||||
|
install: make p7zip git mingw-w64-${{matrix.env}}-gcc
|
||||||
|
update: true
|
||||||
|
|
||||||
- name: Building zlib to static link
|
- name: display versions (MSYS2)
|
||||||
run: |
|
if: matrix.shell == 'msys2'
|
||||||
git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib
|
run: |
|
||||||
make -C zlib -f win32/Makefile.gcc libz.a
|
make -v
|
||||||
|
cc -v
|
||||||
|
|
||||||
- name: Building zstd programs
|
- name: display versions (CMake)
|
||||||
run: |
|
if: matrix.shell == 'cmake'
|
||||||
CPPFLAGS=-I../zlib LDFLAGS=../zlib/libz.a make -j allzstd MOREFLAGS=-static V=1
|
run: |
|
||||||
|
cmake --version
|
||||||
|
|
||||||
- name: Create artifacts
|
# Build dependencies (MSYS2 only)
|
||||||
run: |
|
- name: Building zlib to static link
|
||||||
./lib/dll/example/build_package.bat
|
if: matrix.shell == 'msys2'
|
||||||
mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
|
run: |
|
||||||
7z a -tzip -mx9 zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
|
git clone --depth 1 --branch v1.3.1 https://github.com/madler/zlib
|
||||||
cd ..
|
make -C zlib -f win32/Makefile.gcc libz.a
|
||||||
|
|
||||||
- name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip
|
- name: Building lz4 to static link
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1
|
if: matrix.shell == 'msys2'
|
||||||
with:
|
run: |
|
||||||
path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip
|
git clone --depth 1 --branch v1.10.0 https://github.com/lz4/lz4
|
||||||
name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip
|
# 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
|
||||||
|
|
||||||
|
# Build zstd
|
||||||
|
- name: Building zstd programs
|
||||||
|
if: matrix.shell == 'msys2'
|
||||||
|
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"
|
||||||
|
|
||||||
|
- name: Build zstd (CMake ARM64)
|
||||||
|
if: matrix.shell == 'cmake'
|
||||||
|
run: |
|
||||||
|
cd build\cmake
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake.exe -G "Visual Studio 17 2022" -A ARM64 -DCMAKE_BUILD_TYPE=Release -DZSTD_BUILD_PROGRAMS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=ON ..
|
||||||
|
cmake.exe --build . --config Release --parallel
|
||||||
|
|
||||||
|
- name: Create artifacts (MSYS2)
|
||||||
|
if: matrix.shell == 'msys2'
|
||||||
|
run: |
|
||||||
|
./lib/dll/example/build_package.bat || exit 1
|
||||||
|
mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
|
||||||
|
|
||||||
|
- name: Create artifacts (CMake)
|
||||||
|
if: matrix.shell == 'cmake'
|
||||||
|
run: |
|
||||||
|
.\lib\dll\example\build_package.bat
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit 1 }
|
||||||
|
mv bin/ zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
|
||||||
|
|
||||||
|
- name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip for manual inspection
|
||||||
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v7.0.1
|
||||||
|
with:
|
||||||
|
compression-level: 9 # maximum compression
|
||||||
|
if-no-files-found: error # defaults to `warn`
|
||||||
|
path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
|
||||||
|
name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}
|
||||||
|
|
||||||
|
- name: Package artifact for upload (MSYS2)
|
||||||
|
if: matrix.shell == 'msys2'
|
||||||
|
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: Package artifact for upload (CMake)
|
||||||
|
if: matrix.shell == 'cmake'
|
||||||
|
run: |
|
||||||
|
Compress-Archive -Path "zstd-${{ github.ref_name }}-${{ matrix.ziparch }}" -DestinationPath "zstd-${{ github.ref_name }}-${{ matrix.ziparch }}.zip" -CompressionLevel Optimal
|
||||||
|
|
||||||
|
- 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
|
||||||
+11
-10
@@ -22,16 +22,6 @@ zstdmt
|
|||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
# Test artefacts
|
|
||||||
tmp*
|
|
||||||
*.zst
|
|
||||||
*.zstd
|
|
||||||
dictionary.
|
|
||||||
dictionary
|
|
||||||
NUL
|
|
||||||
cmakebuild/
|
|
||||||
install/
|
|
||||||
|
|
||||||
# Build artefacts
|
# Build artefacts
|
||||||
contrib/linux-kernel/linux/
|
contrib/linux-kernel/linux/
|
||||||
projects/
|
projects/
|
||||||
@@ -40,6 +30,17 @@ bin/
|
|||||||
buck-out/
|
buck-out/
|
||||||
build-*
|
build-*
|
||||||
*.gcda
|
*.gcda
|
||||||
|
cmakebuild/
|
||||||
|
cmake-build/
|
||||||
|
|
||||||
|
# Test artefacts
|
||||||
|
tmp*
|
||||||
|
*.zst
|
||||||
|
*.zstd
|
||||||
|
dictionary.
|
||||||
|
dictionary
|
||||||
|
NUL
|
||||||
|
install/
|
||||||
|
|
||||||
# IDE
|
# IDE
|
||||||
.clang_complete
|
.clang_complete
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
v1.6.0 (Dec 2025)
|
||||||
|
api: legacy format support is now disabled by default
|
||||||
|
build: `ZSTD_LEGACY_SUPPORT` defaults to `0` in Makefile and CMake
|
||||||
|
|
||||||
V1.5.7 (Feb 2025)
|
V1.5.7 (Feb 2025)
|
||||||
fix: compression bug in 32-bit mode associated with long-lasting sessions
|
fix: compression bug in 32-bit mode associated with long-lasting sessions
|
||||||
api: new method `ZSTD_compressSequencesAndLiterals()` (#4217, #4232)
|
api: new method `ZSTD_compressSequencesAndLiterals()` (#4217, #4232)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
# Thin wrapper so `cmake -S .` behaves like `cmake -S build/cmake`.
|
||||||
|
# Policy lives in build/cmake; keep parent project language-less.
|
||||||
|
project(zstd-superbuild LANGUAGES NONE)
|
||||||
|
|
||||||
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||||
|
message(FATAL_ERROR "In-source builds are not supported. Specify -B <build-dir>.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(build/cmake)
|
||||||
+6
-1
@@ -373,7 +373,12 @@ counter `L1-dcache-load-misses`
|
|||||||
|
|
||||||
#### Visual Studio
|
#### Visual Studio
|
||||||
|
|
||||||
TODO
|
Build Zstd with symbols first (for example `cmake -B build -S build/cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo && ninja -C build zstd`) so the profiler resolves call stacks.
|
||||||
|
|
||||||
|
* Launch Visual Studio’s Performance Profiler (`Alt+F2`), enable CPU Usage (optionally Instrumentation), and point it at the `programs/zstd` benchmark you want to run.
|
||||||
|
* If you prefer to start the benchmark from a terminal, use “Attach to running process” to latch onto it mid-run; keep frame pointers (`-fno-omit-frame-pointer`) for clean stacks.
|
||||||
|
* When you stop the capture, review the call tree, hot path, and annotated source panes
|
||||||
|
* Microsoft’s [Performance Profiling docs](https://learn.microsoft.com/en-us/visualstudio/profiling/?view=vs-2022) cover deeper sampling, ETW, and collection options if required.
|
||||||
|
|
||||||
## Issues
|
## Issues
|
||||||
We use GitHub issues to track public bugs. Please ensure your description is
|
We use GitHub issues to track public bugs. Please ensure your description is
|
||||||
|
|||||||
@@ -144,10 +144,13 @@ clean:
|
|||||||
$(Q)$(RM) -r lz4 cmakebuild mesonbuild install
|
$(Q)$(RM) -r lz4 cmakebuild mesonbuild install
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|
||||||
|
LIBZSTD_MK_DIR = $(ZSTDDIR)
|
||||||
|
include $(LIBZSTD_MK_DIR)/install_oses.mk # UNAME, INSTALL_OS_LIST
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# 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 $(INSTALL_OS_LIST),$(UNAME)))
|
||||||
|
|
||||||
HOST_OS = POSIX
|
HOST_OS = POSIX
|
||||||
|
|
||||||
@@ -351,7 +354,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 lz4install
|
.PHONY: ppcinstall arminstall valgrindinstall libc6install gcc6install gcc7install gcc8install gpp6install clang38install
|
||||||
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,10 +382,6 @@ 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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ a list of known ports and bindings is provided on [Zstandard homepage](https://f
|
|||||||
|
|
||||||
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 featuring a Core i7-9700K CPU @ 4.9GHz
|
||||||
and running Ubuntu 20.04 (`Linux ubu20 5.15.0-101-generic`),
|
and running Ubuntu 24.04 (`Linux 6.8.0-53-generic`),
|
||||||
using [lzbench], an open-source in-memory benchmark by @inikep
|
using [lzbench], an open-source in-memory benchmark by @inikep
|
||||||
compiled with [gcc] 9.4.0,
|
compiled with [gcc] 14.2.0,
|
||||||
on the [Silesia compression corpus].
|
on the [Silesia compression corpus].
|
||||||
|
|
||||||
[lzbench]: https://github.com/inikep/lzbench
|
[lzbench]: https://github.com/inikep/lzbench
|
||||||
@@ -41,16 +41,16 @@ on the [Silesia compression corpus].
|
|||||||
|
|
||||||
| Compressor name | Ratio | Compression| Decompress.|
|
| Compressor name | Ratio | Compression| Decompress.|
|
||||||
| --------------- | ------| -----------| ---------- |
|
| --------------- | ------| -----------| ---------- |
|
||||||
| **zstd 1.5.6 -1** | 2.887 | 510 MB/s | 1580 MB/s |
|
| **zstd 1.5.7 -1** | 2.896 | 510 MB/s | 1550 MB/s |
|
||||||
| [zlib] 1.2.11 -1 | 2.743 | 95 MB/s | 400 MB/s |
|
| brotli 1.1.0 -1 | 2.883 | 290 MB/s | 425 MB/s |
|
||||||
| brotli 1.0.9 -0 | 2.702 | 395 MB/s | 430 MB/s |
|
| [zlib] 1.3.1 -1 | 2.743 | 105 MB/s | 390 MB/s |
|
||||||
| **zstd 1.5.6 --fast=1** | 2.437 | 545 MB/s | 1890 MB/s |
|
| **zstd 1.5.7 --fast=1** | 2.439 | 545 MB/s | 1850 MB/s |
|
||||||
| **zstd 1.5.6 --fast=3** | 2.239 | 650 MB/s | 2000 MB/s |
|
| quicklz 1.5.0 -1 | 2.238 | 520 MB/s | 750 MB/s |
|
||||||
| quicklz 1.5.0 -1 | 2.238 | 525 MB/s | 750 MB/s |
|
| **zstd 1.5.7 --fast=4** | 2.146 | 665 MB/s | 2050 MB/s |
|
||||||
| lzo1x 2.10 -1 | 2.106 | 650 MB/s | 825 MB/s |
|
| lzo1x 2.10 -1 | 2.106 | 650 MB/s | 780 MB/s |
|
||||||
| [lz4] 1.9.4 | 2.101 | 700 MB/s | 4000 MB/s |
|
| [lz4] 1.10.0 | 2.101 | 675 MB/s | 3850 MB/s |
|
||||||
| lzf 3.6 -1 | 2.077 | 420 MB/s | 830 MB/s |
|
| snappy 1.2.1 | 2.089 | 520 MB/s | 1500 MB/s |
|
||||||
| snappy 1.1.9 | 2.073 | 530 MB/s | 1660 MB/s |
|
| lzf 3.6 -1 | 2.077 | 410 MB/s | 820 MB/s |
|
||||||
|
|
||||||
[zlib]: https://www.zlib.net/
|
[zlib]: https://www.zlib.net/
|
||||||
[lz4]: https://lz4.github.io/lz4/
|
[lz4]: https://lz4.github.io/lz4/
|
||||||
@@ -120,33 +120,40 @@ Dictionary gains are mostly effective in the first few KB. Then, the compression
|
|||||||
|
|
||||||
## Build instructions
|
## Build instructions
|
||||||
|
|
||||||
`make` is the officially maintained build system of this project.
|
`make` is the main build system of this project.
|
||||||
All other build systems are "compatible" and 3rd-party maintained,
|
It is the reference, and other build systems are periodically updated to stay compatible.
|
||||||
they may feature small differences in advanced options.
|
However, small drifts and feature differences can be present, since perfect synchronization is difficult.
|
||||||
When your system allows it, prefer using `make` to build `zstd` and `libzstd`.
|
For this reason, when your build system allows it, prefer employing `make`.
|
||||||
|
|
||||||
### Makefile
|
### Makefile
|
||||||
|
|
||||||
If your system is compatible with standard `make` (or `gmake`),
|
Assuming your system supports standard `make` (or `gmake`),
|
||||||
invoking `make` in root directory will generate `zstd` cli in root directory.
|
just invoking `make` in root directory generates `zstd` cli at root,
|
||||||
It will also create `libzstd` into `lib/`.
|
and also generates `libzstd` into `lib/`.
|
||||||
|
|
||||||
Other available options include:
|
Other standard targets include:
|
||||||
- `make install` : create and install zstd cli, library and man pages
|
- `make install` : install zstd cli, library and man pages
|
||||||
- `make check` : create and run `zstd`, test its behavior on local platform
|
- `make check` : run `zstd`, test its essential behavior on local platform
|
||||||
|
|
||||||
The `Makefile` follows the [GNU Standard Makefile conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html),
|
The `Makefile` follows the [GNU Standard Makefile conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html),
|
||||||
allowing staged install, standard flags, directory variables and command variables.
|
allowing staged install, standard compilation flags, directory variables and command variables.
|
||||||
|
|
||||||
For advanced use cases, specialized compilation flags which control binary generation
|
For advanced use cases, specialized flags which control binary generation and installation paths are documented
|
||||||
are documented in [`lib/README.md`](lib/README.md#modular-build) for the `libzstd` library
|
in [`lib/README.md`](lib/README.md#modular-build) for the `libzstd` library
|
||||||
and in [`programs/README.md`](programs/README.md#compilation-variables) for the `zstd` CLI.
|
and in [`programs/README.md`](programs/README.md#compilation-variables) for the `zstd` CLI.
|
||||||
|
|
||||||
### cmake
|
### cmake
|
||||||
|
|
||||||
A `cmake` project generator is provided within `build/cmake`.
|
A `cmake` project generator is available for generating Makefiles or other build scripts
|
||||||
It can generate Makefiles or other build scripts
|
to create the `zstd` binary as well as `libzstd` dynamic and static libraries.
|
||||||
to create `zstd` binary, and `libzstd` dynamic and static libraries.
|
The repository root now contains a minimal `CMakeLists.txt` that forwards to `build/cmake`,
|
||||||
|
so you can configure the project with a standard `cmake -S .` invocation,
|
||||||
|
while the historical `cmake -S build/cmake` entry point remains fully supported.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake -S . -B build-cmake
|
||||||
|
cmake --build build-cmake
|
||||||
|
```
|
||||||
|
|
||||||
By default, `CMAKE_BUILD_TYPE` is set to `Release`.
|
By default, `CMAKE_BUILD_TYPE` is set to `Release`.
|
||||||
|
|
||||||
@@ -156,7 +163,7 @@ By default, `CMAKE_BUILD_TYPE` is set to `Release`.
|
|||||||
To perform a Fat/Universal2 build and install use the following commands:
|
To perform a Fat/Universal2 build and install use the following commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cmake -B build-cmake-debug -S build/cmake -G Ninja -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h;arm64"
|
cmake -S . -B build-cmake-debug -G Ninja -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h;arm64"
|
||||||
cd build-cmake-debug
|
cd build-cmake-debug
|
||||||
ninja
|
ninja
|
||||||
sudo ninja install
|
sudo ninja install
|
||||||
@@ -198,10 +205,11 @@ If the version is out of date, please [create an issue or pull request](https://
|
|||||||
### Visual Studio (Windows)
|
### Visual Studio (Windows)
|
||||||
|
|
||||||
Going into `build` directory, you will find additional possibilities:
|
Going into `build` directory, you will find additional possibilities:
|
||||||
- Projects for Visual Studio 2005, 2008 and 2010.
|
- Projects for Visual Studio 2008 and 2010.
|
||||||
+ VS2010 project is compatible with VS2012, VS2013, VS2015 and VS2017.
|
+ VS2010 project is compatible with VS2012, VS2013, VS2015 and VS2017.
|
||||||
- Automated build scripts for Visual compiler by [@KrzysFR](https://github.com/KrzysFR), in `build/VS_scripts`,
|
- Automated build scripts for Visual compiler by [@KrzysFR](https://github.com/KrzysFR), in `build/VS_scripts`,
|
||||||
which will build `zstd` cli and `libzstd` library without any need to open Visual Studio solution.
|
which will build `zstd` cli and `libzstd` library without any need to open Visual Studio solution.
|
||||||
|
- It is now recommended to generate Visual Studio solutions from `cmake`
|
||||||
|
|
||||||
### Buck
|
### Buck
|
||||||
|
|
||||||
@@ -210,7 +218,7 @@ The output binary will be in `buck-out/gen/programs/`.
|
|||||||
|
|
||||||
### Bazel
|
### Bazel
|
||||||
|
|
||||||
You easily can integrate zstd into your Bazel project by using the module hosted on the [Bazel Central Repository](https://registry.bazel.build/modules/zstd).
|
You can integrate zstd into your Bazel project by using the module hosted on the [Bazel Central Repository](https://registry.bazel.build/modules/zstd).
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
@@ -221,9 +229,9 @@ For information on CI testing, please refer to `TESTING.md`.
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Zstandard is currently deployed within Facebook and many other large cloud infrastructures.
|
Zstandard is deployed within Meta and many other large cloud infrastructures,
|
||||||
It is run continuously to compress large amounts of data in multiple formats and use cases.
|
to compress humongous amounts of data in various formats and use cases.
|
||||||
Zstandard is considered safe for production environments.
|
It is also continuously fuzzed for security issues by Google's [oss-fuzz](https://github.com/google/oss-fuzz/tree/master/projects/zstd) program.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@@ -232,6 +240,5 @@ Zstandard is dual-licensed under [BSD](LICENSE) OR [GPLv2](COPYING).
|
|||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
The `dev` branch is the one where all contributions are merged before reaching `release`.
|
The `dev` branch is the one where all contributions are merged before reaching `release`.
|
||||||
If you plan to propose a patch, please commit into the `dev` branch, or its own feature branch.
|
|
||||||
Direct commit to `release` are not permitted.
|
Direct commit to `release` are not permitted.
|
||||||
For more information, please read [CONTRIBUTING](CONTRIBUTING.md).
|
For more information, please read [CONTRIBUTING](CONTRIBUTING.md).
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
||||||
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
||||||
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
||||||
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -275,7 +275,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\lib\dictBuilder;$(SolutionDir)..\..\lib\compress"
|
||||||
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE"
|
||||||
MinimalRebuild="true"
|
MinimalRebuild="true"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="3"
|
RuntimeLibrary="3"
|
||||||
@@ -272,7 +272,7 @@
|
|||||||
EnableIntrinsicFunctions="true"
|
EnableIntrinsicFunctions="true"
|
||||||
OmitFramePointers="true"
|
OmitFramePointers="true"
|
||||||
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
AdditionalIncludeDirectories="$(SolutionDir)..\..\lib;$(SolutionDir)..\..\lib\common;$(SolutionDir)..\..\lib\legacy;$(SolutionDir)..\..\programs\legacy;$(SolutionDir)..\..\lib\dictBuilder"
|
||||||
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE"
|
PreprocessorDefinitions="ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
EnableFunctionLevelLinking="true"
|
EnableFunctionLevelLinking="true"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
|
|||||||
@@ -169,7 +169,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_DLL_EXPORT=1;ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|||||||
@@ -162,7 +162,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
@@ -201,7 +201,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
@@ -222,7 +222,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|||||||
@@ -187,7 +187,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<EnableEnhancedInstructionSet>$(InstructionSet)</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>$(InstructionSet)</EnableEnhancedInstructionSet>
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<EnableEnhancedInstructionSet>$(InstructionSet)</EnableEnhancedInstructionSet>
|
<EnableEnhancedInstructionSet>$(InstructionSet)</EnableEnhancedInstructionSet>
|
||||||
@@ -223,7 +223,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
@@ -245,7 +245,7 @@
|
|||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=5;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>ZSTD_MULTITHREAD=1;ZSTD_LEGACY_SUPPORT=0;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<TreatWarningAsError>false</TreatWarningAsError>
|
<TreatWarningAsError>false</TreatWarningAsError>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
|
|||||||
+39
-186
@@ -9,220 +9,73 @@
|
|||||||
|
|
||||||
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.10 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
|
# Setup CMake environment
|
||||||
set(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3")
|
#-----------------------------------------------------------------------------
|
||||||
set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13") #Policies never changed at PATCH level
|
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||||
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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
set(ZSTD_SHORT_VERSION "${zstd_VERSION_MAJOR}.${zstd_VERSION_MINOR}")
|
#-----------------------------------------------------------------------------
|
||||||
set(ZSTD_FULL_VERSION "${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_FULL_VERSION}"
|
||||||
LANGUAGES C # Main library is in C
|
LANGUAGES C # Main library is in C and ASM, ASM is enabled conditionally
|
||||||
ASM # And ASM
|
HOMEPAGE_URL "${zstd_HOMEPAGE_URL}"
|
||||||
CXX # Testing contributed code also utilizes CXX
|
DESCRIPTION "${zstd_DESCRIPTION}"
|
||||||
)
|
)
|
||||||
|
|
||||||
message(STATUS "ZSTD VERSION: ${zstd_VERSION}")
|
#-----------------------------------------------------------------------------
|
||||||
set(zstd_HOMEPAGE_URL "https://facebook.github.io/zstd")
|
# Build type configuration
|
||||||
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 the possible values of build type for cmake-gui
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# Include standard modules
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Add extra compilation flags
|
# Display installation information
|
||||||
#-----------------------------------------------------------------------------
|
|
||||||
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}")
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Options
|
# Configure build 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 (APPLE)
|
|
||||||
option(ZSTD_FRAMEWORK "Build as Apple Frameworks" OFF)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (ANDROID)
|
|
||||||
set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT OFF)
|
|
||||||
# Old versions of bionic libc don't have fseeko/ftello
|
|
||||||
if ((NOT ${ANDROID_PLATFORM_LEVEL}) OR ${ANDROID_PLATFORM_LEVEL} VERSION_LESS 24)
|
|
||||||
message(STATUS "Setting compile definitions for old Android API")
|
|
||||||
add_compile_definitions(LIBC_NO_FSEEKO)
|
|
||||||
endif ()
|
|
||||||
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 ()
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# External dependencies
|
# Configure compilation flags
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Define a function to handle special thread settings for HP-UX
|
include(AddZstdCompilationFlags)
|
||||||
# See https://github.com/facebook/zstd/pull/3862 for details.
|
ADD_ZSTD_COMPILATION_FLAGS(ON ZSTD_ENABLE_CXX ON)
|
||||||
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 ()
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Add source directories
|
# Configure dependencies
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
add_subdirectory(lib)
|
include(ZstdDependencies)
|
||||||
|
|
||||||
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 ()
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Add clean-all target
|
# Configure build targets
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
add_custom_target(clean-all
|
include(ZstdBuild)
|
||||||
COMMAND ${CMAKE_BUILD_TOOL} clean
|
|
||||||
COMMAND rm -rf ${CMAKE_BINARY_DIR}/
|
|
||||||
)
|
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# Generate Package Config files
|
# Configure package generation
|
||||||
#
|
|
||||||
# This section is based on the boiler plate code from:
|
|
||||||
# https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
include(CMakePackageConfigHelpers)
|
include(ZstdPackage)
|
||||||
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}
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
include(CheckCXXCompilerFlag)
|
|
||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
|
if(CMAKE_CXX_COMPILER)
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
||||||
set(ZSTD_HAVE_CHECK_LINKER_FLAG true)
|
set(ZSTD_HAVE_CHECK_LINKER_FLAG true)
|
||||||
@@ -21,7 +23,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)
|
if (_CXX AND CMAKE_CXX_COMPILER)
|
||||||
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)
|
||||||
@@ -49,7 +51,7 @@ function(EnableCompilerFlag _flag _C _CXX _LD)
|
|||||||
endif ()
|
endif ()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
macro(ADD_ZSTD_COMPILATION_FLAGS)
|
macro(ADD_ZSTD_COMPILATION_FLAGS _C _CXX _LD)
|
||||||
# We set ZSTD_HAS_NOEXECSTACK if we are certain we've set all the required
|
# We set ZSTD_HAS_NOEXECSTACK if we are certain we've set all the required
|
||||||
# compiler flags to mark the stack as non-executable.
|
# compiler flags to mark the stack as non-executable.
|
||||||
set(ZSTD_HAS_NOEXECSTACK false)
|
set(ZSTD_HAS_NOEXECSTACK false)
|
||||||
@@ -63,26 +65,26 @@ macro(ADD_ZSTD_COMPILATION_FLAGS)
|
|||||||
# EnableCompilerFlag("-std=c99" true false) # Set C compilation to c99 standard
|
# EnableCompilerFlag("-std=c99" true false) # Set C compilation to c99 standard
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC)
|
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC)
|
||||||
# clang-cl normally maps -Wall to -Weverything.
|
# clang-cl normally maps -Wall to -Weverything.
|
||||||
EnableCompilerFlag("/clang:-Wall" true true false)
|
EnableCompilerFlag("/clang:-Wall" _C _CXX false)
|
||||||
else ()
|
else ()
|
||||||
EnableCompilerFlag("-Wall" true true false)
|
EnableCompilerFlag("-Wall" _C _CXX false)
|
||||||
endif ()
|
endif ()
|
||||||
EnableCompilerFlag("-Wextra" true true false)
|
EnableCompilerFlag("-Wextra" _C _CXX false)
|
||||||
EnableCompilerFlag("-Wundef" true true false)
|
EnableCompilerFlag("-Wundef" _C _CXX false)
|
||||||
EnableCompilerFlag("-Wshadow" true true false)
|
EnableCompilerFlag("-Wshadow" _C _CXX false)
|
||||||
EnableCompilerFlag("-Wcast-align" true true false)
|
EnableCompilerFlag("-Wcast-align" _C _CXX false)
|
||||||
EnableCompilerFlag("-Wcast-qual" true true false)
|
EnableCompilerFlag("-Wcast-qual" _C _CXX false)
|
||||||
EnableCompilerFlag("-Wstrict-prototypes" true false false)
|
EnableCompilerFlag("-Wstrict-prototypes" _C false false)
|
||||||
# Enable asserts in Debug mode
|
# Enable asserts in Debug mode
|
||||||
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
EnableCompilerFlag("-DDEBUGLEVEL=1" true true false)
|
EnableCompilerFlag("-DDEBUGLEVEL=1" _C _CXX false)
|
||||||
endif ()
|
endif ()
|
||||||
# Add noexecstack flags
|
# Add noexecstack flags
|
||||||
# LDFLAGS
|
# LDFLAGS
|
||||||
EnableCompilerFlag("-Wl,-z,noexecstack" false false true)
|
EnableCompilerFlag("-Wl,-z,noexecstack" false false _LD)
|
||||||
# CFLAGS & CXXFLAGS
|
# CFLAGS & CXXFLAGS
|
||||||
EnableCompilerFlag("-Qunused-arguments" true true false)
|
EnableCompilerFlag("-Qunused-arguments" _C _CXX false)
|
||||||
EnableCompilerFlag("-Wa,--noexecstack" true true false)
|
EnableCompilerFlag("-Wa,--noexecstack" _C _CXX false)
|
||||||
# NOTE: Using 3 nested ifs because the variables are sometimes
|
# NOTE: Using 3 nested ifs because the variables are sometimes
|
||||||
# empty if the condition is false, and sometimes equal to false.
|
# empty if the condition is false, and sometimes equal to false.
|
||||||
# This implicitly converts them to truthy values. There may be
|
# This implicitly converts them to truthy values. There may be
|
||||||
@@ -99,15 +101,15 @@ macro(ADD_ZSTD_COMPILATION_FLAGS)
|
|||||||
|
|
||||||
set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)")
|
set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)")
|
||||||
if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION)
|
if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION)
|
||||||
EnableCompilerFlag("/MP" true true false)
|
EnableCompilerFlag("/MP" _C _CXX false)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# UNICODE SUPPORT
|
# UNICODE SUPPORT
|
||||||
EnableCompilerFlag("/D_UNICODE" true true false)
|
EnableCompilerFlag("/D_UNICODE" _C _CXX false)
|
||||||
EnableCompilerFlag("/DUNICODE" true true false)
|
EnableCompilerFlag("/DUNICODE" _C _CXX false)
|
||||||
# Enable asserts in Debug mode
|
# Enable asserts in Debug mode
|
||||||
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
EnableCompilerFlag("/DDEBUGLEVEL=1" true true false)
|
EnableCompilerFlag("/DDEBUGLEVEL=1" _C _CXX false)
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# ################################################################
|
||||||
|
# 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"
|
||||||
|
)
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# ################################################################
|
||||||
|
# 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()
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# ################################################################
|
||||||
|
# ZSTD Build Options Configuration
|
||||||
|
# ################################################################
|
||||||
|
|
||||||
|
# Legacy support configuration (disabled by default)
|
||||||
|
option(ZSTD_LEGACY_SUPPORT "Enable legacy format support" OFF)
|
||||||
|
|
||||||
|
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_)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# ################################################################
|
||||||
|
# ZSTD Package Configuration
|
||||||
|
# ################################################################
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
# Generate version file
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
|
||||||
|
VERSION ${zstd_VERSION}
|
||||||
|
COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configure package for installation
|
||||||
|
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/zstd)
|
||||||
|
|
||||||
|
foreach(target_suffix IN ITEMS "_shared" "_static" "")
|
||||||
|
if(TARGET "libzstd${target_suffix}")
|
||||||
|
# Export targets for build directory
|
||||||
|
export(EXPORT "zstdExports${target_suffix}"
|
||||||
|
FILE "${CMAKE_CURRENT_BINARY_DIR}/zstdTargets${target_suffix}.cmake"
|
||||||
|
NAMESPACE zstd::
|
||||||
|
)
|
||||||
|
# Install exported targets
|
||||||
|
install(EXPORT "zstdExports${target_suffix}"
|
||||||
|
FILE "zstdTargets${target_suffix}.cmake"
|
||||||
|
NAMESPACE zstd::
|
||||||
|
DESTINATION ${ConfigPackageLocation}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# 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}
|
||||||
|
)
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# ################################################################
|
||||||
|
# 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}")
|
||||||
@@ -7,6 +7,15 @@ variables.
|
|||||||
|
|
||||||
## How to build
|
## How to build
|
||||||
|
|
||||||
|
You can configure the project from the repository root thanks to the forwarding
|
||||||
|
`CMakeLists.txt`:
|
||||||
|
```sh
|
||||||
|
cmake -S . -B build-cmake
|
||||||
|
cmake --build build-cmake
|
||||||
|
```
|
||||||
|
The historical workflow that starts configuration from `build/cmake` continues
|
||||||
|
to work as described below.
|
||||||
|
|
||||||
As cmake doesn't support command like `cmake clean`, it's recommended to perform an "out of source build".
|
As cmake doesn't support command like `cmake clean`, it's recommended to perform an "out of source build".
|
||||||
To do this, you can create a new directory and build in it:
|
To do this, you can create a new directory and build in it:
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
# in the COPYING file in the root directory of this source tree).
|
# in the COPYING file in the root directory of this source tree).
|
||||||
# ################################################################
|
# ################################################################
|
||||||
|
|
||||||
project(libzstd C ASM)
|
project(libzstd C) # ASM language is conditionally enabled where supported
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
||||||
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
|
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
|
||||||
@@ -40,6 +40,7 @@ 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.*" AND ${ZSTD_HAS_NOEXECSTACK})
|
||||||
|
enable_language(ASM)
|
||||||
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,9 +98,11 @@ if (ZSTD_LEGACY_SUPPORT)
|
|||||||
${LIBRARY_LEGACY_DIR}/zstd_v07.h)
|
${LIBRARY_LEGACY_DIR}/zstd_v07.h)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC AND NOT (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
|
||||||
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.
|
||||||
@@ -112,7 +115,7 @@ endif()
|
|||||||
|
|
||||||
macro (add_definition target var)
|
macro (add_definition target var)
|
||||||
if (NOT ("${${var}}" STREQUAL ""))
|
if (NOT ("${${var}}" STREQUAL ""))
|
||||||
set_property(TARGET ${target} APPEND PROPERTY COMPILE_DEFINITIONS "${var}=__attribute__((visibility(\"${${var}}\")))")
|
target_compile_definitions(${target} PUBLIC "${var}=__attribute__((visibility(\"${${var}}\")))")
|
||||||
endif ()
|
endif ()
|
||||||
endmacro ()
|
endmacro ()
|
||||||
|
|
||||||
@@ -120,13 +123,11 @@ endmacro ()
|
|||||||
set(PUBLIC_INCLUDE_DIRS ${LIBRARY_DIR})
|
set(PUBLIC_INCLUDE_DIRS ${LIBRARY_DIR})
|
||||||
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /I \"${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)
|
|
||||||
if (ZSTD_BUILD_SHARED)
|
if (ZSTD_BUILD_SHARED)
|
||||||
add_library(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources})
|
add_library(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources})
|
||||||
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)
|
|
||||||
if (ZSTD_MULTITHREAD_SUPPORT)
|
if (ZSTD_MULTITHREAD_SUPPORT)
|
||||||
set_property(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD")
|
target_compile_definitions(libzstd_shared PUBLIC ZSTD_MULTITHREAD)
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_link_libraries(libzstd_shared ${THREADS_LIBS})
|
target_link_libraries(libzstd_shared ${THREADS_LIBS})
|
||||||
endif ()
|
endif ()
|
||||||
@@ -138,9 +139,8 @@ endif ()
|
|||||||
if (ZSTD_BUILD_STATIC)
|
if (ZSTD_BUILD_STATIC)
|
||||||
add_library(libzstd_static STATIC ${Sources} ${Headers})
|
add_library(libzstd_static STATIC ${Sources} ${Headers})
|
||||||
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)
|
|
||||||
if (ZSTD_MULTITHREAD_SUPPORT)
|
if (ZSTD_MULTITHREAD_SUPPORT)
|
||||||
set_property(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_MULTITHREAD")
|
target_compile_definitions(libzstd_static PUBLIC ZSTD_MULTITHREAD)
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_link_libraries(libzstd_static ${THREADS_LIBS})
|
target_link_libraries(libzstd_static ${THREADS_LIBS})
|
||||||
endif ()
|
endif ()
|
||||||
@@ -157,7 +157,6 @@ if (ZSTD_BUILD_SHARED AND NOT ZSTD_BUILD_STATIC)
|
|||||||
endif ()
|
endif ()
|
||||||
add_library(libzstd INTERFACE)
|
add_library(libzstd INTERFACE)
|
||||||
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
||||||
list(APPEND library_targets libzstd)
|
|
||||||
endif ()
|
endif ()
|
||||||
if (ZSTD_BUILD_STATIC AND NOT ZSTD_BUILD_SHARED)
|
if (ZSTD_BUILD_STATIC AND NOT ZSTD_BUILD_SHARED)
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
@@ -165,7 +164,6 @@ if (ZSTD_BUILD_STATIC AND NOT ZSTD_BUILD_SHARED)
|
|||||||
endif ()
|
endif ()
|
||||||
add_library(libzstd INTERFACE)
|
add_library(libzstd INTERFACE)
|
||||||
target_link_libraries(libzstd INTERFACE libzstd_static)
|
target_link_libraries(libzstd INTERFACE libzstd_static)
|
||||||
list(APPEND library_targets libzstd)
|
|
||||||
endif ()
|
endif ()
|
||||||
if (ZSTD_BUILD_SHARED AND ZSTD_BUILD_STATIC)
|
if (ZSTD_BUILD_SHARED AND ZSTD_BUILD_STATIC)
|
||||||
# If both ZSTD_BUILD_SHARED and ZSTD_BUILD_STATIC are set, which is the
|
# If both ZSTD_BUILD_SHARED and ZSTD_BUILD_STATIC are set, which is the
|
||||||
@@ -174,11 +172,9 @@ if (ZSTD_BUILD_SHARED AND ZSTD_BUILD_STATIC)
|
|||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
add_library(libzstd INTERFACE)
|
add_library(libzstd INTERFACE)
|
||||||
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
||||||
list(APPEND library_targets libzstd)
|
|
||||||
else ()
|
else ()
|
||||||
add_library(libzstd INTERFACE)
|
add_library(libzstd INTERFACE)
|
||||||
target_link_libraries(libzstd INTERFACE libzstd_static)
|
target_link_libraries(libzstd INTERFACE libzstd_static)
|
||||||
list(APPEND library_targets libzstd)
|
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
@@ -207,7 +203,7 @@ if (ZSTD_BUILD_SHARED)
|
|||||||
OUTPUT_NAME zstd
|
OUTPUT_NAME zstd
|
||||||
VERSION ${ZSTD_FULL_VERSION}
|
VERSION ${ZSTD_FULL_VERSION}
|
||||||
SOVERSION ${zstd_VERSION_MAJOR})
|
SOVERSION ${zstd_VERSION_MAJOR})
|
||||||
|
|
||||||
if (ZSTD_FRAMEWORK)
|
if (ZSTD_FRAMEWORK)
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
libzstd_shared
|
libzstd_shared
|
||||||
@@ -272,16 +268,20 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" DESTINATION "${CMAKE_INST
|
|||||||
# install target
|
# install target
|
||||||
install(FILES ${PublicHeaders} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
install(FILES ${PublicHeaders} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||||
|
|
||||||
install(TARGETS ${library_targets}
|
foreach(target_suffix IN ITEMS "_shared" "_static" "")
|
||||||
EXPORT zstdExports
|
if(TARGET "libzstd${target_suffix}")
|
||||||
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
install(TARGETS "libzstd${target_suffix}"
|
||||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
EXPORT "zstdExports${target_suffix}"
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime OPTIONAL
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||||
)
|
FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime OPTIONAL
|
||||||
|
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
# uninstall target
|
# uninstall target
|
||||||
if (NOT TARGET uninstall)
|
if (NOT TARGET uninstall)
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ if(@ZSTD_MULTITHREAD_SUPPORT@ AND "@UNIX@")
|
|||||||
find_dependency(Threads)
|
find_dependency(Threads)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
foreach(lib_suffix IN ITEMS "_shared" "_static")
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/zstdTargets${lib_suffix}.cmake" OPTIONAL)
|
||||||
|
endforeach()
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/zstdTargets.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/zstdTargets.cmake")
|
||||||
|
|
||||||
check_required_components("zstd")
|
check_required_components("zstd")
|
||||||
|
|||||||
@@ -127,6 +127,10 @@ libzstd = library('zstd',
|
|||||||
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: join_paths(zstd_rootdir,'lib')) # Do not expose private headers
|
||||||
|
|
||||||
|
if meson.version().version_compare('>=0.54.0')
|
||||||
|
meson.override_dependency('libzstd', libzstd_dep)
|
||||||
|
endif
|
||||||
|
|
||||||
# we link to both:
|
# we link to both:
|
||||||
# - the shared library (for public symbols)
|
# - the shared library (for public symbols)
|
||||||
# - the static library (for private symbols)
|
# - the static library (for private symbols)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
project('zstd',
|
project('zstd',
|
||||||
['c', 'cpp'],
|
['c', 'cpp'],
|
||||||
license: ['BSD', 'GPLv2'],
|
license: 'BSD-3-Clause OR GPL-2.0-only',
|
||||||
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,7 +65,6 @@ 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
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
# Read guidelines from https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting
|
# Read guidelines from https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting
|
||||||
|
|
||||||
option('legacy_level', type: 'integer', min: 0, max: 7, value: 5,
|
option('legacy_level', type: 'integer', min: 0, max: 7, value: 0,
|
||||||
description: 'Support any legacy format: 7 to 1 for v0.7+ to v0.1+')
|
description: 'Support legacy format: 0=disabled, 1-7=support v0.1+ to v0.7+')
|
||||||
option('debug_level', type: 'integer', min: 0, max: 9, value: 1,
|
option('debug_level', type: 'integer', min: 0, max: 9, value: 1,
|
||||||
description: 'Enable run-time debug. See lib/common/debug.h')
|
description: 'Enable run-time debug. See lib/common/debug.h')
|
||||||
option('backtrace', type: 'feature', value: 'disabled',
|
option('backtrace', type: 'feature', value: 'disabled',
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ def valgrindTest(valgrind, datagen, fuzzer, zstd, fullbench):
|
|||||||
|
|
||||||
subprocess.check_call([*VALGRIND_ARGS, datagen, '-g50M'], stdout=subprocess.DEVNULL)
|
subprocess.check_call([*VALGRIND_ARGS, datagen, '-g50M'], stdout=subprocess.DEVNULL)
|
||||||
|
|
||||||
if subprocess.call([*VALGRIND_ARGS, zstd],
|
if subprocess.call([*VALGRIND_ARGS, zstd, '--fake-stdin-is-console'],
|
||||||
stdout=subprocess.DEVNULL) == 0:
|
stdout=subprocess.DEVNULL) == 0:
|
||||||
raise subprocess.SubprocessError('zstd without argument should have failed')
|
raise subprocess.SubprocessError('zstd without argument should have failed')
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ 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;
|
||||||
@@ -96,12 +97,12 @@ int main(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
retn = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTD_freeCCtx(zc);
|
ZSTD_freeCCtx(zc);
|
||||||
free(src);
|
free(src);
|
||||||
free(dst);
|
free(dst);
|
||||||
free(val);
|
free(val);
|
||||||
return 0;
|
return retn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,9 @@
|
|||||||
#define RUN_TIME_DEFAULT_MS 1000
|
#define RUN_TIME_DEFAULT_MS 1000
|
||||||
#define BENCH_TIME_DEFAULT_MS (BENCH_TIME_DEFAULT_S * RUN_TIME_DEFAULT_MS)
|
#define BENCH_TIME_DEFAULT_MS (BENCH_TIME_DEFAULT_S * RUN_TIME_DEFAULT_MS)
|
||||||
|
|
||||||
#define DISPLAY_LEVEL_DEFAULT 3
|
#ifndef ZSTD_DISPLAY_LEVEL_DEFAULT
|
||||||
|
# define ZSTD_DISPLAY_LEVEL_DEFAULT 3
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BENCH_SIZE_MAX (1200 MB)
|
#define BENCH_SIZE_MAX (1200 MB)
|
||||||
|
|
||||||
@@ -61,7 +63,7 @@
|
|||||||
|
|
||||||
#define DISPLAY(...) fprintf(stdout, __VA_ARGS__)
|
#define DISPLAY(...) fprintf(stdout, __VA_ARGS__)
|
||||||
#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
|
#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
|
||||||
static int g_displayLevel = DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
|
static int g_displayLevel = ZSTD_DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
|
||||||
|
|
||||||
|
|
||||||
/*--- buffer_t ---*/
|
/*--- buffer_t ---*/
|
||||||
@@ -739,6 +741,8 @@ 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
|
||||||
|
|||||||
@@ -77,6 +77,30 @@ 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 ====== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,6 +160,18 @@ 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
typedef ZSTD_cParameter zstd_cparameter;
|
||||||
|
|
||||||
@@ -205,6 +241,71 @@ 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;
|
||||||
@@ -245,6 +346,71 @@ 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 ====== */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ 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);
|
||||||
@@ -80,6 +86,13 @@ 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)
|
size_t zstd_cctx_set_param(zstd_cctx *cctx, ZSTD_cParameter param, int value)
|
||||||
{
|
{
|
||||||
return ZSTD_CCtx_setParameter(cctx, param, value);
|
return ZSTD_CCtx_setParameter(cctx, param, value);
|
||||||
@@ -146,6 +159,33 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -154,6 +194,15 @@ 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);
|
||||||
|
|||||||
@@ -44,6 +44,33 @@ 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)
|
||||||
@@ -59,6 +86,15 @@ 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);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
-- Basic usage: project_zstd(ZSTD_DIR)
|
-- Basic usage: project_zstd(ZSTD_DIR)
|
||||||
|
|
||||||
function project_zstd(dir, compression, decompression, deprecated, dictbuilder, legacy)
|
function project_zstd(dir, compression, decompression, deprecated, dictbuilder, legacy)
|
||||||
|
if string.sub(dir, -1, 1) ~= '/' then dir = dir .. '/' end
|
||||||
if compression == nil then compression = true end
|
if compression == nil then compression = true end
|
||||||
if decompression == nil then decompression = true end
|
if decompression == nil then decompression = true end
|
||||||
if deprecated == nil then deprecated = false end
|
if deprecated == nil then deprecated = false end
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
namespace pzstd {
|
namespace pzstd {
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
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
|
||||||
@@ -28,7 +30,7 @@ all: seekable_compression seekable_decompression seekable_decompression_mem \
|
|||||||
parallel_processing
|
parallel_processing
|
||||||
|
|
||||||
$(ZSTDLIB):
|
$(ZSTDLIB):
|
||||||
make -C $(ZSTDLIB_PATH) $(ZSTDLIB_NAME)
|
$(MAKE) -C $(ZSTDLIB_PATH) $(ZSTDLIB_TARGET)
|
||||||
|
|
||||||
seekable_compression : seekable_compression.c $(SEEKABLE_OBJS)
|
seekable_compression : seekable_compression.c $(SEEKABLE_OBJS)
|
||||||
$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@
|
$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#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"
|
||||||
@@ -72,114 +74,87 @@ static size_t fclose_orDie(FILE* file)
|
|||||||
exit(6);
|
exit(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fseek_orDie(FILE* file, long int offset, int origin)
|
struct state {
|
||||||
{
|
FILE* fout;
|
||||||
if (!fseek(file, offset, origin)) {
|
ZSTD_pthread_mutex_t mutex;
|
||||||
if (!fflush(file)) return;
|
size_t nextID;
|
||||||
}
|
struct job* pending;
|
||||||
/* error */
|
ZSTD_frameLog* frameLog;
|
||||||
perror("fseek");
|
const int compressionLevel;
|
||||||
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 {
|
||||||
const void* src;
|
size_t id;
|
||||||
|
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 = XXH64(job->src, job->srcSize, 0);
|
job->checksum = (unsigned)XXH64(job->src, job->srcSize, 0);
|
||||||
|
|
||||||
size_t ret = ZSTD_compress(job->dst, job->dstSize, job->src, job->srcSize, job->compressionLevel);
|
size_t ret = ZSTD_compress(job->dst, job->dstSize, job->src, job->srcSize, job->state->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize, int nbThreads)
|
// No longer need
|
||||||
{
|
free(job->src);
|
||||||
POOL_ctx* pool = POOL_create(nbThreads, nbThreads);
|
job->src = NULL;
|
||||||
if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); }
|
|
||||||
|
|
||||||
FILE* const fin = fopen_orDie(fname, "rb");
|
finishFrame(job);
|
||||||
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)
|
||||||
@@ -193,6 +168,72 @@ 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) {
|
||||||
@@ -204,10 +245,9 @@ 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]);
|
||||||
int const nbThreads = atoi(argv[3]);
|
size_t const nbThreads = (size_t)atoi(argv[3]);
|
||||||
|
|
||||||
const char* const outFileName = createOutFilename_orDie(inFileName);
|
compressFile_orDie(inFileName, 5, frameSize, nbThreads);
|
||||||
compressFile_orDie(inFileName, outFileName, 5, frameSize, nbThreads);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -100,13 +100,11 @@ 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");
|
||||||
|
|
||||||
@@ -128,7 +126,6 @@ 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);
|
||||||
@@ -153,14 +150,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, 0 };
|
jobs[fnb] = (struct sum_job){ fname, 0, fnb };
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
seekable_tests
|
seekable_tests
|
||||||
|
data.txt
|
||||||
|
|||||||
@@ -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
|
test: seekable_tests parallel_compression_test
|
||||||
./seekable_tests
|
./seekable_tests
|
||||||
|
|
||||||
$(ZSTDLIB):
|
$(ZSTDLIB):
|
||||||
@@ -32,7 +32,27 @@ $(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
|
seekable_tests data.txt
|
||||||
@echo Cleaning completed
|
@echo Cleaning completed
|
||||||
|
|||||||
@@ -316,6 +316,10 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -323,6 +327,10 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,6 +350,10 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Distribution of this document is unlimited.
|
|||||||
|
|
||||||
### Version
|
### Version
|
||||||
|
|
||||||
0.4.3 (2024-10-07)
|
0.4.5 (2026-05-14)
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
@@ -387,20 +387,24 @@ When `Block_Type` is `RLE_Block`, since `Block_Content`’s size is always 1,
|
|||||||
|
|
||||||
__`Block_Content`__ and __`Block_Maximum_Size`__
|
__`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
|
||||||
which is the smallest of:
|
determined once for a given frame and is the smallest of:
|
||||||
- `Window_Size`
|
- `Window_Size`
|
||||||
- 128 KB
|
- 128 KiB (131.072 bytes)
|
||||||
|
|
||||||
`Block_Maximum_Size` is constant for a given frame.
|
Both the `Block_Content` and the decompressed size of any block in the frame must
|
||||||
This maximum is applicable to both the decompressed size
|
be no larger than `Block_Maximum_Size`.
|
||||||
and the compressed size of any block in the frame.
|
|
||||||
|
|
||||||
The reasoning for this limit is that a decoder can read this information
|
The reasoning for this limit is that a decoder can read this information
|
||||||
at the beginning of a frame and use it to allocate buffers.
|
at the beginning of a frame and use it to allocate buffers.
|
||||||
The guarantees on the size of blocks ensure that
|
The guarantees on the size of blocks ensure that
|
||||||
the buffers will be large enough for any following block of the valid frame.
|
the buffers will be large enough for any following block of the valid frame.
|
||||||
|
|
||||||
|
If a compressed block is larger than its uncompressed content, it is recommended
|
||||||
|
to send it uncompressed (i.e., a `Raw_Block`). However, as long as
|
||||||
|
`Block_Content` is no larger than `Block_Maximum_Size`, it is legal to send such
|
||||||
|
a compressed block, even if it's larger than its uncompressed content.
|
||||||
|
|
||||||
|
|
||||||
Compressed Blocks
|
Compressed Blocks
|
||||||
-----------------
|
-----------------
|
||||||
@@ -1742,6 +1746,8 @@ or at least provide a meaningful error code explaining for which reason it canno
|
|||||||
|
|
||||||
Version changes
|
Version changes
|
||||||
---------------
|
---------------
|
||||||
|
- 0.4.5 : minor clarification regarding Block_Maximum_Size
|
||||||
|
- 0.4.4 : minor clarification for block size
|
||||||
- 0.4.3 : clarifications for Huffman prefix code assignment example
|
- 0.4.3 : clarifications for Huffman prefix code assignment example
|
||||||
- 0.4.2 : refactor FSE table construction process, inspired by Donald Pian
|
- 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.1 : clarifications on a few error scenarios, by Eric Lasota
|
||||||
|
|||||||
+31
-24
@@ -110,6 +110,7 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
|
|||||||
- 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.
|
||||||
@@ -128,9 +129,8 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
|
|||||||
</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> NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize().
|
</b><p> 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,7 +142,12 @@ 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>Compression helper functions</h3><pre></pre><b><pre></pre></b><BR>
|
||||||
@@ -166,8 +171,7 @@ size_t ZSTD_compressBound(size_t srcSize); </b>/*!< maximum compressed size in w
|
|||||||
|
|
||||||
</p></pre><BR>
|
</p></pre><BR>
|
||||||
|
|
||||||
<h3>Error helper functions</h3><pre></pre><b><pre>#include "zstd_errors.h" </b>/* list of errors */<b>
|
<h3>Error helper functions</h3><pre></pre><b><pre></b>/* ZSTD_isError() :<b>
|
||||||
</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
|
||||||
@@ -1239,7 +1243,7 @@ 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 >= ZSTD_FRAMEHEADERSIZE_PREFIX.
|
</b><p> srcSize must be large enough, aka >= 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>
|
||||||
@@ -1252,20 +1256,20 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
|||||||
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;
|
unsigned dictID; </b>/* for ZSTD_skippableFrame, contains the skippable magic variant [0-15] */<b>
|
||||||
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); </b>/**< doesn't consume input */<b>
|
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize);
|
||||||
</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, or requires larger `srcSize`.
|
</b><p> decode Frame Header into `zfhPtr`, or requires larger `srcSize`.
|
||||||
@return : 0, `zfhPtr` is correctly filled,
|
@return : 0 => header is complete, `zfhPtr` is correctly filled,
|
||||||
>0, `srcSize` is too small, value is wanted `srcSize` amount,
|
>0 => `srcSize` is too small, @return value is the wanted `srcSize` amount, `zfhPtr` is not filled,
|
||||||
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>
|
||||||
|
|
||||||
@@ -1421,7 +1425,7 @@ ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|||||||
ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
||||||
void* dst, size_t dstCapacity,
|
void* dst, size_t dstCapacity,
|
||||||
const ZSTD_Sequence* inSeqs, size_t nbSequences,
|
const ZSTD_Sequence* inSeqs, size_t nbSequences,
|
||||||
const void* literals, size_t litSize, size_t litCapacity,
|
const void* literals, size_t litSize, size_t litBufCapacity,
|
||||||
size_t decompressedSize);
|
size_t decompressedSize);
|
||||||
</b><p> This is a variant of ZSTD_compressSequences() which,
|
</b><p> This is a variant of ZSTD_compressSequences() which,
|
||||||
instead of receiving (src,srcSize) as input parameter, receives (literals,litSize),
|
instead of receiving (src,srcSize) as input parameter, receives (literals,litSize),
|
||||||
@@ -1435,20 +1439,22 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
|||||||
- Not compatible with frame checksum, which must be disabled
|
- Not compatible with frame checksum, which must be disabled
|
||||||
- If any block is incompressible, will fail and return an error
|
- 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.
|
- @litSize must be == sum of all @.litLength fields in @inSeqs. Any discrepancy will generate an error.
|
||||||
- the buffer @literals must have a size @litCapacity which is larger than @litSize by at least 8 bytes.
|
- @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.
|
- @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, unsigned magicVariant);
|
const void* src, size_t srcSize,
|
||||||
|
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, so
|
As such, the parameter magicVariant controls the exact skippable frame magic number variant used,
|
||||||
the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant.
|
so 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).
|
||||||
@@ -1457,13 +1463,14 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
|||||||
|
|
||||||
</p></pre><BR>
|
</p></pre><BR>
|
||||||
|
|
||||||
<pre><b>size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
|
<pre><b>ZSTDLIB_STATIC_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
|
||||||
const void* src, size_t srcSize);
|
unsigned* magicVariant,
|
||||||
</b><p> Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
|
const void* src, size_t srcSize);
|
||||||
|
</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. This can be NULL if the caller is not interested
|
i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START.
|
||||||
in the magicVariant.
|
This can be NULL if the caller is not interested 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.
|
||||||
|
|
||||||
@@ -1471,7 +1478,7 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
|||||||
|
|
||||||
</p></pre><BR>
|
</p></pre><BR>
|
||||||
|
|
||||||
<pre><b>unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
|
<pre><b>ZSTDLIB_STATIC_API 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>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ cxx_library(
|
|||||||
srcs=glob(['legacy/*.c']),
|
srcs=glob(['legacy/*.c']),
|
||||||
deps=[':common'],
|
deps=[':common'],
|
||||||
exported_preprocessor_flags=[
|
exported_preprocessor_flags=[
|
||||||
'-DZSTD_LEGACY_SUPPORT=4',
|
'-DZSTD_LEGACY_SUPPORT=0',
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -128,7 +128,7 @@ $(ZSTD_STATICLIB): $(ZSTD_STATICLIB_OBJ)
|
|||||||
$(AR) $(ARFLAGS) $@ $^
|
$(AR) $(ARFLAGS) $@ $^
|
||||||
|
|
||||||
libzstd.a: $(ZSTD_STATICLIB)
|
libzstd.a: $(ZSTD_STATICLIB)
|
||||||
cp -f $< $@
|
$(CP) $< $@
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -166,13 +166,13 @@ $(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) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
|
$(CC) $(FLAGS) $^ $(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)
|
||||||
|
|
||||||
$(LIBZSTD): $(ZSTD_DYNLIB)
|
$(LIBZSTD): $(ZSTD_DYNLIB)
|
||||||
cp -f $< $@
|
$(CP) $< $@
|
||||||
|
|
||||||
endif # ifndef BUILD_DIR
|
endif # ifndef BUILD_DIR
|
||||||
endif # if windows
|
endif # if windows
|
||||||
@@ -255,7 +255,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) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
|
$(CC) $(FLAGS) $^ $(SONAME_FLAGS) -o $@
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@@ -268,7 +268,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 $(INSTALL_OS_LIST),$(UNAME)))
|
||||||
|
|
||||||
lib: libzstd.pc
|
lib: libzstd.pc
|
||||||
|
|
||||||
@@ -363,8 +363,8 @@ install-shared:
|
|||||||
[ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/
|
[ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/
|
||||||
@echo Installing shared library
|
@echo Installing shared library
|
||||||
$(INSTALL_PROGRAM) $(LIBZSTD) $(DESTDIR)$(LIBDIR)
|
$(INSTALL_PROGRAM) $(LIBZSTD) $(DESTDIR)$(LIBDIR)
|
||||||
ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
|
$(LN) -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
|
||||||
ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
|
$(LN) -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
|
||||||
|
|
||||||
.PHONY: install-includes
|
.PHONY: install-includes
|
||||||
install-includes:
|
install-includes:
|
||||||
|
|||||||
+25
-5
@@ -7,15 +7,30 @@ in order to make it easier to select or exclude features.
|
|||||||
|
|
||||||
#### Building
|
#### Building
|
||||||
|
|
||||||
`Makefile` script is provided, supporting [Makefile conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html#Makefile-Conventions),
|
A `Makefile` script is provided, supporting [Makefile conventions](https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html#Makefile-Conventions),
|
||||||
including commands variables, staged install, directory variables and standard targets.
|
including commands variables, staged install, directory variables and standard targets.
|
||||||
- `make` : generates both static and dynamic libraries
|
- `make` : generates both static and dynamic libraries
|
||||||
- `make install` : install libraries and headers in target system directories
|
- `make install` : install libraries, headers and pkg-config in local system directories
|
||||||
|
|
||||||
`libzstd` default scope is pretty large, including compression, decompression, dictionary builder,
|
`libzstd` default scope includes compression, decompression, and dictionary builder.
|
||||||
and support for decoding legacy formats >= v0.5.0.
|
Note: starting v1.6.0, support for decoding legacy formats is disabled by default.
|
||||||
|
See _modular build_ below to learn how to enable it.
|
||||||
The scope can be reduced on demand (see paragraph _modular build_).
|
The scope can be reduced on demand (see paragraph _modular build_).
|
||||||
|
|
||||||
|
#### Multiarch Support
|
||||||
|
|
||||||
|
For multiarch systems (like Debian/Ubuntu), libraries should be installed to architecture-specific directories.
|
||||||
|
When creating packages for such systems, use the `LIBDIR` variable to specify the correct multiarch path:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# For x86_64 systems on Ubuntu/Debian:
|
||||||
|
make install PREFIX=/usr LIBDIR=/usr/lib/x86_64-linux-gnu
|
||||||
|
|
||||||
|
# For ARM64 systems on Ubuntu/Debian:
|
||||||
|
make install PREFIX=/usr LIBDIR=/usr/lib/aarch64-linux-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
This will not only install the files in the correct directories, but also generate the correct paths for `pkg-config`.
|
||||||
|
|
||||||
#### Multithreading support
|
#### Multithreading support
|
||||||
|
|
||||||
@@ -85,7 +100,7 @@ The file structure is designed to make this selection manually achievable for an
|
|||||||
Specifying a number limits versions supported to that version onward.
|
Specifying a number limits versions supported to that version onward.
|
||||||
For example, `ZSTD_LEGACY_SUPPORT=2` means : "support legacy formats >= v0.2.0".
|
For example, `ZSTD_LEGACY_SUPPORT=2` means : "support legacy formats >= v0.2.0".
|
||||||
Conversely, `ZSTD_LEGACY_SUPPORT=0` means "do __not__ support legacy formats".
|
Conversely, `ZSTD_LEGACY_SUPPORT=0` means "do __not__ support legacy formats".
|
||||||
By default, this build macro is set as `ZSTD_LEGACY_SUPPORT=5`.
|
By default, this build macro is set as `ZSTD_LEGACY_SUPPORT=0` (disabled).
|
||||||
Decoding supported legacy format is a transparent capability triggered within decompression functions.
|
Decoding supported legacy format is a transparent capability triggered within decompression functions.
|
||||||
It's also allowed to invoke legacy API directly, exposed in `lib/legacy/zstd_legacy.h`.
|
It's also allowed to invoke legacy API directly, exposed in `lib/legacy/zstd_legacy.h`.
|
||||||
Each version does also provide its own set of advanced API.
|
Each version does also provide its own set of advanced API.
|
||||||
@@ -193,6 +208,11 @@ 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.
|
||||||
|
|||||||
@@ -33,9 +33,13 @@ MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
|
|||||||
MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
|
MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
|
||||||
{
|
{
|
||||||
if (customMem.customAlloc) {
|
if (customMem.customAlloc) {
|
||||||
/* calloc implemented as malloc+memset;
|
/* calloc implemented as malloc+memset */
|
||||||
* not as efficient as calloc, but next best guess for custom malloc */
|
|
||||||
void* const ptr = customMem.customAlloc(customMem.opaque, size);
|
void* const ptr = customMem.customAlloc(customMem.opaque, size);
|
||||||
|
|
||||||
|
if (ptr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ZSTD_memset(ptr, 0, size);
|
ZSTD_memset(ptr, 0, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ 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 & -(S32) val) * 0x077CB531U)) >> 27];
|
return DeBruijnBytePos[((U32) ((val & (0-val)) * 0x077CB531U)) >> 27];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ 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);
|
FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
|
||||||
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
|
FORCE_INLINE_TEMPLATE 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);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+24
-6
@@ -218,6 +218,18 @@
|
|||||||
# 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)
|
||||||
|
# if ((defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 14) || \
|
||||||
|
(defined(__clang__) && __clang_major__ >= 19))
|
||||||
|
#define ZSTD_ARCH_RISCV_RVV
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
#
|
#
|
||||||
# if defined(ZSTD_ARCH_X86_AVX2)
|
# if defined(ZSTD_ARCH_X86_AVX2)
|
||||||
# include <immintrin.h>
|
# include <immintrin.h>
|
||||||
@@ -227,6 +239,12 @@
|
|||||||
# 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. */
|
||||||
@@ -357,9 +375,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
|
||||||
unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add)
|
const void* ZSTD_wrappedPtrAdd(const void* ptr, ptrdiff_t add)
|
||||||
{
|
{
|
||||||
return ptr + add;
|
return (const char*)ptr + add;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -370,9 +388,9 @@ unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add)
|
|||||||
*/
|
*/
|
||||||
MEM_STATIC
|
MEM_STATIC
|
||||||
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
||||||
unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub)
|
const void* ZSTD_wrappedPtrSub(const void* ptr, ptrdiff_t sub)
|
||||||
{
|
{
|
||||||
return ptr - sub;
|
return (const char*)ptr - sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -382,9 +400,9 @@ unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* 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
|
||||||
unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add)
|
void* ZSTD_maybeNullPtrAdd(void* ptr, ptrdiff_t add)
|
||||||
{
|
{
|
||||||
return add > 0 ? ptr + add : ptr;
|
return add > 0 ? (char*)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
|
||||||
|
|||||||
+16
-19
@@ -142,19 +142,17 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
|
|||||||
/* Allocate space for the thread handles */
|
/* Allocate space for the thread handles */
|
||||||
ctx->threads = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
|
ctx->threads = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
|
||||||
ctx->threadCapacity = 0;
|
ctx->threadCapacity = 0;
|
||||||
|
ctx->threadLimit = numThreads;
|
||||||
ctx->customMem = customMem;
|
ctx->customMem = customMem;
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
|
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
|
||||||
/* Initialize the threads */
|
/* Initialize the threads */
|
||||||
{ size_t i;
|
while (ctx->threadCapacity < numThreads) {
|
||||||
for (i = 0; i < numThreads; ++i) {
|
if (ZSTD_pthread_create(&ctx->threads[ctx->threadCapacity++], NULL, &POOL_thread, ctx)) {
|
||||||
if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
|
--ctx->threadCapacity;
|
||||||
ctx->threadCapacity = i;
|
POOL_free(ctx);
|
||||||
POOL_free(ctx);
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
} }
|
|
||||||
ctx->threadCapacity = numThreads;
|
|
||||||
ctx->threadLimit = numThreads;
|
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
@@ -220,23 +218,22 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* numThreads > threadCapacity */
|
/* numThreads > threadCapacity */
|
||||||
|
ctx->threadLimit = numThreads;
|
||||||
{ ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
|
{ ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
|
||||||
if (!threadPool) return 1;
|
if (!threadPool) return 1;
|
||||||
/* replace existing thread pool */
|
/* extend existing thread pool */
|
||||||
ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t));
|
ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t));
|
||||||
ZSTD_customFree(ctx->threads, ctx->customMem);
|
ZSTD_customFree(ctx->threads, ctx->customMem);
|
||||||
ctx->threads = threadPool;
|
ctx->threads = threadPool;
|
||||||
/* Initialize additional threads */
|
/* Initialize additional threads */
|
||||||
{ size_t threadId;
|
while (ctx->threadCapacity < numThreads) {
|
||||||
for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
|
if (ZSTD_pthread_create(&threadPool[ctx->threadCapacity++], NULL, &POOL_thread, ctx)) {
|
||||||
if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
|
--ctx->threadCapacity;
|
||||||
ctx->threadCapacity = threadId;
|
return 1;
|
||||||
return 1;
|
}
|
||||||
} }
|
}
|
||||||
} }
|
}
|
||||||
/* successfully expanded */
|
/* successfully expanded */
|
||||||
ctx->threadCapacity = numThreads;
|
|
||||||
ctx->threadLimit = numThreads;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,4 +168,23 @@
|
|||||||
# 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 */
|
||||||
|
|||||||
+16
-2
@@ -143,7 +143,14 @@ int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t con
|
|||||||
*mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
|
*mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
|
||||||
if (!*mutex)
|
if (!*mutex)
|
||||||
return 1;
|
return 1;
|
||||||
return pthread_mutex_init(*mutex, attr);
|
{
|
||||||
|
int const ret = pthread_mutex_init(*mutex, attr);
|
||||||
|
if (ret != 0) {
|
||||||
|
ZSTD_free(*mutex);
|
||||||
|
*mutex = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
|
int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
|
||||||
@@ -164,7 +171,14 @@ int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const*
|
|||||||
*cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
|
*cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
|
||||||
if (!*cond)
|
if (!*cond)
|
||||||
return 1;
|
return 1;
|
||||||
return pthread_cond_init(*cond, attr);
|
{
|
||||||
|
int const ret = pthread_cond_init(*cond, attr);
|
||||||
|
if (ret != 0) {
|
||||||
|
ZSTD_free(*cond);
|
||||||
|
*cond = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
|
int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
|
||||||
|
|||||||
@@ -46,3 +46,12 @@ 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
|
||||||
|
}
|
||||||
|
|||||||
@@ -168,7 +168,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)
|
#if defined(ZSTD_ARCH_ARM_NEON) && !defined(__aarch64__)
|
||||||
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);
|
||||||
@@ -185,6 +185,8 @@ static void ZSTD_copy16(void* dst, const void* src) {
|
|||||||
vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
|
vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
|
||||||
#elif defined(ZSTD_ARCH_X86_SSE2)
|
#elif defined(ZSTD_ARCH_X86_SSE2)
|
||||||
_mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src));
|
_mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src));
|
||||||
|
#elif defined(ZSTD_ARCH_RISCV_RVV)
|
||||||
|
__riscv_vse8_v_u8m1((uint8_t*)dst, __riscv_vle8_v_u8m1((const uint8_t*)src, 16), 16);
|
||||||
#elif defined(__clang__)
|
#elif defined(__clang__)
|
||||||
ZSTD_memmove(dst, src, 16);
|
ZSTD_memmove(dst, src, 16);
|
||||||
#else
|
#else
|
||||||
@@ -213,7 +215,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, ptrdiff_t length, ZSTD_overlap_e const ovtype)
|
void ZSTD_wildcopy(void* dst, const void* src, size_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;
|
||||||
|
|||||||
+258
-3
@@ -19,6 +19,12 @@
|
|||||||
#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); }
|
||||||
@@ -65,6 +71,244 @@ 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,
|
||||||
@@ -73,8 +317,8 @@ typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
|
|||||||
* `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 size_t HIST_count_parallel_wksp(
|
static UNUSED_ATTR
|
||||||
unsigned* count, unsigned* maxSymbolValuePtr,
|
size_t HIST_count_parallel_wksp(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)
|
||||||
@@ -151,11 +395,17 @@ 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 < 1500) /* heuristic threshold */
|
if (sourceSize < HIST_FAST_THRESHOLD) /* 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() :
|
||||||
@@ -165,10 +415,15 @@ 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,11 @@ 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.
|
||||||
|
|||||||
@@ -425,6 +425,7 @@ 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];
|
||||||
|
|||||||
+545
-18
@@ -56,6 +56,14 @@
|
|||||||
# define ZSTD_HASHLOG3_MAX 17
|
# define ZSTD_HASHLOG3_MAX 17
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-*************************************
|
||||||
|
* Forward declarations
|
||||||
|
***************************************/
|
||||||
|
size_t convertSequences_noRepcodes(SeqDef* dstSeqs, const ZSTD_Sequence* inSeqs,
|
||||||
|
size_t nbSequences);
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Helper functions
|
* Helper functions
|
||||||
***************************************/
|
***************************************/
|
||||||
@@ -237,10 +245,18 @@ static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_Para
|
|||||||
/* Returns row matchfinder usage given an initial mode and cParams */
|
/* Returns row matchfinder usage given an initial mode and cParams */
|
||||||
static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode,
|
static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode,
|
||||||
const ZSTD_compressionParameters* const cParams) {
|
const ZSTD_compressionParameters* const cParams) {
|
||||||
|
#ifdef ZSTD_LINUX_KERNEL
|
||||||
|
/* The Linux Kernel does not use SIMD, and 128KB is a very common size, e.g. in BtrFS.
|
||||||
|
* The row match finder is slower for this size without SIMD, so disable it.
|
||||||
|
*/
|
||||||
|
const unsigned kWindowLogLowerBound = 17;
|
||||||
|
#else
|
||||||
|
const unsigned kWindowLogLowerBound = 14;
|
||||||
|
#endif
|
||||||
if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
|
if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
|
||||||
mode = ZSTD_ps_disable;
|
mode = ZSTD_ps_disable;
|
||||||
if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
|
if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
|
||||||
if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
|
if (cParams->windowLog > kWindowLogLowerBound) mode = ZSTD_ps_enable;
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1755,15 +1771,19 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|||||||
{
|
{
|
||||||
ZSTD_compressionParameters const cParams =
|
ZSTD_compressionParameters const cParams =
|
||||||
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
||||||
|
ldmParams_t ldmParams = params->ldmParams;
|
||||||
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
|
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
|
||||||
&cParams);
|
&cParams);
|
||||||
|
|
||||||
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
|
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
|
||||||
|
if (ldmParams.enableLdm == ZSTD_ps_enable) {
|
||||||
|
ZSTD_ldm_adjustParameters(&ldmParams, &cParams);
|
||||||
|
}
|
||||||
/* estimateCCtxSize is for one-shot compression. So no buffers should
|
/* estimateCCtxSize is for one-shot compression. So no buffers should
|
||||||
* be needed. However, we still allocate two 0-sized buffers, which can
|
* be needed. However, we still allocate two 0-sized buffers, which can
|
||||||
* take space under ASAN. */
|
* take space under ASAN. */
|
||||||
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
||||||
&cParams, ¶ms->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
|
&cParams, &ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
|
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
|
||||||
@@ -1813,6 +1833,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|||||||
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
|
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
|
||||||
{ ZSTD_compressionParameters const cParams =
|
{ ZSTD_compressionParameters const cParams =
|
||||||
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
||||||
|
ldmParams_t ldmParams = params->ldmParams;
|
||||||
size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(params->maxBlockSize), (size_t)1 << cParams.windowLog);
|
size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(params->maxBlockSize), (size_t)1 << cParams.windowLog);
|
||||||
size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
|
size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
|
||||||
? ((size_t)1 << cParams.windowLog) + blockSize
|
? ((size_t)1 << cParams.windowLog) + blockSize
|
||||||
@@ -1822,8 +1843,11 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|||||||
: 0;
|
: 0;
|
||||||
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams);
|
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams);
|
||||||
|
|
||||||
|
if (ldmParams.enableLdm == ZSTD_ps_enable) {
|
||||||
|
ZSTD_ldm_adjustParameters(&ldmParams, &cParams);
|
||||||
|
}
|
||||||
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
||||||
&cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
|
&cParams, &ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
|
||||||
ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
|
ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7110,7 +7134,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__AVX2__)
|
#if defined(ZSTD_ARCH_X86_AVX2)
|
||||||
|
|
||||||
#include <immintrin.h> /* AVX2 intrinsics */
|
#include <immintrin.h> /* AVX2 intrinsics */
|
||||||
|
|
||||||
@@ -7130,7 +7154,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|||||||
* @returns > 0 if there is one long length (> 65535),
|
* @returns > 0 if there is one long length (> 65535),
|
||||||
* indicating the position, and type.
|
* indicating the position, and type.
|
||||||
*/
|
*/
|
||||||
static size_t convertSequences_noRepcodes(
|
size_t convertSequences_noRepcodes(
|
||||||
SeqDef* dstSeqs,
|
SeqDef* dstSeqs,
|
||||||
const ZSTD_Sequence* inSeqs,
|
const ZSTD_Sequence* inSeqs,
|
||||||
size_t nbSequences)
|
size_t nbSequences)
|
||||||
@@ -7276,13 +7300,378 @@ static size_t convertSequences_noRepcodes(
|
|||||||
return longLen;
|
return longLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined (ZSTD_ARCH_RISCV_RVV)
|
||||||
|
#include <riscv_vector.h>
|
||||||
|
/*
|
||||||
|
* Convert `vl` sequences per iteration, using RVV intrinsics:
|
||||||
|
* - offset -> offBase = offset + 2
|
||||||
|
* - litLength -> (U16) litLength
|
||||||
|
* - matchLength -> (U16)(matchLength - 3)
|
||||||
|
* - rep is ignored
|
||||||
|
* Store only 8 bytes per SeqDef (offBase[4], litLength[2], mlBase[2]).
|
||||||
|
*
|
||||||
|
* @returns 0 on succes, with no long length detected
|
||||||
|
* @returns > 0 if there is one long length (> 65535),
|
||||||
|
* indicating the position, and type.
|
||||||
|
*/
|
||||||
|
size_t convertSequences_noRepcodes(SeqDef* dstSeqs, const ZSTD_Sequence* inSeqs, size_t nbSequences) {
|
||||||
|
size_t longLen = 0;
|
||||||
|
size_t vl = 0;
|
||||||
|
typedef uint32_t __attribute__((may_alias)) aliased_u32;
|
||||||
|
/* RVV depends on the specific definition of target structures */
|
||||||
|
ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
|
||||||
|
ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nbSequences; i += vl) {
|
||||||
|
|
||||||
|
vl = __riscv_vsetvl_e32m2(nbSequences-i);
|
||||||
|
{
|
||||||
|
// Loading structure member variables
|
||||||
|
vuint32m2x4_t v_tuple = __riscv_vlseg4e32_v_u32m2x4(
|
||||||
|
(const aliased_u32*)((const void*)&inSeqs[i]),
|
||||||
|
vl
|
||||||
|
);
|
||||||
|
vuint32m2_t v_offset = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 0);
|
||||||
|
vuint32m2_t v_lit = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 1);
|
||||||
|
vuint32m2_t v_match = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 2);
|
||||||
|
// offset + ZSTD_REP_NUM
|
||||||
|
vuint32m2_t v_offBase = __riscv_vadd_vx_u32m2(v_offset, ZSTD_REP_NUM, vl);
|
||||||
|
// Check for integer overflow
|
||||||
|
// Cast to a 16-bit variable
|
||||||
|
vbool16_t lit_overflow = __riscv_vmsgtu_vx_u32m2_b16(v_lit, 65535, vl);
|
||||||
|
vuint16m1_t v_lit_clamped = __riscv_vncvt_x_x_w_u16m1(v_lit, vl);
|
||||||
|
|
||||||
|
vbool16_t ml_overflow = __riscv_vmsgtu_vx_u32m2_b16(v_match, 65535+MINMATCH, vl);
|
||||||
|
vuint16m1_t v_ml_clamped = __riscv_vncvt_x_x_w_u16m1(__riscv_vsub_vx_u32m2(v_match, MINMATCH, vl), vl);
|
||||||
|
|
||||||
|
// Pack two 16-bit fields into a 32-bit value (little-endian)
|
||||||
|
// The lower 16 bits contain litLength, and the upper 16 bits contain mlBase
|
||||||
|
vuint32m2_t v_lit_ml_combined = __riscv_vsll_vx_u32m2(
|
||||||
|
__riscv_vwcvtu_x_x_v_u32m2(v_ml_clamped, vl), // Convert matchLength to 32-bit
|
||||||
|
16,
|
||||||
|
vl
|
||||||
|
);
|
||||||
|
v_lit_ml_combined = __riscv_vor_vv_u32m2(
|
||||||
|
v_lit_ml_combined,
|
||||||
|
__riscv_vwcvtu_x_x_v_u32m2(v_lit_clamped, vl),
|
||||||
|
vl
|
||||||
|
);
|
||||||
|
{
|
||||||
|
// Create a vector of SeqDef structures
|
||||||
|
// Store the offBase, litLength, and mlBase in a vector of SeqDef
|
||||||
|
vuint32m2x2_t store_data = __riscv_vcreate_v_u32m2x2(
|
||||||
|
v_offBase,
|
||||||
|
v_lit_ml_combined
|
||||||
|
);
|
||||||
|
__riscv_vsseg2e32_v_u32m2x2(
|
||||||
|
(aliased_u32*)((void*)&dstSeqs[i]),
|
||||||
|
store_data,
|
||||||
|
vl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Find the first index where an overflow occurs
|
||||||
|
int first_ml = __riscv_vfirst_m_b16(ml_overflow, vl);
|
||||||
|
int first_lit = __riscv_vfirst_m_b16(lit_overflow, vl);
|
||||||
|
|
||||||
|
if (UNLIKELY(first_ml != -1)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = i + first_ml + 1;
|
||||||
|
}
|
||||||
|
if (UNLIKELY(first_lit != -1)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = i + first_lit + 1 + nbSequences;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return longLen;
|
||||||
|
}
|
||||||
|
|
||||||
/* the vector implementation could also be ported to SSSE3,
|
/* the vector implementation could also be ported to SSSE3,
|
||||||
* but since this implementation is targeting modern systems (>= Sapphire Rapid),
|
* but since this implementation is targeting modern systems (>= Sapphire Rapid),
|
||||||
* it's not useful to develop and maintain code for older pre-AVX2 platforms */
|
* it's not useful to develop and maintain code for older pre-AVX2 platforms */
|
||||||
|
|
||||||
#else /* no AVX2 */
|
#elif defined(ZSTD_ARCH_ARM_SVE2)
|
||||||
|
|
||||||
static size_t convertSequences_noRepcodes(
|
/*
|
||||||
|
* Checks if any active element in a signed 8-bit integer vector is greater
|
||||||
|
* than zero.
|
||||||
|
*
|
||||||
|
* @param g Governing predicate selecting active lanes.
|
||||||
|
* @param a Input vector of signed 8-bit integers.
|
||||||
|
*
|
||||||
|
* @return True if any active element in `a` is > 0, false otherwise.
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_TEMPLATE int cmpgtz_any_s8(svbool_t g, svint8_t a)
|
||||||
|
{
|
||||||
|
svbool_t ptest = svcmpgt_n_s8(g, a, 0);
|
||||||
|
return svptest_any(ptest, ptest);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t convertSequences_noRepcodes(
|
||||||
|
SeqDef* dstSeqs,
|
||||||
|
const ZSTD_Sequence* inSeqs,
|
||||||
|
size_t nbSequences)
|
||||||
|
{
|
||||||
|
/* Process the input with `8 * VL / element` lanes. */
|
||||||
|
const size_t lanes = 8 * svcntb() / sizeof(ZSTD_Sequence);
|
||||||
|
size_t longLen = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
/* SVE permutation depends on the specific definition of target structures. */
|
||||||
|
ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
|
||||||
|
ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
|
||||||
|
|
||||||
|
if (nbSequences >= lanes) {
|
||||||
|
const svbool_t ptrue = svptrue_b8();
|
||||||
|
/* 16-bit of {ZSTD_REP_NUM, 0, -MINMATCH, 0} extended to 32-bit lanes. */
|
||||||
|
const svuint32_t vaddition = svreinterpret_u32(
|
||||||
|
svunpklo_s32(svreinterpret_s16(svdup_n_u64(ZSTD_REP_NUM | (((U64)(U16)-MINMATCH) << 32)))));
|
||||||
|
/* For permutation of 16-bit units: 0, 1, 2, 4, 8, 9, 10, 12, ... */
|
||||||
|
const svuint16_t vmask = svreinterpret_u16(
|
||||||
|
svindex_u64(0x0004000200010000, 0x0008000800080008));
|
||||||
|
/* Upper bytes of `litLength` and `matchLength` will be packed into the
|
||||||
|
* middle of overflow check vector. */
|
||||||
|
const svbool_t pmid = svcmpne_n_u8(
|
||||||
|
ptrue, svreinterpret_u8(svdup_n_u64(0x0000FFFFFFFF0000)), 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Load `lanes` number of `ZSTD_Sequence` into 8 vectors. */
|
||||||
|
const svuint32_t vin0 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 0);
|
||||||
|
const svuint32_t vin1 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 1);
|
||||||
|
const svuint32_t vin2 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 2);
|
||||||
|
const svuint32_t vin3 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 3);
|
||||||
|
const svuint32_t vin4 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 4);
|
||||||
|
const svuint32_t vin5 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 5);
|
||||||
|
const svuint32_t vin6 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 6);
|
||||||
|
const svuint32_t vin7 = svld1_vnum_u32(ptrue, &inSeqs[n].offset, 7);
|
||||||
|
|
||||||
|
/* Add {ZSTD_REP_NUM, 0, -MINMATCH, 0} to each structures. */
|
||||||
|
const svuint16x2_t vadd01 = svcreate2_u16(
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin0, vaddition)),
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin1, vaddition)));
|
||||||
|
const svuint16x2_t vadd23 = svcreate2_u16(
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin2, vaddition)),
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin3, vaddition)));
|
||||||
|
const svuint16x2_t vadd45 = svcreate2_u16(
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin4, vaddition)),
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin5, vaddition)));
|
||||||
|
const svuint16x2_t vadd67 = svcreate2_u16(
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin6, vaddition)),
|
||||||
|
svreinterpret_u16(svadd_u32_x(ptrue, vin7, vaddition)));
|
||||||
|
|
||||||
|
/* Shuffle and pack bytes so each vector contains SeqDef structures. */
|
||||||
|
const svuint16_t vout01 = svtbl2_u16(vadd01, vmask);
|
||||||
|
const svuint16_t vout23 = svtbl2_u16(vadd23, vmask);
|
||||||
|
const svuint16_t vout45 = svtbl2_u16(vadd45, vmask);
|
||||||
|
const svuint16_t vout67 = svtbl2_u16(vadd67, vmask);
|
||||||
|
|
||||||
|
/* Pack the upper 16-bits of 32-bit lanes for overflow check. */
|
||||||
|
const svuint16_t voverflow01 = svuzp2_u16(svget2_u16(vadd01, 0),
|
||||||
|
svget2_u16(vadd01, 1));
|
||||||
|
const svuint16_t voverflow23 = svuzp2_u16(svget2_u16(vadd23, 0),
|
||||||
|
svget2_u16(vadd23, 1));
|
||||||
|
const svuint16_t voverflow45 = svuzp2_u16(svget2_u16(vadd45, 0),
|
||||||
|
svget2_u16(vadd45, 1));
|
||||||
|
const svuint16_t voverflow67 = svuzp2_u16(svget2_u16(vadd67, 0),
|
||||||
|
svget2_u16(vadd67, 1));
|
||||||
|
|
||||||
|
/* We don't need the whole 16 bits of the overflow part. Only 1 bit
|
||||||
|
* is needed, so we pack tightly and merge multiple vectors to be
|
||||||
|
* able to use a single comparison to handle the overflow case.
|
||||||
|
* However, we also need to handle the possible negative values of
|
||||||
|
* matchLength parts, so we use signed comparison later. */
|
||||||
|
const svint8_t voverflow =
|
||||||
|
svmax_s8_x(pmid,
|
||||||
|
svtrn1_s8(svreinterpret_s8(voverflow01),
|
||||||
|
svreinterpret_s8(voverflow23)),
|
||||||
|
svtrn1_s8(svreinterpret_s8(voverflow45),
|
||||||
|
svreinterpret_s8(voverflow67)));
|
||||||
|
|
||||||
|
/* Store `lanes` number of `SeqDef` structures from 4 vectors. */
|
||||||
|
svst1_vnum_u32(ptrue, &dstSeqs[n].offBase, 0, svreinterpret_u32(vout01));
|
||||||
|
svst1_vnum_u32(ptrue, &dstSeqs[n].offBase, 1, svreinterpret_u32(vout23));
|
||||||
|
svst1_vnum_u32(ptrue, &dstSeqs[n].offBase, 2, svreinterpret_u32(vout45));
|
||||||
|
svst1_vnum_u32(ptrue, &dstSeqs[n].offBase, 3, svreinterpret_u32(vout67));
|
||||||
|
|
||||||
|
/* Check if any enabled lanes of the overflow vector is larger than
|
||||||
|
* zero, only one such may happen. */
|
||||||
|
if (UNLIKELY(cmpgtz_any_s8(pmid, voverflow))) {
|
||||||
|
/* Scalar search for long match is needed because we merged
|
||||||
|
* multiple overflow bytes with `max`. */
|
||||||
|
size_t i;
|
||||||
|
for (i = n; i < n + lanes; i++) {
|
||||||
|
if (inSeqs[i].matchLength > 65535 + MINMATCH) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = i + 1;
|
||||||
|
}
|
||||||
|
if (inSeqs[i].litLength > 65535) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = i + nbSequences + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n += lanes;
|
||||||
|
} while(n <= nbSequences - lanes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle remaining elements. */
|
||||||
|
for (; n < nbSequences; n++) {
|
||||||
|
dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
|
||||||
|
dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
|
||||||
|
dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
|
||||||
|
/* Check for long length > 65535. */
|
||||||
|
if (UNLIKELY(inSeqs[n].matchLength > 65535 + MINMATCH)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = n + 1;
|
||||||
|
}
|
||||||
|
if (UNLIKELY(inSeqs[n].litLength > 65535)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = n + nbSequences + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return longLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ZSTD_ARCH_ARM_NEON) && (defined(__aarch64__) || defined(_M_ARM64))
|
||||||
|
|
||||||
|
size_t convertSequences_noRepcodes(
|
||||||
|
SeqDef* dstSeqs,
|
||||||
|
const ZSTD_Sequence* inSeqs,
|
||||||
|
size_t nbSequences)
|
||||||
|
{
|
||||||
|
size_t longLen = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
/* Neon permutation depends on the specific definition of target structures. */
|
||||||
|
ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
|
||||||
|
ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
|
||||||
|
|
||||||
|
if (nbSequences > 3) {
|
||||||
|
static const ZSTD_ALIGNED(16) U32 constAddition[4] = {
|
||||||
|
ZSTD_REP_NUM, 0, -MINMATCH, 0
|
||||||
|
};
|
||||||
|
static const ZSTD_ALIGNED(16) U8 constMask[16] = {
|
||||||
|
0, 1, 2, 3, 4, 5, 8, 9, 16, 17, 18, 19, 20, 21, 24, 25
|
||||||
|
};
|
||||||
|
static const ZSTD_ALIGNED(16) U16 constCounter[8] = {
|
||||||
|
1, 1, 1, 1, 2, 2, 2, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32x4_t vaddition = vld1q_u32(constAddition);
|
||||||
|
const uint8x16_t vmask = vld1q_u8(constMask);
|
||||||
|
uint16x8_t vcounter = vld1q_u16(constCounter);
|
||||||
|
uint16x8_t vindex01 = vdupq_n_u16(0);
|
||||||
|
uint16x8_t vindex23 = vdupq_n_u16(0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Load 4 ZSTD_Sequence (64 bytes). */
|
||||||
|
const uint32x4_t vin0 = vld1q_u32(&inSeqs[n + 0].offset);
|
||||||
|
const uint32x4_t vin1 = vld1q_u32(&inSeqs[n + 1].offset);
|
||||||
|
const uint32x4_t vin2 = vld1q_u32(&inSeqs[n + 2].offset);
|
||||||
|
const uint32x4_t vin3 = vld1q_u32(&inSeqs[n + 3].offset);
|
||||||
|
|
||||||
|
/* Add {ZSTD_REP_NUM, 0, -MINMATCH, 0} to each vector. */
|
||||||
|
const uint8x16x2_t vadd01 = { {
|
||||||
|
vreinterpretq_u8_u32(vaddq_u32(vin0, vaddition)),
|
||||||
|
vreinterpretq_u8_u32(vaddq_u32(vin1, vaddition)),
|
||||||
|
} };
|
||||||
|
const uint8x16x2_t vadd23 = { {
|
||||||
|
vreinterpretq_u8_u32(vaddq_u32(vin2, vaddition)),
|
||||||
|
vreinterpretq_u8_u32(vaddq_u32(vin3, vaddition)),
|
||||||
|
} };
|
||||||
|
|
||||||
|
/* Shuffle and pack bytes so each vector contains 2 SeqDef structures. */
|
||||||
|
const uint8x16_t vout01 = vqtbl2q_u8(vadd01, vmask);
|
||||||
|
const uint8x16_t vout23 = vqtbl2q_u8(vadd23, vmask);
|
||||||
|
|
||||||
|
/* Pack the upper 16-bits of 32-bit lanes for overflow check. */
|
||||||
|
uint16x8_t voverflow01 = vuzp2q_u16(vreinterpretq_u16_u8(vadd01.val[0]),
|
||||||
|
vreinterpretq_u16_u8(vadd01.val[1]));
|
||||||
|
uint16x8_t voverflow23 = vuzp2q_u16(vreinterpretq_u16_u8(vadd23.val[0]),
|
||||||
|
vreinterpretq_u16_u8(vadd23.val[1]));
|
||||||
|
|
||||||
|
/* Store 4 SeqDef structures. */
|
||||||
|
vst1q_u32(&dstSeqs[n + 0].offBase, vreinterpretq_u32_u8(vout01));
|
||||||
|
vst1q_u32(&dstSeqs[n + 2].offBase, vreinterpretq_u32_u8(vout23));
|
||||||
|
|
||||||
|
/* Create masks in case of overflow. */
|
||||||
|
voverflow01 = vcgtzq_s16(vreinterpretq_s16_u16(voverflow01));
|
||||||
|
voverflow23 = vcgtzq_s16(vreinterpretq_s16_u16(voverflow23));
|
||||||
|
|
||||||
|
/* Update overflow indices. */
|
||||||
|
vindex01 = vbslq_u16(voverflow01, vcounter, vindex01);
|
||||||
|
vindex23 = vbslq_u16(voverflow23, vcounter, vindex23);
|
||||||
|
|
||||||
|
/* Update counter for overflow check. */
|
||||||
|
vcounter = vaddq_u16(vcounter, vdupq_n_u16(4));
|
||||||
|
|
||||||
|
n += 4;
|
||||||
|
} while(n < nbSequences - 3);
|
||||||
|
|
||||||
|
/* Fixup indices in the second vector, we saved an additional counter
|
||||||
|
in the loop to update the second overflow index, we need to add 2
|
||||||
|
here when the indices are not 0. */
|
||||||
|
{ uint16x8_t nonzero = vtstq_u16(vindex23, vindex23);
|
||||||
|
vindex23 = vsubq_u16(vindex23, nonzero);
|
||||||
|
vindex23 = vsubq_u16(vindex23, nonzero);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge indices in the vectors, maximums are needed. */
|
||||||
|
vindex01 = vmaxq_u16(vindex01, vindex23);
|
||||||
|
vindex01 = vmaxq_u16(vindex01, vextq_u16(vindex01, vindex01, 4));
|
||||||
|
|
||||||
|
/* Compute `longLen`, maximums of matchLength and litLength
|
||||||
|
with a preference on litLength. */
|
||||||
|
{ U64 maxLitMatchIndices = vgetq_lane_u64(vreinterpretq_u64_u16(vindex01), 0);
|
||||||
|
size_t maxLitIndex = (maxLitMatchIndices >> 16) & 0xFFFF;
|
||||||
|
size_t maxMatchIndex = (maxLitMatchIndices >> 32) & 0xFFFF;
|
||||||
|
longLen = maxLitIndex > maxMatchIndex ? maxLitIndex + nbSequences
|
||||||
|
: maxMatchIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle remaining elements. */
|
||||||
|
for (; n < nbSequences; n++) {
|
||||||
|
dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
|
||||||
|
dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
|
||||||
|
dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
|
||||||
|
/* Check for long length > 65535. */
|
||||||
|
if (UNLIKELY(inSeqs[n].matchLength > 65535 + MINMATCH)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = n + 1;
|
||||||
|
}
|
||||||
|
if (UNLIKELY(inSeqs[n].litLength > 65535)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = n + nbSequences + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return longLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* No vectorization. */
|
||||||
|
|
||||||
|
size_t convertSequences_noRepcodes(
|
||||||
SeqDef* dstSeqs,
|
SeqDef* dstSeqs,
|
||||||
const ZSTD_Sequence* inSeqs,
|
const ZSTD_Sequence* inSeqs,
|
||||||
size_t nbSequences)
|
size_t nbSequences)
|
||||||
@@ -7293,7 +7682,7 @@ static size_t convertSequences_noRepcodes(
|
|||||||
dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
|
dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
|
||||||
dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
|
dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
|
||||||
dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
|
dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
|
||||||
/* check for long length > 65535 */
|
/* Check for long length > 65535. */
|
||||||
if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
|
if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
|
||||||
assert(longLen == 0);
|
assert(longLen == 0);
|
||||||
longLen = n + 1;
|
longLen = n + 1;
|
||||||
@@ -7443,34 +7832,172 @@ BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#elif defined (ZSTD_ARCH_RISCV_RVV)
|
||||||
|
|
||||||
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
|
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
|
||||||
{
|
{
|
||||||
size_t totalMatchSize = 0;
|
size_t totalMatchSize = 0;
|
||||||
size_t litSize = 0;
|
size_t litSize = 0;
|
||||||
size_t n;
|
size_t i = 0;
|
||||||
assert(seqs);
|
int found_terminator = 0;
|
||||||
for (n=0; n<nbSeqs; n++) {
|
size_t vl_max = __riscv_vsetvlmax_e32m1();
|
||||||
totalMatchSize += seqs[n].matchLength;
|
typedef uint32_t __attribute__((may_alias)) aliased_u32;
|
||||||
litSize += seqs[n].litLength;
|
vuint32m1_t v_lit_sum = __riscv_vmv_v_x_u32m1(0, vl_max);
|
||||||
if (seqs[n].matchLength == 0) {
|
vuint32m1_t v_match_sum = __riscv_vmv_v_x_u32m1(0, vl_max);
|
||||||
assert(seqs[n].offset == 0);
|
|
||||||
|
for (; i < nbSeqs; ) {
|
||||||
|
size_t vl = __riscv_vsetvl_e32m2(nbSeqs - i);
|
||||||
|
|
||||||
|
vuint32m2x4_t v_tuple = __riscv_vlseg4e32_v_u32m2x4(
|
||||||
|
(const aliased_u32*)((const void*)&seqs[i]),
|
||||||
|
vl
|
||||||
|
);
|
||||||
|
vuint32m2_t v_lit = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 1);
|
||||||
|
vuint32m2_t v_match = __riscv_vget_v_u32m2x4_u32m2(v_tuple, 2);
|
||||||
|
|
||||||
|
// Check if any element has a matchLength of 0
|
||||||
|
vbool16_t mask = __riscv_vmseq_vx_u32m2_b16(v_match, 0, vl);
|
||||||
|
int first_zero = __riscv_vfirst_m_b16(mask, vl);
|
||||||
|
|
||||||
|
if (first_zero >= 0) {
|
||||||
|
// Find the first zero byte and set the effective length to that index + 1 to
|
||||||
|
// recompute the cumulative vector length of literals and matches
|
||||||
|
vl = first_zero + 1;
|
||||||
|
|
||||||
|
// recompute the cumulative vector length of literals and matches
|
||||||
|
v_lit_sum = __riscv_vredsum_vs_u32m2_u32m1(__riscv_vslidedown_vx_u32m2(v_lit, 0, vl), v_lit_sum, vl);
|
||||||
|
v_match_sum = __riscv_vredsum_vs_u32m2_u32m1(__riscv_vslidedown_vx_u32m2(v_match, 0, vl), v_match_sum, vl);
|
||||||
|
|
||||||
|
i += vl;
|
||||||
|
found_terminator = 1;
|
||||||
|
assert(seqs[i - 1].offset == 0);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
v_lit_sum = __riscv_vredsum_vs_u32m2_u32m1(v_lit, v_lit_sum, vl);
|
||||||
|
v_match_sum = __riscv_vredsum_vs_u32m2_u32m1(v_match, v_match_sum, vl);
|
||||||
|
i += vl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n==nbSeqs) {
|
litSize = __riscv_vmv_x_s_u32m1_u32(v_lit_sum);
|
||||||
|
totalMatchSize = __riscv_vmv_x_s_u32m1_u32(v_match_sum);
|
||||||
|
|
||||||
|
if (!found_terminator && i==nbSeqs) {
|
||||||
BlockSummary bs;
|
BlockSummary bs;
|
||||||
bs.nbSequences = ERROR(externalSequences_invalid);
|
bs.nbSequences = ERROR(externalSequences_invalid);
|
||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
{ BlockSummary bs;
|
{ BlockSummary bs;
|
||||||
bs.nbSequences = n+1;
|
bs.nbSequences = i;
|
||||||
bs.blockSize = litSize + totalMatchSize;
|
bs.blockSize = litSize + totalMatchSize;
|
||||||
bs.litSize = litSize;
|
bs.litSize = litSize;
|
||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The function assumes `litMatchLength` is a packed 64-bit value where the
|
||||||
|
* lower 32 bits represent the match length. The check varies based on the
|
||||||
|
* system's endianness:
|
||||||
|
* - On little-endian systems, it verifies if the entire 64-bit value is at most
|
||||||
|
* 0xFFFFFFFF, indicating the match length (lower 32 bits) is zero.
|
||||||
|
* - On big-endian systems, it directly checks if the lower 32 bits are zero.
|
||||||
|
*
|
||||||
|
* @returns 1 if the match length is zero, 0 otherwise.
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_TEMPLATE int matchLengthHalfIsZero(U64 litMatchLength)
|
||||||
|
{
|
||||||
|
if (MEM_isLittleEndian()) {
|
||||||
|
return litMatchLength <= 0xFFFFFFFFULL;
|
||||||
|
} else {
|
||||||
|
return (U32)litMatchLength == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
|
||||||
|
{
|
||||||
|
/* Use multiple accumulators for efficient use of wide out-of-order machines. */
|
||||||
|
U64 litMatchSize0 = 0;
|
||||||
|
U64 litMatchSize1 = 0;
|
||||||
|
U64 litMatchSize2 = 0;
|
||||||
|
U64 litMatchSize3 = 0;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) + 4 == offsetof(ZSTD_Sequence, matchLength));
|
||||||
|
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) + 4 == offsetof(ZSTD_Sequence, rep));
|
||||||
|
assert(seqs);
|
||||||
|
|
||||||
|
if (nbSeqs > 3) {
|
||||||
|
/* Process the input in 4 independent streams to reach high throughput. */
|
||||||
|
do {
|
||||||
|
/* Load `litLength` and `matchLength` as a packed `U64`. It is safe
|
||||||
|
* to use 64-bit unsigned arithmetic here because the sum of `litLength`
|
||||||
|
* and `matchLength` cannot exceed the block size, so the 32-bit
|
||||||
|
* subparts will never overflow. */
|
||||||
|
U64 litMatchLength = MEM_read64(&seqs[n].litLength);
|
||||||
|
litMatchSize0 += litMatchLength;
|
||||||
|
if (matchLengthHalfIsZero(litMatchLength)) {
|
||||||
|
assert(seqs[n].offset == 0);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
litMatchLength = MEM_read64(&seqs[n + 1].litLength);
|
||||||
|
litMatchSize1 += litMatchLength;
|
||||||
|
if (matchLengthHalfIsZero(litMatchLength)) {
|
||||||
|
n += 1;
|
||||||
|
assert(seqs[n].offset == 0);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
litMatchLength = MEM_read64(&seqs[n + 2].litLength);
|
||||||
|
litMatchSize2 += litMatchLength;
|
||||||
|
if (matchLengthHalfIsZero(litMatchLength)) {
|
||||||
|
n += 2;
|
||||||
|
assert(seqs[n].offset == 0);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
litMatchLength = MEM_read64(&seqs[n + 3].litLength);
|
||||||
|
litMatchSize3 += litMatchLength;
|
||||||
|
if (matchLengthHalfIsZero(litMatchLength)) {
|
||||||
|
n += 3;
|
||||||
|
assert(seqs[n].offset == 0);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
|
||||||
|
n += 4;
|
||||||
|
} while(n < nbSeqs - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; n < nbSeqs; n++) {
|
||||||
|
U64 litMatchLength = MEM_read64(&seqs[n].litLength);
|
||||||
|
litMatchSize0 += litMatchLength;
|
||||||
|
if (matchLengthHalfIsZero(litMatchLength)) {
|
||||||
|
assert(seqs[n].offset == 0);
|
||||||
|
goto _out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* At this point n == nbSeqs, so no end terminator. */
|
||||||
|
{ BlockSummary bs;
|
||||||
|
bs.nbSequences = ERROR(externalSequences_invalid);
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
_out:
|
||||||
|
litMatchSize0 += litMatchSize1 + litMatchSize2 + litMatchSize3;
|
||||||
|
{ BlockSummary bs;
|
||||||
|
bs.nbSequences = n + 1;
|
||||||
|
if (MEM_isLittleEndian()) {
|
||||||
|
bs.litSize = (U32)litMatchSize0;
|
||||||
|
bs.blockSize = bs.litSize + (litMatchSize0 >> 32);
|
||||||
|
} else {
|
||||||
|
bs.litSize = litMatchSize0 >> 32;
|
||||||
|
bs.blockSize = bs.litSize + (U32)litMatchSize0;
|
||||||
|
}
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -707,7 +707,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, ilimit_w - ip, ZSTD_no_overlap);
|
ZSTD_wildcopy(op, ip, (size_t)(ilimit_w - ip), ZSTD_no_overlap);
|
||||||
op += ilimit_w - ip;
|
op += ilimit_w - ip;
|
||||||
ip = ilimit_w;
|
ip = ilimit_w;
|
||||||
}
|
}
|
||||||
@@ -800,7 +800,7 @@ 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, (ptrdiff_t)litLength-16, ZSTD_no_overlap);
|
ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, litLength-16, ZSTD_no_overlap);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);
|
ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);
|
||||||
@@ -1523,7 +1523,7 @@ typedef struct {
|
|||||||
/* for benchmark */
|
/* for benchmark */
|
||||||
size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
|
size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
|
||||||
const ZSTD_Sequence* const inSeqs, size_t nbSequences,
|
const ZSTD_Sequence* const inSeqs, size_t nbSequences,
|
||||||
int const repcodeResolution);
|
int repcodeResolution);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t nbSequences;
|
size_t nbSequences;
|
||||||
|
|||||||
@@ -1050,6 +1050,44 @@ ZSTD_row_getNEONMask(const U32 rowEntries, const BYTE* const src, const BYTE tag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(ZSTD_ARCH_RISCV_RVV) && (__riscv_xlen == 64)
|
||||||
|
FORCE_INLINE_TEMPLATE ZSTD_VecMask
|
||||||
|
ZSTD_row_getRVVMask(int rowEntries, const BYTE* const src, const BYTE tag, const U32 head)
|
||||||
|
{
|
||||||
|
ZSTD_VecMask matches;
|
||||||
|
size_t vl;
|
||||||
|
|
||||||
|
if (rowEntries == 16) {
|
||||||
|
vl = __riscv_vsetvl_e8m1(16);
|
||||||
|
{
|
||||||
|
vuint8m1_t chunk = __riscv_vle8_v_u8m1(src, vl);
|
||||||
|
vbool8_t mask = __riscv_vmseq_vx_u8m1_b8(chunk, tag, vl);
|
||||||
|
vuint16m1_t mask_u16 = __riscv_vreinterpret_v_b8_u16m1(mask);
|
||||||
|
matches = __riscv_vmv_x_s_u16m1_u16(mask_u16);
|
||||||
|
return ZSTD_rotateRight_U16((U16)matches, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (rowEntries == 32) {
|
||||||
|
vl = __riscv_vsetvl_e8m2(32);
|
||||||
|
{
|
||||||
|
vuint8m2_t chunk = __riscv_vle8_v_u8m2(src, vl);
|
||||||
|
vbool4_t mask = __riscv_vmseq_vx_u8m2_b4(chunk, tag, vl);
|
||||||
|
vuint32m1_t mask_u32 = __riscv_vreinterpret_v_b4_u32m1(mask);
|
||||||
|
matches = __riscv_vmv_x_s_u32m1_u32(mask_u32);
|
||||||
|
return ZSTD_rotateRight_U32((U32)matches, head);
|
||||||
|
}
|
||||||
|
} else { // rowEntries = 64
|
||||||
|
vl = __riscv_vsetvl_e8m4(64);
|
||||||
|
{
|
||||||
|
vuint8m4_t chunk = __riscv_vle8_v_u8m4(src, vl);
|
||||||
|
vbool2_t mask = __riscv_vmseq_vx_u8m4_b2(chunk, tag, vl);
|
||||||
|
vuint64m1_t mask_u64 = __riscv_vreinterpret_v_b2_u64m1(mask);
|
||||||
|
matches = __riscv_vmv_x_s_u64m1_u64(mask_u64);
|
||||||
|
return ZSTD_rotateRight_U64(matches, head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Returns a ZSTD_VecMask (U64) that has the nth group (determined by
|
/* Returns a ZSTD_VecMask (U64) that has the nth group (determined by
|
||||||
* ZSTD_row_matchMaskGroupWidth) of bits set to 1 if the newly-computed "tag"
|
* ZSTD_row_matchMaskGroupWidth) of bits set to 1 if the newly-computed "tag"
|
||||||
@@ -1069,14 +1107,20 @@ ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 headGr
|
|||||||
|
|
||||||
return ZSTD_row_getSSEMask(rowEntries / 16, src, tag, headGrouped);
|
return ZSTD_row_getSSEMask(rowEntries / 16, src, tag, headGrouped);
|
||||||
|
|
||||||
#else /* SW or NEON-LE */
|
#elif defined(ZSTD_ARCH_RISCV_RVV) && (__riscv_xlen == 64)
|
||||||
|
|
||||||
# if defined(ZSTD_ARCH_ARM_NEON)
|
return ZSTD_row_getRVVMask(rowEntries, src, tag, headGrouped);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if defined(ZSTD_ARCH_ARM_NEON)
|
||||||
/* This NEON path only works for little endian - otherwise use SWAR below */
|
/* This NEON path only works for little endian - otherwise use SWAR below */
|
||||||
if (MEM_isLittleEndian()) {
|
if (MEM_isLittleEndian()) {
|
||||||
return ZSTD_row_getNEONMask(rowEntries, src, tag, headGrouped);
|
return ZSTD_row_getNEONMask(rowEntries, src, tag, headGrouped);
|
||||||
}
|
}
|
||||||
# endif /* ZSTD_ARCH_ARM_NEON */
|
|
||||||
|
|
||||||
|
#endif
|
||||||
/* SWAR */
|
/* SWAR */
|
||||||
{ const int chunkSize = sizeof(size_t);
|
{ const int chunkSize = sizeof(size_t);
|
||||||
const size_t shiftAmount = ((chunkSize * 8) - chunkSize);
|
const size_t shiftAmount = ((chunkSize * 8) - chunkSize);
|
||||||
|
|||||||
@@ -152,7 +152,11 @@ void ZSTD_ldm_adjustParameters(ldmParams_t* params,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params->hashLog == 0) {
|
if (params->hashLog == 0) {
|
||||||
params->hashLog = BOUNDED(ZSTD_HASHLOG_MIN, params->windowLog - params->hashRateLog, ZSTD_HASHLOG_MAX);
|
if (params->windowLog <= params->hashRateLog) {
|
||||||
|
params->hashLog = ZSTD_HASHLOG_MIN;
|
||||||
|
} else {
|
||||||
|
params->hashLog = BOUNDED(ZSTD_HASHLOG_MIN, params->windowLog - params->hashRateLog, ZSTD_HASHLOG_MAX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (params->minMatchLength == 0) {
|
if (params->minMatchLength == 0) {
|
||||||
params->minMatchLength = LDM_MIN_MATCH_LENGTH;
|
params->minMatchLength = LDM_MIN_MATCH_LENGTH;
|
||||||
|
|||||||
+2
-10
@@ -1382,16 +1382,8 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||||||
assert(storeEnd < ZSTD_OPT_SIZE);
|
assert(storeEnd < ZSTD_OPT_SIZE);
|
||||||
DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
|
DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
|
||||||
storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off);
|
storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off);
|
||||||
if (lastStretch.litlen > 0) {
|
opt[storeEnd] = lastStretch; /* note: litlen will be fixed */
|
||||||
/* last "sequence" is unfinished: just a bunch of literals */
|
storeStart = storeEnd;
|
||||||
opt[storeEnd].litlen = lastStretch.litlen;
|
|
||||||
opt[storeEnd].mlen = 0;
|
|
||||||
storeStart = storeEnd-1;
|
|
||||||
opt[storeStart] = lastStretch;
|
|
||||||
} {
|
|
||||||
opt[storeEnd] = lastStretch; /* note: litlen will be fixed */
|
|
||||||
storeStart = storeEnd;
|
|
||||||
}
|
|
||||||
while (1) {
|
while (1) {
|
||||||
ZSTD_optimal_t nextStretch = opt[stretchPos];
|
ZSTD_optimal_t nextStretch = opt[stretchPos];
|
||||||
opt[storeStart].litlen = nextStretch.litlen;
|
opt[storeStart].litlen = nextStretch.litlen;
|
||||||
|
|||||||
@@ -1008,18 +1008,20 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
|
|||||||
{
|
{
|
||||||
unsigned jobID;
|
unsigned jobID;
|
||||||
DEBUGLOG(3, "ZSTDMT_releaseAllJobResources");
|
DEBUGLOG(3, "ZSTDMT_releaseAllJobResources");
|
||||||
for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
|
if (mtctx->jobs) {
|
||||||
/* Copy the mutex/cond out */
|
for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
|
||||||
ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;
|
/* Copy the mutex/cond out */
|
||||||
ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond;
|
ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;
|
||||||
|
ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond;
|
||||||
DEBUGLOG(4, "job%02u: release dst address %08X", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start);
|
|
||||||
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
|
DEBUGLOG(4, "job%02u: release dst address %08X", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start);
|
||||||
|
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
|
||||||
/* Clear the job description, but keep the mutex/cond */
|
|
||||||
ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
|
/* Clear the job description, but keep the mutex/cond */
|
||||||
mtctx->jobs[jobID].job_mutex = mutex;
|
ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
|
||||||
mtctx->jobs[jobID].job_cond = cond;
|
mtctx->jobs[jobID].job_mutex = mutex;
|
||||||
|
mtctx->jobs[jobID].job_cond = cond;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mtctx->inBuff.buffer = g_nullBuffer;
|
mtctx->inBuff.buffer = g_nullBuffer;
|
||||||
mtctx->inBuff.filled = 0;
|
mtctx->inBuff.filled = 0;
|
||||||
@@ -1268,8 +1270,7 @@ size_t ZSTDMT_initCStream_internal(
|
|||||||
|
|
||||||
if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
|
if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
|
||||||
ZSTDMT_waitForAllJobsCompleted(mtctx);
|
ZSTDMT_waitForAllJobsCompleted(mtctx);
|
||||||
ZSTDMT_releaseAllJobResources(mtctx);
|
ZSTDMT_releaseAllJobResources(mtctx); /* Will set allJobsCompleted to 1 */
|
||||||
mtctx->allJobsCompleted = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtctx->params = params;
|
mtctx->params = params;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
|
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
|
||||||
#include "../common/compiler.h"
|
#include "../common/compiler.h"
|
||||||
#include "../common/bitstream.h" /* BIT_* */
|
#include "../common/bitstream.h" /* BIT_* */
|
||||||
@@ -195,7 +196,7 @@ static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* ds
|
|||||||
|
|
||||||
const BYTE* const istart = (const BYTE*)src;
|
const BYTE* const istart = (const BYTE*)src;
|
||||||
|
|
||||||
BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize);
|
BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
|
||||||
|
|
||||||
/* The fast decoding loop assumes 64-bit little-endian.
|
/* The fast decoding loop assumes 64-bit little-endian.
|
||||||
* This condition is false on x32.
|
* This condition is false on x32.
|
||||||
@@ -578,7 +579,7 @@ HUF_decompress1X1_usingDTable_internal_body(
|
|||||||
const HUF_DTable* DTable)
|
const HUF_DTable* DTable)
|
||||||
{
|
{
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
BYTE* const oend = ZSTD_maybeNullPtrAdd(op, dstSize);
|
BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(op, (ptrdiff_t)dstSize);
|
||||||
const void* dtPtr = DTable + 1;
|
const void* dtPtr = DTable + 1;
|
||||||
const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
|
const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
|
||||||
BIT_DStream_t bitD;
|
BIT_DStream_t bitD;
|
||||||
@@ -784,19 +785,19 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \
|
#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \
|
||||||
do { \
|
do { \
|
||||||
int const index = (int)(bits[(_stream)] >> 53); \
|
U64 const index = bits[(_stream)] >> 53; \
|
||||||
int const entry = (int)dtable[index]; \
|
U16 const entry = dtable[index]; \
|
||||||
bits[(_stream)] <<= (entry & 0x3F); \
|
bits[(_stream)] <<= entry & 0x3F; \
|
||||||
op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \
|
op[(_stream)][(_symbol)] = (BYTE)(entry >> 8); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define HUF_4X1_RELOAD_STREAM(_stream) \
|
#define HUF_5X1_RELOAD_STREAM(_stream) \
|
||||||
do { \
|
do { \
|
||||||
int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
U64 const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||||
int const nbBits = ctz & 7; \
|
U64 const nbBits = ctz & 7; \
|
||||||
int const nbBytes = ctz >> 3; \
|
U64 const nbBytes = ctz >> 3; \
|
||||||
op[(_stream)] += 5; \
|
op[(_stream)] += 5; \
|
||||||
ip[(_stream)] -= nbBytes; \
|
ip[(_stream)] -= nbBytes; \
|
||||||
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
||||||
@@ -815,11 +816,11 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4);
|
||||||
|
|
||||||
/* Reload each of the 4 the bitstreams */
|
/* Reload each of the 4 the bitstreams */
|
||||||
HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM);
|
HUF_4X_FOR_EACH_STREAM(HUF_5X1_RELOAD_STREAM);
|
||||||
} while (op[3] < olimit);
|
} while (op[3] < olimit);
|
||||||
|
|
||||||
#undef HUF_4X1_DECODE_SYMBOL
|
#undef HUF_4X1_DECODE_SYMBOL
|
||||||
#undef HUF_4X1_RELOAD_STREAM
|
#undef HUF_5X1_RELOAD_STREAM
|
||||||
}
|
}
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
@@ -845,7 +846,7 @@ HUF_decompress4X1_usingDTable_internal_fast(
|
|||||||
{
|
{
|
||||||
void const* dt = DTable + 1;
|
void const* dt = DTable + 1;
|
||||||
BYTE const* const ilowest = (BYTE const*)cSrc;
|
BYTE const* const ilowest = (BYTE const*)cSrc;
|
||||||
BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize);
|
BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
|
||||||
HUF_DecompressFastArgs args;
|
HUF_DecompressFastArgs args;
|
||||||
{ size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
|
{ size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
|
||||||
FORWARD_IF_ERROR(ret, "Failed to init fast loop args");
|
FORWARD_IF_ERROR(ret, "Failed to init fast loop args");
|
||||||
@@ -1362,7 +1363,7 @@ HUF_decompress1X2_usingDTable_internal_body(
|
|||||||
|
|
||||||
/* decode */
|
/* decode */
|
||||||
{ BYTE* const ostart = (BYTE*) dst;
|
{ BYTE* const ostart = (BYTE*) dst;
|
||||||
BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, dstSize);
|
BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(ostart, (ptrdiff_t)dstSize);
|
||||||
const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */
|
const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */
|
||||||
const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
|
const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
|
||||||
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||||
@@ -1602,57 +1603,65 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \
|
#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \
|
||||||
do { \
|
do { \
|
||||||
if ((_decode3) || (_stream) != 3) { \
|
if ((_decode3) || (_stream) != 3) { \
|
||||||
int const index = (int)(bits[(_stream)] >> 53); \
|
U64 const index = bits[(_stream)] >> 53; \
|
||||||
HUF_DEltX2 const entry = dtable[index]; \
|
size_t const entry = MEM_readLE32(&dtable[index]); \
|
||||||
MEM_write16(op[(_stream)], entry.sequence); \
|
MEM_write16(op[(_stream)], (U16)entry); \
|
||||||
bits[(_stream)] <<= (entry.nbBits) & 0x3F; \
|
bits[(_stream)] <<= (entry >> 16) & 0x3F; \
|
||||||
op[(_stream)] += (entry.length); \
|
op[(_stream)] += entry >> 24; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define HUF_4X2_RELOAD_STREAM(_stream) \
|
#define HUF_5X2_RELOAD_STREAM(_stream, _decode3) \
|
||||||
do { \
|
do { \
|
||||||
HUF_4X2_DECODE_SYMBOL(3, 1); \
|
if (_decode3) HUF_4X2_DECODE_SYMBOL(3, 1); \
|
||||||
{ \
|
{ \
|
||||||
int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
U64 const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||||
int const nbBits = ctz & 7; \
|
U64 const nbBits = ctz & 7; \
|
||||||
int const nbBytes = ctz >> 3; \
|
U64 const nbBytes = ctz >> 3; \
|
||||||
ip[(_stream)] -= nbBytes; \
|
ip[(_stream)] -= nbBytes; \
|
||||||
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
||||||
bits[(_stream)] <<= nbBits; \
|
bits[(_stream)] <<= nbBits; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
# define HUF_4X2_4WAY 1
|
||||||
|
#else
|
||||||
|
# define HUF_4X2_4WAY 0
|
||||||
|
#endif
|
||||||
|
#define HUF_4X2_3WAY !HUF_4X2_4WAY
|
||||||
|
|
||||||
/* Manually unroll the loop because compilers don't consistently
|
/* Manually unroll the loop because compilers don't consistently
|
||||||
* unroll the inner loops, which destroys performance.
|
* unroll the inner loops, which destroys performance.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
/* Decode 5 symbols from each of the first 3 streams.
|
/* Decode 5 symbols from each of the first 3 or 4 streams.
|
||||||
* The final stream will be decoded during the reload phase
|
* In the 3-way case the final stream will be decoded during
|
||||||
* to reduce register pressure.
|
* the reload phase to reduce register pressure.
|
||||||
*/
|
*/
|
||||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
|
||||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
|
||||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
|
||||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
|
||||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
|
||||||
|
|
||||||
/* Decode one symbol from the final stream */
|
/* In the 3-way case decode one symbol from the final stream. */
|
||||||
HUF_4X2_DECODE_SYMBOL(3, 1);
|
HUF_4X2_DECODE_SYMBOL(3, HUF_4X2_3WAY);
|
||||||
|
|
||||||
/* Decode 4 symbols from the final stream & reload bitstreams.
|
/* In the 3-way case decode 4 symbols from the final stream &
|
||||||
* The final stream is reloaded last, meaning that all 5 symbols
|
* reload bitstreams. The final stream is reloaded last, meaning
|
||||||
* are decoded from the final stream before it is reloaded.
|
* that all 5 symbols are decoded from the final stream before
|
||||||
|
* it is reloaded.
|
||||||
*/
|
*/
|
||||||
HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM);
|
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_5X2_RELOAD_STREAM, HUF_4X2_3WAY);
|
||||||
} while (op[3] < olimit);
|
} while (op[3] < olimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef HUF_4X2_DECODE_SYMBOL
|
#undef HUF_4X2_DECODE_SYMBOL
|
||||||
#undef HUF_4X2_RELOAD_STREAM
|
#undef HUF_5X2_RELOAD_STREAM
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
|
|
||||||
@@ -1671,7 +1680,7 @@ HUF_decompress4X2_usingDTable_internal_fast(
|
|||||||
HUF_DecompressFastLoopFn loopFn) {
|
HUF_DecompressFastLoopFn loopFn) {
|
||||||
void const* dt = DTable + 1;
|
void const* dt = DTable + 1;
|
||||||
const BYTE* const ilowest = (const BYTE*)cSrc;
|
const BYTE* const ilowest = (const BYTE*)cSrc;
|
||||||
BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize);
|
BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)dstSize);
|
||||||
HUF_DecompressFastArgs args;
|
HUF_DecompressFastArgs args;
|
||||||
{
|
{
|
||||||
size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
|
size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
|
||||||
|
|||||||
@@ -38,6 +38,16 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// There appears to be an unreconcilable syntax difference between Linux and Darwin assemblers.
|
||||||
|
// Name of a private label (i.e. not exported to symbol table) on Darwin has to start with "L",
|
||||||
|
// on Linux has to start with ".". There's no way to have a name start with both "." and "L", so
|
||||||
|
// we have to use a macro.
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#define LOCAL_LABEL(label) L_ ## label
|
||||||
|
#else
|
||||||
|
#define LOCAL_LABEL(label) .L_ ## label
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ZSTD_ENABLE_ASM_X86_64_BMI2
|
#if ZSTD_ENABLE_ASM_X86_64_BMI2
|
||||||
|
|
||||||
/* Calling convention:
|
/* Calling convention:
|
||||||
@@ -117,22 +127,55 @@ ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X1_usingDTable_internal_fast_asm_loop)
|
|||||||
_HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
_HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
||||||
HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
||||||
ZSTD_CET_ENDBRANCH
|
ZSTD_CET_ENDBRANCH
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
.cfi_offset %rip, -8
|
||||||
/* Save all registers - even if they are callee saved for simplicity. */
|
/* Save all registers - even if they are callee saved for simplicity. */
|
||||||
push %rax
|
push %rax
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
.cfi_offset rax, -16
|
||||||
push %rbx
|
push %rbx
|
||||||
|
.cfi_def_cfa_offset 24
|
||||||
|
.cfi_offset rbx, -24
|
||||||
push %rcx
|
push %rcx
|
||||||
|
.cfi_def_cfa_offset 32
|
||||||
|
.cfi_offset rcx, -32
|
||||||
push %rdx
|
push %rdx
|
||||||
|
.cfi_def_cfa_offset 40
|
||||||
|
.cfi_offset rdx, -40
|
||||||
push %rbp
|
push %rbp
|
||||||
|
.cfi_def_cfa_offset 48
|
||||||
|
.cfi_offset rbp, -48
|
||||||
push %rsi
|
push %rsi
|
||||||
|
.cfi_def_cfa_offset 56
|
||||||
|
.cfi_offset rsi, -56
|
||||||
push %rdi
|
push %rdi
|
||||||
|
.cfi_def_cfa_offset 64
|
||||||
|
.cfi_offset rdi, -64
|
||||||
push %r8
|
push %r8
|
||||||
|
.cfi_def_cfa_offset 72
|
||||||
|
.cfi_offset r8, -72
|
||||||
push %r9
|
push %r9
|
||||||
|
.cfi_def_cfa_offset 80
|
||||||
|
.cfi_offset r9, -80
|
||||||
push %r10
|
push %r10
|
||||||
|
.cfi_def_cfa_offset 88
|
||||||
|
.cfi_offset r10, -88
|
||||||
push %r11
|
push %r11
|
||||||
|
.cfi_def_cfa_offset 96
|
||||||
|
.cfi_offset r11, -96
|
||||||
push %r12
|
push %r12
|
||||||
|
.cfi_def_cfa_offset 104
|
||||||
|
.cfi_offset r12, -104
|
||||||
push %r13
|
push %r13
|
||||||
|
.cfi_def_cfa_offset 112
|
||||||
|
.cfi_offset r13, -112
|
||||||
push %r14
|
push %r14
|
||||||
|
.cfi_def_cfa_offset 120
|
||||||
|
.cfi_offset r14, -120
|
||||||
push %r15
|
push %r15
|
||||||
|
.cfi_def_cfa_offset 128
|
||||||
|
.cfi_offset r15, -128
|
||||||
|
|
||||||
/* Read HUF_DecompressAsmArgs* args from %rax */
|
/* Read HUF_DecompressAsmArgs* args from %rax */
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@@ -154,13 +197,18 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||||||
movq 88(%rax), %bits3
|
movq 88(%rax), %bits3
|
||||||
movq 96(%rax), %dtable
|
movq 96(%rax), %dtable
|
||||||
push %rax /* argument */
|
push %rax /* argument */
|
||||||
|
.cfi_def_cfa_offset 136
|
||||||
push 104(%rax) /* ilowest */
|
push 104(%rax) /* ilowest */
|
||||||
|
.cfi_def_cfa_offset 144
|
||||||
push 112(%rax) /* oend */
|
push 112(%rax) /* oend */
|
||||||
|
.cfi_def_cfa_offset 152
|
||||||
push %olimit /* olimit space */
|
push %olimit /* olimit space */
|
||||||
|
.cfi_def_cfa_offset 160
|
||||||
|
|
||||||
subq $24, %rsp
|
subq $24, %rsp
|
||||||
|
.cfi_def_cfa_offset 184
|
||||||
|
|
||||||
.L_4X1_compute_olimit:
|
LOCAL_LABEL(4X1_compute_olimit):
|
||||||
/* Computes how many iterations we can do safely
|
/* Computes how many iterations we can do safely
|
||||||
* %r15, %rax may be clobbered
|
* %r15, %rax may be clobbered
|
||||||
* rbx, rdx must be saved
|
* rbx, rdx must be saved
|
||||||
@@ -207,19 +255,19 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||||||
/* If (op3 + 20 > olimit) */
|
/* If (op3 + 20 > olimit) */
|
||||||
movq %op3, %rax /* rax = op3 */
|
movq %op3, %rax /* rax = op3 */
|
||||||
cmpq %rax, %olimit /* op3 == olimit */
|
cmpq %rax, %olimit /* op3 == olimit */
|
||||||
je .L_4X1_exit
|
je LOCAL_LABEL(4X1_exit)
|
||||||
|
|
||||||
/* If (ip1 < ip0) go to exit */
|
/* If (ip1 < ip0) go to exit */
|
||||||
cmpq %ip0, %ip1
|
cmpq %ip0, %ip1
|
||||||
jb .L_4X1_exit
|
jb LOCAL_LABEL(4X1_exit)
|
||||||
|
|
||||||
/* If (ip2 < ip1) go to exit */
|
/* If (ip2 < ip1) go to exit */
|
||||||
cmpq %ip1, %ip2
|
cmpq %ip1, %ip2
|
||||||
jb .L_4X1_exit
|
jb LOCAL_LABEL(4X1_exit)
|
||||||
|
|
||||||
/* If (ip3 < ip2) go to exit */
|
/* If (ip3 < ip2) go to exit */
|
||||||
cmpq %ip2, %ip3
|
cmpq %ip2, %ip3
|
||||||
jb .L_4X1_exit
|
jb LOCAL_LABEL(4X1_exit)
|
||||||
|
|
||||||
/* Reads top 11 bits from bits[n]
|
/* Reads top 11 bits from bits[n]
|
||||||
* Loads dt[bits[n]] into var[n]
|
* Loads dt[bits[n]] into var[n]
|
||||||
@@ -280,7 +328,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||||||
|
|
||||||
.p2align 6
|
.p2align 6
|
||||||
|
|
||||||
.L_4X1_loop_body:
|
LOCAL_LABEL(4X1_loop_body):
|
||||||
/* Decode 5 symbols in each of the 4 streams (20 total)
|
/* Decode 5 symbols in each of the 4 streams (20 total)
|
||||||
* Must have called GET_NEXT_DELT for each stream
|
* Must have called GET_NEXT_DELT for each stream
|
||||||
*/
|
*/
|
||||||
@@ -318,7 +366,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||||||
|
|
||||||
/* If op3 < olimit: continue the loop */
|
/* If op3 < olimit: continue the loop */
|
||||||
cmp %op3, 24(%rsp)
|
cmp %op3, 24(%rsp)
|
||||||
ja .L_4X1_loop_body
|
ja LOCAL_LABEL(4X1_loop_body)
|
||||||
|
|
||||||
/* Reload ip[1,2,3] from stack */
|
/* Reload ip[1,2,3] from stack */
|
||||||
movq 0(%rsp), %ip1
|
movq 0(%rsp), %ip1
|
||||||
@@ -326,20 +374,25 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||||||
movq 16(%rsp), %ip3
|
movq 16(%rsp), %ip3
|
||||||
|
|
||||||
/* Re-compute olimit */
|
/* Re-compute olimit */
|
||||||
jmp .L_4X1_compute_olimit
|
jmp LOCAL_LABEL(4X1_compute_olimit)
|
||||||
|
|
||||||
#undef GET_NEXT_DELT
|
#undef GET_NEXT_DELT
|
||||||
#undef DECODE_FROM_DELT
|
#undef DECODE_FROM_DELT
|
||||||
#undef DECODE
|
#undef DECODE
|
||||||
#undef RELOAD_BITS
|
#undef RELOAD_BITS
|
||||||
.L_4X1_exit:
|
LOCAL_LABEL(4X1_exit):
|
||||||
addq $24, %rsp
|
addq $24, %rsp
|
||||||
|
.cfi_def_cfa_offset 160
|
||||||
|
|
||||||
/* Restore stack (oend & olimit) */
|
/* Restore stack (oend & olimit) */
|
||||||
pop %rax /* olimit */
|
pop %rax /* olimit */
|
||||||
|
.cfi_def_cfa_offset 152
|
||||||
pop %rax /* oend */
|
pop %rax /* oend */
|
||||||
|
.cfi_def_cfa_offset 144
|
||||||
pop %rax /* ilowest */
|
pop %rax /* ilowest */
|
||||||
|
.cfi_def_cfa_offset 136
|
||||||
pop %rax /* arg */
|
pop %rax /* arg */
|
||||||
|
.cfi_def_cfa_offset 128
|
||||||
|
|
||||||
/* Save ip / op / bits */
|
/* Save ip / op / bits */
|
||||||
movq %ip0, 0(%rax)
|
movq %ip0, 0(%rax)
|
||||||
@@ -357,41 +410,105 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||||||
|
|
||||||
/* Restore registers */
|
/* Restore registers */
|
||||||
pop %r15
|
pop %r15
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_def_cfa_offset 120
|
||||||
pop %r14
|
pop %r14
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_def_cfa_offset 112
|
||||||
pop %r13
|
pop %r13
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_def_cfa_offset 104
|
||||||
pop %r12
|
pop %r12
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_def_cfa_offset 96
|
||||||
pop %r11
|
pop %r11
|
||||||
|
.cfi_restore r11
|
||||||
|
.cfi_def_cfa_offset 88
|
||||||
pop %r10
|
pop %r10
|
||||||
|
.cfi_restore r10
|
||||||
|
.cfi_def_cfa_offset 80
|
||||||
pop %r9
|
pop %r9
|
||||||
|
.cfi_restore r9
|
||||||
|
.cfi_def_cfa_offset 72
|
||||||
pop %r8
|
pop %r8
|
||||||
|
.cfi_restore r8
|
||||||
|
.cfi_def_cfa_offset 64
|
||||||
pop %rdi
|
pop %rdi
|
||||||
|
.cfi_restore rdi
|
||||||
|
.cfi_def_cfa_offset 56
|
||||||
pop %rsi
|
pop %rsi
|
||||||
|
.cfi_restore rsi
|
||||||
|
.cfi_def_cfa_offset 48
|
||||||
pop %rbp
|
pop %rbp
|
||||||
|
.cfi_restore rbp
|
||||||
|
.cfi_def_cfa_offset 40
|
||||||
pop %rdx
|
pop %rdx
|
||||||
|
.cfi_restore rdx
|
||||||
|
.cfi_def_cfa_offset 32
|
||||||
pop %rcx
|
pop %rcx
|
||||||
|
.cfi_restore rcx
|
||||||
|
.cfi_def_cfa_offset 24
|
||||||
pop %rbx
|
pop %rbx
|
||||||
|
.cfi_restore rbx
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
pop %rax
|
pop %rax
|
||||||
|
.cfi_restore rax
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
_HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
_HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
||||||
HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
||||||
ZSTD_CET_ENDBRANCH
|
ZSTD_CET_ENDBRANCH
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
|
.cfi_offset %rip, -8
|
||||||
/* Save all registers - even if they are callee saved for simplicity. */
|
/* Save all registers - even if they are callee saved for simplicity. */
|
||||||
push %rax
|
push %rax
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
|
.cfi_offset rax, -16
|
||||||
push %rbx
|
push %rbx
|
||||||
|
.cfi_def_cfa_offset 24
|
||||||
|
.cfi_offset rbx, -24
|
||||||
push %rcx
|
push %rcx
|
||||||
|
.cfi_def_cfa_offset 32
|
||||||
|
.cfi_offset rcx, -32
|
||||||
push %rdx
|
push %rdx
|
||||||
|
.cfi_def_cfa_offset 40
|
||||||
|
.cfi_offset rdx, -40
|
||||||
push %rbp
|
push %rbp
|
||||||
|
.cfi_def_cfa_offset 48
|
||||||
|
.cfi_offset rbp, -48
|
||||||
push %rsi
|
push %rsi
|
||||||
|
.cfi_def_cfa_offset 56
|
||||||
|
.cfi_offset rsi, -56
|
||||||
push %rdi
|
push %rdi
|
||||||
|
.cfi_def_cfa_offset 64
|
||||||
|
.cfi_offset rdi, -64
|
||||||
push %r8
|
push %r8
|
||||||
|
.cfi_def_cfa_offset 72
|
||||||
|
.cfi_offset r8, -72
|
||||||
push %r9
|
push %r9
|
||||||
|
.cfi_def_cfa_offset 80
|
||||||
|
.cfi_offset r9, -80
|
||||||
push %r10
|
push %r10
|
||||||
|
.cfi_def_cfa_offset 88
|
||||||
|
.cfi_offset r10, -88
|
||||||
push %r11
|
push %r11
|
||||||
|
.cfi_def_cfa_offset 96
|
||||||
|
.cfi_offset r11, -96
|
||||||
push %r12
|
push %r12
|
||||||
|
.cfi_def_cfa_offset 104
|
||||||
|
.cfi_offset r12, -104
|
||||||
push %r13
|
push %r13
|
||||||
|
.cfi_def_cfa_offset 112
|
||||||
|
.cfi_offset r13, -112
|
||||||
push %r14
|
push %r14
|
||||||
|
.cfi_def_cfa_offset 120
|
||||||
|
.cfi_offset r14, -120
|
||||||
push %r15
|
push %r15
|
||||||
|
.cfi_def_cfa_offset 128
|
||||||
|
.cfi_offset r15, -128
|
||||||
|
|
||||||
/* Read HUF_DecompressAsmArgs* args from %rax */
|
/* Read HUF_DecompressAsmArgs* args from %rax */
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@@ -413,25 +530,33 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||||||
movq 88(%rax), %bits3
|
movq 88(%rax), %bits3
|
||||||
movq 96(%rax), %dtable
|
movq 96(%rax), %dtable
|
||||||
push %rax /* argument */
|
push %rax /* argument */
|
||||||
|
.cfi_def_cfa_offset 136
|
||||||
push %rax /* olimit */
|
push %rax /* olimit */
|
||||||
|
.cfi_def_cfa_offset 144
|
||||||
push 104(%rax) /* ilowest */
|
push 104(%rax) /* ilowest */
|
||||||
|
.cfi_def_cfa_offset 152
|
||||||
|
|
||||||
movq 112(%rax), %rax
|
movq 112(%rax), %rax
|
||||||
push %rax /* oend3 */
|
push %rax /* oend3 */
|
||||||
|
.cfi_def_cfa_offset 160
|
||||||
|
|
||||||
movq %op3, %rax
|
movq %op3, %rax
|
||||||
push %rax /* oend2 */
|
push %rax /* oend2 */
|
||||||
|
.cfi_def_cfa_offset 168
|
||||||
|
|
||||||
movq %op2, %rax
|
movq %op2, %rax
|
||||||
push %rax /* oend1 */
|
push %rax /* oend1 */
|
||||||
|
.cfi_def_cfa_offset 176
|
||||||
|
|
||||||
movq %op1, %rax
|
movq %op1, %rax
|
||||||
push %rax /* oend0 */
|
push %rax /* oend0 */
|
||||||
|
.cfi_def_cfa_offset 184
|
||||||
|
|
||||||
/* Scratch space */
|
/* Scratch space */
|
||||||
subq $8, %rsp
|
subq $8, %rsp
|
||||||
|
.cfi_def_cfa_offset 192
|
||||||
|
|
||||||
.L_4X2_compute_olimit:
|
LOCAL_LABEL(4X2_compute_olimit):
|
||||||
/* Computes how many iterations we can do safely
|
/* Computes how many iterations we can do safely
|
||||||
* %r15, %rax may be clobbered
|
* %r15, %rax may be clobbered
|
||||||
* rdx must be saved
|
* rdx must be saved
|
||||||
@@ -495,19 +620,19 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||||||
/* If (op3 + 10 > olimit) */
|
/* If (op3 + 10 > olimit) */
|
||||||
movq %op3, %rax /* rax = op3 */
|
movq %op3, %rax /* rax = op3 */
|
||||||
cmpq %rax, %olimit /* op3 == olimit */
|
cmpq %rax, %olimit /* op3 == olimit */
|
||||||
je .L_4X2_exit
|
je LOCAL_LABEL(4X2_exit)
|
||||||
|
|
||||||
/* If (ip1 < ip0) go to exit */
|
/* If (ip1 < ip0) go to exit */
|
||||||
cmpq %ip0, %ip1
|
cmpq %ip0, %ip1
|
||||||
jb .L_4X2_exit
|
jb LOCAL_LABEL(4X2_exit)
|
||||||
|
|
||||||
/* If (ip2 < ip1) go to exit */
|
/* If (ip2 < ip1) go to exit */
|
||||||
cmpq %ip1, %ip2
|
cmpq %ip1, %ip2
|
||||||
jb .L_4X2_exit
|
jb LOCAL_LABEL(4X2_exit)
|
||||||
|
|
||||||
/* If (ip3 < ip2) go to exit */
|
/* If (ip3 < ip2) go to exit */
|
||||||
cmpq %ip2, %ip3
|
cmpq %ip2, %ip3
|
||||||
jb .L_4X2_exit
|
jb LOCAL_LABEL(4X2_exit)
|
||||||
|
|
||||||
#define DECODE(n, idx) \
|
#define DECODE(n, idx) \
|
||||||
movq %bits##n, %rax; \
|
movq %bits##n, %rax; \
|
||||||
@@ -534,7 +659,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||||||
|
|
||||||
.p2align 6
|
.p2align 6
|
||||||
|
|
||||||
.L_4X2_loop_body:
|
LOCAL_LABEL(4X2_loop_body):
|
||||||
/* We clobber r8, so store it on the stack */
|
/* We clobber r8, so store it on the stack */
|
||||||
movq %r8, 0(%rsp)
|
movq %r8, 0(%rsp)
|
||||||
|
|
||||||
@@ -551,21 +676,29 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||||||
FOR_EACH_STREAM(RELOAD_BITS)
|
FOR_EACH_STREAM(RELOAD_BITS)
|
||||||
|
|
||||||
cmp %op3, 48(%rsp)
|
cmp %op3, 48(%rsp)
|
||||||
ja .L_4X2_loop_body
|
ja LOCAL_LABEL(4X2_loop_body)
|
||||||
jmp .L_4X2_compute_olimit
|
jmp LOCAL_LABEL(4X2_compute_olimit)
|
||||||
|
|
||||||
#undef DECODE
|
#undef DECODE
|
||||||
#undef RELOAD_BITS
|
#undef RELOAD_BITS
|
||||||
.L_4X2_exit:
|
LOCAL_LABEL(4X2_exit):
|
||||||
addq $8, %rsp
|
addq $8, %rsp
|
||||||
|
.cfi_def_cfa_offset 184
|
||||||
/* Restore stack (oend & olimit) */
|
/* Restore stack (oend & olimit) */
|
||||||
pop %rax /* oend0 */
|
pop %rax /* oend0 */
|
||||||
|
.cfi_def_cfa_offset 176
|
||||||
pop %rax /* oend1 */
|
pop %rax /* oend1 */
|
||||||
|
.cfi_def_cfa_offset 168
|
||||||
pop %rax /* oend2 */
|
pop %rax /* oend2 */
|
||||||
|
.cfi_def_cfa_offset 160
|
||||||
pop %rax /* oend3 */
|
pop %rax /* oend3 */
|
||||||
|
.cfi_def_cfa_offset 152
|
||||||
pop %rax /* ilowest */
|
pop %rax /* ilowest */
|
||||||
|
.cfi_def_cfa_offset 144
|
||||||
pop %rax /* olimit */
|
pop %rax /* olimit */
|
||||||
|
.cfi_def_cfa_offset 136
|
||||||
pop %rax /* arg */
|
pop %rax /* arg */
|
||||||
|
.cfi_def_cfa_offset 128
|
||||||
|
|
||||||
/* Save ip / op / bits */
|
/* Save ip / op / bits */
|
||||||
movq %ip0, 0(%rax)
|
movq %ip0, 0(%rax)
|
||||||
@@ -583,20 +716,51 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||||||
|
|
||||||
/* Restore registers */
|
/* Restore registers */
|
||||||
pop %r15
|
pop %r15
|
||||||
|
.cfi_restore r15
|
||||||
|
.cfi_def_cfa_offset 120
|
||||||
pop %r14
|
pop %r14
|
||||||
|
.cfi_restore r14
|
||||||
|
.cfi_def_cfa_offset 112
|
||||||
pop %r13
|
pop %r13
|
||||||
|
.cfi_restore r13
|
||||||
|
.cfi_def_cfa_offset 104
|
||||||
pop %r12
|
pop %r12
|
||||||
|
.cfi_restore r12
|
||||||
|
.cfi_def_cfa_offset 96
|
||||||
pop %r11
|
pop %r11
|
||||||
|
.cfi_restore r11
|
||||||
|
.cfi_def_cfa_offset 88
|
||||||
pop %r10
|
pop %r10
|
||||||
|
.cfi_restore r10
|
||||||
|
.cfi_def_cfa_offset 80
|
||||||
pop %r9
|
pop %r9
|
||||||
|
.cfi_restore r9
|
||||||
|
.cfi_def_cfa_offset 72
|
||||||
pop %r8
|
pop %r8
|
||||||
|
.cfi_restore r8
|
||||||
|
.cfi_def_cfa_offset 64
|
||||||
pop %rdi
|
pop %rdi
|
||||||
|
.cfi_restore rdi
|
||||||
|
.cfi_def_cfa_offset 56
|
||||||
pop %rsi
|
pop %rsi
|
||||||
|
.cfi_restore rsi
|
||||||
|
.cfi_def_cfa_offset 48
|
||||||
pop %rbp
|
pop %rbp
|
||||||
|
.cfi_restore rbp
|
||||||
|
.cfi_def_cfa_offset 40
|
||||||
pop %rdx
|
pop %rdx
|
||||||
|
.cfi_restore rdx
|
||||||
|
.cfi_def_cfa_offset 32
|
||||||
pop %rcx
|
pop %rcx
|
||||||
|
.cfi_restore rcx
|
||||||
|
.cfi_def_cfa_offset 24
|
||||||
pop %rbx
|
pop %rbx
|
||||||
|
.cfi_restore rbx
|
||||||
|
.cfi_def_cfa_offset 16
|
||||||
pop %rax
|
pop %rax
|
||||||
|
.cfi_restore rax
|
||||||
|
.cfi_def_cfa_offset 8
|
||||||
ret
|
ret
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,14 +16,13 @@
|
|||||||
*********************************************************/
|
*********************************************************/
|
||||||
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
|
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
|
||||||
#include "../common/compiler.h" /* prefetch */
|
#include "../common/compiler.h" /* prefetch */
|
||||||
#include "../common/cpu.h" /* bmi2 */
|
|
||||||
#include "../common/mem.h" /* low level memory routines */
|
#include "../common/mem.h" /* low level memory routines */
|
||||||
|
#include <stddef.h>
|
||||||
#define FSE_STATIC_LINKING_ONLY
|
#define FSE_STATIC_LINKING_ONLY
|
||||||
#include "../common/fse.h"
|
#include "../common/fse.h"
|
||||||
#include "../common/huf.h"
|
#include "../common/huf.h"
|
||||||
#include "../common/zstd_internal.h"
|
#include "../common/zstd_internal.h"
|
||||||
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
||||||
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
|
||||||
#include "zstd_decompress_block.h"
|
#include "zstd_decompress_block.h"
|
||||||
#include "../common/bits.h" /* ZSTD_highbit32 */
|
#include "../common/bits.h" /* ZSTD_highbit32 */
|
||||||
|
|
||||||
@@ -734,9 +733,10 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||||||
ip++;
|
ip++;
|
||||||
|
|
||||||
/* Build DTables */
|
/* Build DTables */
|
||||||
|
assert(ip <= iend);
|
||||||
{ size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
|
{ size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
|
||||||
LLtype, MaxLL, LLFSELog,
|
LLtype, MaxLL, LLFSELog,
|
||||||
ip, iend-ip,
|
ip, (size_t)(iend-ip),
|
||||||
LL_base, LL_bits,
|
LL_base, LL_bits,
|
||||||
LL_defaultDTable, dctx->fseEntropy,
|
LL_defaultDTable, dctx->fseEntropy,
|
||||||
dctx->ddictIsCold, nbSeq,
|
dctx->ddictIsCold, nbSeq,
|
||||||
@@ -746,9 +746,10 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||||||
ip += llhSize;
|
ip += llhSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(ip <= iend);
|
||||||
{ size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
|
{ size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
|
||||||
OFtype, MaxOff, OffFSELog,
|
OFtype, MaxOff, OffFSELog,
|
||||||
ip, iend-ip,
|
ip, (size_t)(iend-ip),
|
||||||
OF_base, OF_bits,
|
OF_base, OF_bits,
|
||||||
OF_defaultDTable, dctx->fseEntropy,
|
OF_defaultDTable, dctx->fseEntropy,
|
||||||
dctx->ddictIsCold, nbSeq,
|
dctx->ddictIsCold, nbSeq,
|
||||||
@@ -758,9 +759,10 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||||||
ip += ofhSize;
|
ip += ofhSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(ip <= iend);
|
||||||
{ size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
|
{ size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
|
||||||
MLtype, MaxML, MLFSELog,
|
MLtype, MaxML, MLFSELog,
|
||||||
ip, iend-ip,
|
ip, (size_t)(iend-ip),
|
||||||
ML_base, ML_bits,
|
ML_base, ML_bits,
|
||||||
ML_defaultDTable, dctx->fseEntropy,
|
ML_defaultDTable, dctx->fseEntropy,
|
||||||
dctx->ddictIsCold, nbSeq,
|
dctx->ddictIsCold, nbSeq,
|
||||||
@@ -771,7 +773,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip-istart;
|
return (size_t)(ip-istart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -801,7 +803,8 @@ typedef struct {
|
|||||||
* Precondition: *ip <= *op
|
* Precondition: *ip <= *op
|
||||||
* Postcondition: *op - *op >= 8
|
* Postcondition: *op - *op >= 8
|
||||||
*/
|
*/
|
||||||
HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
|
HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset)
|
||||||
|
{
|
||||||
assert(*ip <= *op);
|
assert(*ip <= *op);
|
||||||
if (offset < 8) {
|
if (offset < 8) {
|
||||||
/* close range match, overlap */
|
/* close range match, overlap */
|
||||||
@@ -834,7 +837,9 @@ HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
|
|||||||
* - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart.
|
* - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart.
|
||||||
* The src buffer must be before the dst buffer.
|
* The src buffer must be before the dst buffer.
|
||||||
*/
|
*/
|
||||||
static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) {
|
static void
|
||||||
|
ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, size_t length, ZSTD_overlap_e ovtype)
|
||||||
|
{
|
||||||
ptrdiff_t const diff = op - ip;
|
ptrdiff_t const diff = op - ip;
|
||||||
BYTE* const oend = op + length;
|
BYTE* const oend = op + length;
|
||||||
|
|
||||||
@@ -849,7 +854,8 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt
|
|||||||
if (ovtype == ZSTD_overlap_src_before_dst) {
|
if (ovtype == ZSTD_overlap_src_before_dst) {
|
||||||
/* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */
|
/* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */
|
||||||
assert(length >= 8);
|
assert(length >= 8);
|
||||||
ZSTD_overlapCopy8(&op, &ip, diff);
|
assert(diff > 0);
|
||||||
|
ZSTD_overlapCopy8(&op, &ip, (size_t)diff);
|
||||||
length -= 8;
|
length -= 8;
|
||||||
assert(op - ip >= 8);
|
assert(op - ip >= 8);
|
||||||
assert(op <= oend);
|
assert(op <= oend);
|
||||||
@@ -863,7 +869,7 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt
|
|||||||
if (op <= oend_w) {
|
if (op <= oend_w) {
|
||||||
/* Wildcopy until we get close to the end. */
|
/* Wildcopy until we get close to the end. */
|
||||||
assert(oend > oend_w);
|
assert(oend > oend_w);
|
||||||
ZSTD_wildcopy(op, ip, oend_w - op, ovtype);
|
ZSTD_wildcopy(op, ip, (size_t)(oend_w - op), ovtype);
|
||||||
ip += oend_w - op;
|
ip += oend_w - op;
|
||||||
op += oend_w - op;
|
op += oend_w - op;
|
||||||
}
|
}
|
||||||
@@ -874,7 +880,8 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt
|
|||||||
/* ZSTD_safecopyDstBeforeSrc():
|
/* ZSTD_safecopyDstBeforeSrc():
|
||||||
* This version allows overlap with dst before src, or handles the non-overlap case with dst after src
|
* This version allows overlap with dst before src, or handles the non-overlap case with dst after src
|
||||||
* Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
|
* Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
|
||||||
static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) {
|
static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, size_t length)
|
||||||
|
{
|
||||||
ptrdiff_t const diff = op - ip;
|
ptrdiff_t const diff = op - ip;
|
||||||
BYTE* const oend = op + length;
|
BYTE* const oend = op + length;
|
||||||
|
|
||||||
@@ -885,7 +892,7 @@ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) {
|
if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) {
|
||||||
ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap);
|
ZSTD_wildcopy(op, ip, (size_t)(oend - WILDCOPY_OVERLENGTH - op), ZSTD_no_overlap);
|
||||||
ip += oend - WILDCOPY_OVERLENGTH - op;
|
ip += oend - WILDCOPY_OVERLENGTH - op;
|
||||||
op += oend - WILDCOPY_OVERLENGTH - op;
|
op += oend - WILDCOPY_OVERLENGTH - op;
|
||||||
}
|
}
|
||||||
@@ -936,11 +943,11 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
|
|||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
/* span extDict & currentPrefixSegment */
|
/* span extDict & currentPrefixSegment */
|
||||||
{ size_t const length1 = dictEnd - match;
|
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||||
ZSTD_memmove(oLitEnd, match, length1);
|
ZSTD_memmove(oLitEnd, match, length1);
|
||||||
op = oLitEnd + length1;
|
op = oLitEnd + length1;
|
||||||
sequence.matchLength -= length1;
|
sequence.matchLength -= length1;
|
||||||
match = prefixStart;
|
match = prefixStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
|
ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
|
||||||
@@ -985,11 +992,11 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
|
|||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
/* span extDict & currentPrefixSegment */
|
/* span extDict & currentPrefixSegment */
|
||||||
{ size_t const length1 = dictEnd - match;
|
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||||
ZSTD_memmove(oLitEnd, match, length1);
|
ZSTD_memmove(oLitEnd, match, length1);
|
||||||
op = oLitEnd + length1;
|
op = oLitEnd + length1;
|
||||||
sequence.matchLength -= length1;
|
sequence.matchLength -= length1;
|
||||||
match = prefixStart;
|
match = prefixStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
|
ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
|
||||||
@@ -1058,11 +1065,11 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
/* span extDict & currentPrefixSegment */
|
/* span extDict & currentPrefixSegment */
|
||||||
{ size_t const length1 = dictEnd - match;
|
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||||
ZSTD_memmove(oLitEnd, match, length1);
|
ZSTD_memmove(oLitEnd, match, length1);
|
||||||
op = oLitEnd + length1;
|
op = oLitEnd + length1;
|
||||||
sequence.matchLength -= length1;
|
sequence.matchLength -= length1;
|
||||||
match = prefixStart;
|
match = prefixStart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Match within prefix of 1 or more bytes */
|
/* Match within prefix of 1 or more bytes */
|
||||||
@@ -1079,7 +1086,7 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||||||
* longer than literals (in general). In silesia, ~10% of matches are longer
|
* longer than literals (in general). In silesia, ~10% of matches are longer
|
||||||
* than 16 bytes.
|
* than 16 bytes.
|
||||||
*/
|
*/
|
||||||
ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
|
ZSTD_wildcopy(op, match, sequence.matchLength, ZSTD_no_overlap);
|
||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
assert(sequence.offset < WILDCOPY_VECLEN);
|
assert(sequence.offset < WILDCOPY_VECLEN);
|
||||||
@@ -1090,7 +1097,7 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||||||
/* If the match length is > 8 bytes, then continue with the wildcopy. */
|
/* If the match length is > 8 bytes, then continue with the wildcopy. */
|
||||||
if (sequence.matchLength > 8) {
|
if (sequence.matchLength > 8) {
|
||||||
assert(op < oMatchEnd);
|
assert(op < oMatchEnd);
|
||||||
ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst);
|
ZSTD_wildcopy(op, match, sequence.matchLength - 8, ZSTD_overlap_src_before_dst);
|
||||||
}
|
}
|
||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
@@ -1151,7 +1158,7 @@ size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
|
|||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
/* span extDict & currentPrefixSegment */
|
/* span extDict & currentPrefixSegment */
|
||||||
{ size_t const length1 = dictEnd - match;
|
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||||
ZSTD_memmove(oLitEnd, match, length1);
|
ZSTD_memmove(oLitEnd, match, length1);
|
||||||
op = oLitEnd + length1;
|
op = oLitEnd + length1;
|
||||||
sequence.matchLength -= length1;
|
sequence.matchLength -= length1;
|
||||||
@@ -1171,7 +1178,7 @@ size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
|
|||||||
* longer than literals (in general). In silesia, ~10% of matches are longer
|
* longer than literals (in general). In silesia, ~10% of matches are longer
|
||||||
* than 16 bytes.
|
* than 16 bytes.
|
||||||
*/
|
*/
|
||||||
ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
|
ZSTD_wildcopy(op, match, sequence.matchLength, ZSTD_no_overlap);
|
||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
assert(sequence.offset < WILDCOPY_VECLEN);
|
assert(sequence.offset < WILDCOPY_VECLEN);
|
||||||
@@ -1182,7 +1189,7 @@ size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
|
|||||||
/* If the match length is > 8 bytes, then continue with the wildcopy. */
|
/* If the match length is > 8 bytes, then continue with the wildcopy. */
|
||||||
if (sequence.matchLength > 8) {
|
if (sequence.matchLength > 8) {
|
||||||
assert(op < oMatchEnd);
|
assert(op < oMatchEnd);
|
||||||
ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst);
|
ZSTD_wildcopy(op, match, sequence.matchLength-8, ZSTD_overlap_src_before_dst);
|
||||||
}
|
}
|
||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
}
|
}
|
||||||
@@ -1229,6 +1236,10 @@ FORCE_INLINE_TEMPLATE seq_t
|
|||||||
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
|
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
|
||||||
{
|
{
|
||||||
seq_t seq;
|
seq_t seq;
|
||||||
|
#if defined(__aarch64__)
|
||||||
|
size_t prevOffset0 = seqState->prevOffset[0];
|
||||||
|
size_t prevOffset1 = seqState->prevOffset[1];
|
||||||
|
size_t prevOffset2 = seqState->prevOffset[2];
|
||||||
/*
|
/*
|
||||||
* ZSTD_seqSymbol is a 64 bits wide structure.
|
* ZSTD_seqSymbol is a 64 bits wide structure.
|
||||||
* It can be loaded in one operation
|
* It can be loaded in one operation
|
||||||
@@ -1237,7 +1248,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||||||
* operations that cause performance drop. This can be avoided by using this
|
* operations that cause performance drop. This can be avoided by using this
|
||||||
* ZSTD_memcpy hack.
|
* ZSTD_memcpy hack.
|
||||||
*/
|
*/
|
||||||
#if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__))
|
# if defined(__GNUC__) && !defined(__clang__)
|
||||||
ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS;
|
ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS;
|
||||||
ZSTD_seqSymbol* const llDInfo = &llDInfoS;
|
ZSTD_seqSymbol* const llDInfo = &llDInfoS;
|
||||||
ZSTD_seqSymbol* const mlDInfo = &mlDInfoS;
|
ZSTD_seqSymbol* const mlDInfo = &mlDInfoS;
|
||||||
@@ -1245,11 +1256,12 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||||||
ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol));
|
ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol));
|
||||||
ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol));
|
ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol));
|
||||||
ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol));
|
ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol));
|
||||||
#else
|
# else
|
||||||
const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
|
const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
|
||||||
const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
|
const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
|
||||||
const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
|
const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
|
||||||
#endif
|
# endif
|
||||||
|
(void)longOffsets;
|
||||||
seq.matchLength = mlDInfo->baseValue;
|
seq.matchLength = mlDInfo->baseValue;
|
||||||
seq.litLength = llDInfo->baseValue;
|
seq.litLength = llDInfo->baseValue;
|
||||||
{ U32 const ofBase = ofDInfo->baseValue;
|
{ U32 const ofBase = ofDInfo->baseValue;
|
||||||
@@ -1268,10 +1280,98 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||||||
assert(llBits <= MaxLLBits);
|
assert(llBits <= MaxLLBits);
|
||||||
assert(mlBits <= MaxMLBits);
|
assert(mlBits <= MaxMLBits);
|
||||||
assert(ofBits <= MaxOff);
|
assert(ofBits <= MaxOff);
|
||||||
/*
|
/* As GCC has better branch and block analyzers, sometimes it is only
|
||||||
* As gcc has better branch and block analyzers, sometimes it is only
|
* valuable to mark likeliness for Clang.
|
||||||
* valuable to mark likeliness for clang, it gives around 3-4% of
|
*/
|
||||||
* performance.
|
|
||||||
|
/* sequence */
|
||||||
|
{ size_t offset;
|
||||||
|
if (ofBits > 1) {
|
||||||
|
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
||||||
|
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
|
||||||
|
ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32);
|
||||||
|
ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits);
|
||||||
|
offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
||||||
|
prevOffset2 = prevOffset1;
|
||||||
|
prevOffset1 = prevOffset0;
|
||||||
|
prevOffset0 = offset;
|
||||||
|
} else {
|
||||||
|
U32 const ll0 = (llDInfo->baseValue == 0);
|
||||||
|
if (LIKELY((ofBits == 0))) {
|
||||||
|
if (ll0) {
|
||||||
|
offset = prevOffset1;
|
||||||
|
prevOffset1 = prevOffset0;
|
||||||
|
prevOffset0 = offset;
|
||||||
|
} else {
|
||||||
|
offset = prevOffset0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
|
||||||
|
{ size_t temp = (offset == 1) ? prevOffset1
|
||||||
|
: (offset == 3) ? prevOffset0 - 1
|
||||||
|
: (offset >= 2) ? prevOffset2
|
||||||
|
: prevOffset0;
|
||||||
|
/* 0 is not valid: input corrupted => force offset to -1 =>
|
||||||
|
* corruption detected at execSequence.
|
||||||
|
*/
|
||||||
|
temp -= !temp;
|
||||||
|
prevOffset2 = (offset == 1) ? prevOffset2 : prevOffset1;
|
||||||
|
prevOffset1 = prevOffset0;
|
||||||
|
prevOffset0 = offset = temp;
|
||||||
|
} } }
|
||||||
|
seq.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mlBits > 0)
|
||||||
|
seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
|
||||||
|
|
||||||
|
if (UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
|
||||||
|
BIT_reloadDStream(&seqState->DStream);
|
||||||
|
|
||||||
|
/* Ensure there are enough bits to read the rest of data in 64-bit mode. */
|
||||||
|
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
|
||||||
|
|
||||||
|
if (llBits > 0)
|
||||||
|
seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
|
||||||
|
|
||||||
|
DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
|
||||||
|
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
||||||
|
|
||||||
|
if (!isLastSeq) {
|
||||||
|
/* Don't update FSE state for last sequence. */
|
||||||
|
ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
|
||||||
|
ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
|
||||||
|
ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */
|
||||||
|
BIT_reloadDStream(&seqState->DStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seqState->prevOffset[0] = prevOffset0;
|
||||||
|
seqState->prevOffset[1] = prevOffset1;
|
||||||
|
seqState->prevOffset[2] = prevOffset2;
|
||||||
|
#else /* !defined(__aarch64__) */
|
||||||
|
const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
|
||||||
|
const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
|
||||||
|
const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
|
||||||
|
seq.matchLength = mlDInfo->baseValue;
|
||||||
|
seq.litLength = llDInfo->baseValue;
|
||||||
|
{ U32 const ofBase = ofDInfo->baseValue;
|
||||||
|
BYTE const llBits = llDInfo->nbAdditionalBits;
|
||||||
|
BYTE const mlBits = mlDInfo->nbAdditionalBits;
|
||||||
|
BYTE const ofBits = ofDInfo->nbAdditionalBits;
|
||||||
|
BYTE const totalBits = llBits+mlBits+ofBits;
|
||||||
|
|
||||||
|
U16 const llNext = llDInfo->nextState;
|
||||||
|
U16 const mlNext = mlDInfo->nextState;
|
||||||
|
U16 const ofNext = ofDInfo->nextState;
|
||||||
|
U32 const llnbBits = llDInfo->nbBits;
|
||||||
|
U32 const mlnbBits = mlDInfo->nbBits;
|
||||||
|
U32 const ofnbBits = ofDInfo->nbBits;
|
||||||
|
|
||||||
|
assert(llBits <= MaxLLBits);
|
||||||
|
assert(mlBits <= MaxMLBits);
|
||||||
|
assert(ofBits <= MaxOff);
|
||||||
|
/* As GCC has better branch and block analyzers, sometimes it is only
|
||||||
|
* valuable to mark likeliness for Clang.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* sequence */
|
/* sequence */
|
||||||
@@ -1333,7 +1433,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||||||
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
||||||
|
|
||||||
if (!isLastSeq) {
|
if (!isLastSeq) {
|
||||||
/* don't update FSE state for last Sequence */
|
/* Don't update FSE state for last sequence. */
|
||||||
ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
|
ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
|
||||||
ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
|
ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
|
||||||
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
|
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
|
||||||
@@ -1341,6 +1441,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||||||
BIT_reloadDStream(&seqState->DStream);
|
BIT_reloadDStream(&seqState->DStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* defined(__aarch64__) */
|
||||||
|
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
@@ -1405,10 +1506,8 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|||||||
const void* seqStart, size_t seqSize, int nbSeq,
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)seqStart;
|
|
||||||
const BYTE* const iend = ip + seqSize;
|
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
|
BYTE* const oend = (BYTE*)ZSTD_maybeNullPtrAdd(ostart, (ptrdiff_t)maxDstSize);
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
const BYTE* litPtr = dctx->litPtr;
|
const BYTE* litPtr = dctx->litPtr;
|
||||||
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
||||||
@@ -1423,7 +1522,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|||||||
dctx->fseEntropy = 1;
|
dctx->fseEntropy = 1;
|
||||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||||
RETURN_ERROR_IF(
|
RETURN_ERROR_IF(
|
||||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
|
ERR_isError(BIT_initDStream(&seqState.DStream, seqStart, seqSize)),
|
||||||
corruption_detected, "");
|
corruption_detected, "");
|
||||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||||
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||||
@@ -1515,7 +1614,8 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|||||||
|
|
||||||
/* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
|
/* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
|
||||||
if (nbSeq > 0) {
|
if (nbSeq > 0) {
|
||||||
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
const size_t leftoverLit = (size_t)(dctx->litBufferEnd - litPtr);
|
||||||
|
assert(dctx->litBufferEnd >= litPtr);
|
||||||
DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength);
|
DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength);
|
||||||
if (leftoverLit) {
|
if (leftoverLit) {
|
||||||
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
||||||
@@ -1617,10 +1717,10 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
|
|||||||
const void* seqStart, size_t seqSize, int nbSeq,
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)seqStart;
|
|
||||||
const BYTE* const iend = ip + seqSize;
|
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer;
|
BYTE* const oend = (dctx->litBufferLocation == ZSTD_not_in_dst) ?
|
||||||
|
(BYTE*)ZSTD_maybeNullPtrAdd(ostart, (ptrdiff_t)maxDstSize) :
|
||||||
|
dctx->litBuffer;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
const BYTE* litPtr = dctx->litPtr;
|
const BYTE* litPtr = dctx->litPtr;
|
||||||
const BYTE* const litEnd = litPtr + dctx->litSize;
|
const BYTE* const litEnd = litPtr + dctx->litSize;
|
||||||
@@ -1635,7 +1735,7 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
|
|||||||
dctx->fseEntropy = 1;
|
dctx->fseEntropy = 1;
|
||||||
{ U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
{ U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||||
RETURN_ERROR_IF(
|
RETURN_ERROR_IF(
|
||||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)),
|
ERR_isError(BIT_initDStream(&seqState.DStream, seqStart, seqSize)),
|
||||||
corruption_detected, "");
|
corruption_detected, "");
|
||||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||||
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||||
@@ -1719,8 +1819,8 @@ size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
|
|||||||
{ const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
|
{ const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
|
||||||
/* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
|
/* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
|
||||||
* No consequence though : memory address is only used for prefetching, not for dereferencing */
|
* No consequence though : memory address is only used for prefetching, not for dereferencing */
|
||||||
const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset);
|
const BYTE* const match = (const BYTE*)ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, (ptrdiff_t)prefetchPos), (ptrdiff_t)sequence.offset);
|
||||||
PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
|
PREFETCH_L1(match); PREFETCH_L1(ZSTD_wrappedPtrAdd(match, CACHELINE_SIZE)); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
|
||||||
}
|
}
|
||||||
return prefetchPos + sequence.matchLength;
|
return prefetchPos + sequence.matchLength;
|
||||||
}
|
}
|
||||||
@@ -1736,10 +1836,10 @@ ZSTD_decompressSequencesLong_body(
|
|||||||
const void* seqStart, size_t seqSize, int nbSeq,
|
const void* seqStart, size_t seqSize, int nbSeq,
|
||||||
const ZSTD_longOffset_e isLongOffset)
|
const ZSTD_longOffset_e isLongOffset)
|
||||||
{
|
{
|
||||||
const BYTE* ip = (const BYTE*)seqStart;
|
|
||||||
const BYTE* const iend = ip + seqSize;
|
|
||||||
BYTE* const ostart = (BYTE*)dst;
|
BYTE* const ostart = (BYTE*)dst;
|
||||||
BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
|
BYTE* const oend = (dctx->litBufferLocation == ZSTD_in_dst) ?
|
||||||
|
dctx->litBuffer :
|
||||||
|
(BYTE*)ZSTD_maybeNullPtrAdd(ostart, (ptrdiff_t)maxDstSize);
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
const BYTE* litPtr = dctx->litPtr;
|
const BYTE* litPtr = dctx->litPtr;
|
||||||
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
||||||
@@ -1761,9 +1861,8 @@ ZSTD_decompressSequencesLong_body(
|
|||||||
dctx->fseEntropy = 1;
|
dctx->fseEntropy = 1;
|
||||||
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||||
assert(dst != NULL);
|
assert(dst != NULL);
|
||||||
assert(iend >= ip);
|
|
||||||
RETURN_ERROR_IF(
|
RETURN_ERROR_IF(
|
||||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
|
ERR_isError(BIT_initDStream(&seqState.DStream, seqStart, seqSize)),
|
||||||
corruption_detected, "");
|
corruption_detected, "");
|
||||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||||
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
|
||||||
@@ -1782,9 +1881,9 @@ ZSTD_decompressSequencesLong_body(
|
|||||||
|
|
||||||
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) {
|
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) {
|
||||||
/* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
|
/* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
|
||||||
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
const size_t leftoverLit = (size_t)(dctx->litBufferEnd - litPtr);
|
||||||
if (leftoverLit)
|
assert(dctx->litBufferEnd >= litPtr);
|
||||||
{
|
if (leftoverLit) {
|
||||||
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
||||||
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
||||||
sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit;
|
sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit;
|
||||||
@@ -1828,7 +1927,8 @@ ZSTD_decompressSequencesLong_body(
|
|||||||
for ( ; seqNb<nbSeq ; seqNb++) {
|
for ( ; seqNb<nbSeq ; seqNb++) {
|
||||||
seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
|
seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
|
||||||
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) {
|
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) {
|
||||||
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
const size_t leftoverLit = (size_t)(dctx->litBufferEnd - litPtr);
|
||||||
|
assert(dctx->litBufferEnd >= litPtr);
|
||||||
if (leftoverLit) {
|
if (leftoverLit) {
|
||||||
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
||||||
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
||||||
@@ -1867,7 +1967,8 @@ ZSTD_decompressSequencesLong_body(
|
|||||||
|
|
||||||
/* last literal segment */
|
/* last literal segment */
|
||||||
if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */
|
if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */
|
||||||
size_t const lastLLSize = litBufferEnd - litPtr;
|
size_t const lastLLSize = (size_t)(litBufferEnd - litPtr);
|
||||||
|
assert(litBufferEnd >= litPtr);
|
||||||
RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
|
||||||
if (op != NULL) {
|
if (op != NULL) {
|
||||||
ZSTD_memmove(op, litPtr, lastLLSize);
|
ZSTD_memmove(op, litPtr, lastLLSize);
|
||||||
@@ -1876,7 +1977,8 @@ ZSTD_decompressSequencesLong_body(
|
|||||||
litPtr = dctx->litExtraBuffer;
|
litPtr = dctx->litExtraBuffer;
|
||||||
litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
|
litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
|
||||||
}
|
}
|
||||||
{ size_t const lastLLSize = litBufferEnd - litPtr;
|
{ size_t const lastLLSize = (size_t)(litBufferEnd - litPtr);
|
||||||
|
assert(litBufferEnd >= litPtr);
|
||||||
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
||||||
if (op != NULL) {
|
if (op != NULL) {
|
||||||
ZSTD_memmove(op, litPtr, lastLLSize);
|
ZSTD_memmove(op, litPtr, lastLLSize);
|
||||||
@@ -1993,9 +2095,9 @@ ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
|
|||||||
* both the prefix and the extDict. At @p op any offset larger than this
|
* both the prefix and the extDict. At @p op any offset larger than this
|
||||||
* is invalid.
|
* is invalid.
|
||||||
*/
|
*/
|
||||||
static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart)
|
static size_t ZSTD_totalHistorySize(void* curPtr, const void* virtualStart)
|
||||||
{
|
{
|
||||||
return (size_t)(op - virtualStart);
|
return (size_t)((char*)curPtr - (const char*)virtualStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -2094,7 +2196,7 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|||||||
* Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
|
* Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
|
||||||
*/
|
*/
|
||||||
size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx));
|
size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx));
|
||||||
size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart);
|
size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd(dst, (ptrdiff_t)blockSizeMax), (BYTE const*)dctx->virtualStart);
|
||||||
/* isLongOffset must be true if there are long offsets.
|
/* isLongOffset must be true if there are long offsets.
|
||||||
* Offsets are long if they are larger than ZSTD_maxShortOffset().
|
* Offsets are long if they are larger than ZSTD_maxShortOffset().
|
||||||
* We don't expect that to be the case in 64-bit mode.
|
* We don't expect that to be the case in 64-bit mode.
|
||||||
|
|||||||
+98
-67
@@ -21,14 +21,18 @@
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Dependencies
|
* Dependencies
|
||||||
***************************************/
|
***************************************/
|
||||||
/* qsort_r is an extension. */
|
/* qsort_r is an extension.
|
||||||
#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \
|
*
|
||||||
defined(__CYGWIN__) || defined(__MSYS__)
|
* Android NDK does not ship qsort_r().
|
||||||
#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */
|
*/
|
||||||
#define _GNU_SOURCE
|
#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__CYGWIN__) || defined(__MSYS__)
|
||||||
#endif
|
# ifndef _GNU_SOURCE
|
||||||
|
# define _GNU_SOURCE
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define __STDC_WANT_LIB_EXT1__ 1 /* request C11 Annex K, which includes qsort_s() */
|
||||||
|
|
||||||
#include <stdio.h> /* fprintf */
|
#include <stdio.h> /* fprintf */
|
||||||
#include <stdlib.h> /* malloc, free, qsort_r */
|
#include <stdlib.h> /* malloc, free, qsort_r */
|
||||||
|
|
||||||
@@ -39,6 +43,7 @@
|
|||||||
# define ZDICT_STATIC_LINKING_ONLY
|
# define ZDICT_STATIC_LINKING_ONLY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../common/debug.h" /* DEBUG_STATIC_ASSERT */
|
||||||
#include "../common/mem.h" /* read */
|
#include "../common/mem.h" /* read */
|
||||||
#include "../common/pool.h" /* POOL_ctx */
|
#include "../common/pool.h" /* POOL_ctx */
|
||||||
#include "../common/threading.h" /* ZSTD_pthread_mutex_t */
|
#include "../common/threading.h" /* ZSTD_pthread_mutex_t */
|
||||||
@@ -60,40 +65,58 @@
|
|||||||
#define COVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB))
|
#define COVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB))
|
||||||
#define COVER_DEFAULT_SPLITPOINT 1.0
|
#define COVER_DEFAULT_SPLITPOINT 1.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select the qsort() variant used by cover
|
||||||
|
*/
|
||||||
|
#define ZDICT_QSORT_MIN 0
|
||||||
|
#define ZDICT_QSORT_C90 ZDICT_QSORT_MIN
|
||||||
|
#define ZDICT_QSORT_GNU 1
|
||||||
|
#define ZDICT_QSORT_APPLE 2
|
||||||
|
#define ZDICT_QSORT_MSVC 3
|
||||||
|
#define ZDICT_QSORT_C11 ZDICT_QSORT_MAX
|
||||||
|
#define ZDICT_QSORT_MAX 4
|
||||||
|
|
||||||
|
#ifndef ZDICT_QSORT
|
||||||
|
# if defined(__APPLE__)
|
||||||
|
# define ZDICT_QSORT ZDICT_QSORT_APPLE /* uses qsort_r() with a different order for parameters */
|
||||||
|
# elif (defined(__linux__) && !defined(__ANDROID__)) || defined(__CYGWIN__) || defined(__MSYS__)
|
||||||
|
# define ZDICT_QSORT ZDICT_QSORT_GNU /* uses qsort_r() */
|
||||||
|
# elif defined(_WIN32) && defined(_MSC_VER)
|
||||||
|
# define ZDICT_QSORT ZDICT_QSORT_MSVC /* uses qsort_s() with a different order for parameters */
|
||||||
|
# elif defined(STDC_LIB_EXT1) && (STDC_LIB_EXT1 > 0) /* C11 Annex K */
|
||||||
|
# define ZDICT_QSORT ZDICT_QSORT_C11 /* uses qsort_s() */
|
||||||
|
# else
|
||||||
|
# define ZDICT_QSORT ZDICT_QSORT_C90 /* uses standard qsort() which is not re-entrant (requires global variable) */
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Console display
|
* Console display
|
||||||
|
*
|
||||||
|
* Captures the `displayLevel` variable in the local scope.
|
||||||
***************************************/
|
***************************************/
|
||||||
#ifndef LOCALDISPLAYLEVEL
|
|
||||||
static int g_displayLevel = 0;
|
|
||||||
#endif
|
|
||||||
#undef DISPLAY
|
#undef DISPLAY
|
||||||
#define DISPLAY(...) \
|
#define DISPLAY(...) \
|
||||||
{ \
|
{ \
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
fflush(stderr); \
|
fflush(stderr); \
|
||||||
}
|
}
|
||||||
#undef LOCALDISPLAYLEVEL
|
#undef DISPLAYLEVEL
|
||||||
#define LOCALDISPLAYLEVEL(displayLevel, l, ...) \
|
#define DISPLAYLEVEL(l, ...) \
|
||||||
if (displayLevel >= l) { \
|
if (displayLevel >= l) { \
|
||||||
DISPLAY(__VA_ARGS__); \
|
DISPLAY(__VA_ARGS__); \
|
||||||
} /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
} /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
||||||
#undef DISPLAYLEVEL
|
|
||||||
#define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__)
|
|
||||||
|
|
||||||
#ifndef LOCALDISPLAYUPDATE
|
#undef DISPLAYUPDATE
|
||||||
static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
|
#define DISPLAYUPDATE(lastUpdateTime, l, ...) \
|
||||||
static clock_t g_time = 0;
|
|
||||||
#endif
|
|
||||||
#undef LOCALDISPLAYUPDATE
|
|
||||||
#define LOCALDISPLAYUPDATE(displayLevel, l, ...) \
|
|
||||||
if (displayLevel >= l) { \
|
if (displayLevel >= l) { \
|
||||||
if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \
|
const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100; \
|
||||||
g_time = clock(); \
|
if ((clock() - lastUpdateTime > refreshRate) || (displayLevel >= 4)) { \
|
||||||
|
lastUpdateTime = clock(); \
|
||||||
DISPLAY(__VA_ARGS__); \
|
DISPLAY(__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#undef DISPLAYUPDATE
|
|
||||||
#define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__)
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Hash table
|
* Hash table
|
||||||
@@ -188,7 +211,7 @@ static U32 *COVER_map_at(COVER_map_t *map, U32 key) {
|
|||||||
*/
|
*/
|
||||||
static void COVER_map_remove(COVER_map_t *map, U32 key) {
|
static void COVER_map_remove(COVER_map_t *map, U32 key) {
|
||||||
U32 i = COVER_map_index(map, key);
|
U32 i = COVER_map_index(map, key);
|
||||||
COVER_map_pair_t *del = &map->data[i];
|
COVER_map_pair_t* del = &map->data[i];
|
||||||
U32 shift = 1;
|
U32 shift = 1;
|
||||||
if (del->value == MAP_EMPTY_VALUE) {
|
if (del->value == MAP_EMPTY_VALUE) {
|
||||||
return;
|
return;
|
||||||
@@ -239,10 +262,11 @@ typedef struct {
|
|||||||
U32 *freqs;
|
U32 *freqs;
|
||||||
U32 *dmerAt;
|
U32 *dmerAt;
|
||||||
unsigned d;
|
unsigned d;
|
||||||
|
int displayLevel;
|
||||||
} COVER_ctx_t;
|
} COVER_ctx_t;
|
||||||
|
|
||||||
#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER)
|
#if ZDICT_QSORT == ZDICT_QSORT_C90
|
||||||
/* C90 only offers qsort() that needs a global context. */
|
/* Use global context for non-reentrant sort functions */
|
||||||
static COVER_ctx_t *g_coverCtx = NULL;
|
static COVER_ctx_t *g_coverCtx = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -288,9 +312,9 @@ static int COVER_cmp8(COVER_ctx_t *ctx, const void *lp, const void *rp) {
|
|||||||
/**
|
/**
|
||||||
* Same as COVER_cmp() except ties are broken by pointer value
|
* Same as COVER_cmp() except ties are broken by pointer value
|
||||||
*/
|
*/
|
||||||
#if (defined(_WIN32) && defined(_MSC_VER)) || defined(__APPLE__)
|
#if (ZDICT_QSORT == ZDICT_QSORT_MSVC) || (ZDICT_QSORT == ZDICT_QSORT_APPLE)
|
||||||
static int WIN_CDECL COVER_strict_cmp(void* g_coverCtx, const void* lp, const void* rp) {
|
static int WIN_CDECL COVER_strict_cmp(void* g_coverCtx, const void* lp, const void* rp) {
|
||||||
#elif defined(_GNU_SOURCE)
|
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU) || (ZDICT_QSORT == ZDICT_QSORT_C11)
|
||||||
static int COVER_strict_cmp(const void *lp, const void *rp, void *g_coverCtx) {
|
static int COVER_strict_cmp(const void *lp, const void *rp, void *g_coverCtx) {
|
||||||
#else /* C90 fallback.*/
|
#else /* C90 fallback.*/
|
||||||
static int COVER_strict_cmp(const void *lp, const void *rp) {
|
static int COVER_strict_cmp(const void *lp, const void *rp) {
|
||||||
@@ -304,9 +328,9 @@ static int COVER_strict_cmp(const void *lp, const void *rp) {
|
|||||||
/**
|
/**
|
||||||
* Faster version for d <= 8.
|
* Faster version for d <= 8.
|
||||||
*/
|
*/
|
||||||
#if (defined(_WIN32) && defined(_MSC_VER)) || defined(__APPLE__)
|
#if (ZDICT_QSORT == ZDICT_QSORT_MSVC) || (ZDICT_QSORT == ZDICT_QSORT_APPLE)
|
||||||
static int WIN_CDECL COVER_strict_cmp8(void* g_coverCtx, const void* lp, const void* rp) {
|
static int WIN_CDECL COVER_strict_cmp8(void* g_coverCtx, const void* lp, const void* rp) {
|
||||||
#elif defined(_GNU_SOURCE)
|
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU) || (ZDICT_QSORT == ZDICT_QSORT_C11)
|
||||||
static int COVER_strict_cmp8(const void *lp, const void *rp, void *g_coverCtx) {
|
static int COVER_strict_cmp8(const void *lp, const void *rp, void *g_coverCtx) {
|
||||||
#else /* C90 fallback.*/
|
#else /* C90 fallback.*/
|
||||||
static int COVER_strict_cmp8(const void *lp, const void *rp) {
|
static int COVER_strict_cmp8(const void *lp, const void *rp) {
|
||||||
@@ -323,26 +347,28 @@ static int COVER_strict_cmp8(const void *lp, const void *rp) {
|
|||||||
* Hopefully when C11 become the norm, we will be able
|
* Hopefully when C11 become the norm, we will be able
|
||||||
* to clean it up.
|
* to clean it up.
|
||||||
*/
|
*/
|
||||||
static void stableSort(COVER_ctx_t *ctx) {
|
static void stableSort(COVER_ctx_t *ctx)
|
||||||
#if defined(__APPLE__)
|
{
|
||||||
|
DEBUG_STATIC_ASSERT(ZDICT_QSORT_MIN <= ZDICT_QSORT && ZDICT_QSORT <= ZDICT_QSORT_MAX);
|
||||||
|
#if (ZDICT_QSORT == ZDICT_QSORT_APPLE)
|
||||||
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
||||||
ctx,
|
ctx,
|
||||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
|
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
|
||||||
#elif defined(_GNU_SOURCE)
|
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU)
|
||||||
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
qsort_r(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
||||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
||||||
ctx);
|
ctx);
|
||||||
#elif defined(_WIN32) && defined(_MSC_VER)
|
#elif (ZDICT_QSORT == ZDICT_QSORT_MSVC)
|
||||||
|
qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
||||||
|
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
||||||
|
ctx);
|
||||||
|
#elif (ZDICT_QSORT == ZDICT_QSORT_C11)
|
||||||
qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
||||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
||||||
ctx);
|
ctx);
|
||||||
#elif defined(__OpenBSD__)
|
|
||||||
g_coverCtx = ctx;
|
|
||||||
mergesort(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
|
||||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
|
|
||||||
#else /* C90 fallback.*/
|
#else /* C90 fallback.*/
|
||||||
g_coverCtx = ctx;
|
g_coverCtx = ctx;
|
||||||
/* TODO(cavalcanti): implement a reentrant qsort() when is not available. */
|
/* TODO(cavalcanti): implement a reentrant qsort() when _r is not available. */
|
||||||
qsort(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
qsort(ctx->suffix, ctx->suffixSize, sizeof(U32),
|
||||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
|
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
|
||||||
#endif
|
#endif
|
||||||
@@ -601,7 +627,7 @@ static void COVER_ctx_destroy(COVER_ctx_t *ctx) {
|
|||||||
*/
|
*/
|
||||||
static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
|
static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
|
||||||
const size_t *samplesSizes, unsigned nbSamples,
|
const size_t *samplesSizes, unsigned nbSamples,
|
||||||
unsigned d, double splitPoint)
|
unsigned d, double splitPoint, int displayLevel)
|
||||||
{
|
{
|
||||||
const BYTE *const samples = (const BYTE *)samplesBuffer;
|
const BYTE *const samples = (const BYTE *)samplesBuffer;
|
||||||
const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples);
|
const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples);
|
||||||
@@ -610,6 +636,7 @@ static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
|
|||||||
const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples;
|
const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples;
|
||||||
const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
|
const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
|
||||||
const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
|
const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
|
||||||
|
ctx->displayLevel = displayLevel;
|
||||||
/* Checks */
|
/* Checks */
|
||||||
if (totalSamplesSize < MAX(d, sizeof(U64)) ||
|
if (totalSamplesSize < MAX(d, sizeof(U64)) ||
|
||||||
totalSamplesSize >= (size_t)COVER_MAX_SAMPLES_SIZE) {
|
totalSamplesSize >= (size_t)COVER_MAX_SAMPLES_SIZE) {
|
||||||
@@ -694,14 +721,14 @@ void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLeve
|
|||||||
if (ratio >= 10) {
|
if (ratio >= 10) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1,
|
DISPLAYLEVEL(1,
|
||||||
"WARNING: The maximum dictionary size %u is too large "
|
"WARNING: The maximum dictionary size %u is too large "
|
||||||
"compared to the source size %u! "
|
"compared to the source size %u! "
|
||||||
"size(source)/size(dictionary) = %f, but it should be >= "
|
"size(source)/size(dictionary) = %f, but it should be >= "
|
||||||
"10! This may lead to a subpar dictionary! We recommend "
|
"10! This may lead to a subpar dictionary! We recommend "
|
||||||
"training on sources at least 10x, and preferably 100x "
|
"training on sources at least 10x, and preferably 100x "
|
||||||
"the size of the dictionary! \n", (U32)maxDictSize,
|
"the size of the dictionary! \n", (U32)maxDictSize,
|
||||||
(U32)nbDmers, ratio);
|
(U32)nbDmers, ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
COVER_epoch_info_t COVER_computeEpochs(U32 maxDictSize,
|
COVER_epoch_info_t COVER_computeEpochs(U32 maxDictSize,
|
||||||
@@ -736,6 +763,8 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
|
|||||||
const size_t maxZeroScoreRun = MAX(10, MIN(100, epochs.num >> 3));
|
const size_t maxZeroScoreRun = MAX(10, MIN(100, epochs.num >> 3));
|
||||||
size_t zeroScoreRun = 0;
|
size_t zeroScoreRun = 0;
|
||||||
size_t epoch;
|
size_t epoch;
|
||||||
|
clock_t lastUpdateTime = 0;
|
||||||
|
const int displayLevel = ctx->displayLevel;
|
||||||
DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
|
DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
|
||||||
(U32)epochs.num, (U32)epochs.size);
|
(U32)epochs.num, (U32)epochs.size);
|
||||||
/* Loop through the epochs until there are no more segments or the dictionary
|
/* Loop through the epochs until there are no more segments or the dictionary
|
||||||
@@ -769,6 +798,7 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
|
|||||||
tail -= segmentSize;
|
tail -= segmentSize;
|
||||||
memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
|
memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
|
||||||
DISPLAYUPDATE(
|
DISPLAYUPDATE(
|
||||||
|
lastUpdateTime,
|
||||||
2, "\r%u%% ",
|
2, "\r%u%% ",
|
||||||
(unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
|
(unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
|
||||||
}
|
}
|
||||||
@@ -784,9 +814,8 @@ ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
|
|||||||
BYTE* const dict = (BYTE*)dictBuffer;
|
BYTE* const dict = (BYTE*)dictBuffer;
|
||||||
COVER_ctx_t ctx;
|
COVER_ctx_t ctx;
|
||||||
COVER_map_t activeDmers;
|
COVER_map_t activeDmers;
|
||||||
|
const int displayLevel = (int)parameters.zParams.notificationLevel;
|
||||||
parameters.splitPoint = 1.0;
|
parameters.splitPoint = 1.0;
|
||||||
/* Initialize global data */
|
|
||||||
g_displayLevel = (int)parameters.zParams.notificationLevel;
|
|
||||||
/* Checks */
|
/* Checks */
|
||||||
if (!COVER_checkParameters(parameters, dictBufferCapacity)) {
|
if (!COVER_checkParameters(parameters, dictBufferCapacity)) {
|
||||||
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
|
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
|
||||||
@@ -804,12 +833,12 @@ ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
|
|||||||
/* Initialize context and activeDmers */
|
/* Initialize context and activeDmers */
|
||||||
{
|
{
|
||||||
size_t const initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
|
size_t const initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
|
||||||
parameters.d, parameters.splitPoint);
|
parameters.d, parameters.splitPoint, displayLevel);
|
||||||
if (ZSTD_isError(initVal)) {
|
if (ZSTD_isError(initVal)) {
|
||||||
return initVal;
|
return initVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.suffixSize, g_displayLevel);
|
COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.suffixSize, displayLevel);
|
||||||
if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
|
if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
|
||||||
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
||||||
COVER_ctx_destroy(&ctx);
|
COVER_ctx_destroy(&ctx);
|
||||||
@@ -1132,6 +1161,7 @@ static void COVER_tryParameters(void *opaque)
|
|||||||
BYTE* const dict = (BYTE*)malloc(dictBufferCapacity);
|
BYTE* const dict = (BYTE*)malloc(dictBufferCapacity);
|
||||||
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
||||||
U32* const freqs = (U32*)malloc(ctx->suffixSize * sizeof(U32));
|
U32* const freqs = (U32*)malloc(ctx->suffixSize * sizeof(U32));
|
||||||
|
const int displayLevel = ctx->displayLevel;
|
||||||
if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
|
if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
|
||||||
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
@@ -1183,21 +1213,22 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||||||
(1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize);
|
(1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize);
|
||||||
const unsigned shrinkDict = 0;
|
const unsigned shrinkDict = 0;
|
||||||
/* Local variables */
|
/* Local variables */
|
||||||
const int displayLevel = parameters->zParams.notificationLevel;
|
int displayLevel = (int)parameters->zParams.notificationLevel;
|
||||||
unsigned iteration = 1;
|
unsigned iteration = 1;
|
||||||
unsigned d;
|
unsigned d;
|
||||||
unsigned k;
|
unsigned k;
|
||||||
COVER_best_t best;
|
COVER_best_t best;
|
||||||
POOL_ctx *pool = NULL;
|
POOL_ctx *pool = NULL;
|
||||||
int warned = 0;
|
int warned = 0;
|
||||||
|
clock_t lastUpdateTime = 0;
|
||||||
|
|
||||||
/* Checks */
|
/* Checks */
|
||||||
if (splitPoint <= 0 || splitPoint > 1) {
|
if (splitPoint <= 0 || splitPoint > 1) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n");
|
DISPLAYLEVEL(1, "Incorrect parameters\n");
|
||||||
return ERROR(parameter_outOfBound);
|
return ERROR(parameter_outOfBound);
|
||||||
}
|
}
|
||||||
if (kMinK < kMaxD || kMaxK < kMinK) {
|
if (kMinK < kMaxD || kMaxK < kMinK) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n");
|
DISPLAYLEVEL(1, "Incorrect parameters\n");
|
||||||
return ERROR(parameter_outOfBound);
|
return ERROR(parameter_outOfBound);
|
||||||
}
|
}
|
||||||
if (nbSamples == 0) {
|
if (nbSamples == 0) {
|
||||||
@@ -1217,19 +1248,19 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||||||
}
|
}
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
COVER_best_init(&best);
|
COVER_best_init(&best);
|
||||||
/* Turn down global display level to clean up display at level 2 and below */
|
|
||||||
g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1;
|
|
||||||
/* Loop through d first because each new value needs a new context */
|
/* Loop through d first because each new value needs a new context */
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
|
DISPLAYLEVEL(2, "Trying %u different sets of parameters\n",
|
||||||
kIterations);
|
kIterations);
|
||||||
for (d = kMinD; d <= kMaxD; d += 2) {
|
for (d = kMinD; d <= kMaxD; d += 2) {
|
||||||
/* Initialize the context for this value of d */
|
/* Initialize the context for this value of d */
|
||||||
COVER_ctx_t ctx;
|
COVER_ctx_t ctx;
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 3, "d=%u\n", d);
|
DISPLAYLEVEL(3, "d=%u\n", d);
|
||||||
{
|
{
|
||||||
const size_t initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint);
|
/* Turn down global display level to clean up display at level 2 and below */
|
||||||
|
const int childDisplayLevel = (displayLevel == 0) ? 0 : displayLevel - 1;
|
||||||
|
const size_t initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint, childDisplayLevel);
|
||||||
if (ZSTD_isError(initVal)) {
|
if (ZSTD_isError(initVal)) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n");
|
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
||||||
COVER_best_destroy(&best);
|
COVER_best_destroy(&best);
|
||||||
POOL_free(pool);
|
POOL_free(pool);
|
||||||
return initVal;
|
return initVal;
|
||||||
@@ -1244,9 +1275,9 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||||||
/* Prepare the arguments */
|
/* Prepare the arguments */
|
||||||
COVER_tryParameters_data_t *data = (COVER_tryParameters_data_t *)malloc(
|
COVER_tryParameters_data_t *data = (COVER_tryParameters_data_t *)malloc(
|
||||||
sizeof(COVER_tryParameters_data_t));
|
sizeof(COVER_tryParameters_data_t));
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k);
|
DISPLAYLEVEL(3, "k=%u\n", k);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n");
|
DISPLAYLEVEL(1, "Failed to allocate parameters\n");
|
||||||
COVER_best_destroy(&best);
|
COVER_best_destroy(&best);
|
||||||
COVER_ctx_destroy(&ctx);
|
COVER_ctx_destroy(&ctx);
|
||||||
POOL_free(pool);
|
POOL_free(pool);
|
||||||
@@ -1261,7 +1292,7 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||||||
data->parameters.splitPoint = splitPoint;
|
data->parameters.splitPoint = splitPoint;
|
||||||
data->parameters.steps = kSteps;
|
data->parameters.steps = kSteps;
|
||||||
data->parameters.shrinkDict = shrinkDict;
|
data->parameters.shrinkDict = shrinkDict;
|
||||||
data->parameters.zParams.notificationLevel = g_displayLevel;
|
data->parameters.zParams.notificationLevel = (unsigned)ctx.displayLevel;
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
if (!COVER_checkParameters(data->parameters, dictBufferCapacity)) {
|
if (!COVER_checkParameters(data->parameters, dictBufferCapacity)) {
|
||||||
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
|
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
|
||||||
@@ -1276,14 +1307,14 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||||||
COVER_tryParameters(data);
|
COVER_tryParameters(data);
|
||||||
}
|
}
|
||||||
/* Print status */
|
/* Print status */
|
||||||
LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ",
|
DISPLAYUPDATE(lastUpdateTime, 2, "\r%u%% ",
|
||||||
(unsigned)((iteration * 100) / kIterations));
|
(unsigned)((iteration * 100) / kIterations));
|
||||||
++iteration;
|
++iteration;
|
||||||
}
|
}
|
||||||
COVER_best_wait(&best);
|
COVER_best_wait(&best);
|
||||||
COVER_ctx_destroy(&ctx);
|
COVER_ctx_destroy(&ctx);
|
||||||
}
|
}
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 2, "\r%79s\r", "");
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
/* Fill the output buffer and parameters with output of the best parameters */
|
/* Fill the output buffer and parameters with output of the best parameters */
|
||||||
{
|
{
|
||||||
const size_t dictSize = best.dictSize;
|
const size_t dictSize = best.dictSize;
|
||||||
|
|||||||
@@ -25,23 +25,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*- Compiler specifics -*/
|
/*- Compiler specifics -*/
|
||||||
#ifdef __clang__
|
|
||||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(disable : 4244)
|
|
||||||
# pragma warning(disable : 4127) /* C4127 : Condition expression is constant */
|
# pragma warning(disable : 4127) /* C4127 : Condition expression is constant */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*- Dependencies -*/
|
/*- Dependencies -*/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "divsufsort.h"
|
#include "divsufsort.h"
|
||||||
|
|
||||||
|
#define PTRDIFF_TO_INT(x) (assert((x) <= INT_MAX && (x) >= INT_MIN), (int)(x))
|
||||||
|
|
||||||
/*- Constants -*/
|
/*- Constants -*/
|
||||||
#if defined(INLINE)
|
#if defined(INLINE)
|
||||||
# undef INLINE
|
# undef INLINE
|
||||||
@@ -199,8 +198,8 @@ ss_isqrt(int x) {
|
|||||||
int y, e;
|
int y, e;
|
||||||
|
|
||||||
if(x >= (SS_BLOCKSIZE * SS_BLOCKSIZE)) { return SS_BLOCKSIZE; }
|
if(x >= (SS_BLOCKSIZE * SS_BLOCKSIZE)) { return SS_BLOCKSIZE; }
|
||||||
e = (x & 0xffff0000) ?
|
e = ((unsigned)x & 0xffff0000) ?
|
||||||
((x & 0xff000000) ?
|
(((unsigned)x & 0xff000000) ?
|
||||||
24 + lg_table[(x >> 24) & 0xff] :
|
24 + lg_table[(x >> 24) & 0xff] :
|
||||||
16 + lg_table[(x >> 16) & 0xff]) :
|
16 + lg_table[(x >> 16) & 0xff]) :
|
||||||
((x & 0x0000ff00) ?
|
((x & 0x0000ff00) ?
|
||||||
@@ -354,7 +353,7 @@ ss_pivot(const unsigned char *Td, const int *PA, int *first, int *last) {
|
|||||||
int *middle;
|
int *middle;
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
t = last - first;
|
t = PTRDIFF_TO_INT(last - first);
|
||||||
middle = first + t / 2;
|
middle = first + t / 2;
|
||||||
|
|
||||||
if(t <= 512) {
|
if(t <= 512) {
|
||||||
@@ -409,7 +408,7 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||||||
int limit;
|
int limit;
|
||||||
int v, x = 0;
|
int v, x = 0;
|
||||||
|
|
||||||
for(ssize = 0, limit = ss_ilg(last - first);;) {
|
for(ssize = 0, limit = ss_ilg(PTRDIFF_TO_INT(last - first));;) {
|
||||||
|
|
||||||
if((last - first) <= SS_INSERTIONSORT_THRESHOLD) {
|
if((last - first) <= SS_INSERTIONSORT_THRESHOLD) {
|
||||||
#if 1 < SS_INSERTIONSORT_THRESHOLD
|
#if 1 < SS_INSERTIONSORT_THRESHOLD
|
||||||
@@ -420,7 +419,7 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Td = T + depth;
|
Td = T + depth;
|
||||||
if(limit-- == 0) { ss_heapsort(Td, PA, first, last - first); }
|
if(limit-- == 0) { ss_heapsort(Td, PA, first, PTRDIFF_TO_INT(last - first)); }
|
||||||
if(limit < 0) {
|
if(limit < 0) {
|
||||||
for(a = first + 1, v = Td[PA[*first]]; a < last; ++a) {
|
for(a = first + 1, v = Td[PA[*first]]; a < last; ++a) {
|
||||||
if((x = Td[PA[*a]]) != v) {
|
if((x = Td[PA[*a]]) != v) {
|
||||||
@@ -435,16 +434,16 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||||||
if((a - first) <= (last - a)) {
|
if((a - first) <= (last - a)) {
|
||||||
if(1 < (a - first)) {
|
if(1 < (a - first)) {
|
||||||
STACK_PUSH(a, last, depth, -1);
|
STACK_PUSH(a, last, depth, -1);
|
||||||
last = a, depth += 1, limit = ss_ilg(a - first);
|
last = a, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(a - first));
|
||||||
} else {
|
} else {
|
||||||
first = a, limit = -1;
|
first = a, limit = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(1 < (last - a)) {
|
if(1 < (last - a)) {
|
||||||
STACK_PUSH(first, a, depth + 1, ss_ilg(a - first));
|
STACK_PUSH(first, a, depth + 1, ss_ilg(PTRDIFF_TO_INT(a - first)));
|
||||||
first = a, limit = -1;
|
first = a, limit = -1;
|
||||||
} else {
|
} else {
|
||||||
last = a, depth += 1, limit = ss_ilg(a - first);
|
last = a, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(a - first));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -481,9 +480,9 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||||||
if(a <= d) {
|
if(a <= d) {
|
||||||
c = b - 1;
|
c = b - 1;
|
||||||
|
|
||||||
if((s = a - first) > (t = b - a)) { s = t; }
|
if((s = PTRDIFF_TO_INT(a - first)) > (t = PTRDIFF_TO_INT(b - a))) { s = t; }
|
||||||
for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
||||||
if((s = d - c) > (t = last - d - 1)) { s = t; }
|
if((s = PTRDIFF_TO_INT(d - c)) > (t = PTRDIFF_TO_INT(last - d - 1))) { s = t; }
|
||||||
for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
||||||
|
|
||||||
a = first + (b - a), c = last - (d - c);
|
a = first + (b - a), c = last - (d - c);
|
||||||
@@ -491,38 +490,38 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||||||
|
|
||||||
if((a - first) <= (last - c)) {
|
if((a - first) <= (last - c)) {
|
||||||
if((last - c) <= (c - b)) {
|
if((last - c) <= (c - b)) {
|
||||||
STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
|
STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
|
||||||
STACK_PUSH(c, last, depth, limit);
|
STACK_PUSH(c, last, depth, limit);
|
||||||
last = a;
|
last = a;
|
||||||
} else if((a - first) <= (c - b)) {
|
} else if((a - first) <= (c - b)) {
|
||||||
STACK_PUSH(c, last, depth, limit);
|
STACK_PUSH(c, last, depth, limit);
|
||||||
STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
|
STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
|
||||||
last = a;
|
last = a;
|
||||||
} else {
|
} else {
|
||||||
STACK_PUSH(c, last, depth, limit);
|
STACK_PUSH(c, last, depth, limit);
|
||||||
STACK_PUSH(first, a, depth, limit);
|
STACK_PUSH(first, a, depth, limit);
|
||||||
first = b, last = c, depth += 1, limit = ss_ilg(c - b);
|
first = b, last = c, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(c - b));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if((a - first) <= (c - b)) {
|
if((a - first) <= (c - b)) {
|
||||||
STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
|
STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
|
||||||
STACK_PUSH(first, a, depth, limit);
|
STACK_PUSH(first, a, depth, limit);
|
||||||
first = c;
|
first = c;
|
||||||
} else if((last - c) <= (c - b)) {
|
} else if((last - c) <= (c - b)) {
|
||||||
STACK_PUSH(first, a, depth, limit);
|
STACK_PUSH(first, a, depth, limit);
|
||||||
STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
|
STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
|
||||||
first = c;
|
first = c;
|
||||||
} else {
|
} else {
|
||||||
STACK_PUSH(first, a, depth, limit);
|
STACK_PUSH(first, a, depth, limit);
|
||||||
STACK_PUSH(c, last, depth, limit);
|
STACK_PUSH(c, last, depth, limit);
|
||||||
first = b, last = c, depth += 1, limit = ss_ilg(c - b);
|
first = b, last = c, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(c - b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
limit += 1;
|
limit += 1;
|
||||||
if(Td[PA[*first] - 1] < v) {
|
if(Td[PA[*first] - 1] < v) {
|
||||||
first = ss_partition(PA, first, last, depth);
|
first = ss_partition(PA, first, last, depth);
|
||||||
limit = ss_ilg(last - first);
|
limit = ss_ilg(PTRDIFF_TO_INT(last - first));
|
||||||
}
|
}
|
||||||
depth += 1;
|
depth += 1;
|
||||||
}
|
}
|
||||||
@@ -551,7 +550,8 @@ void
|
|||||||
ss_rotate(int *first, int *middle, int *last) {
|
ss_rotate(int *first, int *middle, int *last) {
|
||||||
int *a, *b, t;
|
int *a, *b, t;
|
||||||
int l, r;
|
int l, r;
|
||||||
l = middle - first, r = last - middle;
|
l = PTRDIFF_TO_INT(middle - first);
|
||||||
|
r = PTRDIFF_TO_INT(last - middle);
|
||||||
for(; (0 < l) && (0 < r);) {
|
for(; (0 < l) && (0 < r);) {
|
||||||
if(l == r) { ss_blockswap(first, middle, l); break; }
|
if(l == r) { ss_blockswap(first, middle, l); break; }
|
||||||
if(l < r) {
|
if(l < r) {
|
||||||
@@ -601,7 +601,7 @@ ss_inplacemerge(const unsigned char *T, const int *PA,
|
|||||||
for(;;) {
|
for(;;) {
|
||||||
if(*(last - 1) < 0) { x = 1; p = PA + ~*(last - 1); }
|
if(*(last - 1) < 0) { x = 1; p = PA + ~*(last - 1); }
|
||||||
else { x = 0; p = PA + *(last - 1); }
|
else { x = 0; p = PA + *(last - 1); }
|
||||||
for(a = first, len = middle - first, half = len >> 1, r = -1;
|
for(a = first, len = PTRDIFF_TO_INT(middle - first), half = len >> 1, r = -1;
|
||||||
0 < len;
|
0 < len;
|
||||||
len = half, half >>= 1) {
|
len = half, half >>= 1) {
|
||||||
b = a + half;
|
b = a + half;
|
||||||
@@ -640,7 +640,7 @@ ss_mergeforward(const unsigned char *T, const int *PA,
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
bufend = buf + (middle - first) - 1;
|
bufend = buf + (middle - first) - 1;
|
||||||
ss_blockswap(buf, first, middle - first);
|
ss_blockswap(buf, first, PTRDIFF_TO_INT(middle - first));
|
||||||
|
|
||||||
for(t = *(a = first), b = buf, c = middle;;) {
|
for(t = *(a = first), b = buf, c = middle;;) {
|
||||||
r = ss_compare(T, PA + *b, PA + *c, depth);
|
r = ss_compare(T, PA + *b, PA + *c, depth);
|
||||||
@@ -692,7 +692,7 @@ ss_mergebackward(const unsigned char *T, const int *PA,
|
|||||||
int x;
|
int x;
|
||||||
|
|
||||||
bufend = buf + (last - middle) - 1;
|
bufend = buf + (last - middle) - 1;
|
||||||
ss_blockswap(buf, middle, last - middle);
|
ss_blockswap(buf, middle, PTRDIFF_TO_INT(last - middle));
|
||||||
|
|
||||||
x = 0;
|
x = 0;
|
||||||
if(*bufend < 0) { p1 = PA + ~*bufend; x |= 1; }
|
if(*bufend < 0) { p1 = PA + ~*bufend; x |= 1; }
|
||||||
@@ -781,7 +781,7 @@ ss_swapmerge(const unsigned char *T, const int *PA,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(m = 0, len = MIN(middle - first, last - middle), half = len >> 1;
|
for(m = 0, len = PTRDIFF_TO_INT(MIN(middle - first, last - middle)), half = len >> 1;
|
||||||
0 < len;
|
0 < len;
|
||||||
len = half, half >>= 1) {
|
len = half, half >>= 1) {
|
||||||
if(ss_compare(T, PA + GETIDX(*(middle + m + half)),
|
if(ss_compare(T, PA + GETIDX(*(middle + m + half)),
|
||||||
@@ -850,8 +850,8 @@ sssort(const unsigned char *T, const int *PA,
|
|||||||
ss_mintrosort(T, PA, first, last, depth);
|
ss_mintrosort(T, PA, first, last, depth);
|
||||||
#else
|
#else
|
||||||
if((bufsize < SS_BLOCKSIZE) &&
|
if((bufsize < SS_BLOCKSIZE) &&
|
||||||
(bufsize < (last - first)) &&
|
(bufsize < PTRDIFF_TO_INT(last - first)) &&
|
||||||
(bufsize < (limit = ss_isqrt(last - first)))) {
|
(bufsize < (limit = ss_isqrt(PTRDIFF_TO_INT(last - first))))) {
|
||||||
if(SS_BLOCKSIZE < limit) { limit = SS_BLOCKSIZE; }
|
if(SS_BLOCKSIZE < limit) { limit = SS_BLOCKSIZE; }
|
||||||
buf = middle = last - limit, bufsize = limit;
|
buf = middle = last - limit, bufsize = limit;
|
||||||
} else {
|
} else {
|
||||||
@@ -863,7 +863,7 @@ sssort(const unsigned char *T, const int *PA,
|
|||||||
#elif 1 < SS_BLOCKSIZE
|
#elif 1 < SS_BLOCKSIZE
|
||||||
ss_insertionsort(T, PA, a, a + SS_BLOCKSIZE, depth);
|
ss_insertionsort(T, PA, a, a + SS_BLOCKSIZE, depth);
|
||||||
#endif
|
#endif
|
||||||
curbufsize = last - (a + SS_BLOCKSIZE);
|
curbufsize = PTRDIFF_TO_INT(last - (a + SS_BLOCKSIZE));
|
||||||
curbuf = a + SS_BLOCKSIZE;
|
curbuf = a + SS_BLOCKSIZE;
|
||||||
if(curbufsize <= bufsize) { curbufsize = bufsize, curbuf = buf; }
|
if(curbufsize <= bufsize) { curbufsize = bufsize, curbuf = buf; }
|
||||||
for(b = a, k = SS_BLOCKSIZE, j = i; j & 1; b -= k, k <<= 1, j >>= 1) {
|
for(b = a, k = SS_BLOCKSIZE, j = i; j & 1; b -= k, k <<= 1, j >>= 1) {
|
||||||
@@ -1016,7 +1016,7 @@ tr_pivot(const int *ISAd, int *first, int *last) {
|
|||||||
int *middle;
|
int *middle;
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
t = last - first;
|
t = PTRDIFF_TO_INT(last - first);
|
||||||
middle = first + t / 2;
|
middle = first + t / 2;
|
||||||
|
|
||||||
if(t <= 512) {
|
if(t <= 512) {
|
||||||
@@ -1098,9 +1098,9 @@ tr_partition(const int *ISAd,
|
|||||||
|
|
||||||
if(a <= d) {
|
if(a <= d) {
|
||||||
c = b - 1;
|
c = b - 1;
|
||||||
if((s = a - first) > (t = b - a)) { s = t; }
|
if((s = PTRDIFF_TO_INT(a - first)) > (t = PTRDIFF_TO_INT(b - a))) { s = t; }
|
||||||
for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
||||||
if((s = d - c) > (t = last - d - 1)) { s = t; }
|
if((s = PTRDIFF_TO_INT(d - c)) > (t = PTRDIFF_TO_INT(last - d - 1))) { s = t; }
|
||||||
for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
|
||||||
first += (b - a), last -= (d - c);
|
first += (b - a), last -= (d - c);
|
||||||
}
|
}
|
||||||
@@ -1117,17 +1117,17 @@ tr_copy(int *ISA, const int *SA,
|
|||||||
int *c, *d, *e;
|
int *c, *d, *e;
|
||||||
int s, v;
|
int s, v;
|
||||||
|
|
||||||
v = b - SA - 1;
|
v = PTRDIFF_TO_INT(b - SA - 1);
|
||||||
for(c = first, d = a - 1; c <= d; ++c) {
|
for(c = first, d = a - 1; c <= d; ++c) {
|
||||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||||
*++d = s;
|
*++d = s;
|
||||||
ISA[s] = d - SA;
|
ISA[s] = PTRDIFF_TO_INT(d - SA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(c = last - 1, e = d + 1, d = b; e < d; --c) {
|
for(c = last - 1, e = d + 1, d = b; e < d; --c) {
|
||||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||||
*--d = s;
|
*--d = s;
|
||||||
ISA[s] = d - SA;
|
ISA[s] = PTRDIFF_TO_INT(d - SA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1141,13 +1141,13 @@ tr_partialcopy(int *ISA, const int *SA,
|
|||||||
int s, v;
|
int s, v;
|
||||||
int rank, lastrank, newrank = -1;
|
int rank, lastrank, newrank = -1;
|
||||||
|
|
||||||
v = b - SA - 1;
|
v = PTRDIFF_TO_INT(b - SA - 1);
|
||||||
lastrank = -1;
|
lastrank = -1;
|
||||||
for(c = first, d = a - 1; c <= d; ++c) {
|
for(c = first, d = a - 1; c <= d; ++c) {
|
||||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||||
*++d = s;
|
*++d = s;
|
||||||
rank = ISA[s + depth];
|
rank = ISA[s + depth];
|
||||||
if(lastrank != rank) { lastrank = rank; newrank = d - SA; }
|
if(lastrank != rank) { lastrank = rank; newrank = PTRDIFF_TO_INT(d - SA); }
|
||||||
ISA[s] = newrank;
|
ISA[s] = newrank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1155,7 +1155,7 @@ tr_partialcopy(int *ISA, const int *SA,
|
|||||||
lastrank = -1;
|
lastrank = -1;
|
||||||
for(e = d; first <= e; --e) {
|
for(e = d; first <= e; --e) {
|
||||||
rank = ISA[*e];
|
rank = ISA[*e];
|
||||||
if(lastrank != rank) { lastrank = rank; newrank = e - SA; }
|
if(lastrank != rank) { lastrank = rank; newrank = PTRDIFF_TO_INT(e - SA); }
|
||||||
if(newrank != rank) { ISA[*e] = newrank; }
|
if(newrank != rank) { ISA[*e] = newrank; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1164,7 +1164,7 @@ tr_partialcopy(int *ISA, const int *SA,
|
|||||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||||
*--d = s;
|
*--d = s;
|
||||||
rank = ISA[s + depth];
|
rank = ISA[s + depth];
|
||||||
if(lastrank != rank) { lastrank = rank; newrank = d - SA; }
|
if(lastrank != rank) { lastrank = rank; newrank = PTRDIFF_TO_INT(d - SA); }
|
||||||
ISA[s] = newrank;
|
ISA[s] = newrank;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1180,23 +1180,23 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||||||
int *a, *b, *c;
|
int *a, *b, *c;
|
||||||
int t;
|
int t;
|
||||||
int v, x = 0;
|
int v, x = 0;
|
||||||
int incr = ISAd - ISA;
|
int incr = PTRDIFF_TO_INT(ISAd - ISA);
|
||||||
int limit, next;
|
int limit, next;
|
||||||
int ssize, trlink = -1;
|
int ssize, trlink = -1;
|
||||||
|
|
||||||
for(ssize = 0, limit = tr_ilg(last - first);;) {
|
for(ssize = 0, limit = tr_ilg(PTRDIFF_TO_INT(last - first));;) {
|
||||||
|
|
||||||
if(limit < 0) {
|
if(limit < 0) {
|
||||||
if(limit == -1) {
|
if(limit == -1) {
|
||||||
/* tandem repeat partition */
|
/* tandem repeat partition */
|
||||||
tr_partition(ISAd - incr, first, first, last, &a, &b, last - SA - 1);
|
tr_partition(ISAd - incr, first, first, last, &a, &b, PTRDIFF_TO_INT(last - SA - 1));
|
||||||
|
|
||||||
/* update ranks */
|
/* update ranks */
|
||||||
if(a < last) {
|
if(a < last) {
|
||||||
for(c = first, v = a - SA - 1; c < a; ++c) { ISA[*c] = v; }
|
for(c = first, v = PTRDIFF_TO_INT(a - SA - 1); c < a; ++c) { ISA[*c] = v; }
|
||||||
}
|
}
|
||||||
if(b < last) {
|
if(b < last) {
|
||||||
for(c = a, v = b - SA - 1; c < b; ++c) { ISA[*c] = v; }
|
for(c = a, v = PTRDIFF_TO_INT(b - SA - 1); c < b; ++c) { ISA[*c] = v; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push */
|
/* push */
|
||||||
@@ -1207,19 +1207,19 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||||||
}
|
}
|
||||||
if((a - first) <= (last - b)) {
|
if((a - first) <= (last - b)) {
|
||||||
if(1 < (a - first)) {
|
if(1 < (a - first)) {
|
||||||
STACK_PUSH5(ISAd, b, last, tr_ilg(last - b), trlink);
|
STACK_PUSH5(ISAd, b, last, tr_ilg(PTRDIFF_TO_INT(last - b)), trlink);
|
||||||
last = a, limit = tr_ilg(a - first);
|
last = a, limit = tr_ilg(PTRDIFF_TO_INT(a - first));
|
||||||
} else if(1 < (last - b)) {
|
} else if(1 < (last - b)) {
|
||||||
first = b, limit = tr_ilg(last - b);
|
first = b, limit = tr_ilg(PTRDIFF_TO_INT(last - b));
|
||||||
} else {
|
} else {
|
||||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(1 < (last - b)) {
|
if(1 < (last - b)) {
|
||||||
STACK_PUSH5(ISAd, first, a, tr_ilg(a - first), trlink);
|
STACK_PUSH5(ISAd, first, a, tr_ilg(PTRDIFF_TO_INT(a - first)), trlink);
|
||||||
first = b, limit = tr_ilg(last - b);
|
first = b, limit = tr_ilg(PTRDIFF_TO_INT(last - b));
|
||||||
} else if(1 < (a - first)) {
|
} else if(1 < (a - first)) {
|
||||||
last = a, limit = tr_ilg(a - first);
|
last = a, limit = tr_ilg(PTRDIFF_TO_INT(a - first));
|
||||||
} else {
|
} else {
|
||||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||||
}
|
}
|
||||||
@@ -1228,26 +1228,26 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||||||
/* tandem repeat copy */
|
/* tandem repeat copy */
|
||||||
a = stack[--ssize].b, b = stack[ssize].c;
|
a = stack[--ssize].b, b = stack[ssize].c;
|
||||||
if(stack[ssize].d == 0) {
|
if(stack[ssize].d == 0) {
|
||||||
tr_copy(ISA, SA, first, a, b, last, ISAd - ISA);
|
tr_copy(ISA, SA, first, a, b, last, PTRDIFF_TO_INT(ISAd - ISA));
|
||||||
} else {
|
} else {
|
||||||
if(0 <= trlink) { stack[trlink].d = -1; }
|
if(0 <= trlink) { stack[trlink].d = -1; }
|
||||||
tr_partialcopy(ISA, SA, first, a, b, last, ISAd - ISA);
|
tr_partialcopy(ISA, SA, first, a, b, last, PTRDIFF_TO_INT(ISAd - ISA));
|
||||||
}
|
}
|
||||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||||
} else {
|
} else {
|
||||||
/* sorted partition */
|
/* sorted partition */
|
||||||
if(0 <= *first) {
|
if(0 <= *first) {
|
||||||
a = first;
|
a = first;
|
||||||
do { ISA[*a] = a - SA; } while((++a < last) && (0 <= *a));
|
do { ISA[*a] = PTRDIFF_TO_INT(a - SA); } while((++a < last) && (0 <= *a));
|
||||||
first = a;
|
first = a;
|
||||||
}
|
}
|
||||||
if(first < last) {
|
if(first < last) {
|
||||||
a = first; do { *a = ~*a; } while(*++a < 0);
|
a = first; do { *a = ~*a; } while(*++a < 0);
|
||||||
next = (ISA[*a] != ISAd[*a]) ? tr_ilg(a - first + 1) : -1;
|
next = (ISA[*a] != ISAd[*a]) ? tr_ilg(PTRDIFF_TO_INT(a - first + 1)) : -1;
|
||||||
if(++a < last) { for(b = first, v = a - SA - 1; b < a; ++b) { ISA[*b] = v; } }
|
if(++a < last) { for(b = first, v = PTRDIFF_TO_INT(a - SA - 1); b < a; ++b) { ISA[*b] = v; } }
|
||||||
|
|
||||||
/* push */
|
/* push */
|
||||||
if(trbudget_check(budget, a - first)) {
|
if(trbudget_check(budget, PTRDIFF_TO_INT(a - first))) {
|
||||||
if((a - first) <= (last - a)) {
|
if((a - first) <= (last - a)) {
|
||||||
STACK_PUSH5(ISAd, a, last, -3, trlink);
|
STACK_PUSH5(ISAd, a, last, -3, trlink);
|
||||||
ISAd += incr, last = a, limit = next;
|
ISAd += incr, last = a, limit = next;
|
||||||
@@ -1281,7 +1281,7 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(limit-- == 0) {
|
if(limit-- == 0) {
|
||||||
tr_heapsort(ISAd, first, last - first);
|
tr_heapsort(ISAd, first, PTRDIFF_TO_INT(last - first));
|
||||||
for(a = last - 1; first < a; a = b) {
|
for(a = last - 1; first < a; a = b) {
|
||||||
for(x = ISAd[*a], b = a - 1; (first <= b) && (ISAd[*b] == x); --b) { *b = ~*b; }
|
for(x = ISAd[*a], b = a - 1; (first <= b) && (ISAd[*b] == x); --b) { *b = ~*b; }
|
||||||
}
|
}
|
||||||
@@ -1297,14 +1297,14 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||||||
/* partition */
|
/* partition */
|
||||||
tr_partition(ISAd, first, first + 1, last, &a, &b, v);
|
tr_partition(ISAd, first, first + 1, last, &a, &b, v);
|
||||||
if((last - first) != (b - a)) {
|
if((last - first) != (b - a)) {
|
||||||
next = (ISA[*a] != v) ? tr_ilg(b - a) : -1;
|
next = (ISA[*a] != v) ? tr_ilg(PTRDIFF_TO_INT(b - a)) : -1;
|
||||||
|
|
||||||
/* update ranks */
|
/* update ranks */
|
||||||
for(c = first, v = a - SA - 1; c < a; ++c) { ISA[*c] = v; }
|
for(c = first, v = PTRDIFF_TO_INT(a - SA - 1); c < a; ++c) { ISA[*c] = v; }
|
||||||
if(b < last) { for(c = a, v = b - SA - 1; c < b; ++c) { ISA[*c] = v; } }
|
if(b < last) { for(c = a, v = PTRDIFF_TO_INT(b - SA - 1); c < b; ++c) { ISA[*c] = v; } }
|
||||||
|
|
||||||
/* push */
|
/* push */
|
||||||
if((1 < (b - a)) && (trbudget_check(budget, b - a))) {
|
if((1 < (b - a)) && (trbudget_check(budget, PTRDIFF_TO_INT(b - a)))) {
|
||||||
if((a - first) <= (last - b)) {
|
if((a - first) <= (last - b)) {
|
||||||
if((last - b) <= (b - a)) {
|
if((last - b) <= (b - a)) {
|
||||||
if(1 < (a - first)) {
|
if(1 < (a - first)) {
|
||||||
@@ -1381,8 +1381,8 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(trbudget_check(budget, last - first)) {
|
if(trbudget_check(budget, PTRDIFF_TO_INT(last - first))) {
|
||||||
limit = tr_ilg(last - first), ISAd += incr;
|
limit = tr_ilg(PTRDIFF_TO_INT(last - first)), ISAd += incr;
|
||||||
} else {
|
} else {
|
||||||
if(0 <= trlink) { stack[trlink].d = -1; }
|
if(0 <= trlink) { stack[trlink].d = -1; }
|
||||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||||
@@ -1420,7 +1420,7 @@ trsort(int *ISA, int *SA, int n, int depth) {
|
|||||||
budget.count = 0;
|
budget.count = 0;
|
||||||
tr_introsort(ISA, ISAd, SA, first, last, &budget);
|
tr_introsort(ISA, ISAd, SA, first, last, &budget);
|
||||||
if(budget.count != 0) { unsorted += budget.count; }
|
if(budget.count != 0) { unsorted += budget.count; }
|
||||||
else { skip = first - last; }
|
else { skip = PTRDIFF_TO_INT(first - last); }
|
||||||
} else if((last - first) == 1) {
|
} else if((last - first) == 1) {
|
||||||
skip = -1;
|
skip = -1;
|
||||||
}
|
}
|
||||||
@@ -1634,7 +1634,7 @@ construct_SA(const unsigned char *T, int *SA,
|
|||||||
c0 = T[--s];
|
c0 = T[--s];
|
||||||
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
||||||
if(c0 != c2) {
|
if(c0 != c2) {
|
||||||
if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; }
|
if(0 <= c2) { BUCKET_B(c2, c1) = PTRDIFF_TO_INT(k - SA); }
|
||||||
k = SA + BUCKET_B(c2 = c0, c1);
|
k = SA + BUCKET_B(c2 = c0, c1);
|
||||||
}
|
}
|
||||||
assert(k < j); assert(k != NULL);
|
assert(k < j); assert(k != NULL);
|
||||||
@@ -1658,7 +1658,7 @@ construct_SA(const unsigned char *T, int *SA,
|
|||||||
c0 = T[--s];
|
c0 = T[--s];
|
||||||
if((s == 0) || (T[s - 1] < c0)) { s = ~s; }
|
if((s == 0) || (T[s - 1] < c0)) { s = ~s; }
|
||||||
if(c0 != c2) {
|
if(c0 != c2) {
|
||||||
BUCKET_A(c2) = k - SA;
|
BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
|
||||||
k = SA + BUCKET_A(c2 = c0);
|
k = SA + BUCKET_A(c2 = c0);
|
||||||
}
|
}
|
||||||
assert(i < k);
|
assert(i < k);
|
||||||
@@ -1698,7 +1698,7 @@ construct_BWT(const unsigned char *T, int *SA,
|
|||||||
*j = ~((int)c0);
|
*j = ~((int)c0);
|
||||||
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
||||||
if(c0 != c2) {
|
if(c0 != c2) {
|
||||||
if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; }
|
if(0 <= c2) { BUCKET_B(c2, c1) = PTRDIFF_TO_INT(k - SA); }
|
||||||
k = SA + BUCKET_B(c2 = c0, c1);
|
k = SA + BUCKET_B(c2 = c0, c1);
|
||||||
}
|
}
|
||||||
assert(k < j); assert(k != NULL);
|
assert(k < j); assert(k != NULL);
|
||||||
@@ -1726,7 +1726,7 @@ construct_BWT(const unsigned char *T, int *SA,
|
|||||||
*i = c0;
|
*i = c0;
|
||||||
if((0 < s) && (T[s - 1] < c0)) { s = ~((int)T[s - 1]); }
|
if((0 < s) && (T[s - 1] < c0)) { s = ~((int)T[s - 1]); }
|
||||||
if(c0 != c2) {
|
if(c0 != c2) {
|
||||||
BUCKET_A(c2) = k - SA;
|
BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
|
||||||
k = SA + BUCKET_A(c2 = c0);
|
k = SA + BUCKET_A(c2 = c0);
|
||||||
}
|
}
|
||||||
assert(i < k);
|
assert(i < k);
|
||||||
@@ -1738,7 +1738,7 @@ construct_BWT(const unsigned char *T, int *SA,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return orig - SA;
|
return PTRDIFF_TO_INT(orig - SA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Constructs the burrows-wheeler transformed string directly
|
/* Constructs the burrows-wheeler transformed string directly
|
||||||
@@ -1776,13 +1776,13 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||||||
assert(((s + 1) < n) && (T[s] <= T[s + 1]));
|
assert(((s + 1) < n) && (T[s] <= T[s + 1]));
|
||||||
assert(T[s - 1] <= T[s]);
|
assert(T[s - 1] <= T[s]);
|
||||||
|
|
||||||
if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = j - SA;
|
if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = PTRDIFF_TO_INT(j - SA);
|
||||||
|
|
||||||
c0 = T[--s];
|
c0 = T[--s];
|
||||||
*j = ~((int)c0);
|
*j = ~((int)c0);
|
||||||
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
||||||
if(c0 != c2) {
|
if(c0 != c2) {
|
||||||
if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; }
|
if(0 <= c2) { BUCKET_B(c2, c1) = PTRDIFF_TO_INT(k - SA); }
|
||||||
k = SA + BUCKET_B(c2 = c0, c1);
|
k = SA + BUCKET_B(c2 = c0, c1);
|
||||||
}
|
}
|
||||||
assert(k < j); assert(k != NULL);
|
assert(k < j); assert(k != NULL);
|
||||||
@@ -1802,7 +1802,7 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||||||
the sorted order of type B suffixes. */
|
the sorted order of type B suffixes. */
|
||||||
k = SA + BUCKET_A(c2 = T[n - 1]);
|
k = SA + BUCKET_A(c2 = T[n - 1]);
|
||||||
if (T[n - 2] < c2) {
|
if (T[n - 2] < c2) {
|
||||||
if (((n - 1) & mod) == 0) indexes[(n - 1) / (mod + 1) - 1] = k - SA;
|
if (((n - 1) & mod) == 0) indexes[(n - 1) / (mod + 1) - 1] = PTRDIFF_TO_INT(k - SA);
|
||||||
*k++ = ~((int)T[n - 2]);
|
*k++ = ~((int)T[n - 2]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1814,17 +1814,17 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||||||
if(0 < (s = *i)) {
|
if(0 < (s = *i)) {
|
||||||
assert(T[s - 1] >= T[s]);
|
assert(T[s - 1] >= T[s]);
|
||||||
|
|
||||||
if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = i - SA;
|
if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = PTRDIFF_TO_INT(i - SA);
|
||||||
|
|
||||||
c0 = T[--s];
|
c0 = T[--s];
|
||||||
*i = c0;
|
*i = c0;
|
||||||
if(c0 != c2) {
|
if(c0 != c2) {
|
||||||
BUCKET_A(c2) = k - SA;
|
BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
|
||||||
k = SA + BUCKET_A(c2 = c0);
|
k = SA + BUCKET_A(c2 = c0);
|
||||||
}
|
}
|
||||||
assert(i < k);
|
assert(i < k);
|
||||||
if((0 < s) && (T[s - 1] < c0)) {
|
if((0 < s) && (T[s - 1] < c0)) {
|
||||||
if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = k - SA;
|
if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = PTRDIFF_TO_INT(k - SA);
|
||||||
*k++ = ~((int)T[s - 1]);
|
*k++ = ~((int)T[s - 1]);
|
||||||
} else
|
} else
|
||||||
*k++ = s;
|
*k++ = s;
|
||||||
@@ -1835,7 +1835,7 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return orig - SA;
|
return PTRDIFF_TO_INT(orig - SA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+39
-40
@@ -49,38 +49,30 @@
|
|||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Console display
|
* Console display
|
||||||
|
*
|
||||||
|
* Captures the `displayLevel` variable in the local scope.
|
||||||
***************************************/
|
***************************************/
|
||||||
#ifndef LOCALDISPLAYLEVEL
|
|
||||||
static int g_displayLevel = 0;
|
|
||||||
#endif
|
|
||||||
#undef DISPLAY
|
#undef DISPLAY
|
||||||
#define DISPLAY(...) \
|
#define DISPLAY(...) \
|
||||||
{ \
|
{ \
|
||||||
fprintf(stderr, __VA_ARGS__); \
|
fprintf(stderr, __VA_ARGS__); \
|
||||||
fflush(stderr); \
|
fflush(stderr); \
|
||||||
}
|
}
|
||||||
#undef LOCALDISPLAYLEVEL
|
#undef DISPLAYLEVEL
|
||||||
#define LOCALDISPLAYLEVEL(displayLevel, l, ...) \
|
#define DISPLAYLEVEL(l, ...) \
|
||||||
if (displayLevel >= l) { \
|
if (displayLevel >= l) { \
|
||||||
DISPLAY(__VA_ARGS__); \
|
DISPLAY(__VA_ARGS__); \
|
||||||
} /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
} /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
||||||
#undef DISPLAYLEVEL
|
|
||||||
#define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__)
|
|
||||||
|
|
||||||
#ifndef LOCALDISPLAYUPDATE
|
#undef DISPLAYUPDATE
|
||||||
static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
|
#define DISPLAYUPDATE(lastUpdateTime, l, ...) \
|
||||||
static clock_t g_time = 0;
|
|
||||||
#endif
|
|
||||||
#undef LOCALDISPLAYUPDATE
|
|
||||||
#define LOCALDISPLAYUPDATE(displayLevel, l, ...) \
|
|
||||||
if (displayLevel >= l) { \
|
if (displayLevel >= l) { \
|
||||||
if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \
|
const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100; \
|
||||||
g_time = clock(); \
|
if ((clock() - lastUpdateTime > refreshRate) || (displayLevel >= 4)) { \
|
||||||
|
lastUpdateTime = clock(); \
|
||||||
DISPLAY(__VA_ARGS__); \
|
DISPLAY(__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
#undef DISPLAYUPDATE
|
|
||||||
#define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__)
|
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -136,6 +128,7 @@ typedef struct {
|
|||||||
unsigned d;
|
unsigned d;
|
||||||
unsigned f;
|
unsigned f;
|
||||||
FASTCOVER_accel_t accelParams;
|
FASTCOVER_accel_t accelParams;
|
||||||
|
int displayLevel;
|
||||||
} FASTCOVER_ctx_t;
|
} FASTCOVER_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -314,7 +307,8 @@ FASTCOVER_ctx_init(FASTCOVER_ctx_t* ctx,
|
|||||||
const void* samplesBuffer,
|
const void* samplesBuffer,
|
||||||
const size_t* samplesSizes, unsigned nbSamples,
|
const size_t* samplesSizes, unsigned nbSamples,
|
||||||
unsigned d, double splitPoint, unsigned f,
|
unsigned d, double splitPoint, unsigned f,
|
||||||
FASTCOVER_accel_t accelParams)
|
FASTCOVER_accel_t accelParams,
|
||||||
|
int displayLevel)
|
||||||
{
|
{
|
||||||
const BYTE* const samples = (const BYTE*)samplesBuffer;
|
const BYTE* const samples = (const BYTE*)samplesBuffer;
|
||||||
const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples);
|
const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples);
|
||||||
@@ -323,6 +317,7 @@ FASTCOVER_ctx_init(FASTCOVER_ctx_t* ctx,
|
|||||||
const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples;
|
const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples;
|
||||||
const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
|
const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
|
||||||
const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
|
const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
|
||||||
|
ctx->displayLevel = displayLevel;
|
||||||
|
|
||||||
/* Checks */
|
/* Checks */
|
||||||
if (totalSamplesSize < MAX(d, sizeof(U64)) ||
|
if (totalSamplesSize < MAX(d, sizeof(U64)) ||
|
||||||
@@ -409,7 +404,9 @@ FASTCOVER_buildDictionary(const FASTCOVER_ctx_t* ctx,
|
|||||||
const COVER_epoch_info_t epochs = COVER_computeEpochs(
|
const COVER_epoch_info_t epochs = COVER_computeEpochs(
|
||||||
(U32)dictBufferCapacity, (U32)ctx->nbDmers, parameters.k, 1);
|
(U32)dictBufferCapacity, (U32)ctx->nbDmers, parameters.k, 1);
|
||||||
const size_t maxZeroScoreRun = 10;
|
const size_t maxZeroScoreRun = 10;
|
||||||
|
const int displayLevel = ctx->displayLevel;
|
||||||
size_t zeroScoreRun = 0;
|
size_t zeroScoreRun = 0;
|
||||||
|
clock_t lastUpdateTime = 0;
|
||||||
size_t epoch;
|
size_t epoch;
|
||||||
DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
|
DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
|
||||||
(U32)epochs.num, (U32)epochs.size);
|
(U32)epochs.num, (U32)epochs.size);
|
||||||
@@ -447,6 +444,7 @@ FASTCOVER_buildDictionary(const FASTCOVER_ctx_t* ctx,
|
|||||||
tail -= segmentSize;
|
tail -= segmentSize;
|
||||||
memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
|
memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
|
||||||
DISPLAYUPDATE(
|
DISPLAYUPDATE(
|
||||||
|
lastUpdateTime,
|
||||||
2, "\r%u%% ",
|
2, "\r%u%% ",
|
||||||
(unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
|
(unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
|
||||||
}
|
}
|
||||||
@@ -484,6 +482,7 @@ static void FASTCOVER_tryParameters(void* opaque)
|
|||||||
BYTE *const dict = (BYTE*)malloc(dictBufferCapacity);
|
BYTE *const dict = (BYTE*)malloc(dictBufferCapacity);
|
||||||
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
||||||
U32* freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32));
|
U32* freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32));
|
||||||
|
const int displayLevel = ctx->displayLevel;
|
||||||
if (!segmentFreqs || !dict || !freqs) {
|
if (!segmentFreqs || !dict || !freqs) {
|
||||||
DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n");
|
DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n");
|
||||||
goto _cleanup;
|
goto _cleanup;
|
||||||
@@ -555,8 +554,7 @@ ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity,
|
|||||||
FASTCOVER_ctx_t ctx;
|
FASTCOVER_ctx_t ctx;
|
||||||
ZDICT_cover_params_t coverParams;
|
ZDICT_cover_params_t coverParams;
|
||||||
FASTCOVER_accel_t accelParams;
|
FASTCOVER_accel_t accelParams;
|
||||||
/* Initialize global data */
|
const int displayLevel = (int)parameters.zParams.notificationLevel;
|
||||||
g_displayLevel = (int)parameters.zParams.notificationLevel;
|
|
||||||
/* Assign splitPoint and f if not provided */
|
/* Assign splitPoint and f if not provided */
|
||||||
parameters.splitPoint = 1.0;
|
parameters.splitPoint = 1.0;
|
||||||
parameters.f = parameters.f == 0 ? DEFAULT_F : parameters.f;
|
parameters.f = parameters.f == 0 ? DEFAULT_F : parameters.f;
|
||||||
@@ -585,13 +583,13 @@ ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity,
|
|||||||
{
|
{
|
||||||
size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
|
size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
|
||||||
coverParams.d, parameters.splitPoint, parameters.f,
|
coverParams.d, parameters.splitPoint, parameters.f,
|
||||||
accelParams);
|
accelParams, displayLevel);
|
||||||
if (ZSTD_isError(initVal)) {
|
if (ZSTD_isError(initVal)) {
|
||||||
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
||||||
return initVal;
|
return initVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, g_displayLevel);
|
COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, displayLevel);
|
||||||
/* Build the dictionary */
|
/* Build the dictionary */
|
||||||
DISPLAYLEVEL(2, "Building dictionary\n");
|
DISPLAYLEVEL(2, "Building dictionary\n");
|
||||||
{
|
{
|
||||||
@@ -646,25 +644,26 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||||||
COVER_best_t best;
|
COVER_best_t best;
|
||||||
POOL_ctx *pool = NULL;
|
POOL_ctx *pool = NULL;
|
||||||
int warned = 0;
|
int warned = 0;
|
||||||
|
clock_t lastUpdateTime = 0;
|
||||||
/* Checks */
|
/* Checks */
|
||||||
if (splitPoint <= 0 || splitPoint > 1) {
|
if (splitPoint <= 0 || splitPoint > 1) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect splitPoint\n");
|
DISPLAYLEVEL(1, "Incorrect splitPoint\n");
|
||||||
return ERROR(parameter_outOfBound);
|
return ERROR(parameter_outOfBound);
|
||||||
}
|
}
|
||||||
if (accel == 0 || accel > FASTCOVER_MAX_ACCEL) {
|
if (accel == 0 || accel > FASTCOVER_MAX_ACCEL) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect accel\n");
|
DISPLAYLEVEL(1, "Incorrect accel\n");
|
||||||
return ERROR(parameter_outOfBound);
|
return ERROR(parameter_outOfBound);
|
||||||
}
|
}
|
||||||
if (kMinK < kMaxD || kMaxK < kMinK) {
|
if (kMinK < kMaxD || kMaxK < kMinK) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect k\n");
|
DISPLAYLEVEL(1, "Incorrect k\n");
|
||||||
return ERROR(parameter_outOfBound);
|
return ERROR(parameter_outOfBound);
|
||||||
}
|
}
|
||||||
if (nbSamples == 0) {
|
if (nbSamples == 0) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "FASTCOVER must have at least one input file\n");
|
DISPLAYLEVEL(1, "FASTCOVER must have at least one input file\n");
|
||||||
return ERROR(srcSize_wrong);
|
return ERROR(srcSize_wrong);
|
||||||
}
|
}
|
||||||
if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) {
|
if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "dictBufferCapacity must be at least %u\n",
|
DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n",
|
||||||
ZDICT_DICTSIZE_MIN);
|
ZDICT_DICTSIZE_MIN);
|
||||||
return ERROR(dstSize_tooSmall);
|
return ERROR(dstSize_tooSmall);
|
||||||
}
|
}
|
||||||
@@ -679,19 +678,18 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||||||
memset(&coverParams, 0 , sizeof(coverParams));
|
memset(&coverParams, 0 , sizeof(coverParams));
|
||||||
FASTCOVER_convertToCoverParams(*parameters, &coverParams);
|
FASTCOVER_convertToCoverParams(*parameters, &coverParams);
|
||||||
accelParams = FASTCOVER_defaultAccelParameters[accel];
|
accelParams = FASTCOVER_defaultAccelParameters[accel];
|
||||||
/* Turn down global display level to clean up display at level 2 and below */
|
|
||||||
g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1;
|
|
||||||
/* Loop through d first because each new value needs a new context */
|
/* Loop through d first because each new value needs a new context */
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
|
DISPLAYLEVEL(2, "Trying %u different sets of parameters\n", kIterations);
|
||||||
kIterations);
|
|
||||||
for (d = kMinD; d <= kMaxD; d += 2) {
|
for (d = kMinD; d <= kMaxD; d += 2) {
|
||||||
/* Initialize the context for this value of d */
|
/* Initialize the context for this value of d */
|
||||||
FASTCOVER_ctx_t ctx;
|
FASTCOVER_ctx_t ctx;
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 3, "d=%u\n", d);
|
DISPLAYLEVEL(3, "d=%u\n", d);
|
||||||
{
|
{
|
||||||
size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint, f, accelParams);
|
/* Turn down global display level to clean up display at level 2 and below */
|
||||||
|
const int childDisplayLevel = displayLevel == 0 ? 0 : displayLevel - 1;
|
||||||
|
size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint, f, accelParams, childDisplayLevel);
|
||||||
if (ZSTD_isError(initVal)) {
|
if (ZSTD_isError(initVal)) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n");
|
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
||||||
COVER_best_destroy(&best);
|
COVER_best_destroy(&best);
|
||||||
POOL_free(pool);
|
POOL_free(pool);
|
||||||
return initVal;
|
return initVal;
|
||||||
@@ -706,9 +704,9 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||||||
/* Prepare the arguments */
|
/* Prepare the arguments */
|
||||||
FASTCOVER_tryParameters_data_t *data = (FASTCOVER_tryParameters_data_t *)malloc(
|
FASTCOVER_tryParameters_data_t *data = (FASTCOVER_tryParameters_data_t *)malloc(
|
||||||
sizeof(FASTCOVER_tryParameters_data_t));
|
sizeof(FASTCOVER_tryParameters_data_t));
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k);
|
DISPLAYLEVEL(3, "k=%u\n", k);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n");
|
DISPLAYLEVEL(1, "Failed to allocate parameters\n");
|
||||||
COVER_best_destroy(&best);
|
COVER_best_destroy(&best);
|
||||||
FASTCOVER_ctx_destroy(&ctx);
|
FASTCOVER_ctx_destroy(&ctx);
|
||||||
POOL_free(pool);
|
POOL_free(pool);
|
||||||
@@ -723,7 +721,7 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||||||
data->parameters.splitPoint = splitPoint;
|
data->parameters.splitPoint = splitPoint;
|
||||||
data->parameters.steps = kSteps;
|
data->parameters.steps = kSteps;
|
||||||
data->parameters.shrinkDict = shrinkDict;
|
data->parameters.shrinkDict = shrinkDict;
|
||||||
data->parameters.zParams.notificationLevel = (unsigned)g_displayLevel;
|
data->parameters.zParams.notificationLevel = (unsigned)ctx.displayLevel;
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
if (!FASTCOVER_checkParameters(data->parameters, dictBufferCapacity,
|
if (!FASTCOVER_checkParameters(data->parameters, dictBufferCapacity,
|
||||||
data->ctx->f, accel)) {
|
data->ctx->f, accel)) {
|
||||||
@@ -739,14 +737,15 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||||||
FASTCOVER_tryParameters(data);
|
FASTCOVER_tryParameters(data);
|
||||||
}
|
}
|
||||||
/* Print status */
|
/* Print status */
|
||||||
LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ",
|
DISPLAYUPDATE(lastUpdateTime,
|
||||||
(unsigned)((iteration * 100) / kIterations));
|
2, "\r%u%% ",
|
||||||
|
(unsigned)((iteration * 100) / kIterations));
|
||||||
++iteration;
|
++iteration;
|
||||||
}
|
}
|
||||||
COVER_best_wait(&best);
|
COVER_best_wait(&best);
|
||||||
FASTCOVER_ctx_destroy(&ctx);
|
FASTCOVER_ctx_destroy(&ctx);
|
||||||
}
|
}
|
||||||
LOCALDISPLAYLEVEL(displayLevel, 2, "\r%79s\r", "");
|
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||||
/* Fill the output buffer and parameters with output of the best parameters */
|
/* Fill the output buffer and parameters with output of the best parameters */
|
||||||
{
|
{
|
||||||
const size_t dictSize = best.dictSize;
|
const size_t dictSize = best.dictSize;
|
||||||
|
|||||||
+18
-14
@@ -168,7 +168,7 @@ static void ZDICT_initDictItem(dictItem* d)
|
|||||||
#define MINMATCHLENGTH 7 /* heuristic determined experimentally */
|
#define MINMATCHLENGTH 7 /* heuristic determined experimentally */
|
||||||
static dictItem ZDICT_analyzePos(
|
static dictItem ZDICT_analyzePos(
|
||||||
BYTE* doneMarks,
|
BYTE* doneMarks,
|
||||||
const int* suffix, U32 start,
|
const unsigned* suffix, U32 start,
|
||||||
const void* buffer, U32 minRatio, U32 notificationLevel)
|
const void* buffer, U32 minRatio, U32 notificationLevel)
|
||||||
{
|
{
|
||||||
U32 lengthList[LLIMIT] = {0};
|
U32 lengthList[LLIMIT] = {0};
|
||||||
@@ -293,8 +293,10 @@ static dictItem ZDICT_analyzePos(
|
|||||||
for (i=(int)(maxLength-2); i>=0; i--)
|
for (i=(int)(maxLength-2); i>=0; i--)
|
||||||
cumulLength[i] = cumulLength[i+1] + lengthList[i];
|
cumulLength[i] = cumulLength[i+1] + lengthList[i];
|
||||||
|
|
||||||
for (i=LLIMIT-1; i>=MINMATCHLENGTH; i--) if (cumulLength[i]>=minRatio) break;
|
{ unsigned u;
|
||||||
maxLength = i;
|
for (u=LLIMIT-1; u>=MINMATCHLENGTH; u--) if (cumulLength[u]>=minRatio) break;
|
||||||
|
maxLength = u;
|
||||||
|
}
|
||||||
|
|
||||||
/* reduce maxLength in case of final into repetitive data */
|
/* reduce maxLength in case of final into repetitive data */
|
||||||
{ U32 l = (U32)maxLength;
|
{ U32 l = (U32)maxLength;
|
||||||
@@ -306,8 +308,10 @@ static dictItem ZDICT_analyzePos(
|
|||||||
|
|
||||||
/* calculate savings */
|
/* calculate savings */
|
||||||
savings[5] = 0;
|
savings[5] = 0;
|
||||||
for (i=MINMATCHLENGTH; i<=(int)maxLength; i++)
|
{ unsigned u;
|
||||||
savings[i] = savings[i-1] + (lengthList[i] * (i-3));
|
for (u=MINMATCHLENGTH; u<=maxLength; u++)
|
||||||
|
savings[u] = savings[u-1] + (lengthList[u] * (u-3));
|
||||||
|
}
|
||||||
|
|
||||||
DISPLAYLEVEL(4, "Selected dict at position %u, of length %u : saves %u (ratio: %.2f) \n",
|
DISPLAYLEVEL(4, "Selected dict at position %u, of length %u : saves %u (ratio: %.2f) \n",
|
||||||
(unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / (double)maxLength);
|
(unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / (double)maxLength);
|
||||||
@@ -383,11 +387,11 @@ static U32 ZDICT_tryMerge(dictItem* table, dictItem elt, U32 eltNbToSkip, const
|
|||||||
|
|
||||||
if ((table[u].pos + table[u].length >= elt.pos) && (table[u].pos < elt.pos)) { /* overlap, existing < new */
|
if ((table[u].pos + table[u].length >= elt.pos) && (table[u].pos < elt.pos)) { /* overlap, existing < new */
|
||||||
/* append */
|
/* append */
|
||||||
int const addedLength = (int)eltEnd - (int)(table[u].pos + table[u].length);
|
int const addedLength = (int)eltEnd - (int)(table[u].pos + table[u].length); /* note: can be negative */
|
||||||
table[u].savings += elt.length / 8; /* rough approx bonus */
|
table[u].savings += elt.length / 8; /* rough approx bonus */
|
||||||
if (addedLength > 0) { /* otherwise, elt fully included into existing */
|
if (addedLength > 0) { /* otherwise, elt fully included into existing */
|
||||||
table[u].length += addedLength;
|
table[u].length += (unsigned)addedLength;
|
||||||
table[u].savings += elt.savings * addedLength / elt.length; /* rough approx */
|
table[u].savings += elt.savings * (unsigned)addedLength / elt.length; /* rough approx */
|
||||||
}
|
}
|
||||||
/* sort : improve rank */
|
/* sort : improve rank */
|
||||||
elt = table[u];
|
elt = table[u];
|
||||||
@@ -399,7 +403,7 @@ static U32 ZDICT_tryMerge(dictItem* table, dictItem elt, U32 eltNbToSkip, const
|
|||||||
|
|
||||||
if (MEM_read64(buf + table[u].pos) == MEM_read64(buf + elt.pos + 1)) {
|
if (MEM_read64(buf + table[u].pos) == MEM_read64(buf + elt.pos + 1)) {
|
||||||
if (isIncluded(buf + table[u].pos, buf + elt.pos + 1, table[u].length)) {
|
if (isIncluded(buf + table[u].pos, buf + elt.pos + 1, table[u].length)) {
|
||||||
size_t const addedLength = MAX( (int)elt.length - (int)table[u].length , 1 );
|
size_t const addedLength = MAX( elt.length - table[u].length , 1 );
|
||||||
table[u].pos = elt.pos;
|
table[u].pos = elt.pos;
|
||||||
table[u].savings += (U32)(elt.savings * addedLength / elt.length);
|
table[u].savings += (U32)(elt.savings * addedLength / elt.length);
|
||||||
table[u].length = MIN(elt.length, table[u].length + 1);
|
table[u].length = MIN(elt.length, table[u].length + 1);
|
||||||
@@ -467,8 +471,8 @@ static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
|
|||||||
const size_t* fileSizes, unsigned nbFiles,
|
const size_t* fileSizes, unsigned nbFiles,
|
||||||
unsigned minRatio, U32 notificationLevel)
|
unsigned minRatio, U32 notificationLevel)
|
||||||
{
|
{
|
||||||
int* const suffix0 = (int*)malloc((bufferSize+2)*sizeof(*suffix0));
|
unsigned* const suffix0 = (unsigned*)malloc((bufferSize+2)*sizeof(*suffix0));
|
||||||
int* const suffix = suffix0+1;
|
unsigned* const suffix = suffix0+1;
|
||||||
U32* reverseSuffix = (U32*)malloc((bufferSize)*sizeof(*reverseSuffix));
|
U32* reverseSuffix = (U32*)malloc((bufferSize)*sizeof(*reverseSuffix));
|
||||||
BYTE* doneMarks = (BYTE*)malloc((bufferSize+16)*sizeof(*doneMarks)); /* +16 for overflow security */
|
BYTE* doneMarks = (BYTE*)malloc((bufferSize+16)*sizeof(*doneMarks)); /* +16 for overflow security */
|
||||||
U32* filePos = (U32*)malloc(nbFiles * sizeof(*filePos));
|
U32* filePos = (U32*)malloc(nbFiles * sizeof(*filePos));
|
||||||
@@ -503,11 +507,11 @@ static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
|
|||||||
|
|
||||||
/* sort */
|
/* sort */
|
||||||
DISPLAYLEVEL(2, "sorting %u files of total size %u MB ...\n", nbFiles, (unsigned)(bufferSize>>20));
|
DISPLAYLEVEL(2, "sorting %u files of total size %u MB ...\n", nbFiles, (unsigned)(bufferSize>>20));
|
||||||
{ int const divSuftSortResult = divsufsort((const unsigned char*)buffer, suffix, (int)bufferSize, 0);
|
{ int const divSuftSortResult = divsufsort((const unsigned char*)buffer, (int*)suffix, (int)bufferSize, 0);
|
||||||
if (divSuftSortResult != 0) { result = ERROR(GENERIC); goto _cleanup; }
|
if (divSuftSortResult != 0) { result = ERROR(GENERIC); goto _cleanup; }
|
||||||
}
|
}
|
||||||
suffix[bufferSize] = (int)bufferSize; /* leads into noise */
|
suffix[bufferSize] = (unsigned)bufferSize; /* leads into noise */
|
||||||
suffix0[0] = (int)bufferSize; /* leads into noise */
|
suffix0[0] = (unsigned)bufferSize; /* leads into noise */
|
||||||
/* build reverse suffix sort */
|
/* build reverse suffix sort */
|
||||||
{ size_t pos;
|
{ size_t pos;
|
||||||
for (pos=0; pos < bufferSize; pos++)
|
for (pos=0; pos < bufferSize; pos++)
|
||||||
|
|||||||
@@ -1,20 +1,55 @@
|
|||||||
@ECHO OFF
|
@echo off
|
||||||
MKDIR bin\dll bin\static bin\example bin\include
|
setlocal
|
||||||
COPY tests\fullbench.c bin\example\
|
|
||||||
COPY programs\datagen.c bin\example\
|
rem Detect build type based on available files
|
||||||
COPY programs\datagen.h bin\example\
|
set BUILD_TYPE=make
|
||||||
COPY programs\util.h bin\example\
|
if exist "build\cmake\build\lib\Release\zstd_static.lib" set BUILD_TYPE=cmake
|
||||||
COPY programs\platform.h bin\example\
|
|
||||||
COPY lib\common\mem.h bin\example\
|
echo Detected build type: %BUILD_TYPE%
|
||||||
COPY lib\common\zstd_internal.h bin\example\
|
|
||||||
COPY lib\common\error_private.h bin\example\
|
rem Create required directories
|
||||||
COPY lib\common\xxhash.h bin\example\
|
mkdir bin\dll bin\static bin\example bin\include
|
||||||
COPY lib\libzstd.a bin\static\libzstd_static.lib
|
|
||||||
COPY lib\dll\libzstd.* bin\dll\
|
rem Copy common files using a subroutine. Exits immediately on failure.
|
||||||
COPY lib\dll\example\Makefile bin\example\
|
call :copyFile "tests\fullbench.c" "bin\example\"
|
||||||
COPY lib\dll\example\fullbench-dll.* bin\example\
|
call :copyFile "programs\datagen.c" "bin\example\"
|
||||||
COPY lib\dll\example\README.md bin\
|
call :copyFile "programs\datagen.h" "bin\example\"
|
||||||
COPY lib\zstd.h bin\include\
|
call :copyFile "programs\util.h" "bin\example\"
|
||||||
COPY lib\common\zstd_errors.h bin\include\
|
call :copyFile "programs\platform.h" "bin\example\"
|
||||||
COPY lib\dictBuilder\zdict.h bin\include\
|
call :copyFile "lib\common\mem.h" "bin\example\"
|
||||||
COPY programs\zstd.exe bin\zstd.exe
|
call :copyFile "lib\common\zstd_internal.h" "bin\example\"
|
||||||
|
call :copyFile "lib\common\error_private.h" "bin\example\"
|
||||||
|
call :copyFile "lib\common\xxhash.h" "bin\example\"
|
||||||
|
call :copyFile "lib\dll\example\Makefile" "bin\example\"
|
||||||
|
call :copyFile "lib\dll\example\fullbench-dll.*" "bin\example\"
|
||||||
|
call :copyFile "lib\zstd.h" "bin\include\"
|
||||||
|
call :copyFile "lib\zstd_errors.h" "bin\include\"
|
||||||
|
call :copyFile "lib\zdict.h" "bin\include\"
|
||||||
|
|
||||||
|
rem Copy build-specific files
|
||||||
|
if "%BUILD_TYPE%"=="cmake" (
|
||||||
|
echo Copying CMake build artifacts...
|
||||||
|
call :copyFile "build\cmake\build\lib\Release\zstd_static.lib" "bin\static\libzstd_static.lib"
|
||||||
|
call :copyFile "build\cmake\build\lib\Release\zstd.dll" "bin\dll\libzstd.dll"
|
||||||
|
call :copyFile "build\cmake\build\lib\Release\zstd.lib" "bin\dll\zstd.lib"
|
||||||
|
call :copyFile "build\cmake\build\programs\Release\zstd.exe" "bin\zstd.exe"
|
||||||
|
call :copyFile "lib\dll\example\README.md" "bin\README.md"
|
||||||
|
) else (
|
||||||
|
echo Copying Make build artifacts...
|
||||||
|
call :copyFile "lib\libzstd.a" "bin\static\libzstd_static.lib"
|
||||||
|
call :copyFile "lib\dll\libzstd.*" "bin\dll\"
|
||||||
|
call :copyFile "programs\zstd.exe" "bin\zstd.exe"
|
||||||
|
call :copyFile "lib\dll\example\README.md" "bin\"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Build package created successfully for %BUILD_TYPE% build!
|
||||||
|
endlocal
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:copyFile
|
||||||
|
copy "%~1" "%~2"
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo Failed to copy "%~1"
|
||||||
|
exit 1
|
||||||
|
)
|
||||||
|
exit /b
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# ################################################################
|
||||||
|
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This source code is licensed under both the BSD-style license (found in the
|
||||||
|
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||||
|
# in the COPYING file in the root directory of this source tree).
|
||||||
|
# You may select, at your option, one of the above-listed licenses.
|
||||||
|
# ################################################################
|
||||||
|
|
||||||
|
# This included Makefile provides the following variables :
|
||||||
|
# UNAME, INSTALL_OS_LIST
|
||||||
|
|
||||||
|
UNAME := $(shell sh -c 'MSYSTEM="MSYS" uname')
|
||||||
|
|
||||||
|
# List of OSes for which target install is supported
|
||||||
|
INSTALL_OS_LIST ?= Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT% CYGWIN_NT%
|
||||||
@@ -430,7 +430,7 @@ static unsigned FSE_isError(size_t code) { return (code > (size_t)(-FSE_ERROR_ma
|
|||||||
|
|
||||||
static short FSE_abs(short a)
|
static short FSE_abs(short a)
|
||||||
{
|
{
|
||||||
return a<0? -a : a;
|
return a<0? (short)-a : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1823,11 +1823,12 @@ static size_t ZSTD_decompressSequences(
|
|||||||
BYTE* const ostart = (BYTE* const)dst;
|
BYTE* const ostart = (BYTE* const)dst;
|
||||||
BYTE* op = ostart;
|
BYTE* op = ostart;
|
||||||
BYTE* const oend = ostart + maxDstSize;
|
BYTE* const oend = ostart + maxDstSize;
|
||||||
size_t errorCode, dumpsLength;
|
size_t errorCode = 0;
|
||||||
|
size_t dumpsLength = 0;
|
||||||
const BYTE* litPtr = litStart;
|
const BYTE* litPtr = litStart;
|
||||||
const BYTE* const litEnd = litStart + litSize;
|
const BYTE* const litEnd = litStart + litSize;
|
||||||
int nbSeq;
|
int nbSeq = 0;
|
||||||
const BYTE* dumps;
|
const BYTE* dumps = NULL;
|
||||||
U32* DTableLL = dctx->LLTable;
|
U32* DTableLL = dctx->LLTable;
|
||||||
U32* DTableML = dctx->MLTable;
|
U32* DTableML = dctx->MLTable;
|
||||||
U32* DTableOffb = dctx->OffTable;
|
U32* DTableOffb = dctx->OffTable;
|
||||||
@@ -1915,7 +1916,7 @@ size_t ZSTDv01_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const voi
|
|||||||
size_t remainingSize = srcSize;
|
size_t remainingSize = srcSize;
|
||||||
U32 magicNumber;
|
U32 magicNumber;
|
||||||
size_t errorCode=0;
|
size_t errorCode=0;
|
||||||
blockProperties_t blockProperties;
|
blockProperties_t blockProperties = { 0 };
|
||||||
|
|
||||||
/* Frame Header */
|
/* Frame Header */
|
||||||
if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
if (srcSize < ZSTD_frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||||
|
|||||||
@@ -1111,7 +1111,7 @@ static unsigned FSE_isError(size_t code) { return ERR_isError(code); }
|
|||||||
****************************************************************/
|
****************************************************************/
|
||||||
static short FSE_abs(short a)
|
static short FSE_abs(short a)
|
||||||
{
|
{
|
||||||
return a<0 ? -a : a;
|
return a<0 ? (short)-a : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||||
|
|||||||
@@ -1094,7 +1094,7 @@ static unsigned FSE_isError(size_t code) { return ERR_isError(code); }
|
|||||||
****************************************************************/
|
****************************************************************/
|
||||||
static short FSE_abs(short a)
|
static short FSE_abs(short a)
|
||||||
{
|
{
|
||||||
return a<0 ? -a : a;
|
return a<0 ? (short)-a : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||||
|
|||||||
+10
-3
@@ -1224,7 +1224,7 @@ const char* FSEv05_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
|||||||
/*-**************************************************************
|
/*-**************************************************************
|
||||||
* FSEv05 NCount encoding-decoding
|
* FSEv05 NCount encoding-decoding
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
static short FSEv05_abs(short a) { return a<0 ? -a : a; }
|
static short FSEv05_abs(short a) { return a<0 ? (short)-a : a; }
|
||||||
|
|
||||||
|
|
||||||
size_t FSEv05_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
size_t FSEv05_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||||
@@ -3972,8 +3972,15 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
|
|||||||
zbc->outStart += flushedSize;
|
zbc->outStart += flushedSize;
|
||||||
if (flushedSize == toFlushSize) {
|
if (flushedSize == toFlushSize) {
|
||||||
zbc->stage = ZBUFFv05ds_read;
|
zbc->stage = ZBUFFv05ds_read;
|
||||||
if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize)
|
if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize) {
|
||||||
zbc->outStart = zbc->outEnd = 0;
|
/* Not enough room for next block - need to wrap buffer.
|
||||||
|
* Preserve history: copy the last windowSize bytes to the
|
||||||
|
* beginning so that back-references can still find valid data. */
|
||||||
|
size_t const windowSize = (size_t)1 << zbc->params.windowLog;
|
||||||
|
size_t const preserveSize = MIN(zbc->outEnd, windowSize);
|
||||||
|
memmove(zbc->outBuff, zbc->outBuff + zbc->outEnd - preserveSize, preserveSize);
|
||||||
|
zbc->outStart = zbc->outEnd = preserveSize;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* cannot flush everything */
|
/* cannot flush everything */
|
||||||
|
|||||||
@@ -1202,7 +1202,7 @@ static unsigned HUFv06_isError(size_t code) { return ERR_isError(code); }
|
|||||||
/*-**************************************************************
|
/*-**************************************************************
|
||||||
* FSE NCount encoding-decoding
|
* FSE NCount encoding-decoding
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
static short FSEv06_abs(short a) { return a<0 ? -a : a; }
|
static short FSEv06_abs(short a) { return a<0 ? (short)-a : a; }
|
||||||
|
|
||||||
size_t FSEv06_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
size_t FSEv06_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||||
const void* headerBuffer, size_t hbSize)
|
const void* headerBuffer, size_t hbSize)
|
||||||
|
|||||||
+6
-7
@@ -28,12 +28,8 @@ LIB_BINDIR ?= $(LIB_SRCDIR)
|
|||||||
# configures a bunch of other variables to space-optimized defaults.
|
# configures a bunch of other variables to space-optimized defaults.
|
||||||
ZSTD_LIB_MINIFY ?= 0
|
ZSTD_LIB_MINIFY ?= 0
|
||||||
|
|
||||||
# Legacy support
|
# Legacy support disabled by default
|
||||||
ifneq ($(ZSTD_LIB_MINIFY), 0)
|
ZSTD_LEGACY_SUPPORT ?= 0
|
||||||
ZSTD_LEGACY_SUPPORT ?= 0
|
|
||||||
else
|
|
||||||
ZSTD_LEGACY_SUPPORT ?= 5
|
|
||||||
endif
|
|
||||||
ZSTD_LEGACY_MULTITHREADED_API ?= 0
|
ZSTD_LEGACY_MULTITHREADED_API ?= 0
|
||||||
|
|
||||||
# Build size optimizations
|
# Build size optimizations
|
||||||
@@ -206,7 +202,10 @@ endif
|
|||||||
endif
|
endif
|
||||||
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
|
CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
|
||||||
|
|
||||||
UNAME := $(shell sh -c 'MSYSTEM="MSYS" uname')
|
# Include install_oses.mk from the same directory
|
||||||
|
include $(dir $(lastword $(MAKEFILE_LIST)))/install_oses.mk
|
||||||
|
LN ?= ln
|
||||||
|
CP ?= cp -f
|
||||||
|
|
||||||
ifndef BUILD_DIR
|
ifndef BUILD_DIR
|
||||||
ifeq ($(UNAME), Darwin)
|
ifeq ($(UNAME), Darwin)
|
||||||
|
|||||||
@@ -14,3 +14,4 @@ Version: @VERSION@
|
|||||||
Libs: -L${libdir} -lzstd @LIBS_MT@
|
Libs: -L${libdir} -lzstd @LIBS_MT@
|
||||||
Libs.private: @LIBS_PRIVATE@
|
Libs.private: @LIBS_PRIVATE@
|
||||||
Cflags: -I${includedir} @LIBS_MT@
|
Cflags: -I${includedir} @LIBS_MT@
|
||||||
|
License: BSD-3-Clause OR GPL-2.0-only
|
||||||
|
|||||||
@@ -1,27 +1,6 @@
|
|||||||
module libzstd [extern_c] {
|
module libzstd [extern_c] {
|
||||||
header "zstd.h"
|
header "zstd.h"
|
||||||
export *
|
export *
|
||||||
config_macros [exhaustive] \
|
|
||||||
/* zstd.h */ \
|
|
||||||
ZSTD_STATIC_LINKING_ONLY, \
|
|
||||||
ZSTDLIB_VISIBILITY, \
|
|
||||||
ZSTDLIB_VISIBLE, \
|
|
||||||
ZSTDLIB_HIDDEN, \
|
|
||||||
ZSTD_DLL_EXPORT, \
|
|
||||||
ZSTDLIB_STATIC_API, \
|
|
||||||
ZSTD_DISABLE_DEPRECATE_WARNINGS, \
|
|
||||||
ZSTD_CLEVEL_DEFAULT, \
|
|
||||||
/* zdict.h */ \
|
|
||||||
ZDICT_STATIC_LINKING_ONLY, \
|
|
||||||
ZDICTLIB_VISIBLE, \
|
|
||||||
ZDICTLIB_HIDDEN, \
|
|
||||||
ZDICTLIB_VISIBILITY, \
|
|
||||||
ZDICTLIB_STATIC_API, \
|
|
||||||
ZDICT_DISABLE_DEPRECATE_WARNINGS, \
|
|
||||||
/* zstd_errors.h */ \
|
|
||||||
ZSTDERRORLIB_VISIBLE, \
|
|
||||||
ZSTDERRORLIB_HIDDEN, \
|
|
||||||
ZSTDERRORLIB_VISIBILITY
|
|
||||||
|
|
||||||
module dictbuilder [extern_c] {
|
module dictbuilder [extern_c] {
|
||||||
header "zdict.h"
|
header "zdict.h"
|
||||||
|
|||||||
+42
-31
@@ -110,8 +110,8 @@ extern "C" {
|
|||||||
|
|
||||||
/*------ Version ------*/
|
/*------ Version ------*/
|
||||||
#define ZSTD_VERSION_MAJOR 1
|
#define ZSTD_VERSION_MAJOR 1
|
||||||
#define ZSTD_VERSION_MINOR 5
|
#define ZSTD_VERSION_MINOR 6
|
||||||
#define ZSTD_VERSION_RELEASE 7
|
#define ZSTD_VERSION_RELEASE 0
|
||||||
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
|
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
|
||||||
|
|
||||||
/*! ZSTD_versionNumber() :
|
/*! ZSTD_versionNumber() :
|
||||||
@@ -176,30 +176,30 @@ ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
|
|||||||
|
|
||||||
/*====== Decompression helper functions ======*/
|
/*====== Decompression helper functions ======*/
|
||||||
|
|
||||||
/*! ZSTD_getFrameContentSize() : requires v1.3.0+
|
/*! @brief Returns the decompressed content size stored in a ZSTD frame header.
|
||||||
* `src` should point to the start of a ZSTD encoded frame.
|
*
|
||||||
* `srcSize` must be at least as large as the frame header.
|
* @since v1.3.0
|
||||||
* hint : any size >= `ZSTD_frameHeaderSize_max` is large enough.
|
*
|
||||||
* @return : - decompressed size of `src` frame content, if known
|
* @param src Pointer to the beginning of a ZSTD encoded frame.
|
||||||
* - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
|
* @param srcSize Size of the buffer pointed to by @p src. It must be at least as large as the frame header.
|
||||||
* - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small)
|
* Any value greater than or equal to `ZSTD_frameHeaderSize_max` is sufficient.
|
||||||
* note 1 : a 0 return value means the frame is valid but "empty".
|
* @return The decompressed size in bytes when the value is available in the frame header.
|
||||||
* When invoking this method on a skippable frame, it will return 0.
|
* @retval ZSTD_CONTENTSIZE_UNKNOWN The frame does not encode a decompressed size (typical for streaming).
|
||||||
* note 2 : decompressed size is an optional field, it may not be present (typically in streaming mode).
|
* @retval ZSTD_CONTENTSIZE_ERROR An error occurred (e.g. invalid magic number, @p srcSize too small).
|
||||||
* 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.
|
* @note The return value is not compatible with `ZSTD_isError()`.
|
||||||
* Optionally, application can rely on some implicit limit,
|
* @note A return value of 0 denotes a valid but empty frame. Skippable frames also report 0.
|
||||||
* as ZSTD_decompress() only needs an upper bound of decompressed size.
|
* @note The decompressed size field is optional. When it is absent (the function returns @c ZSTD_CONTENTSIZE_UNKNOWN),
|
||||||
* (For example, data could be necessarily cut into blocks <= 16 KB).
|
* the caller must rely on streaming decompression or an application-specific upper bound. `ZSTD_decompress()`
|
||||||
* note 3 : decompressed size is always present when compression is completed using single-pass functions,
|
* only requires an upper bound, so applications may enforce their own block limits (for example 16 KB).
|
||||||
* such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict().
|
* @note The decompressed size is guaranteed to be present when compression was performed with single-pass APIs such as
|
||||||
* note 4 : decompressed size can be very large (64-bits value),
|
* `ZSTD_compress()`, `ZSTD_compressCCtx()`, `ZSTD_compress_usingDict()`, or `ZSTD_compress_usingCDict()`.
|
||||||
* potentially larger than what local system can handle as a single memory segment.
|
* @note The decompressed size is a 64-bit value and may exceed the addressable space of the system. Use streaming
|
||||||
* In which case, it's necessary to use streaming mode to decompress data.
|
* decompression when the value is too large to materialize in contiguous memory.
|
||||||
* note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified.
|
* @warning When processing untrusted input, validate the returned size against the application's limits; attackers may
|
||||||
* Always ensure return value fits within application's authorized limits.
|
* forge an arbitrarily large value.
|
||||||
* Each application can set its own limits.
|
* @note This function replaces `ZSTD_getDecompressedSize()`.
|
||||||
* note 6 : This function replaces ZSTD_getDecompressedSize() */
|
*/
|
||||||
#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
|
#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
|
||||||
#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
|
#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
|
||||||
ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
|
ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
|
||||||
@@ -1868,15 +1868,14 @@ ZSTDLIB_STATIC_API const ZSTD_DDict* ZSTD_initStaticDDict(
|
|||||||
typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
|
typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
|
||||||
typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
|
typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
|
||||||
typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
|
typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
|
||||||
static
|
|
||||||
#ifdef __GNUC__
|
|
||||||
__attribute__((__unused__))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__) && __clang_major__ >= 5
|
#if defined(__clang__) && __clang_major__ >= 5
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
#endif
|
#endif
|
||||||
|
static
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__((__unused__))
|
||||||
|
#endif
|
||||||
ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
|
ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
|
||||||
#if defined(__clang__) && __clang_major__ >= 5
|
#if defined(__clang__) && __clang_major__ >= 5
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
@@ -3138,6 +3137,18 @@ ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTD_isDeterministicBuild() :
|
||||||
|
* Returns 1 if the library is built using standard compilation flags,
|
||||||
|
* and participates in determinism guarantees with other builds of the
|
||||||
|
* same version.
|
||||||
|
* If this function returns 0, it means the library was compiled with
|
||||||
|
* non-standard compilation flags that change the output of the
|
||||||
|
* compressor.
|
||||||
|
* This is mainly used for Zstd's determinism test suite, which is only
|
||||||
|
* run when this function returns 1.
|
||||||
|
*/
|
||||||
|
ZSTDLIB_API int ZSTD_isDeterministicBuild(void);
|
||||||
|
|
||||||
|
|
||||||
/* ========================================= */
|
/* ========================================= */
|
||||||
/** Block level API (DEPRECATED) */
|
/** Block level API (DEPRECATED) */
|
||||||
|
|||||||
+8
-8
@@ -170,7 +170,7 @@ endif
|
|||||||
|
|
||||||
zstd : $(BUILD_DIR)/zstd
|
zstd : $(BUILD_DIR)/zstd
|
||||||
if [ $(BIN_ISDIFFERENT) -eq 1 ]; then \
|
if [ $(BIN_ISDIFFERENT) -eq 1 ]; then \
|
||||||
cp -f $<$(EXT) $@$(EXT); \
|
$(CP) $<$(EXT) $@$(EXT); \
|
||||||
echo zstd build completed; \
|
echo zstd build completed; \
|
||||||
else \
|
else \
|
||||||
echo zstd already built; \
|
echo zstd already built; \
|
||||||
@@ -271,7 +271,7 @@ zstd-dictBuilder: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) $(ZDICT_SRC) zst
|
|||||||
|
|
||||||
CLEAN += zstdmt
|
CLEAN += zstdmt
|
||||||
zstdmt: zstd
|
zstdmt: zstd
|
||||||
ln -sf zstd zstdmt
|
$(LN) -sf zstd zstdmt
|
||||||
|
|
||||||
.PHONY: generate_res
|
.PHONY: generate_res
|
||||||
generate_res: $(RES64_FILE) $(RES32_FILE)
|
generate_res: $(RES64_FILE) $(RES32_FILE)
|
||||||
@@ -345,7 +345,7 @@ include $(wildcard $(DEPFILES))
|
|||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
# make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets
|
# make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
ifneq (,$(filter Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX MSYS_NT% CYGWIN_NT%,$(UNAME)))
|
ifneq (,$(filter $(INSTALL_OS_LIST),$(UNAME)))
|
||||||
|
|
||||||
HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0)
|
HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0)
|
||||||
EGREP_OPTIONS ?=
|
EGREP_OPTIONS ?=
|
||||||
@@ -414,15 +414,15 @@ install:
|
|||||||
[ -e $(DESTDIR)$(MAN1DIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(MAN1DIR)/
|
[ -e $(DESTDIR)$(MAN1DIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(MAN1DIR)/
|
||||||
@echo Installing binaries
|
@echo Installing binaries
|
||||||
$(INSTALL_PROGRAM) zstd$(EXT) $(DESTDIR)$(BINDIR)/zstd$(EXT)
|
$(INSTALL_PROGRAM) zstd$(EXT) $(DESTDIR)$(BINDIR)/zstd$(EXT)
|
||||||
ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdcat$(EXT)
|
$(LN) -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdcat$(EXT)
|
||||||
ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd$(EXT)
|
$(LN) -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd$(EXT)
|
||||||
ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdmt$(EXT)
|
$(LN) -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdmt$(EXT)
|
||||||
$(INSTALL_SCRIPT) zstdless $(DESTDIR)$(BINDIR)/zstdless
|
$(INSTALL_SCRIPT) zstdless $(DESTDIR)$(BINDIR)/zstdless
|
||||||
$(INSTALL_SCRIPT) zstdgrep $(DESTDIR)$(BINDIR)/zstdgrep
|
$(INSTALL_SCRIPT) zstdgrep $(DESTDIR)$(BINDIR)/zstdgrep
|
||||||
@echo Installing man pages
|
@echo Installing man pages
|
||||||
$(INSTALL_MAN) zstd.1 $(DESTDIR)$(MAN1DIR)/zstd.1
|
$(INSTALL_MAN) zstd.1 $(DESTDIR)$(MAN1DIR)/zstd.1
|
||||||
ln -sf zstd.1 $(DESTDIR)$(MAN1DIR)/zstdcat.1
|
$(LN) -sf zstd.1 $(DESTDIR)$(MAN1DIR)/zstdcat.1
|
||||||
ln -sf zstd.1 $(DESTDIR)$(MAN1DIR)/unzstd.1
|
$(LN) -sf zstd.1 $(DESTDIR)$(MAN1DIR)/unzstd.1
|
||||||
$(INSTALL_MAN) zstdgrep.1 $(DESTDIR)$(MAN1DIR)/zstdgrep.1
|
$(INSTALL_MAN) zstdgrep.1 $(DESTDIR)$(MAN1DIR)/zstdgrep.1
|
||||||
$(INSTALL_MAN) zstdless.1 $(DESTDIR)$(MAN1DIR)/zstdless.1
|
$(INSTALL_MAN) zstdless.1 $(DESTDIR)$(MAN1DIR)/zstdless.1
|
||||||
@echo zstd installation completed
|
@echo zstd installation completed
|
||||||
|
|||||||
+9
-2
@@ -79,6 +79,13 @@ There are however other Makefile targets that create different variations of CLI
|
|||||||
This can be useful to produce smaller binaries.
|
This can be useful to produce smaller binaries.
|
||||||
A corresponding `Makefile` target using this ability is `zstd-compress`.
|
A corresponding `Makefile` target using this ability is `zstd-compress`.
|
||||||
|
|
||||||
|
- __ZSTD_DISPLAY_LEVEL_DEFAULT__ : Controls the default verbosity level of `zstd` output.
|
||||||
|
The default value is `2`. Lower values (e.g., `1`) reduce output verbosity,
|
||||||
|
while higher values (e.g., `3`) increase it.
|
||||||
|
This allows setting preferred verbosity at compile time,
|
||||||
|
rather than passing `-q` or `-v` flags at runtime.
|
||||||
|
Example : `CPPFLAGS="-DZSTD_DISPLAY_LEVEL_DEFAULT=1" make`
|
||||||
|
|
||||||
- __BACKTRACE__ : `zstd` can display a stack backtrace when execution
|
- __BACKTRACE__ : `zstd` can display a stack backtrace when execution
|
||||||
generates a runtime exception. By default, this feature may be
|
generates a runtime exception. By default, this feature may be
|
||||||
degraded/disabled on some platforms unless additional compiler directives are
|
degraded/disabled on some platforms unless additional compiler directives are
|
||||||
@@ -153,7 +160,7 @@ Usage: zstd [OPTIONS...] [INPUT... | -] [-o OUTPUT]
|
|||||||
Options:
|
Options:
|
||||||
-o OUTPUT Write output to a single file, OUTPUT.
|
-o OUTPUT Write output to a single file, OUTPUT.
|
||||||
-k, --keep Preserve INPUT file(s). [Default]
|
-k, --keep Preserve INPUT file(s). [Default]
|
||||||
--rm Remove INPUT file(s) after successful (de)compression.
|
--rm Remove INPUT file(s) after successful (de)compression to file.
|
||||||
|
|
||||||
-# Desired compression level, where `#` is a number between 1 and 19;
|
-# Desired compression level, where `#` is a number between 1 and 19;
|
||||||
lower numbers provide faster compression, higher numbers yield
|
lower numbers provide faster compression, higher numbers yield
|
||||||
@@ -224,7 +231,7 @@ Advanced compression options:
|
|||||||
--format=gzip Compress files to the `.gz` format.
|
--format=gzip Compress files to the `.gz` format.
|
||||||
--format=xz Compress files to the `.xz` format.
|
--format=xz Compress files to the `.xz` format.
|
||||||
--format=lzma Compress files to the `.lzma` format.
|
--format=lzma Compress files to the `.lzma` format.
|
||||||
--format=lz4 Compress files to the `.lz4` format.
|
--format=lz4 Compress files to the `.lz4` format.
|
||||||
|
|
||||||
Advanced decompression options:
|
Advanced decompression options:
|
||||||
-l Print information about Zstandard-compressed files.
|
-l Print information about Zstandard-compressed files.
|
||||||
|
|||||||
+51
-62
@@ -208,7 +208,7 @@ BMK_advancedParams_t BMK_initAdvancedParams(void)
|
|||||||
BMK_advancedParams_t const res = {
|
BMK_advancedParams_t const res = {
|
||||||
BMK_both, /* mode */
|
BMK_both, /* mode */
|
||||||
BMK_TIMETEST_DEFAULT_S, /* nbSeconds */
|
BMK_TIMETEST_DEFAULT_S, /* nbSeconds */
|
||||||
0, /* blockSize */
|
0, /* chunkSizeMax */
|
||||||
0, /* targetCBlockSize */
|
0, /* targetCBlockSize */
|
||||||
0, /* nbWorkers */
|
0, /* nbWorkers */
|
||||||
0, /* realTime */
|
0, /* realTime */
|
||||||
@@ -227,16 +227,6 @@ BMK_advancedParams_t BMK_initAdvancedParams(void)
|
|||||||
/* ********************************************************
|
/* ********************************************************
|
||||||
* Bench functions
|
* Bench functions
|
||||||
**********************************************************/
|
**********************************************************/
|
||||||
typedef struct {
|
|
||||||
const void* srcPtr;
|
|
||||||
size_t srcSize;
|
|
||||||
void* cPtr;
|
|
||||||
size_t cRoom;
|
|
||||||
size_t cSize;
|
|
||||||
void* resPtr;
|
|
||||||
size_t resSize;
|
|
||||||
} blockParam_t;
|
|
||||||
|
|
||||||
#undef MIN
|
#undef MIN
|
||||||
#undef MAX
|
#undef MAX
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
@@ -435,16 +425,16 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||||||
const char* displayName,
|
const char* displayName,
|
||||||
const BMK_advancedParams_t* adv)
|
const BMK_advancedParams_t* adv)
|
||||||
{
|
{
|
||||||
size_t const blockSize =
|
size_t const chunkSizeMax =
|
||||||
((adv->blockSize >= 32 && (adv->mode != BMK_decodeOnly))
|
((adv->chunkSizeMax >= 32 && (adv->mode != BMK_decodeOnly))
|
||||||
? adv->blockSize
|
? adv->chunkSizeMax
|
||||||
: srcSize)
|
: srcSize)
|
||||||
+ (!srcSize); /* avoid div by 0 */
|
+ (!srcSize); /* avoid div by 0 */
|
||||||
BMK_benchResult_t benchResult;
|
BMK_benchResult_t benchResult;
|
||||||
size_t const loadedCompressedSize = srcSize;
|
size_t const loadedCompressedSize = srcSize;
|
||||||
size_t cSize = 0;
|
size_t cSize = 0;
|
||||||
double ratio = 0.;
|
double ratio = 0.;
|
||||||
U32 nbBlocks;
|
U32 nbChunks = 0;
|
||||||
|
|
||||||
assert(cctx != NULL);
|
assert(cctx != NULL);
|
||||||
assert(dctx != NULL);
|
assert(dctx != NULL);
|
||||||
@@ -500,41 +490,42 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init data blocks */
|
/* Init data chunks */
|
||||||
{
|
{
|
||||||
const char* srcPtr = (const char*)srcBuffer;
|
const char* srcPtr = (const char*)srcBuffer;
|
||||||
char* cPtr = (char*)compressedBuffer;
|
char* cPtr = (char*)compressedBuffer;
|
||||||
char* resPtr = (char*)(*resultBufferPtr);
|
char* resPtr = (char*)(*resultBufferPtr);
|
||||||
U32 fileNb;
|
U32 fileNb, chunkID;
|
||||||
for (nbBlocks = 0, fileNb = 0; fileNb < nbFiles; fileNb++) {
|
for (chunkID = 0, fileNb = 0; fileNb < nbFiles; fileNb++) {
|
||||||
size_t remaining = fileSizes[fileNb];
|
size_t remaining = fileSizes[fileNb];
|
||||||
U32 const nbBlocksforThisFile = (adv->mode == BMK_decodeOnly)
|
U32 const nbChunksforThisFile = (adv->mode == BMK_decodeOnly)
|
||||||
? 1
|
? 1
|
||||||
: (U32)((remaining + (blockSize - 1)) / blockSize);
|
: (U32)((remaining + (chunkSizeMax - 1)) / chunkSizeMax);
|
||||||
U32 const blockEnd = nbBlocks + nbBlocksforThisFile;
|
U32 const chunkIdEnd = chunkID + nbChunksforThisFile;
|
||||||
for (; nbBlocks < blockEnd; nbBlocks++) {
|
for (; chunkID < chunkIdEnd; chunkID++) {
|
||||||
size_t const thisBlockSize = MIN(remaining, blockSize);
|
size_t const chunkSize = MIN(remaining, chunkSizeMax);
|
||||||
srcPtrs[nbBlocks] = srcPtr;
|
srcPtrs[chunkID] = srcPtr;
|
||||||
srcSizes[nbBlocks] = thisBlockSize;
|
srcSizes[chunkID] = chunkSize;
|
||||||
cPtrs[nbBlocks] = cPtr;
|
cPtrs[chunkID] = cPtr;
|
||||||
cCapacities[nbBlocks] = (adv->mode == BMK_decodeOnly)
|
cCapacities[chunkID] = (adv->mode == BMK_decodeOnly)
|
||||||
? thisBlockSize
|
? chunkSize
|
||||||
: ZSTD_compressBound(thisBlockSize);
|
: ZSTD_compressBound(chunkSize);
|
||||||
resPtrs[nbBlocks] = resPtr;
|
resPtrs[chunkID] = resPtr;
|
||||||
resSizes[nbBlocks] = (adv->mode == BMK_decodeOnly)
|
resSizes[chunkID] = (adv->mode == BMK_decodeOnly)
|
||||||
? (size_t)ZSTD_findDecompressedSize(
|
? (size_t)ZSTD_findDecompressedSize(
|
||||||
srcPtr, thisBlockSize)
|
srcPtr, chunkSize)
|
||||||
: thisBlockSize;
|
: chunkSize;
|
||||||
srcPtr += thisBlockSize;
|
srcPtr += chunkSize;
|
||||||
cPtr += cCapacities[nbBlocks];
|
cPtr += cCapacities[chunkID];
|
||||||
resPtr += thisBlockSize;
|
resPtr += chunkSize;
|
||||||
remaining -= thisBlockSize;
|
remaining -= chunkSize;
|
||||||
if (adv->mode == BMK_decodeOnly) {
|
if (adv->mode == BMK_decodeOnly) {
|
||||||
cSizes[nbBlocks] = thisBlockSize;
|
cSizes[chunkID] = chunkSize;
|
||||||
benchResult.cSize = thisBlockSize;
|
benchResult.cSize = chunkSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nbChunks = chunkID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warming up `compressedBuffer` */
|
/* warming up `compressedBuffer` */
|
||||||
@@ -569,7 +560,7 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||||||
cbp.initFn = local_initCCtx; /* BMK_initCCtx */
|
cbp.initFn = local_initCCtx; /* BMK_initCCtx */
|
||||||
cbp.initPayload = &cctxprep;
|
cbp.initPayload = &cctxprep;
|
||||||
cbp.errorFn = ZSTD_isError;
|
cbp.errorFn = ZSTD_isError;
|
||||||
cbp.blockCount = nbBlocks;
|
cbp.blockCount = nbChunks;
|
||||||
cbp.srcBuffers = srcPtrs;
|
cbp.srcBuffers = srcPtrs;
|
||||||
cbp.srcSizes = srcSizes;
|
cbp.srcSizes = srcSizes;
|
||||||
cbp.dstBuffers = cPtrs;
|
cbp.dstBuffers = cPtrs;
|
||||||
@@ -588,7 +579,7 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||||||
dbp.initFn = local_initDCtx;
|
dbp.initFn = local_initDCtx;
|
||||||
dbp.initPayload = &dctxprep;
|
dbp.initPayload = &dctxprep;
|
||||||
dbp.errorFn = ZSTD_isError;
|
dbp.errorFn = ZSTD_isError;
|
||||||
dbp.blockCount = nbBlocks;
|
dbp.blockCount = nbChunks;
|
||||||
dbp.srcBuffers = (const void* const*)cPtrs;
|
dbp.srcBuffers = (const void* const*)cPtrs;
|
||||||
dbp.srcSizes = cSizes;
|
dbp.srcSizes = cSizes;
|
||||||
dbp.dstBuffers = resPtrs;
|
dbp.dstBuffers = resPtrs;
|
||||||
@@ -690,8 +681,7 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||||||
} /* while (!(compressionCompleted && decompressionCompleted)) */
|
} /* while (!(compressionCompleted && decompressionCompleted)) */
|
||||||
|
|
||||||
/* CRC Checking */
|
/* CRC Checking */
|
||||||
{
|
{ const BYTE* resultBuffer = (const BYTE*)(*resultBufferPtr);
|
||||||
const BYTE* resultBuffer = (const BYTE*)(*resultBufferPtr);
|
|
||||||
U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
|
U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
|
||||||
if ((adv->mode == BMK_both) && (crcOrig != crcCheck)) {
|
if ((adv->mode == BMK_both) && (crcOrig != crcCheck)) {
|
||||||
size_t u;
|
size_t u;
|
||||||
@@ -704,14 +694,14 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||||||
unsigned segNb, bNb, pos;
|
unsigned segNb, bNb, pos;
|
||||||
size_t bacc = 0;
|
size_t bacc = 0;
|
||||||
DISPLAY("Decoding error at pos %u ", (unsigned)u);
|
DISPLAY("Decoding error at pos %u ", (unsigned)u);
|
||||||
for (segNb = 0; segNb < nbBlocks; segNb++) {
|
for (segNb = 0; segNb < nbChunks; segNb++) {
|
||||||
if (bacc + srcSizes[segNb] > u)
|
if (bacc + srcSizes[segNb] > u)
|
||||||
break;
|
break;
|
||||||
bacc += srcSizes[segNb];
|
bacc += srcSizes[segNb];
|
||||||
}
|
}
|
||||||
pos = (U32)(u - bacc);
|
pos = (U32)(u - bacc);
|
||||||
bNb = pos / (128 KB);
|
bNb = pos / (128 KB);
|
||||||
DISPLAY("(sample %u, block %u, pos %u) \n",
|
DISPLAY("(sample %u, chunk %u, pos %u) \n",
|
||||||
segNb,
|
segNb,
|
||||||
bNb,
|
bNb,
|
||||||
pos);
|
pos);
|
||||||
@@ -795,25 +785,24 @@ BMK_benchOutcome_t BMK_benchMemAdvanced(
|
|||||||
int const dstParamsError =
|
int const dstParamsError =
|
||||||
!dstBuffer ^ !dstCapacity; /* must be both NULL or none */
|
!dstBuffer ^ !dstCapacity; /* must be both NULL or none */
|
||||||
|
|
||||||
size_t const blockSize =
|
size_t const chunkSize =
|
||||||
((adv->blockSize >= 32 && (adv->mode != BMK_decodeOnly))
|
((adv->chunkSizeMax >= 32 && (adv->mode != BMK_decodeOnly))
|
||||||
? adv->blockSize
|
? adv->chunkSizeMax
|
||||||
: srcSize)
|
: srcSize)
|
||||||
+ (!srcSize) /* avoid div by 0 */;
|
+ (!srcSize) /* avoid div by 0 */;
|
||||||
U32 const maxNbBlocks =
|
U32 const nbChunksMax =
|
||||||
(U32)((srcSize + (blockSize - 1)) / blockSize) + nbFiles;
|
(U32)((srcSize + (chunkSize - 1)) / chunkSize) + nbFiles;
|
||||||
|
|
||||||
/* these are the blockTable parameters, just split up */
|
|
||||||
const void** const srcPtrs =
|
const void** const srcPtrs =
|
||||||
(const void**)malloc(maxNbBlocks * sizeof(void*));
|
(const void**)malloc(nbChunksMax * sizeof(void*));
|
||||||
size_t* const srcSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
size_t* const srcSizes = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||||
|
|
||||||
void** const cPtrs = (void**)malloc(maxNbBlocks * sizeof(void*));
|
void** const cPtrs = (void**)malloc(nbChunksMax * sizeof(void*));
|
||||||
size_t* const cSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
size_t* const cSizes = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||||
size_t* const cCapacities = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
size_t* const cCapacities = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||||
|
|
||||||
void** const resPtrs = (void**)malloc(maxNbBlocks * sizeof(void*));
|
void** const resPtrs = (void**)malloc(nbChunksMax * sizeof(void*));
|
||||||
size_t* const resSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
size_t* const resSizes = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||||
|
|
||||||
BMK_timedFnState_t* timeStateCompress = BMK_createTimedFnState(
|
BMK_timedFnState_t* timeStateCompress = BMK_createTimedFnState(
|
||||||
adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS);
|
adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS);
|
||||||
@@ -825,7 +814,7 @@ BMK_benchOutcome_t BMK_benchMemAdvanced(
|
|||||||
|
|
||||||
const size_t maxCompressedSize = dstCapacity
|
const size_t maxCompressedSize = dstCapacity
|
||||||
? dstCapacity
|
? dstCapacity
|
||||||
: ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024);
|
: ZSTD_compressBound(srcSize) + (nbChunksMax * 1024);
|
||||||
|
|
||||||
void* const internalDstBuffer =
|
void* const internalDstBuffer =
|
||||||
dstBuffer ? NULL : malloc(maxCompressedSize);
|
dstBuffer ? NULL : malloc(maxCompressedSize);
|
||||||
@@ -964,12 +953,12 @@ static int BMK_benchCLevels(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (displayLevel == 1 && !adv->additionalParam) /* --quiet mode */
|
if (displayLevel == 1 && !adv->additionalParam) /* --quiet mode */
|
||||||
OUTPUT("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n",
|
OUTPUT("bench %s %s: input %u bytes, %u seconds, %u KB chunks\n",
|
||||||
ZSTD_VERSION_STRING,
|
ZSTD_VERSION_STRING,
|
||||||
ZSTD_GIT_COMMIT_STRING,
|
ZSTD_GIT_COMMIT_STRING,
|
||||||
(unsigned)benchedSize,
|
(unsigned)benchedSize,
|
||||||
adv->nbSeconds,
|
adv->nbSeconds,
|
||||||
(unsigned)(adv->blockSize >> 10));
|
(unsigned)(adv->chunkSizeMax >> 10));
|
||||||
|
|
||||||
for (level = startCLevel; level <= endCLevel; level++) {
|
for (level = startCLevel; level <= endCLevel; level++) {
|
||||||
BMK_benchOutcome_t res = BMK_benchMemAdvanced(
|
BMK_benchOutcome_t res = BMK_benchMemAdvanced(
|
||||||
@@ -1000,7 +989,7 @@ int BMK_syntheticTest(
|
|||||||
{
|
{
|
||||||
char nameBuff[20] = { 0 };
|
char nameBuff[20] = { 0 };
|
||||||
const char* name = nameBuff;
|
const char* name = nameBuff;
|
||||||
size_t const benchedSize = adv->blockSize ? adv->blockSize : 10000000;
|
size_t const benchedSize = adv->chunkSizeMax ? adv->chunkSizeMax : 10000000;
|
||||||
|
|
||||||
/* Memory allocation */
|
/* Memory allocation */
|
||||||
void* const srcBuffer = malloc(benchedSize);
|
void* const srcBuffer = malloc(benchedSize);
|
||||||
|
|||||||
@@ -92,9 +92,9 @@ typedef enum {
|
|||||||
} BMK_mode_t;
|
} BMK_mode_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BMK_mode_t mode; /* 0: all, 1: compress only 2: decode only */
|
BMK_mode_t mode; /* 0: both, 1: compress only 2: decode only */
|
||||||
unsigned nbSeconds; /* default timing is in nbSeconds */
|
unsigned nbSeconds; /* default timing is in nbSeconds */
|
||||||
size_t blockSize; /* Maximum size of each block*/
|
size_t chunkSizeMax; /* Maximum size of each independent chunk */
|
||||||
size_t targetCBlockSize;/* Approximative size of compressed blocks */
|
size_t targetCBlockSize;/* Approximative size of compressed blocks */
|
||||||
int nbWorkers; /* multithreading */
|
int nbWorkers; /* multithreading */
|
||||||
unsigned realTime; /* real time priority */
|
unsigned realTime; /* real time priority */
|
||||||
|
|||||||
+12
-5
@@ -280,8 +280,15 @@ static fileStats DiB_fileStats(const char** fileNamesTable, int nbFiles, size_t
|
|||||||
for (n=0; n<nbFiles; n++) {
|
for (n=0; n<nbFiles; n++) {
|
||||||
S64 const fileSize = DiB_getFileSize(fileNamesTable[n]);
|
S64 const fileSize = DiB_getFileSize(fileNamesTable[n]);
|
||||||
/* TODO: is there a minimum sample size? What if the file is 1-byte? */
|
/* TODO: is there a minimum sample size? What if the file is 1-byte? */
|
||||||
if (fileSize == 0) {
|
/* Skip empty or invalid files */
|
||||||
DISPLAYLEVEL(3, "Sample file '%s' has zero size, skipping...\n", fileNamesTable[n]);
|
if (fileSize <= 0) {
|
||||||
|
if (fileSize < 0) {
|
||||||
|
DISPLAYLEVEL(3, "Sample file '%s' is unreadable or stat failed, skipping...\n",
|
||||||
|
fileNamesTable[n]);
|
||||||
|
} else {
|
||||||
|
DISPLAYLEVEL(3, "Sample file '%s' has zero size, skipping...\n",
|
||||||
|
fileNamesTable[n]);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,9 +369,9 @@ int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize,
|
|||||||
DISPLAYLEVEL(2, "! As a consequence, only the first %u bytes of each sample are loaded \n", SAMPLESIZE_MAX);
|
DISPLAYLEVEL(2, "! As a consequence, only the first %u bytes of each sample are loaded \n", SAMPLESIZE_MAX);
|
||||||
}
|
}
|
||||||
if (fs.nbSamples < 5) {
|
if (fs.nbSamples < 5) {
|
||||||
DISPLAYLEVEL(2, "! Warning : nb of samples too low for proper processing ! \n");
|
DISPLAYLEVEL(2, "! Warning : nb of samples too low for proper processing !\n");
|
||||||
DISPLAYLEVEL(2, "! Please provide _one file per sample_. \n");
|
DISPLAYLEVEL(2, "! Please provide _one file per sample_.\n");
|
||||||
DISPLAYLEVEL(2, "! Alternatively, split files into fixed-size blocks representative of samples, with -B# \n");
|
DISPLAYLEVEL(2, "! Alternatively, split file(s) into fixed-size samples, with --split=#\n");
|
||||||
EXM_THROW(14, "nb of samples too low"); /* we now clearly forbid this case */
|
EXM_THROW(14, "nb of samples too low"); /* we now clearly forbid this case */
|
||||||
}
|
}
|
||||||
if (fs.totalSizeToLoad < (S64)maxDictSize * 8) {
|
if (fs.totalSizeToLoad < (S64)maxDictSize * 8) {
|
||||||
|
|||||||
+411
-154
@@ -125,6 +125,271 @@ char const* FIO_lzmaVersion(void)
|
|||||||
#define TEMPORARY_FILE_PERMISSIONS (0600)
|
#define TEMPORARY_FILE_PERMISSIONS (0600)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
|
|
||||||
|
/* *************************************
|
||||||
|
* Synchronous compression IO helpers
|
||||||
|
* Lightweight wrapper used by compression paths to manage buffered
|
||||||
|
* reads/writes without the async job machinery.
|
||||||
|
***************************************/
|
||||||
|
typedef struct {
|
||||||
|
const FIO_prefs_t* prefs;
|
||||||
|
FILE* srcFile;
|
||||||
|
FILE* dstFile;
|
||||||
|
unsigned storedSkips;
|
||||||
|
U8* inBuffer;
|
||||||
|
size_t inCapacity;
|
||||||
|
U8* srcBuffer;
|
||||||
|
size_t srcBufferLoaded;
|
||||||
|
U8* outBuffer;
|
||||||
|
size_t outCapacity;
|
||||||
|
} FIO_SyncCompressIO;
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_init(FIO_SyncCompressIO* io,
|
||||||
|
const FIO_prefs_t* prefs,
|
||||||
|
size_t inCapacity,
|
||||||
|
size_t outCapacity);
|
||||||
|
static void FIO_SyncCompressIO_destroy(FIO_SyncCompressIO* io);
|
||||||
|
static void FIO_SyncCompressIO_setSrc(FIO_SyncCompressIO* io, FILE* file);
|
||||||
|
static void FIO_SyncCompressIO_clearSrc(FIO_SyncCompressIO* io);
|
||||||
|
static void FIO_SyncCompressIO_setDst(FIO_SyncCompressIO* io, FILE* file);
|
||||||
|
static int FIO_SyncCompressIO_closeDst(FIO_SyncCompressIO* io);
|
||||||
|
static size_t FIO_SyncCompressIO_fillBuffer(FIO_SyncCompressIO* io, size_t minToHave);
|
||||||
|
static void FIO_SyncCompressIO_consumeBytes(FIO_SyncCompressIO* io, size_t n);
|
||||||
|
static void FIO_SyncCompressIO_commitOut(FIO_SyncCompressIO* io, const void* buffer, size_t size);
|
||||||
|
static void FIO_SyncCompressIO_finish(FIO_SyncCompressIO* io);
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned FIO_sparseWrite(FILE* file,
|
||||||
|
const void* buffer, size_t bufferSize,
|
||||||
|
const FIO_prefs_t* const prefs,
|
||||||
|
unsigned storedSkips)
|
||||||
|
{
|
||||||
|
const size_t* const bufferT = (const size_t*)buffer; /* Buffer is supposed malloc'ed, hence aligned on size_t */
|
||||||
|
size_t bufferSizeT = bufferSize / sizeof(size_t);
|
||||||
|
const size_t* const bufferTEnd = bufferT + bufferSizeT;
|
||||||
|
const size_t* ptrT = bufferT;
|
||||||
|
static const size_t segmentSizeT = (32 KB) / sizeof(size_t); /* check every 32 KB */
|
||||||
|
|
||||||
|
if (prefs->testMode) return 0; /* do not output anything in test mode */
|
||||||
|
|
||||||
|
if (!prefs->sparseFileSupport) { /* normal write */
|
||||||
|
size_t const sizeCheck = fwrite(buffer, 1, bufferSize, file);
|
||||||
|
if (sizeCheck != bufferSize)
|
||||||
|
EXM_THROW(70, "Write error : cannot write block : %s",
|
||||||
|
strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* avoid int overflow */
|
||||||
|
if (storedSkips > 1 GB) {
|
||||||
|
if (LONG_SEEK(file, 1 GB, SEEK_CUR) != 0)
|
||||||
|
EXM_THROW(91, "1 GB skip error (sparse file support)");
|
||||||
|
storedSkips -= 1 GB;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ptrT < bufferTEnd) {
|
||||||
|
size_t nb0T;
|
||||||
|
|
||||||
|
/* adjust last segment if < 32 KB */
|
||||||
|
size_t seg0SizeT = segmentSizeT;
|
||||||
|
if (seg0SizeT > bufferSizeT) seg0SizeT = bufferSizeT;
|
||||||
|
bufferSizeT -= seg0SizeT;
|
||||||
|
|
||||||
|
/* count leading zeroes */
|
||||||
|
for (nb0T=0; (nb0T < seg0SizeT) && (ptrT[nb0T] == 0); nb0T++) ;
|
||||||
|
storedSkips += (unsigned)(nb0T * sizeof(size_t));
|
||||||
|
|
||||||
|
if (nb0T != seg0SizeT) { /* not all 0s */
|
||||||
|
size_t const nbNon0ST = seg0SizeT - nb0T;
|
||||||
|
/* skip leading zeros */
|
||||||
|
if (LONG_SEEK(file, storedSkips, SEEK_CUR) != 0)
|
||||||
|
EXM_THROW(92, "Sparse skip error ; try --no-sparse");
|
||||||
|
storedSkips = 0;
|
||||||
|
/* write the rest */
|
||||||
|
if (fwrite(ptrT + nb0T, sizeof(size_t), nbNon0ST, file) != nbNon0ST)
|
||||||
|
EXM_THROW(93, "Write error : cannot write block : %s",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
ptrT += seg0SizeT;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ static size_t const maskT = sizeof(size_t)-1;
|
||||||
|
if (bufferSize & maskT) {
|
||||||
|
/* size not multiple of sizeof(size_t) : implies end of block */
|
||||||
|
const char* const restStart = (const char*)bufferTEnd;
|
||||||
|
const char* restPtr = restStart;
|
||||||
|
const char* const restEnd = (const char*)buffer + bufferSize;
|
||||||
|
assert(restEnd > restStart && restEnd < restStart + sizeof(size_t));
|
||||||
|
for ( ; (restPtr < restEnd) && (*restPtr == 0); restPtr++) ;
|
||||||
|
storedSkips += (unsigned) (restPtr - restStart);
|
||||||
|
if (restPtr != restEnd) {
|
||||||
|
/* not all remaining bytes are 0 */
|
||||||
|
size_t const restSize = (size_t)(restEnd - restPtr);
|
||||||
|
if (LONG_SEEK(file, storedSkips, SEEK_CUR) != 0)
|
||||||
|
EXM_THROW(92, "Sparse skip error ; try --no-sparse");
|
||||||
|
if (fwrite(restPtr, 1, restSize, file) != restSize)
|
||||||
|
EXM_THROW(95, "Write error : cannot write end of decoded block : %s",
|
||||||
|
strerror(errno));
|
||||||
|
storedSkips = 0;
|
||||||
|
} } }
|
||||||
|
|
||||||
|
return storedSkips;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_sparseWriteEnd(const FIO_prefs_t* const prefs, FILE* file, unsigned storedSkips)
|
||||||
|
{
|
||||||
|
if (file == NULL) return;
|
||||||
|
if (prefs->testMode) {
|
||||||
|
assert(storedSkips == 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (storedSkips>0) {
|
||||||
|
assert(prefs->sparseFileSupport > 0); /* storedSkips>0 implies sparse support is enabled */
|
||||||
|
if (LONG_SEEK(file, storedSkips-1, SEEK_CUR) != 0)
|
||||||
|
EXM_THROW(69, "Final skip error (sparse file support)");
|
||||||
|
/* last zero must be explicitly written,
|
||||||
|
* so that skipped ones get implicitly translated as zero by FS */
|
||||||
|
{ const char lastZeroByte[1] = { 0 };
|
||||||
|
if (fwrite(lastZeroByte, 1, 1, file) != 1)
|
||||||
|
EXM_THROW(69, "Write error : cannot write last zero : %s", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_init(FIO_SyncCompressIO* io,
|
||||||
|
const FIO_prefs_t* prefs,
|
||||||
|
size_t inCapacity,
|
||||||
|
size_t outCapacity)
|
||||||
|
{
|
||||||
|
memset(io, 0, sizeof(*io));
|
||||||
|
io->prefs = prefs;
|
||||||
|
io->inCapacity = inCapacity;
|
||||||
|
io->outCapacity = outCapacity;
|
||||||
|
io->inBuffer = (U8*)malloc(inCapacity);
|
||||||
|
if (!io->inBuffer)
|
||||||
|
EXM_THROW(101, "Allocation error : not enough memory");
|
||||||
|
io->outBuffer = (U8*)malloc(outCapacity);
|
||||||
|
if (!io->outBuffer) {
|
||||||
|
free(io->inBuffer);
|
||||||
|
io->inBuffer = NULL;
|
||||||
|
EXM_THROW(101, "Allocation error : not enough memory");
|
||||||
|
}
|
||||||
|
io->srcBuffer = io->inBuffer;
|
||||||
|
io->srcBufferLoaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_destroy(FIO_SyncCompressIO* io)
|
||||||
|
{
|
||||||
|
if (!io) return;
|
||||||
|
free(io->inBuffer);
|
||||||
|
free(io->outBuffer);
|
||||||
|
io->inBuffer = NULL;
|
||||||
|
io->outBuffer = NULL;
|
||||||
|
io->srcBuffer = NULL;
|
||||||
|
io->srcBufferLoaded = 0;
|
||||||
|
io->srcFile = NULL;
|
||||||
|
io->dstFile = NULL;
|
||||||
|
io->storedSkips = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_setSrc(FIO_SyncCompressIO* io, FILE* file)
|
||||||
|
{
|
||||||
|
io->srcFile = file;
|
||||||
|
io->srcBuffer = io->inBuffer;
|
||||||
|
io->srcBufferLoaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_clearSrc(FIO_SyncCompressIO* io)
|
||||||
|
{
|
||||||
|
io->srcFile = NULL;
|
||||||
|
io->srcBuffer = io->inBuffer;
|
||||||
|
io->srcBufferLoaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_setDst(FIO_SyncCompressIO* io, FILE* file)
|
||||||
|
{
|
||||||
|
io->dstFile = file;
|
||||||
|
io->storedSkips = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int FIO_SyncCompressIO_closeDst(FIO_SyncCompressIO* io)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (io->dstFile != NULL) {
|
||||||
|
FIO_SyncCompressIO_finish(io);
|
||||||
|
result = fclose(io->dstFile);
|
||||||
|
io->dstFile = NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t FIO_SyncCompressIO_fillBuffer(FIO_SyncCompressIO* io, size_t minToHave)
|
||||||
|
{
|
||||||
|
size_t added = 0;
|
||||||
|
if (io->srcFile == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (minToHave > io->inCapacity)
|
||||||
|
minToHave = io->inCapacity;
|
||||||
|
|
||||||
|
if (io->srcBufferLoaded >= minToHave)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (io->srcBuffer != io->inBuffer) {
|
||||||
|
if (io->srcBufferLoaded > 0)
|
||||||
|
memmove(io->inBuffer, io->srcBuffer, io->srcBufferLoaded);
|
||||||
|
io->srcBuffer = io->inBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (io->srcBufferLoaded < minToHave) {
|
||||||
|
size_t const toRead = io->inCapacity - io->srcBufferLoaded;
|
||||||
|
size_t const readBytes = fread(io->inBuffer + io->srcBufferLoaded, 1, toRead, io->srcFile);
|
||||||
|
if (readBytes == 0) {
|
||||||
|
if (ferror(io->srcFile))
|
||||||
|
EXM_THROW(37, "Read error");
|
||||||
|
break; /* EOF */
|
||||||
|
}
|
||||||
|
io->srcBufferLoaded += readBytes;
|
||||||
|
added += readBytes;
|
||||||
|
if (readBytes < toRead)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return added;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_consumeBytes(FIO_SyncCompressIO* io, size_t n)
|
||||||
|
{
|
||||||
|
assert(n <= io->srcBufferLoaded);
|
||||||
|
io->srcBuffer += n;
|
||||||
|
io->srcBufferLoaded -= n;
|
||||||
|
if (io->srcBufferLoaded == 0)
|
||||||
|
io->srcBuffer = io->inBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_commitOut(FIO_SyncCompressIO* io, const void* buffer, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
if (io->dstFile == NULL) {
|
||||||
|
assert(io->prefs->testMode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
io->storedSkips = FIO_sparseWrite(io->dstFile, buffer, size, io->prefs, io->storedSkips);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_SyncCompressIO_finish(FIO_SyncCompressIO* io)
|
||||||
|
{
|
||||||
|
if (io->dstFile == NULL)
|
||||||
|
return;
|
||||||
|
FIO_sparseWriteEnd(io->prefs, io->dstFile, io->storedSkips);
|
||||||
|
io->storedSkips = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ZSTD_NOCOMPRESS */
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Signal (Ctrl-C trapping)
|
* Signal (Ctrl-C trapping)
|
||||||
**************************************/
|
**************************************/
|
||||||
@@ -288,7 +553,7 @@ FIO_prefs_t* FIO_createPreferences(void)
|
|||||||
ret->removeSrcFile = 0;
|
ret->removeSrcFile = 0;
|
||||||
ret->memLimit = 0;
|
ret->memLimit = 0;
|
||||||
ret->nbWorkers = 1;
|
ret->nbWorkers = 1;
|
||||||
ret->blockSize = 0;
|
ret->jobSize = 0;
|
||||||
ret->overlapLog = FIO_OVERLAP_LOG_NOTSET;
|
ret->overlapLog = FIO_OVERLAP_LOG_NOTSET;
|
||||||
ret->adaptiveMode = 0;
|
ret->adaptiveMode = 0;
|
||||||
ret->rsyncable = 0;
|
ret->rsyncable = 0;
|
||||||
@@ -377,10 +642,10 @@ void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompresse
|
|||||||
|
|
||||||
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices) { prefs->allowBlockDevices = allowBlockDevices; }
|
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices) { prefs->allowBlockDevices = allowBlockDevices; }
|
||||||
|
|
||||||
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) {
|
void FIO_setJobSize(FIO_prefs_t* const prefs, int jobSize) {
|
||||||
if (blockSize && prefs->nbWorkers==0)
|
if (jobSize && prefs->nbWorkers==0)
|
||||||
DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n");
|
DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n");
|
||||||
prefs->blockSize = blockSize;
|
prefs->jobSize = jobSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FIO_setOverlapLog(FIO_prefs_t* const prefs, int overlapLog){
|
void FIO_setOverlapLog(FIO_prefs_t* const prefs, int overlapLog){
|
||||||
@@ -538,14 +803,16 @@ static int FIO_removeFile(const char* path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** FIO_openSrcFile() :
|
/** FIO_openSrcFile() :
|
||||||
* condition : `srcFileName` must be non-NULL. `prefs` may be NULL.
|
* condition : `srcFileName` must be non-NULL.
|
||||||
|
* optional: `prefs` may be NULL.
|
||||||
* @result : FILE* to `srcFileName`, or NULL if it fails */
|
* @result : FILE* to `srcFileName`, or NULL if it fails */
|
||||||
static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFileName, stat_t* statbuf)
|
static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFileName, stat_t* statbuf)
|
||||||
{
|
{
|
||||||
int allowBlockDevices = prefs != NULL ? prefs->allowBlockDevices : 0;
|
int allowBlockDevices = prefs != NULL ? prefs->allowBlockDevices : 0;
|
||||||
assert(srcFileName != NULL);
|
assert(srcFileName != NULL);
|
||||||
assert(statbuf != NULL);
|
assert(statbuf != NULL);
|
||||||
if (!strcmp (srcFileName, stdinmark)) {
|
|
||||||
|
if (!strcmp(srcFileName, stdinmark)) {
|
||||||
DISPLAYLEVEL(4,"Using stdin for input \n");
|
DISPLAYLEVEL(4,"Using stdin for input \n");
|
||||||
SET_BINARY_MODE(stdin);
|
SET_BINARY_MODE(stdin);
|
||||||
return stdin;
|
return stdin;
|
||||||
@@ -557,8 +824,10 @@ static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFile
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Accept regular files, FIFOs, and process substitution file descriptors */
|
||||||
if (!UTIL_isRegularFileStat(statbuf)
|
if (!UTIL_isRegularFileStat(statbuf)
|
||||||
&& !UTIL_isFIFOStat(statbuf)
|
&& !UTIL_isFIFOStat(statbuf)
|
||||||
|
&& !UTIL_isFileDescriptorPipe(srcFileName) /* Process substitution support */
|
||||||
&& !(allowBlockDevices && UTIL_isBlockDevStat(statbuf))
|
&& !(allowBlockDevices && UTIL_isBlockDevStat(statbuf))
|
||||||
) {
|
) {
|
||||||
DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
|
DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
|
||||||
@@ -581,8 +850,6 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
|
|||||||
const char* srcFileName, const char* dstFileName,
|
const char* srcFileName, const char* dstFileName,
|
||||||
const int mode)
|
const int mode)
|
||||||
{
|
{
|
||||||
int isDstRegFile;
|
|
||||||
|
|
||||||
if (prefs->testMode) return NULL; /* do not open file in test mode */
|
if (prefs->testMode) return NULL; /* do not open file in test mode */
|
||||||
|
|
||||||
assert(dstFileName != NULL);
|
assert(dstFileName != NULL);
|
||||||
@@ -602,16 +869,7 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
isDstRegFile = UTIL_isRegularFile(dstFileName); /* invoke once */
|
if (UTIL_isRegularFile(dstFileName)) {
|
||||||
if (prefs->sparseFileSupport == 1) {
|
|
||||||
prefs->sparseFileSupport = ZSTD_SPARSE_DEFAULT;
|
|
||||||
if (!isDstRegFile) {
|
|
||||||
prefs->sparseFileSupport = 0;
|
|
||||||
DISPLAYLEVEL(4, "Sparse File Support is disabled when output is not a file \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDstRegFile) {
|
|
||||||
/* Check if destination file already exists */
|
/* Check if destination file already exists */
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
/* this test does not work on Windows :
|
/* this test does not work on Windows :
|
||||||
@@ -637,6 +895,7 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
int isDstRegFile;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
/* Windows requires opening the file as a "binary" file to avoid
|
/* Windows requires opening the file as a "binary" file to avoid
|
||||||
* mangling. This macro doesn't exist on unix. */
|
* mangling. This macro doesn't exist on unix. */
|
||||||
@@ -654,8 +913,23 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
|
|||||||
f = fdopen(fd, "wb");
|
f = fdopen(fd, "wb");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Check regular file after opening with O_CREAT */
|
||||||
|
isDstRegFile = UTIL_isFdRegularFile(fd);
|
||||||
|
if (prefs->sparseFileSupport == 1) {
|
||||||
|
prefs->sparseFileSupport = ZSTD_SPARSE_DEFAULT;
|
||||||
|
if (!isDstRegFile) {
|
||||||
|
prefs->sparseFileSupport = 0;
|
||||||
|
DISPLAYLEVEL(4, "Sparse File Support is disabled when output is not a file \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
|
if (UTIL_isFileDescriptorPipe(dstFileName)) {
|
||||||
|
DISPLAYLEVEL(1, "zstd: error: no output specified (use -o or -c). \n");
|
||||||
|
} else {
|
||||||
|
DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* An increased buffer size can provide a significant performance
|
/* An increased buffer size can provide a significant performance
|
||||||
* boost on some platforms. Note that providing a NULL buf with a
|
* boost on some platforms. Note that providing a NULL buf with a
|
||||||
@@ -776,7 +1050,9 @@ static size_t FIO_setDictBufferMMap(FIO_Dict_t* dict, const char* fileName, FIO_
|
|||||||
}
|
}
|
||||||
|
|
||||||
*bufferPtr = mmap(NULL, (size_t)fileSize, PROT_READ, MAP_PRIVATE, fileHandle, 0);
|
*bufferPtr = mmap(NULL, (size_t)fileSize, PROT_READ, MAP_PRIVATE, fileHandle, 0);
|
||||||
if (*bufferPtr==NULL) EXM_THROW(34, "%s", strerror(errno));
|
if (*bufferPtr == MAP_FAILED) {
|
||||||
|
EXM_THROW(34, "%s", strerror(errno))
|
||||||
|
}
|
||||||
|
|
||||||
close(fileHandle);
|
close(fileHandle);
|
||||||
return (size_t)fileSize;
|
return (size_t)fileSize;
|
||||||
@@ -1069,8 +1345,7 @@ typedef struct {
|
|||||||
const char* dictFileName;
|
const char* dictFileName;
|
||||||
stat_t dictFileStat;
|
stat_t dictFileStat;
|
||||||
ZSTD_CStream* cctx;
|
ZSTD_CStream* cctx;
|
||||||
WritePoolCtx_t *writeCtx;
|
FIO_SyncCompressIO io;
|
||||||
ReadPoolCtx_t *readCtx;
|
|
||||||
} cRess_t;
|
} cRess_t;
|
||||||
|
|
||||||
/** ZSTD_cycleLog() :
|
/** ZSTD_cycleLog() :
|
||||||
@@ -1138,8 +1413,7 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
|||||||
dictBufferType = (useMMap && !forceNoUseMMap) ? FIO_mmapDict : FIO_mallocDict;
|
dictBufferType = (useMMap && !forceNoUseMMap) ? FIO_mmapDict : FIO_mallocDict;
|
||||||
FIO_initDict(&ress.dict, dictFileName, prefs, &ress.dictFileStat, dictBufferType); /* works with dictFileName==NULL */
|
FIO_initDict(&ress.dict, dictFileName, prefs, &ress.dictFileStat, dictBufferType); /* works with dictFileName==NULL */
|
||||||
|
|
||||||
ress.writeCtx = AIO_WritePool_create(prefs, ZSTD_CStreamOutSize());
|
FIO_SyncCompressIO_init(&ress.io, prefs, ZSTD_CStreamInSize(), ZSTD_CStreamOutSize());
|
||||||
ress.readCtx = AIO_ReadPool_create(prefs, ZSTD_CStreamInSize());
|
|
||||||
|
|
||||||
/* Advanced parameters, including dictionary */
|
/* Advanced parameters, including dictionary */
|
||||||
if (dictFileName && (ress.dict.dictBuffer==NULL))
|
if (dictFileName && (ress.dict.dictBuffer==NULL))
|
||||||
@@ -1183,7 +1457,7 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
|||||||
#ifdef ZSTD_MULTITHREAD
|
#ifdef ZSTD_MULTITHREAD
|
||||||
DISPLAYLEVEL(5,"set nb workers = %u \n", prefs->nbWorkers);
|
DISPLAYLEVEL(5,"set nb workers = %u \n", prefs->nbWorkers);
|
||||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_nbWorkers, prefs->nbWorkers) );
|
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_nbWorkers, prefs->nbWorkers) );
|
||||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_jobSize, prefs->blockSize) );
|
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_jobSize, prefs->jobSize) );
|
||||||
if (prefs->overlapLog != FIO_OVERLAP_LOG_NOTSET) {
|
if (prefs->overlapLog != FIO_OVERLAP_LOG_NOTSET) {
|
||||||
DISPLAYLEVEL(3,"set overlapLog = %u \n", prefs->overlapLog);
|
DISPLAYLEVEL(3,"set overlapLog = %u \n", prefs->overlapLog);
|
||||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_overlapLog, prefs->overlapLog) );
|
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_overlapLog, prefs->overlapLog) );
|
||||||
@@ -1203,21 +1477,20 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
|||||||
static void FIO_freeCResources(cRess_t* const ress)
|
static void FIO_freeCResources(cRess_t* const ress)
|
||||||
{
|
{
|
||||||
FIO_freeDict(&(ress->dict));
|
FIO_freeDict(&(ress->dict));
|
||||||
AIO_WritePool_free(ress->writeCtx);
|
FIO_SyncCompressIO_destroy(&ress->io);
|
||||||
AIO_ReadPool_free(ress->readCtx);
|
|
||||||
ZSTD_freeCStream(ress->cctx); /* never fails */
|
ZSTD_freeCStream(ress->cctx); /* never fails */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ZSTD_GZCOMPRESS
|
#ifdef ZSTD_GZCOMPRESS
|
||||||
static unsigned long long
|
static unsigned long long
|
||||||
FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but not changed */
|
FIO_compressGzFrame(cRess_t* ress,
|
||||||
const char* srcFileName, U64 const srcFileSize,
|
const char* srcFileName, U64 const srcFileSize,
|
||||||
int compressionLevel, U64* readsize)
|
int compressionLevel, U64* readsize)
|
||||||
{
|
{
|
||||||
|
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||||
z_stream strm;
|
z_stream strm;
|
||||||
IOJob_t *writeJob = NULL;
|
|
||||||
|
|
||||||
if (compressionLevel > Z_BEST_COMPRESSION)
|
if (compressionLevel > Z_BEST_COMPRESSION)
|
||||||
compressionLevel = Z_BEST_COMPRESSION;
|
compressionLevel = Z_BEST_COMPRESSION;
|
||||||
@@ -1233,37 +1506,36 @@ FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but no
|
|||||||
EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, ret);
|
EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, ret);
|
||||||
} }
|
} }
|
||||||
|
|
||||||
writeJob = AIO_WritePool_acquireJob(ress->writeCtx);
|
|
||||||
strm.next_in = 0;
|
strm.next_in = 0;
|
||||||
strm.avail_in = 0;
|
strm.avail_in = 0;
|
||||||
strm.next_out = (Bytef*)writeJob->buffer;
|
strm.next_out = (Bytef*)syncIO->outBuffer;
|
||||||
strm.avail_out = (uInt)writeJob->bufferSize;
|
strm.avail_out = (uInt)syncIO->outCapacity;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int ret;
|
int ret;
|
||||||
if (strm.avail_in == 0) {
|
if (strm.avail_in == 0) {
|
||||||
AIO_ReadPool_fillBuffer(ress->readCtx, ZSTD_CStreamInSize());
|
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, ZSTD_CStreamInSize());
|
||||||
if (ress->readCtx->srcBufferLoaded == 0) break;
|
if (syncIO->srcBufferLoaded == 0) break;
|
||||||
inFileSize += ress->readCtx->srcBufferLoaded;
|
inFileSize += added;
|
||||||
strm.next_in = (z_const unsigned char*)ress->readCtx->srcBuffer;
|
*readsize += added;
|
||||||
strm.avail_in = (uInt)ress->readCtx->srcBufferLoaded;
|
strm.next_in = (z_const unsigned char*)syncIO->srcBuffer;
|
||||||
|
strm.avail_in = (uInt)syncIO->srcBufferLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t const availBefore = strm.avail_in;
|
size_t const availBefore = strm.avail_in;
|
||||||
ret = deflate(&strm, Z_NO_FLUSH);
|
ret = deflate(&strm, Z_NO_FLUSH);
|
||||||
AIO_ReadPool_consumeBytes(ress->readCtx, availBefore - strm.avail_in);
|
FIO_SyncCompressIO_consumeBytes(syncIO, availBefore - strm.avail_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, ret);
|
EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, ret);
|
||||||
{ size_t const cSize = writeJob->bufferSize - strm.avail_out;
|
{ size_t const cSize = (size_t)((uInt)syncIO->outCapacity - strm.avail_out);
|
||||||
if (cSize) {
|
if (cSize) {
|
||||||
writeJob->usedBufferSize = cSize;
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, cSize);
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
outFileSize += cSize;
|
outFileSize += cSize;
|
||||||
strm.next_out = (Bytef*)writeJob->buffer;
|
strm.next_out = (Bytef*)syncIO->outBuffer;
|
||||||
strm.avail_out = (uInt)writeJob->bufferSize;
|
strm.avail_out = (uInt)syncIO->outCapacity;
|
||||||
} }
|
} }
|
||||||
if (srcFileSize == UTIL_FILESIZE_UNKNOWN) {
|
if (srcFileSize == UTIL_FILESIZE_UNKNOWN) {
|
||||||
DISPLAYUPDATE_PROGRESS(
|
DISPLAYUPDATE_PROGRESS(
|
||||||
@@ -1279,13 +1551,12 @@ FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but no
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int const ret = deflate(&strm, Z_FINISH);
|
int const ret = deflate(&strm, Z_FINISH);
|
||||||
{ size_t const cSize = writeJob->bufferSize - strm.avail_out;
|
{ size_t const cSize = (size_t)((uInt)syncIO->outCapacity - strm.avail_out);
|
||||||
if (cSize) {
|
if (cSize) {
|
||||||
writeJob->usedBufferSize = cSize;
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, cSize);
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
outFileSize += cSize;
|
outFileSize += cSize;
|
||||||
strm.next_out = (Bytef*)writeJob->buffer;
|
strm.next_out = (Bytef*)syncIO->outBuffer;
|
||||||
strm.avail_out = (uInt)writeJob->bufferSize;
|
strm.avail_out = (uInt)syncIO->outCapacity;
|
||||||
} }
|
} }
|
||||||
if (ret == Z_STREAM_END) break;
|
if (ret == Z_STREAM_END) break;
|
||||||
if (ret != Z_BUF_ERROR)
|
if (ret != Z_BUF_ERROR)
|
||||||
@@ -1297,8 +1568,7 @@ FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but no
|
|||||||
EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, ret);
|
EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, ret);
|
||||||
} }
|
} }
|
||||||
*readsize = inFileSize;
|
*readsize = inFileSize;
|
||||||
AIO_WritePool_releaseIoJob(writeJob);
|
FIO_SyncCompressIO_finish(syncIO);
|
||||||
AIO_WritePool_sparseWriteEnd(ress->writeCtx);
|
|
||||||
return outFileSize;
|
return outFileSize;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1310,11 +1580,11 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
|||||||
const char* srcFileName, U64 const srcFileSize,
|
const char* srcFileName, U64 const srcFileSize,
|
||||||
int compressionLevel, U64* readsize, int plain_lzma)
|
int compressionLevel, U64* readsize, int plain_lzma)
|
||||||
{
|
{
|
||||||
|
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||||
lzma_stream strm = LZMA_STREAM_INIT;
|
lzma_stream strm = LZMA_STREAM_INIT;
|
||||||
lzma_action action = LZMA_RUN;
|
lzma_action action = LZMA_RUN;
|
||||||
lzma_ret ret;
|
lzma_ret ret;
|
||||||
IOJob_t *writeJob = NULL;
|
|
||||||
|
|
||||||
if (compressionLevel < 0) compressionLevel = 0;
|
if (compressionLevel < 0) compressionLevel = 0;
|
||||||
if (compressionLevel > 9) compressionLevel = 9;
|
if (compressionLevel > 9) compressionLevel = 9;
|
||||||
@@ -1332,37 +1602,35 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
|||||||
EXM_THROW(83, "zstd: %s: lzma_easy_encoder error %d", srcFileName, ret);
|
EXM_THROW(83, "zstd: %s: lzma_easy_encoder error %d", srcFileName, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJob =AIO_WritePool_acquireJob(ress->writeCtx);
|
strm.next_out = (BYTE*)syncIO->outBuffer;
|
||||||
strm.next_out = (BYTE*)writeJob->buffer;
|
strm.avail_out = syncIO->outCapacity;
|
||||||
strm.avail_out = writeJob->bufferSize;
|
|
||||||
strm.next_in = 0;
|
strm.next_in = 0;
|
||||||
strm.avail_in = 0;
|
strm.avail_in = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (strm.avail_in == 0) {
|
if (strm.avail_in == 0) {
|
||||||
size_t const inSize = AIO_ReadPool_fillBuffer(ress->readCtx, ZSTD_CStreamInSize());
|
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, ZSTD_CStreamInSize());
|
||||||
if (ress->readCtx->srcBufferLoaded == 0) action = LZMA_FINISH;
|
if (syncIO->srcBufferLoaded == 0) action = LZMA_FINISH;
|
||||||
inFileSize += inSize;
|
inFileSize += added;
|
||||||
strm.next_in = (BYTE const*)ress->readCtx->srcBuffer;
|
*readsize += added;
|
||||||
strm.avail_in = ress->readCtx->srcBufferLoaded;
|
strm.next_in = (BYTE const*)syncIO->srcBuffer;
|
||||||
|
strm.avail_in = syncIO->srcBufferLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t const availBefore = strm.avail_in;
|
size_t const availBefore = strm.avail_in;
|
||||||
ret = lzma_code(&strm, action);
|
ret = lzma_code(&strm, action);
|
||||||
AIO_ReadPool_consumeBytes(ress->readCtx, availBefore - strm.avail_in);
|
FIO_SyncCompressIO_consumeBytes(syncIO, availBefore - strm.avail_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||||
EXM_THROW(84, "zstd: %s: lzma_code encoding error %d", srcFileName, ret);
|
EXM_THROW(84, "zstd: %s: lzma_code encoding error %d", srcFileName, ret);
|
||||||
{ size_t const compBytes = writeJob->bufferSize - strm.avail_out;
|
{ size_t const compBytes = syncIO->outCapacity - strm.avail_out;
|
||||||
if (compBytes) {
|
if (compBytes) {
|
||||||
writeJob->usedBufferSize = compBytes;
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, compBytes);
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
outFileSize += compBytes;
|
outFileSize += compBytes;
|
||||||
strm.next_out = (BYTE*)writeJob->buffer;
|
strm.next_out = (BYTE*)syncIO->outBuffer;
|
||||||
strm.avail_out = writeJob->bufferSize;
|
strm.avail_out = syncIO->outCapacity;
|
||||||
} }
|
} }
|
||||||
if (srcFileSize == UTIL_FILESIZE_UNKNOWN)
|
if (srcFileSize == UTIL_FILESIZE_UNKNOWN)
|
||||||
DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%",
|
DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%",
|
||||||
@@ -1378,8 +1646,7 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
|||||||
lzma_end(&strm);
|
lzma_end(&strm);
|
||||||
*readsize = inFileSize;
|
*readsize = inFileSize;
|
||||||
|
|
||||||
AIO_WritePool_releaseIoJob(writeJob);
|
FIO_SyncCompressIO_finish(syncIO);
|
||||||
AIO_WritePool_sparseWriteEnd(ress->writeCtx);
|
|
||||||
|
|
||||||
return outFileSize;
|
return outFileSize;
|
||||||
}
|
}
|
||||||
@@ -1400,21 +1667,20 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||||||
int compressionLevel, int checksumFlag,
|
int compressionLevel, int checksumFlag,
|
||||||
U64* readsize)
|
U64* readsize)
|
||||||
{
|
{
|
||||||
|
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||||
const size_t blockSize = FIO_LZ4_GetBlockSize_FromBlockId(LZ4F_max64KB);
|
const size_t blockSize = FIO_LZ4_GetBlockSize_FromBlockId(LZ4F_max64KB);
|
||||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||||
|
|
||||||
LZ4F_preferences_t prefs;
|
LZ4F_preferences_t prefs;
|
||||||
LZ4F_compressionContext_t ctx;
|
LZ4F_compressionContext_t ctx;
|
||||||
|
|
||||||
IOJob_t* writeJob = AIO_WritePool_acquireJob(ress->writeCtx);
|
|
||||||
|
|
||||||
LZ4F_errorCode_t const errorCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
LZ4F_errorCode_t const errorCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
||||||
if (LZ4F_isError(errorCode))
|
if (LZ4F_isError(errorCode))
|
||||||
EXM_THROW(31, "zstd: failed to create lz4 compression context");
|
EXM_THROW(31, "zstd: failed to create lz4 compression context");
|
||||||
|
|
||||||
memset(&prefs, 0, sizeof(prefs));
|
memset(&prefs, 0, sizeof(prefs));
|
||||||
|
|
||||||
assert(blockSize <= ress->readCtx->base.jobBufferSize);
|
assert(blockSize <= syncIO->inCapacity);
|
||||||
|
|
||||||
/* autoflush off to mitigate a bug in lz4<=1.9.3 for compression level 12 */
|
/* autoflush off to mitigate a bug in lz4<=1.9.3 for compression level 12 */
|
||||||
prefs.autoFlush = 0;
|
prefs.autoFlush = 0;
|
||||||
@@ -1425,25 +1691,26 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||||||
#if LZ4_VERSION_NUMBER >= 10600
|
#if LZ4_VERSION_NUMBER >= 10600
|
||||||
prefs.frameInfo.contentSize = (srcFileSize==UTIL_FILESIZE_UNKNOWN) ? 0 : srcFileSize;
|
prefs.frameInfo.contentSize = (srcFileSize==UTIL_FILESIZE_UNKNOWN) ? 0 : srcFileSize;
|
||||||
#endif
|
#endif
|
||||||
assert(LZ4F_compressBound(blockSize, &prefs) <= writeJob->bufferSize);
|
assert(LZ4F_compressBound(blockSize, &prefs) <= syncIO->outCapacity);
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t headerSize = LZ4F_compressBegin(ctx, writeJob->buffer, writeJob->bufferSize, &prefs);
|
size_t headerSize = LZ4F_compressBegin(ctx, syncIO->outBuffer, syncIO->outCapacity, &prefs);
|
||||||
if (LZ4F_isError(headerSize))
|
if (LZ4F_isError(headerSize))
|
||||||
EXM_THROW(33, "File header generation failed : %s",
|
EXM_THROW(33, "File header generation failed : %s",
|
||||||
LZ4F_getErrorName(headerSize));
|
LZ4F_getErrorName(headerSize));
|
||||||
writeJob->usedBufferSize = headerSize;
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, headerSize);
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
outFileSize += headerSize;
|
outFileSize += headerSize;
|
||||||
|
|
||||||
/* Read first block */
|
{
|
||||||
inFileSize += AIO_ReadPool_fillBuffer(ress->readCtx, blockSize);
|
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, blockSize);
|
||||||
|
inFileSize += added;
|
||||||
|
*readsize += added;
|
||||||
|
}
|
||||||
|
|
||||||
/* Main Loop */
|
while (syncIO->srcBufferLoaded) {
|
||||||
while (ress->readCtx->srcBufferLoaded) {
|
size_t const inSize = MIN(blockSize, syncIO->srcBufferLoaded);
|
||||||
size_t inSize = MIN(blockSize, ress->readCtx->srcBufferLoaded);
|
size_t const outSize = LZ4F_compressUpdate(ctx, syncIO->outBuffer, syncIO->outCapacity,
|
||||||
size_t const outSize = LZ4F_compressUpdate(ctx, writeJob->buffer, writeJob->bufferSize,
|
syncIO->srcBuffer, inSize, NULL);
|
||||||
ress->readCtx->srcBuffer, inSize, NULL);
|
|
||||||
if (LZ4F_isError(outSize))
|
if (LZ4F_isError(outSize))
|
||||||
EXM_THROW(35, "zstd: %s: lz4 compression failed : %s",
|
EXM_THROW(35, "zstd: %s: lz4 compression failed : %s",
|
||||||
srcFileName, LZ4F_getErrorName(outSize));
|
srcFileName, LZ4F_getErrorName(outSize));
|
||||||
@@ -1458,30 +1725,27 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||||||
(double)outFileSize/(double)inFileSize*100);
|
(double)outFileSize/(double)inFileSize*100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write Block */
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, outSize);
|
||||||
writeJob->usedBufferSize = outSize;
|
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
|
|
||||||
/* Read next block */
|
FIO_SyncCompressIO_consumeBytes(syncIO, inSize);
|
||||||
AIO_ReadPool_consumeBytes(ress->readCtx, inSize);
|
{
|
||||||
inFileSize += AIO_ReadPool_fillBuffer(ress->readCtx, blockSize);
|
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, blockSize);
|
||||||
|
inFileSize += added;
|
||||||
|
*readsize += added;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of Stream mark */
|
headerSize = LZ4F_compressEnd(ctx, syncIO->outBuffer, syncIO->outCapacity, NULL);
|
||||||
headerSize = LZ4F_compressEnd(ctx, writeJob->buffer, writeJob->bufferSize, NULL);
|
|
||||||
if (LZ4F_isError(headerSize))
|
if (LZ4F_isError(headerSize))
|
||||||
EXM_THROW(38, "zstd: %s: lz4 end of file generation failed : %s",
|
EXM_THROW(38, "zstd: %s: lz4 end of file generation failed : %s",
|
||||||
srcFileName, LZ4F_getErrorName(headerSize));
|
srcFileName, LZ4F_getErrorName(headerSize));
|
||||||
|
|
||||||
writeJob->usedBufferSize = headerSize;
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, headerSize);
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
outFileSize += headerSize;
|
outFileSize += headerSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
*readsize = inFileSize;
|
|
||||||
LZ4F_freeCompressionContext(ctx);
|
LZ4F_freeCompressionContext(ctx);
|
||||||
AIO_WritePool_releaseIoJob(writeJob);
|
FIO_SyncCompressIO_finish(syncIO);
|
||||||
AIO_WritePool_sparseWriteEnd(ress->writeCtx);
|
|
||||||
|
|
||||||
return outFileSize;
|
return outFileSize;
|
||||||
}
|
}
|
||||||
@@ -1490,12 +1754,11 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||||||
static unsigned long long
|
static unsigned long long
|
||||||
FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
||||||
FIO_prefs_t* const prefs,
|
FIO_prefs_t* const prefs,
|
||||||
const cRess_t* ressPtr,
|
cRess_t* ress,
|
||||||
const char* srcFileName, U64 fileSize,
|
const char* srcFileName, U64 fileSize,
|
||||||
int compressionLevel, U64* readsize)
|
int compressionLevel, U64* readsize)
|
||||||
{
|
{
|
||||||
cRess_t const ress = *ressPtr;
|
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||||
IOJob_t* writeJob = AIO_WritePool_acquireJob(ressPtr->writeCtx);
|
|
||||||
|
|
||||||
U64 compressedfilesize = 0;
|
U64 compressedfilesize = 0;
|
||||||
ZSTD_EndDirective directive = ZSTD_e_continue;
|
ZSTD_EndDirective directive = ZSTD_e_continue;
|
||||||
@@ -1520,16 +1783,16 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
/* init */
|
/* init */
|
||||||
if (fileSize != UTIL_FILESIZE_UNKNOWN) {
|
if (fileSize != UTIL_FILESIZE_UNKNOWN) {
|
||||||
pledgedSrcSize = fileSize;
|
pledgedSrcSize = fileSize;
|
||||||
CHECK(ZSTD_CCtx_setPledgedSrcSize(ress.cctx, fileSize));
|
CHECK(ZSTD_CCtx_setPledgedSrcSize(ress->cctx, fileSize));
|
||||||
} else if (prefs->streamSrcSize > 0) {
|
} else if (prefs->streamSrcSize > 0) {
|
||||||
/* unknown source size; use the declared stream size */
|
/* unknown source size; use the declared stream size */
|
||||||
pledgedSrcSize = prefs->streamSrcSize;
|
pledgedSrcSize = prefs->streamSrcSize;
|
||||||
CHECK( ZSTD_CCtx_setPledgedSrcSize(ress.cctx, prefs->streamSrcSize) );
|
CHECK( ZSTD_CCtx_setPledgedSrcSize(ress->cctx, prefs->streamSrcSize) );
|
||||||
}
|
}
|
||||||
|
|
||||||
{ int windowLog;
|
{ int windowLog;
|
||||||
UTIL_HumanReadableSize_t windowSize;
|
UTIL_HumanReadableSize_t windowSize;
|
||||||
CHECK(ZSTD_CCtx_getParameter(ress.cctx, ZSTD_c_windowLog, &windowLog));
|
CHECK(ZSTD_CCtx_getParameter(ress->cctx, ZSTD_c_windowLog, &windowLog));
|
||||||
if (windowLog == 0) {
|
if (windowLog == 0) {
|
||||||
if (prefs->ldmFlag) {
|
if (prefs->ldmFlag) {
|
||||||
/* If long mode is set without a window size libzstd will set this size internally */
|
/* If long mode is set without a window size libzstd will set this size internally */
|
||||||
@@ -1547,12 +1810,12 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
do {
|
do {
|
||||||
size_t stillToFlush;
|
size_t stillToFlush;
|
||||||
/* Fill input Buffer */
|
/* Fill input Buffer */
|
||||||
size_t const inSize = AIO_ReadPool_fillBuffer(ress.readCtx, ZSTD_CStreamInSize());
|
size_t const inSize = FIO_SyncCompressIO_fillBuffer(syncIO, ZSTD_CStreamInSize());
|
||||||
ZSTD_inBuffer inBuff = setInBuffer( ress.readCtx->srcBuffer, ress.readCtx->srcBufferLoaded, 0 );
|
ZSTD_inBuffer inBuff = setInBuffer( syncIO->srcBuffer, syncIO->srcBufferLoaded, 0 );
|
||||||
DISPLAYLEVEL(6, "fread %u bytes from source \n", (unsigned)inSize);
|
DISPLAYLEVEL(6, "fread %u bytes from source \n", (unsigned)inSize);
|
||||||
*readsize += inSize;
|
*readsize += inSize;
|
||||||
|
|
||||||
if ((ress.readCtx->srcBufferLoaded == 0) || (*readsize == fileSize))
|
if ((syncIO->srcBufferLoaded == 0) || (*readsize == fileSize))
|
||||||
directive = ZSTD_e_end;
|
directive = ZSTD_e_end;
|
||||||
|
|
||||||
stillToFlush = 1;
|
stillToFlush = 1;
|
||||||
@@ -1560,10 +1823,10 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
|| (directive == ZSTD_e_end && stillToFlush != 0) ) {
|
|| (directive == ZSTD_e_end && stillToFlush != 0) ) {
|
||||||
|
|
||||||
size_t const oldIPos = inBuff.pos;
|
size_t const oldIPos = inBuff.pos;
|
||||||
ZSTD_outBuffer outBuff = setOutBuffer( writeJob->buffer, writeJob->bufferSize, 0 );
|
ZSTD_outBuffer outBuff = setOutBuffer( syncIO->outBuffer, syncIO->outCapacity, 0 );
|
||||||
size_t const toFlushNow = ZSTD_toFlushNow(ress.cctx);
|
size_t const toFlushNow = ZSTD_toFlushNow(ress->cctx);
|
||||||
CHECK_V(stillToFlush, ZSTD_compressStream2(ress.cctx, &outBuff, &inBuff, directive));
|
CHECK_V(stillToFlush, ZSTD_compressStream2(ress->cctx, &outBuff, &inBuff, directive));
|
||||||
AIO_ReadPool_consumeBytes(ress.readCtx, inBuff.pos - oldIPos);
|
FIO_SyncCompressIO_consumeBytes(syncIO, inBuff.pos - oldIPos);
|
||||||
|
|
||||||
/* count stats */
|
/* count stats */
|
||||||
inputPresented++;
|
inputPresented++;
|
||||||
@@ -1574,14 +1837,13 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
DISPLAYLEVEL(6, "ZSTD_compress_generic(end:%u) => input pos(%u)<=(%u)size ; output generated %u bytes \n",
|
DISPLAYLEVEL(6, "ZSTD_compress_generic(end:%u) => input pos(%u)<=(%u)size ; output generated %u bytes \n",
|
||||||
(unsigned)directive, (unsigned)inBuff.pos, (unsigned)inBuff.size, (unsigned)outBuff.pos);
|
(unsigned)directive, (unsigned)inBuff.pos, (unsigned)inBuff.size, (unsigned)outBuff.pos);
|
||||||
if (outBuff.pos) {
|
if (outBuff.pos) {
|
||||||
writeJob->usedBufferSize = outBuff.pos;
|
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, outBuff.pos);
|
||||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
|
||||||
compressedfilesize += outBuff.pos;
|
compressedfilesize += outBuff.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adaptive mode : statistics measurement and speed correction */
|
/* adaptive mode : statistics measurement and speed correction */
|
||||||
if (prefs->adaptiveMode && UTIL_clockSpanMicro(lastAdaptTime) > adaptEveryMicro) {
|
if (prefs->adaptiveMode && UTIL_clockSpanMicro(lastAdaptTime) > adaptEveryMicro) {
|
||||||
ZSTD_frameProgression const zfp = ZSTD_getFrameProgression(ress.cctx);
|
ZSTD_frameProgression const zfp = ZSTD_getFrameProgression(ress->cctx);
|
||||||
|
|
||||||
lastAdaptTime = UTIL_getTime();
|
lastAdaptTime = UTIL_getTime();
|
||||||
|
|
||||||
@@ -1654,14 +1916,14 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
if (compressionLevel > ZSTD_maxCLevel()) compressionLevel = ZSTD_maxCLevel();
|
if (compressionLevel > ZSTD_maxCLevel()) compressionLevel = ZSTD_maxCLevel();
|
||||||
if (compressionLevel > prefs->maxAdaptLevel) compressionLevel = prefs->maxAdaptLevel;
|
if (compressionLevel > prefs->maxAdaptLevel) compressionLevel = prefs->maxAdaptLevel;
|
||||||
compressionLevel += (compressionLevel == 0); /* skip 0 */
|
compressionLevel += (compressionLevel == 0); /* skip 0 */
|
||||||
ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, compressionLevel);
|
ZSTD_CCtx_setParameter(ress->cctx, ZSTD_c_compressionLevel, compressionLevel);
|
||||||
}
|
}
|
||||||
if (speedChange == faster) {
|
if (speedChange == faster) {
|
||||||
DISPLAYLEVEL(6, "faster speed , lighter compression \n")
|
DISPLAYLEVEL(6, "faster speed , lighter compression \n")
|
||||||
compressionLevel --;
|
compressionLevel --;
|
||||||
if (compressionLevel < prefs->minAdaptLevel) compressionLevel = prefs->minAdaptLevel;
|
if (compressionLevel < prefs->minAdaptLevel) compressionLevel = prefs->minAdaptLevel;
|
||||||
compressionLevel -= (compressionLevel == 0); /* skip 0 */
|
compressionLevel -= (compressionLevel == 0); /* skip 0 */
|
||||||
ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, compressionLevel);
|
ZSTD_CCtx_setParameter(ress->cctx, ZSTD_c_compressionLevel, compressionLevel);
|
||||||
}
|
}
|
||||||
speedChange = noChange;
|
speedChange = noChange;
|
||||||
|
|
||||||
@@ -1671,7 +1933,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
|
|
||||||
/* display notification */
|
/* display notification */
|
||||||
if (SHOULD_DISPLAY_PROGRESS() && READY_FOR_UPDATE()) {
|
if (SHOULD_DISPLAY_PROGRESS() && READY_FOR_UPDATE()) {
|
||||||
ZSTD_frameProgression const zfp = ZSTD_getFrameProgression(ress.cctx);
|
ZSTD_frameProgression const zfp = ZSTD_getFrameProgression(ress->cctx);
|
||||||
double const cShare = (double)zfp.produced / (double)(zfp.consumed + !zfp.consumed/*avoid div0*/) * 100;
|
double const cShare = (double)zfp.produced / (double)(zfp.consumed + !zfp.consumed/*avoid div0*/) * 100;
|
||||||
UTIL_HumanReadableSize_t const buffered_hrs = UTIL_makeHumanReadableSize(zfp.ingested - zfp.consumed);
|
UTIL_HumanReadableSize_t const buffered_hrs = UTIL_makeHumanReadableSize(zfp.ingested - zfp.consumed);
|
||||||
UTIL_HumanReadableSize_t const consumed_hrs = UTIL_makeHumanReadableSize(zfp.consumed);
|
UTIL_HumanReadableSize_t const consumed_hrs = UTIL_makeHumanReadableSize(zfp.consumed);
|
||||||
@@ -1718,8 +1980,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
(unsigned long long)*readsize, (unsigned long long)fileSize);
|
(unsigned long long)*readsize, (unsigned long long)fileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
AIO_WritePool_releaseIoJob(writeJob);
|
FIO_SyncCompressIO_finish(syncIO);
|
||||||
AIO_WritePool_sparseWriteEnd(ressPtr->writeCtx);
|
|
||||||
|
|
||||||
return compressedfilesize;
|
return compressedfilesize;
|
||||||
}
|
}
|
||||||
@@ -1732,7 +1993,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||||||
static int
|
static int
|
||||||
FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
||||||
FIO_prefs_t* const prefs,
|
FIO_prefs_t* const prefs,
|
||||||
cRess_t ress,
|
cRess_t* ress,
|
||||||
const char* dstFileName, const char* srcFileName,
|
const char* dstFileName, const char* srcFileName,
|
||||||
int compressionLevel)
|
int compressionLevel)
|
||||||
{
|
{
|
||||||
@@ -1747,12 +2008,12 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
|||||||
switch (prefs->compressionType) {
|
switch (prefs->compressionType) {
|
||||||
default:
|
default:
|
||||||
case FIO_zstdCompression:
|
case FIO_zstdCompression:
|
||||||
compressedfilesize = FIO_compressZstdFrame(fCtx, prefs, &ress, srcFileName, fileSize, compressionLevel, &readsize);
|
compressedfilesize = FIO_compressZstdFrame(fCtx, prefs, ress, srcFileName, fileSize, compressionLevel, &readsize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FIO_gzipCompression:
|
case FIO_gzipCompression:
|
||||||
#ifdef ZSTD_GZCOMPRESS
|
#ifdef ZSTD_GZCOMPRESS
|
||||||
compressedfilesize = FIO_compressGzFrame(&ress, srcFileName, fileSize, compressionLevel, &readsize);
|
compressedfilesize = FIO_compressGzFrame(ress, srcFileName, fileSize, compressionLevel, &readsize);
|
||||||
#else
|
#else
|
||||||
(void)compressionLevel;
|
(void)compressionLevel;
|
||||||
EXM_THROW(20, "zstd: %s: file cannot be compressed as gzip (zstd compiled without ZSTD_GZCOMPRESS) -- ignored \n",
|
EXM_THROW(20, "zstd: %s: file cannot be compressed as gzip (zstd compiled without ZSTD_GZCOMPRESS) -- ignored \n",
|
||||||
@@ -1763,7 +2024,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
|||||||
case FIO_xzCompression:
|
case FIO_xzCompression:
|
||||||
case FIO_lzmaCompression:
|
case FIO_lzmaCompression:
|
||||||
#ifdef ZSTD_LZMACOMPRESS
|
#ifdef ZSTD_LZMACOMPRESS
|
||||||
compressedfilesize = FIO_compressLzmaFrame(&ress, srcFileName, fileSize, compressionLevel, &readsize, prefs->compressionType==FIO_lzmaCompression);
|
compressedfilesize = FIO_compressLzmaFrame(ress, srcFileName, fileSize, compressionLevel, &readsize, prefs->compressionType==FIO_lzmaCompression);
|
||||||
#else
|
#else
|
||||||
(void)compressionLevel;
|
(void)compressionLevel;
|
||||||
EXM_THROW(20, "zstd: %s: file cannot be compressed as xz/lzma (zstd compiled without ZSTD_LZMACOMPRESS) -- ignored \n",
|
EXM_THROW(20, "zstd: %s: file cannot be compressed as xz/lzma (zstd compiled without ZSTD_LZMACOMPRESS) -- ignored \n",
|
||||||
@@ -1773,7 +2034,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
|||||||
|
|
||||||
case FIO_lz4Compression:
|
case FIO_lz4Compression:
|
||||||
#ifdef ZSTD_LZ4COMPRESS
|
#ifdef ZSTD_LZ4COMPRESS
|
||||||
compressedfilesize = FIO_compressLz4Frame(&ress, srcFileName, fileSize, compressionLevel, prefs->checksumFlag, &readsize);
|
compressedfilesize = FIO_compressLz4Frame(ress, srcFileName, fileSize, compressionLevel, prefs->checksumFlag, &readsize);
|
||||||
#else
|
#else
|
||||||
(void)compressionLevel;
|
(void)compressionLevel;
|
||||||
EXM_THROW(20, "zstd: %s: file cannot be compressed as lz4 (zstd compiled without ZSTD_LZ4COMPRESS) -- ignored \n",
|
EXM_THROW(20, "zstd: %s: file cannot be compressed as lz4 (zstd compiled without ZSTD_LZ4COMPRESS) -- ignored \n",
|
||||||
@@ -1829,7 +2090,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
|||||||
*/
|
*/
|
||||||
static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
||||||
FIO_prefs_t* const prefs,
|
FIO_prefs_t* const prefs,
|
||||||
cRess_t ress,
|
cRess_t* ress,
|
||||||
const char* dstFileName,
|
const char* dstFileName,
|
||||||
const char* srcFileName,
|
const char* srcFileName,
|
||||||
const stat_t* srcFileStat,
|
const stat_t* srcFileStat,
|
||||||
@@ -1840,8 +2101,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||||||
int transferStat = 0;
|
int transferStat = 0;
|
||||||
int dstFd = -1;
|
int dstFd = -1;
|
||||||
|
|
||||||
assert(AIO_ReadPool_getFile(ress.readCtx) != NULL);
|
if (ress->io.dstFile == NULL) {
|
||||||
if (AIO_WritePool_getFile(ress.writeCtx) == NULL) {
|
|
||||||
int dstFileInitialPermissions = DEFAULT_FILE_PERMISSIONS;
|
int dstFileInitialPermissions = DEFAULT_FILE_PERMISSIONS;
|
||||||
if ( strcmp (srcFileName, stdinmark)
|
if ( strcmp (srcFileName, stdinmark)
|
||||||
&& strcmp (dstFileName, stdoutmark)
|
&& strcmp (dstFileName, stdoutmark)
|
||||||
@@ -1852,15 +2112,13 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||||||
|
|
||||||
closeDstFile = 1;
|
closeDstFile = 1;
|
||||||
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s \n", dstFileName);
|
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s \n", dstFileName);
|
||||||
{ FILE *dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFileInitialPermissions);
|
{
|
||||||
|
FILE *dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFileInitialPermissions);
|
||||||
if (dstFile==NULL) return 1; /* could not open dstFileName */
|
if (dstFile==NULL) return 1; /* could not open dstFileName */
|
||||||
dstFd = fileno(dstFile);
|
dstFd = fileno(dstFile);
|
||||||
AIO_WritePool_setFile(ress.writeCtx, dstFile);
|
FIO_SyncCompressIO_setDst(&ress->io, dstFile);
|
||||||
}
|
}
|
||||||
/* Must only be added after FIO_openDstFile() succeeds.
|
/* Must only be added after FIO_openDstFile() succeeds. */
|
||||||
* Otherwise we may delete the destination file if it already exists,
|
|
||||||
* and the user presses Ctrl-C when asked if they wish to overwrite.
|
|
||||||
*/
|
|
||||||
addHandler(dstFileName);
|
addHandler(dstFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1874,7 +2132,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: closing dst: %s \n", dstFileName);
|
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: closing dst: %s \n", dstFileName);
|
||||||
if (AIO_WritePool_closeFile(ress.writeCtx)) { /* error closing file */
|
if (FIO_SyncCompressIO_closeDst(&ress->io)) { /* error closing file */
|
||||||
DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
|
DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
|
||||||
result=1;
|
result=1;
|
||||||
}
|
}
|
||||||
@@ -1883,10 +2141,9 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||||||
UTIL_utime(dstFileName, srcFileStat);
|
UTIL_utime(dstFileName, srcFileStat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (result != 0) /* operation failure */
|
if ( (result != 0)
|
||||||
&& strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */
|
&& strcmp(dstFileName, stdoutmark) ) {
|
||||||
) {
|
FIO_removeFile(dstFileName);
|
||||||
FIO_removeFile(dstFileName); /* remove compression artefact; note don't do anything special if remove() fails */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2020,7 +2277,7 @@ static const char *compressedFileExtensions[] = {
|
|||||||
static int
|
static int
|
||||||
FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
||||||
FIO_prefs_t* const prefs,
|
FIO_prefs_t* const prefs,
|
||||||
cRess_t ress,
|
cRess_t* ress,
|
||||||
const char* dstFileName,
|
const char* dstFileName,
|
||||||
const char* srcFileName,
|
const char* srcFileName,
|
||||||
int compressionLevel)
|
int compressionLevel)
|
||||||
@@ -2042,7 +2299,7 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ensure src is not the same as dict (if present) */
|
/* ensure src is not the same as dict (if present) */
|
||||||
if (ress.dictFileName != NULL && UTIL_isSameFileStat(srcFileName, ress.dictFileName, &srcFileStat, &ress.dictFileStat)) {
|
if (ress->dictFileName != NULL && UTIL_isSameFileStat(srcFileName, ress->dictFileName, &srcFileStat, &ress->dictFileStat)) {
|
||||||
DISPLAYLEVEL(1, "zstd: cannot use %s as an input file and dictionary \n", srcFileName);
|
DISPLAYLEVEL(1, "zstd: cannot use %s as an input file and dictionary \n", srcFileName);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -2061,23 +2318,21 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
|||||||
srcFile = FIO_openSrcFile(prefs, srcFileName, &srcFileStat);
|
srcFile = FIO_openSrcFile(prefs, srcFileName, &srcFileStat);
|
||||||
if (srcFile == NULL) return 1; /* srcFile could not be opened */
|
if (srcFile == NULL) return 1; /* srcFile could not be opened */
|
||||||
|
|
||||||
/* Don't use AsyncIO for small files */
|
|
||||||
if (strcmp(srcFileName, stdinmark)) /* Stdin doesn't have stats */
|
if (strcmp(srcFileName, stdinmark)) /* Stdin doesn't have stats */
|
||||||
fileSize = UTIL_getFileSizeStat(&srcFileStat);
|
fileSize = UTIL_getFileSizeStat(&srcFileStat);
|
||||||
if(fileSize != UTIL_FILESIZE_UNKNOWN && fileSize < ZSTD_BLOCKSIZE_MAX * 3) {
|
(void)fileSize;
|
||||||
AIO_ReadPool_setAsync(ress.readCtx, 0);
|
|
||||||
AIO_WritePool_setAsync(ress.writeCtx, 0);
|
|
||||||
} else {
|
|
||||||
AIO_ReadPool_setAsync(ress.readCtx, 1);
|
|
||||||
AIO_WritePool_setAsync(ress.writeCtx, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
AIO_ReadPool_setFile(ress.readCtx, srcFile);
|
FIO_SyncCompressIO_setSrc(&ress->io, srcFile);
|
||||||
result = FIO_compressFilename_dstFile(
|
result = FIO_compressFilename_dstFile(
|
||||||
fCtx, prefs, ress,
|
fCtx, prefs, ress,
|
||||||
dstFileName, srcFileName,
|
dstFileName, srcFileName,
|
||||||
&srcFileStat, compressionLevel);
|
&srcFileStat, compressionLevel);
|
||||||
AIO_ReadPool_closeFile(ress.readCtx);
|
FIO_SyncCompressIO_clearSrc(&ress->io);
|
||||||
|
|
||||||
|
if (srcFile != NULL && fclose(srcFile)) {
|
||||||
|
DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ( prefs->removeSrcFile /* --rm */
|
if ( prefs->removeSrcFile /* --rm */
|
||||||
&& result == 0 /* success */
|
&& result == 0 /* success */
|
||||||
@@ -2118,7 +2373,7 @@ void FIO_displayCompressionParameters(const FIO_prefs_t* prefs)
|
|||||||
DISPLAY("%s", INDEX(sparseOptions, prefs->sparseFileSupport));
|
DISPLAY("%s", INDEX(sparseOptions, prefs->sparseFileSupport));
|
||||||
DISPLAY("%s", prefs->dictIDFlag ? "" : " --no-dictID");
|
DISPLAY("%s", prefs->dictIDFlag ? "" : " --no-dictID");
|
||||||
DISPLAY("%s", INDEX(checkSumOptions, prefs->checksumFlag));
|
DISPLAY("%s", INDEX(checkSumOptions, prefs->checksumFlag));
|
||||||
DISPLAY(" --block-size=%d", prefs->blockSize);
|
DISPLAY(" --jobsize=%d", prefs->jobSize);
|
||||||
if (prefs->adaptiveMode)
|
if (prefs->adaptiveMode)
|
||||||
DISPLAY(" --adapt=min=%d,max=%d", prefs->minAdaptLevel, prefs->maxAdaptLevel);
|
DISPLAY(" --adapt=min=%d,max=%d", prefs->minAdaptLevel, prefs->maxAdaptLevel);
|
||||||
DISPLAY("%s", INDEX(rowMatchFinderOptions, prefs->useRowMatchFinder));
|
DISPLAY("%s", INDEX(rowMatchFinderOptions, prefs->useRowMatchFinder));
|
||||||
@@ -2144,9 +2399,11 @@ int FIO_compressFilename(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs, const
|
|||||||
int compressionLevel, ZSTD_compressionParameters comprParams)
|
int compressionLevel, ZSTD_compressionParameters comprParams)
|
||||||
{
|
{
|
||||||
cRess_t ress = FIO_createCResources(prefs, dictFileName, UTIL_getFileSize(srcFileName), compressionLevel, comprParams);
|
cRess_t ress = FIO_createCResources(prefs, dictFileName, UTIL_getFileSize(srcFileName), compressionLevel, comprParams);
|
||||||
int const result = FIO_compressFilename_srcFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel);
|
int const result = FIO_compressFilename_srcFile(fCtx, prefs, &ress, dstFileName, srcFileName, compressionLevel);
|
||||||
|
|
||||||
#define DISPLAY_LEVEL_DEFAULT 2
|
#ifndef ZSTD_DISPLAY_LEVEL_DEFAULT
|
||||||
|
# define ZSTD_DISPLAY_LEVEL_DEFAULT 2
|
||||||
|
#endif
|
||||||
|
|
||||||
FIO_freeCResources(&ress);
|
FIO_freeCResources(&ress);
|
||||||
return result;
|
return result;
|
||||||
@@ -2241,13 +2498,13 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
|||||||
if (dstFile == NULL) { /* could not open outFileName */
|
if (dstFile == NULL) { /* could not open outFileName */
|
||||||
error = 1;
|
error = 1;
|
||||||
} else {
|
} else {
|
||||||
AIO_WritePool_setFile(ress.writeCtx, dstFile);
|
FIO_SyncCompressIO_setDst(&ress.io, dstFile);
|
||||||
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; ++fCtx->currFileIdx) {
|
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; ++fCtx->currFileIdx) {
|
||||||
status = FIO_compressFilename_srcFile(fCtx, prefs, ress, outFileName, inFileNamesTable[fCtx->currFileIdx], compressionLevel);
|
status = FIO_compressFilename_srcFile(fCtx, prefs, &ress, outFileName, inFileNamesTable[fCtx->currFileIdx], compressionLevel);
|
||||||
if (!status) fCtx->nbFilesProcessed++;
|
if (!status) fCtx->nbFilesProcessed++;
|
||||||
error |= status;
|
error |= status;
|
||||||
}
|
}
|
||||||
if (AIO_WritePool_closeFile(ress.writeCtx))
|
if (FIO_SyncCompressIO_closeDst(&ress.io))
|
||||||
EXM_THROW(29, "Write error (%s) : cannot properly close %s",
|
EXM_THROW(29, "Write error (%s) : cannot properly close %s",
|
||||||
strerror(errno), outFileName);
|
strerror(errno), outFileName);
|
||||||
}
|
}
|
||||||
@@ -2271,7 +2528,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
|||||||
} else {
|
} else {
|
||||||
dstFileName = FIO_determineCompressedName(srcFileName, outDirName, suffix); /* cannot fail */
|
dstFileName = FIO_determineCompressedName(srcFileName, outDirName, suffix); /* cannot fail */
|
||||||
}
|
}
|
||||||
status = FIO_compressFilename_srcFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel);
|
status = FIO_compressFilename_srcFile(fCtx, prefs, &ress, dstFileName, srcFileName, compressionLevel);
|
||||||
if (!status) fCtx->nbFilesProcessed++;
|
if (!status) fCtx->nbFilesProcessed++;
|
||||||
error |= status;
|
error |= status;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -70,7 +70,7 @@ void FIO_setAdaptiveMode(FIO_prefs_t* const prefs, int adapt);
|
|||||||
void FIO_setAdaptMin(FIO_prefs_t* const prefs, int minCLevel);
|
void FIO_setAdaptMin(FIO_prefs_t* const prefs, int minCLevel);
|
||||||
void FIO_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel);
|
void FIO_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel);
|
||||||
void FIO_setUseRowMatchFinder(FIO_prefs_t* const prefs, int useRowMatchFinder);
|
void FIO_setUseRowMatchFinder(FIO_prefs_t* const prefs, int useRowMatchFinder);
|
||||||
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize);
|
void FIO_setJobSize(FIO_prefs_t* const prefs, int jobSize);
|
||||||
void FIO_setChecksumFlag(FIO_prefs_t* const prefs, int checksumFlag);
|
void FIO_setChecksumFlag(FIO_prefs_t* const prefs, int checksumFlag);
|
||||||
void FIO_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag);
|
void FIO_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag);
|
||||||
void FIO_setLdmBucketSizeLog(FIO_prefs_t* const prefs, int ldmBucketSizeLog);
|
void FIO_setLdmBucketSizeLog(FIO_prefs_t* const prefs, int ldmBucketSizeLog);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ typedef struct FIO_prefs_s {
|
|||||||
int sparseFileSupport; /* 0: no sparse allowed; 1: auto (file yes, stdout no); 2: force sparse */
|
int sparseFileSupport; /* 0: no sparse allowed; 1: auto (file yes, stdout no); 2: force sparse */
|
||||||
int dictIDFlag;
|
int dictIDFlag;
|
||||||
int checksumFlag;
|
int checksumFlag;
|
||||||
int blockSize;
|
int jobSize;
|
||||||
int overlapLog;
|
int overlapLog;
|
||||||
int adaptiveMode;
|
int adaptiveMode;
|
||||||
int useRowMatchFinder;
|
int useRowMatchFinder;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
|| defined __x86_64__ || defined _M_X64 /* x86 64-bit */ \
|
|| defined __x86_64__ || defined _M_X64 /* x86 64-bit */ \
|
||||||
|| defined __arm64__ || defined __aarch64__ || defined __ARM64_ARCH_8__ /* ARM 64-bit */ \
|
|| defined __arm64__ || defined __aarch64__ || defined __ARM64_ARCH_8__ /* ARM 64-bit */ \
|
||||||
|| (defined __mips && (__mips == 64 || __mips == 4 || __mips == 3)) /* MIPS 64-bit */ \
|
|| (defined __mips && (__mips == 64 || __mips == 4 || __mips == 3)) /* MIPS 64-bit */ \
|
||||||
|
|| (defined(__riscv) && __riscv_xlen == 64) /* RISC-V 64-bit */ \
|
||||||
|| defined _LP64 || defined __LP64__ /* NetBSD, OpenBSD */ || defined __64BIT__ /* AIX */ || defined _ADDR64 /* Cray */ \
|
|| defined _LP64 || defined __LP64__ /* NetBSD, OpenBSD */ || defined __64BIT__ /* AIX */ || defined _ADDR64 /* Cray */ \
|
||||||
|| (defined __SIZEOF_POINTER__ && __SIZEOF_POINTER__ == 8) /* gcc */
|
|| (defined __SIZEOF_POINTER__ && __SIZEOF_POINTER__ == 8) /* gcc */
|
||||||
# if !defined(__64BIT__)
|
# if !defined(__64BIT__)
|
||||||
|
|||||||
+3
-1
@@ -28,18 +28,20 @@
|
|||||||
UTIL_time_t UTIL_getTime(void)
|
UTIL_time_t UTIL_getTime(void)
|
||||||
{
|
{
|
||||||
static LARGE_INTEGER ticksPerSecond;
|
static LARGE_INTEGER ticksPerSecond;
|
||||||
|
static double nsFactor = 1.0;
|
||||||
static int init = 0;
|
static int init = 0;
|
||||||
if (!init) {
|
if (!init) {
|
||||||
if (!QueryPerformanceFrequency(&ticksPerSecond)) {
|
if (!QueryPerformanceFrequency(&ticksPerSecond)) {
|
||||||
perror("timefn::QueryPerformanceFrequency");
|
perror("timefn::QueryPerformanceFrequency");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
nsFactor = 1000000000.0 / (double)ticksPerSecond.QuadPart;
|
||||||
init = 1;
|
init = 1;
|
||||||
}
|
}
|
||||||
{ UTIL_time_t r;
|
{ UTIL_time_t r;
|
||||||
LARGE_INTEGER x;
|
LARGE_INTEGER x;
|
||||||
QueryPerformanceCounter(&x);
|
QueryPerformanceCounter(&x);
|
||||||
r.t = (PTime)(x.QuadPart * 1000000000ULL / ticksPerSecond.QuadPart);
|
r.t = (PTime)((double)x.QuadPart * nsFactor);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+174
-86
@@ -151,7 +151,8 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg,
|
|||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Constants
|
* Constants
|
||||||
***************************************/
|
***************************************/
|
||||||
#define LIST_SIZE_INCREASE (8*1024)
|
#define KB * (1 << 10)
|
||||||
|
#define LIST_SIZE_INCREASE (8 KB)
|
||||||
#define MAX_FILE_OF_FILE_NAMES_SIZE (1<<20)*50
|
#define MAX_FILE_OF_FILE_NAMES_SIZE (1<<20)*50
|
||||||
|
|
||||||
|
|
||||||
@@ -196,6 +197,16 @@ int UTIL_stat(const char* filename, stat_t* statbuf)
|
|||||||
return UTIL_fstat(-1, filename, statbuf);
|
return UTIL_fstat(-1, filename, statbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int UTIL_isFdRegularFile(int fd)
|
||||||
|
{
|
||||||
|
stat_t statbuf;
|
||||||
|
int ret;
|
||||||
|
UTIL_TRACE_CALL("UTIL_isFdRegularFile(%d)", fd);
|
||||||
|
ret = fd >= 0 && UTIL_fstat(fd, "", &statbuf) && UTIL_isRegularFileStat(&statbuf);
|
||||||
|
UTIL_TRACE_RET(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int UTIL_isRegularFile(const char* infilename)
|
int UTIL_isRegularFile(const char* infilename)
|
||||||
{
|
{
|
||||||
stat_t statbuf;
|
stat_t statbuf;
|
||||||
@@ -448,6 +459,26 @@ int UTIL_isFIFOStat(const stat_t* statbuf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* process substitution */
|
||||||
|
int UTIL_isFileDescriptorPipe(const char* filename)
|
||||||
|
{
|
||||||
|
UTIL_TRACE_CALL("UTIL_isFileDescriptorPipe(%s)", filename);
|
||||||
|
/* Check if the filename is a /dev/fd/ path which indicates a file descriptor */
|
||||||
|
if (filename[0] == '/' && strncmp(filename, "/dev/fd/", 8) == 0) {
|
||||||
|
UTIL_TRACE_RET(1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for alternative process substitution formats on different systems */
|
||||||
|
if (filename[0] == '/' && strncmp(filename, "/proc/self/fd/", 14) == 0) {
|
||||||
|
UTIL_TRACE_RET(1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTIL_TRACE_RET(0);
|
||||||
|
return 0; /* Not recognized as a file descriptor pipe */
|
||||||
|
}
|
||||||
|
|
||||||
/* UTIL_isBlockDevStat : distinguish named pipes */
|
/* UTIL_isBlockDevStat : distinguish named pipes */
|
||||||
int UTIL_isBlockDevStat(const stat_t* statbuf)
|
int UTIL_isBlockDevStat(const stat_t* statbuf)
|
||||||
{
|
{
|
||||||
@@ -614,101 +645,157 @@ U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* condition : @file must be valid, and not have reached its end.
|
/* Read the entire content of a file into a buffer with progressive resizing */
|
||||||
* @return : length of line written into @buf, ended with `\0` instead of '\n',
|
static char* UTIL_readFileContent(FILE* inFile, size_t* totalReadPtr)
|
||||||
* or 0, if there is no new line */
|
|
||||||
static size_t readLineFromFile(char* buf, size_t len, FILE* file)
|
|
||||||
{
|
{
|
||||||
assert(!feof(file));
|
size_t bufSize = 64 KB; /* Start with a reasonable buffer size */
|
||||||
if ( fgets(buf, (int) len, file) == NULL ) return 0;
|
size_t totalRead = 0;
|
||||||
{ size_t linelen = strlen(buf);
|
size_t bytesRead = 0;
|
||||||
if (strlen(buf)==0) return 0;
|
char* buf = (char*)malloc(bufSize);
|
||||||
if (buf[linelen-1] == '\n') linelen--;
|
if (buf == NULL) return NULL;
|
||||||
buf[linelen] = '\0';
|
|
||||||
return linelen+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Conditions :
|
|
||||||
* size of @inputFileName file must be < @dstCapacity
|
|
||||||
* @dst must be initialized
|
|
||||||
* @return : nb of lines
|
|
||||||
* or -1 if there's an error
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
readLinesFromFile(void* dst, size_t dstCapacity,
|
|
||||||
const char* inputFileName)
|
|
||||||
{
|
|
||||||
int nbFiles = 0;
|
|
||||||
size_t pos = 0;
|
|
||||||
char* const buf = (char*)dst;
|
|
||||||
FILE* const inputFile = fopen(inputFileName, "r");
|
|
||||||
|
|
||||||
assert(dst != NULL);
|
/* Read the file incrementally */
|
||||||
|
while ((bytesRead = fread(buf + totalRead, 1, bufSize - totalRead - 1, inFile)) > 0) {
|
||||||
|
totalRead += bytesRead;
|
||||||
|
|
||||||
if(!inputFile) {
|
/* If buffer is nearly full, expand it */
|
||||||
if (g_utilDisplayLevel >= 1) perror("zstd:util:readLinesFromFile");
|
if (bufSize - totalRead < 1 KB) {
|
||||||
return -1;
|
if (bufSize >= MAX_FILE_OF_FILE_NAMES_SIZE) {
|
||||||
}
|
/* Too large, abort */
|
||||||
|
free(buf);
|
||||||
while ( !feof(inputFile) ) {
|
return NULL;
|
||||||
size_t const lineLength = readLineFromFile(buf+pos, dstCapacity-pos, inputFile);
|
|
||||||
if (lineLength == 0) break;
|
|
||||||
assert(pos + lineLength <= dstCapacity); /* '=' for inputFile not terminated with '\n' */
|
|
||||||
pos += lineLength;
|
|
||||||
++nbFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
CONTROL( fclose(inputFile) == 0 );
|
|
||||||
|
|
||||||
return nbFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Note: buf is not freed in case function successfully created table because filesTable->fileNames[0] = buf*/
|
|
||||||
FileNamesTable*
|
|
||||||
UTIL_createFileNamesTable_fromFileName(const char* inputFileName)
|
|
||||||
{
|
|
||||||
size_t nbFiles = 0;
|
|
||||||
char* buf;
|
|
||||||
size_t bufSize;
|
|
||||||
stat_t statbuf;
|
|
||||||
|
|
||||||
if (!UTIL_stat(inputFileName, &statbuf) || !UTIL_isRegularFileStat(&statbuf))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
{ U64 const inputFileSize = UTIL_getFileSizeStat(&statbuf);
|
|
||||||
if(inputFileSize > MAX_FILE_OF_FILE_NAMES_SIZE)
|
|
||||||
return NULL;
|
|
||||||
bufSize = (size_t)(inputFileSize + 1); /* (+1) to add '\0' at the end of last filename */
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = (char*) malloc(bufSize);
|
|
||||||
CONTROL( buf != NULL );
|
|
||||||
|
|
||||||
{ int const ret_nbFiles = readLinesFromFile(buf, bufSize, inputFileName);
|
|
||||||
|
|
||||||
if (ret_nbFiles <= 0) {
|
|
||||||
free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nbFiles = (size_t)ret_nbFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
{ const char** filenamesTable = (const char**) malloc(nbFiles * sizeof(*filenamesTable));
|
|
||||||
CONTROL(filenamesTable != NULL);
|
|
||||||
|
|
||||||
{ size_t fnb, pos = 0;
|
|
||||||
for (fnb = 0; fnb < nbFiles; fnb++) {
|
|
||||||
filenamesTable[fnb] = buf+pos;
|
|
||||||
pos += strlen(buf+pos)+1; /* +1 for the finishing `\0` */
|
|
||||||
}
|
}
|
||||||
assert(pos <= bufSize);
|
|
||||||
|
{ size_t newBufSize = bufSize * 2;
|
||||||
|
if (newBufSize > MAX_FILE_OF_FILE_NAMES_SIZE)
|
||||||
|
newBufSize = MAX_FILE_OF_FILE_NAMES_SIZE;
|
||||||
|
|
||||||
|
{ char* newBuf = (char*)realloc(buf, newBufSize);
|
||||||
|
if (newBuf == NULL) {
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = newBuf;
|
||||||
|
bufSize = newBufSize;
|
||||||
|
} } }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add null terminator to the end */
|
||||||
|
buf[totalRead] = '\0';
|
||||||
|
*totalReadPtr = totalRead;
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process a buffer containing multiple lines and count the number of lines */
|
||||||
|
static size_t UTIL_processLines(char* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
size_t lineCount = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
/* Convert newlines to null terminators and count lines */
|
||||||
|
while (i < bufferSize) {
|
||||||
|
if (buffer[i] == '\n') {
|
||||||
|
buffer[i] = '\0'; /* Replace newlines with null terminators */
|
||||||
|
lineCount++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count the last line if it doesn't end with a newline */
|
||||||
|
if (bufferSize > 0 && (i == 0 || buffer[i-1] != '\0')) {
|
||||||
|
lineCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create an array of pointers to the lines in a buffer */
|
||||||
|
static const char** UTIL_createLinePointers(char* buffer, size_t numLines, size_t bufferSize)
|
||||||
|
{
|
||||||
|
size_t lineIndex = 0;
|
||||||
|
size_t pos = 0;
|
||||||
|
void* const bufferPtrs = malloc(numLines * sizeof(const char**));
|
||||||
|
const char** const linePointers = (const char**)bufferPtrs;
|
||||||
|
if (bufferPtrs == NULL) return NULL;
|
||||||
|
|
||||||
|
while (lineIndex < numLines && pos < bufferSize) {
|
||||||
|
size_t len = 0;
|
||||||
|
linePointers[lineIndex++] = buffer+pos;
|
||||||
|
|
||||||
|
/* Find the next null terminator, being careful not to go past the buffer */
|
||||||
|
while ((pos + len < bufferSize) && buffer[pos + len] != '\0') {
|
||||||
|
len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return UTIL_assembleFileNamesTable(filenamesTable, nbFiles, buf);
|
/* Move past this string and its null terminator */
|
||||||
|
pos += len;
|
||||||
|
if (pos < bufferSize) pos++; /* Skip the null terminator if we're not at buffer end */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify we processed the expected number of lines */
|
||||||
|
if (lineIndex != numLines) {
|
||||||
|
/* Something went wrong - we didn't find as many lines as expected */
|
||||||
|
free(bufferPtrs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return linePointers;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNamesTable*
|
||||||
|
UTIL_createFileNamesTable_fromFileList(const char* fileList)
|
||||||
|
{
|
||||||
|
stat_t statbuf;
|
||||||
|
char* buffer = NULL;
|
||||||
|
size_t numLines = 0;
|
||||||
|
size_t bufferSize = 0;
|
||||||
|
|
||||||
|
/* Check if the input is a valid file */
|
||||||
|
if (!UTIL_stat(fileList, &statbuf)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the input is a supported type */
|
||||||
|
if (!UTIL_isRegularFileStat(&statbuf) &&
|
||||||
|
!UTIL_isFIFOStat(&statbuf) &&
|
||||||
|
!UTIL_isFileDescriptorPipe(fileList)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the input file */
|
||||||
|
{ FILE* const inFile = fopen(fileList, "rb");
|
||||||
|
if (inFile == NULL) return NULL;
|
||||||
|
|
||||||
|
/* Read the file content */
|
||||||
|
buffer = UTIL_readFileContent(inFile, &bufferSize);
|
||||||
|
fclose(inFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer == NULL) return NULL;
|
||||||
|
|
||||||
|
/* Process lines */
|
||||||
|
numLines = UTIL_processLines(buffer, bufferSize);
|
||||||
|
if (numLines == 0) {
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create line pointers */
|
||||||
|
{ const char** linePointers = UTIL_createLinePointers(buffer, numLines, bufferSize);
|
||||||
|
if (linePointers == NULL) {
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the final table */
|
||||||
|
return UTIL_assembleFileNamesTable(linePointers, numLines, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static FileNamesTable*
|
static FileNamesTable*
|
||||||
UTIL_assembleFileNamesTable2(const char** filenames, size_t tableSize, size_t tableCapacity, char* buf)
|
UTIL_assembleFileNamesTable2(const char** filenames, size_t tableSize, size_t tableCapacity, char* buf)
|
||||||
{
|
{
|
||||||
@@ -841,6 +928,7 @@ static int UTIL_prepareFileList(const char* dirName,
|
|||||||
hFile=FindFirstFileA(path, &cFile);
|
hFile=FindFirstFileA(path, &cFile);
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
UTIL_DISPLAYLEVEL(1, "Cannot open directory '%s'\n", dirName);
|
UTIL_DISPLAYLEVEL(1, "Cannot open directory '%s'\n", dirName);
|
||||||
|
free(path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
|
|||||||
+4
-2
@@ -184,6 +184,7 @@ int UTIL_fchmod(const int fd, char const* filename, const stat_t* statbuf, mode_
|
|||||||
* compute the needed information.
|
* compute the needed information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int UTIL_isFdRegularFile(int fd);
|
||||||
int UTIL_isRegularFile(const char* infilename);
|
int UTIL_isRegularFile(const char* infilename);
|
||||||
int UTIL_isDirectory(const char* infilename);
|
int UTIL_isDirectory(const char* infilename);
|
||||||
int UTIL_isSameFile(const char* file1, const char* file2);
|
int UTIL_isSameFile(const char* file1, const char* file2);
|
||||||
@@ -191,6 +192,7 @@ int UTIL_isSameFileStat(const char* file1, const char* file2, const stat_t* file
|
|||||||
int UTIL_isCompressedFile(const char* infilename, const char *extensionList[]);
|
int UTIL_isCompressedFile(const char* infilename, const char *extensionList[]);
|
||||||
int UTIL_isLink(const char* infilename);
|
int UTIL_isLink(const char* infilename);
|
||||||
int UTIL_isFIFO(const char* infilename);
|
int UTIL_isFIFO(const char* infilename);
|
||||||
|
int UTIL_isFileDescriptorPipe(const char* filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns with the given file descriptor is a console.
|
* Returns with the given file descriptor is a console.
|
||||||
@@ -250,13 +252,13 @@ typedef struct
|
|||||||
size_t tableCapacity;
|
size_t tableCapacity;
|
||||||
} FileNamesTable;
|
} FileNamesTable;
|
||||||
|
|
||||||
/*! UTIL_createFileNamesTable_fromFileName() :
|
/*! UTIL_createFileNamesTable_fromFileList() :
|
||||||
* read filenames from @inputFileName, and store them into returned object.
|
* read filenames from @inputFileName, and store them into returned object.
|
||||||
* @return : a FileNamesTable*, or NULL in case of error (ex: @inputFileName doesn't exist).
|
* @return : a FileNamesTable*, or NULL in case of error (ex: @inputFileName doesn't exist).
|
||||||
* Note: inputFileSize must be less than 50MB
|
* Note: inputFileSize must be less than 50MB
|
||||||
*/
|
*/
|
||||||
FileNamesTable*
|
FileNamesTable*
|
||||||
UTIL_createFileNamesTable_fromFileName(const char* inputFileName);
|
UTIL_createFileNamesTable_fromFileList(const char* inputFileName);
|
||||||
|
|
||||||
/*! UTIL_assembleFileNamesTable() :
|
/*! UTIL_assembleFileNamesTable() :
|
||||||
* This function takes ownership of its arguments, @filenames and @buf,
|
* This function takes ownership of its arguments, @filenames and @buf,
|
||||||
|
|||||||
+241
-53
@@ -1,392 +1,580 @@
|
|||||||
.TH "ZSTD" "1" "October 2024" "zstd 1.5.6" "User Commands"
|
.
|
||||||
|
.TH "ZSTD" "1" "February 2025" "zstd 1.5.7" "User Commands"
|
||||||
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
|
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
|
||||||
|
.
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.TS
|
\fBzstd\fR [\fIOPTIONS\fR] [\-|\fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR]
|
||||||
allbox;
|
.
|
||||||
\fBzstd\fR [\fIOPTIONS\fR] [\- \fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR]
|
|
||||||
.TE
|
|
||||||
.P
|
.P
|
||||||
\fBzstdmt\fR is equivalent to \fBzstd \-T0\fR
|
\fBzstdmt\fR is equivalent to \fBzstd \-T0\fR
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBunzstd\fR is equivalent to \fBzstd \-d\fR
|
\fBunzstd\fR is equivalent to \fBzstd \-d\fR
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR
|
\fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR
|
||||||
|
.
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
\fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip\fR(1) and \fBxz\fR(1)\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core, which remains roughly stable at all compression settings\.
|
\fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip\fR(1) and \fBxz\fR(1)\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core, which remains roughly stable at all compression settings\.
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBzstd\fR command line syntax is generally similar to gzip, but features the following few differences:
|
\fBzstd\fR command line syntax is generally similar to gzip, but features the following few differences:
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
Source files are preserved by default\. It's possible to remove them automatically by using the \fB\-\-rm\fR command\.
|
Source files are preserved by default\. It\'s possible to remove them automatically by using the \fB\-\-rm\fR command\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
When compressing a single file, \fBzstd\fR displays progress notifications and result summary by default\. Use \fB\-q\fR to turn them off\.
|
When compressing a single file, \fBzstd\fR displays progress notifications and result summary by default\. Use \fB\-q\fR to turn them off\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fBzstd\fR displays a short help page when command line is an error\. Use \fB\-q\fR to turn it off\.
|
\fBzstd\fR displays a short help page when command line is an error\. Use \fB\-q\fR to turn it off\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fBzstd\fR does not accept input from console, though it does accept \fBstdin\fR when it's not the console\.
|
\fBzstd\fR does not accept input from console, though it does accept \fBstdin\fR when it\'s not the console\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fBzstd\fR does not store the input's filename or attributes, only its contents\.
|
\fBzstd\fR does not store the input\'s filename or attributes, only its contents\.
|
||||||
|
.
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBzstd\fR processes each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal: it will display an error message and skip the file\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\.
|
\fBzstd\fR processes each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal: it will display an error message and skip the file\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\.
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name:
|
Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name:
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
When compressing, the suffix \fB\.zst\fR is appended to the source filename to get the target filename\.
|
When compressing, the suffix \fB\.zst\fR is appended to the source filename to get the target filename\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
When decompressing, the \fB\.zst\fR suffix is removed from the source filename to get the target filename
|
When decompressing, the \fB\.zst\fR suffix is removed from the source filename to get the target filename
|
||||||
|
.
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
|
.
|
||||||
.SS "Concatenation with \.zst Files"
|
.SS "Concatenation with \.zst Files"
|
||||||
It is possible to concatenate multiple \fB\.zst\fR files\. \fBzstd\fR will decompress such agglomerated file as if it was a single \fB\.zst\fR file\.
|
It is possible to concatenate multiple \fB\.zst\fR files\. \fBzstd\fR will decompress such agglomerated file as if it was a single \fB\.zst\fR file\.
|
||||||
|
.
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
|
.
|
||||||
.SS "Integer Suffixes and Special Values"
|
.SS "Integer Suffixes and Special Values"
|
||||||
In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\.
|
In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBKiB\fR
|
\fBKiB\fR
|
||||||
Multiply the integer by 1,024 (2\e^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\.
|
Multiply the integer by 1,024 (2^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBMiB\fR
|
\fBMiB\fR
|
||||||
Multiply the integer by 1,048,576 (2\e^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\.
|
Multiply the integer by 1,048,576 (2^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\.
|
||||||
|
.
|
||||||
.SS "Operation Mode"
|
.SS "Operation Mode"
|
||||||
If multiple operation mode options are given, the last one takes effect\.
|
If multiple operation mode options are given, the last one takes effect\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-z\fR, \fB\-\-compress\fR
|
\fB\-z\fR, \fB\-\-compress\fR
|
||||||
Compress\. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, \fBunzstd\fR implies \fB\-\-decompress\fR)\.
|
Compress\. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, \fBunzstd\fR implies \fB\-\-decompress\fR)\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-d\fR, \fB\-\-decompress\fR, \fB\-\-uncompress\fR
|
\fB\-d\fR, \fB\-\-decompress\fR, \fB\-\-uncompress\fR
|
||||||
Decompress\.
|
Decompress\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-t\fR, \fB\-\-test\fR
|
\fB\-t\fR, \fB\-\-test\fR
|
||||||
Test the integrity of compressed \fIfiles\fR\. This option is equivalent to \fB\-\-decompress \-\-stdout > /dev/null\fR, decompressed data is discarded and checksummed for errors\. No files are created or removed\.
|
Test the integrity of compressed \fIfiles\fR\. This option is equivalent to \fB\-\-decompress \-\-stdout > /dev/null\fR, decompressed data is discarded and checksummed for errors\. No files are created or removed\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-b#\fR
|
\fB\-b#\fR
|
||||||
Benchmark file(s) using compression level \fI#\fR\. See \fIBENCHMARK\fR below for a description of this operation\.
|
Benchmark file(s) using compression level \fI#\fR\. See \fIBENCHMARK\fR below for a description of this operation\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-train FILES\fR
|
\fB\-\-train FILES\fR
|
||||||
Use \fIFILES\fR as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. See \fIDICTIONARY BUILDER\fR below for a description of this operation\.
|
Use \fIFILES\fR as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. See \fIDICTIONARY BUILDER\fR below for a description of this operation\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-l\fR, \fB\-\-list\fR
|
\fB\-l\fR, \fB\-\-list\fR
|
||||||
Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command's output can be augmented with the \fB\-v\fR modifier\.
|
Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command\'s output can be augmented with the \fB\-v\fR modifier\.
|
||||||
|
.
|
||||||
.SS "Operation Modifiers"
|
.SS "Operation Modifiers"
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-#\fR: selects \fB#\fR compression level [1\-19] (default: 3)\. Higher compression levels \fIgenerally\fR produce higher compression ratio at the expense of speed and memory\. A rough rule of thumb is that compression speed is expected to be divided by 2 every 2 levels\. Technically, each level is mapped to a set of advanced parameters (that can also be modified individually, see below)\. Because the compressor's behavior highly depends on the content to compress, there's no guarantee of a smooth progression from one level to another\.
|
\fB\-#\fR: selects \fB#\fR compression level [1\-19] (default: 3)\. Higher compression levels \fIgenerally\fR produce higher compression ratio at the expense of speed and memory\. A rough rule of thumb is that compression speed is expected to be divided by 2 every 2 levels\. Technically, each level is mapped to a set of advanced parameters (that can also be modified individually, see below)\. Because the compressor\'s behavior highly depends on the content to compress, there\'s no guarantee of a smooth progression from one level to another\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\.
|
\fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\.
|
\fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
|
\fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: between 1 and 4 depending on physical CPU cores; see \fBZSTD_NBTHREADS\fR below)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-single\-thread\fR: Use a single thread for both I/O and compression\. As compression is serialized with I/O, this can be slightly slower\. Single\-thread mode features significantly lower memory usage, which can be useful for systems with limited amount of memory, such as 32\-bit systems\.
|
\fB\-\-single\-thread\fR: Use a single thread for both I/O and compression\. As compression is serialized with I/O, this can be slightly slower\. Single\-thread mode features significantly lower memory usage, which can be useful for systems with limited amount of memory, such as 32\-bit systems\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note 1: this mode is the only available one when multithread support is disabled\.
|
Note 1: this mode is the only available one when multithread support is disabled\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note 2: this mode is different from \fB\-T1\fR, which spawns 1 compression thread in parallel with I/O\. Final compressed result is also slightly different from \fB\-T1\fR\.
|
Note 2: this mode is different from \fB\-T1\fR, which spawns 1 compression thread in parallel with I/O\. Final compressed result is also slightly different from \fB\-T1\fR\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\.
|
\fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-adapt[=min=#,max=#]\fR: \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MiB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\.
|
\fB\-\-adapt[=min=#,max=#]\fR: \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MiB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fINote\fR: at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\.
|
\fINote\fR: at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\.
|
\fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\.
|
Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\.
|
||||||
|
.
|
||||||
|
.IP "\(bu" 4
|
||||||
|
\fB\-\-max\fR: set advanced parameters to maximum compression\. warning: this setting is very slow and uses a lot of resources\. It\'s inappropriate for 32\-bit mode and therefore disabled in this mode\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s)
|
\fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s)
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd's diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that \fIwindowSize\fR > \fIsrcSize\fR\.
|
\fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd\'s diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that \fIwindowSize\fR > \fIsrcSize\fR\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note: cannot use both this and \fB\-D\fR together\.
|
Note: cannot use both this and \fB\-D\fR together\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note: \fB\-\-long\fR mode will be automatically activated if \fIchainLog\fR < \fIfileLog\fR (\fIfileLog\fR being the \fIwindowLog\fR required to cover the whole file)\. You can also manually force it\.
|
Note: \fB\-\-long\fR mode will be automatically activated if \fIchainLog\fR < \fIfileLog\fR (\fIfileLog\fR being the \fIwindowLog\fR required to cover the whole file)\. You can also manually force it\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note: up to level 15, you can use \fB\-\-patch\-from\fR in \fB\-\-single\-thread\fR mode to improve compression ratio marginally at the cost of speed\. Using '\-\-single\-thread' above level 15 will lead to lower compression ratios\.
|
Note: up to level 15, you can use \fB\-\-patch\-from\fR in \fB\-\-single\-thread\fR mode to improve compression ratio marginally at the cost of speed\. Using \'\-\-single\-thread\' above level 15 will lead to lower compression ratios\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e\. 4096), and by setting a large \fB\-\-zstd=chainLog=\fR\.
|
Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e\. 4096), and by setting a large \fB\-\-zstd=chainLog=\fR\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-rsyncable\fR: \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and a potential impact to compression speed, perceptible at higher speeds, for example when combining \fB\-\-rsyncable\fR with many parallel worker threads\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don't want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\.
|
\fB\-\-rsyncable\fR: \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and a potential impact to compression speed, perceptible at higher speeds, for example when combining \fB\-\-rsyncable\fR with many parallel worker threads\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled)
|
\fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled)
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \fB\-\-content\-size\fR (meaning that the original size will be placed in the header)\.
|
\fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \fB\-\-content\-size\fR (meaning that the original size will be placed in the header)\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won't be able to check if it's correct\.
|
\fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won\'t be able to check if it\'s correct\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, \fBzstd\fR uses 128 MiB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (i\.e\. you can increase or decrease it)\.
|
\fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, \fBzstd\fR uses 128 MiB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (i\.e\. you can increase or decrease it)\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
This is also used during compression when using with \fB\-\-patch\-from=\fR\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MiB)\.
|
This is also used during compression when using with \fB\-\-patch\-from=\fR\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MiB)\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Additionally, this can be used to limit memory for dictionary training\. This parameter overrides the default limit of 2 GiB\. zstd will load training samples up to the memory limit and ignore the rest\.
|
Additionally, this can be used to limit memory for dictionary training\. This parameter overrides the default limit of 2 GiB\. zstd will load training samples up to the memory limit and ignore the rest\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-stream\-size=#\fR: Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\.
|
\fB\-\-stream\-size=#\fR: Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\.
|
\fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-target\-compressed\-block\-size=#\fR: Attempt to produce compressed blocks of approximately this size\. This will split larger blocks in order to approach this target\. This feature is notably useful for improved latency, when the receiver can leverage receiving early incomplete data\. This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller\. Enabling this feature can decrease compression speed by up to ~10% at level 1\. Higher levels will see smaller relative speed regression, becoming invisible at higher settings\.
|
\fB\-\-target\-compressed\-block\-size=#\fR: Attempt to produce compressed blocks of approximately this size\. This will split larger blocks in order to approach this target\. This feature is notably useful for improved latency, when the receiver can leverage receiving early incomplete data\. This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller\. Enabling this feature can decrease compression speed by up to ~10% at level 1\. Higher levels will see smaller relative speed regression, becoming invisible at higher settings\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. During decompression and when the output destination is stdout, pass\-through unrecognized formats as\-is\.
|
\fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. During decompression and when the output destination is stdout, pass\-through unrecognized formats as\-is\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-c\fR, \fB\-\-stdout\fR: write to standard output (even if it is the console); keep original files (disable \fB\-\-rm\fR)\.
|
\fB\-c\fR, \fB\-\-stdout\fR: write to standard output (even if it is the console); keep original files (disable \fB\-\-rm\fR)\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-o FILE\fR: save result into \fBFILE\fR\. Note that this operation is in conflict with \fB\-c\fR\. If both operations are present on the command line, the last expressed one wins\.
|
\fB\-o FILE\fR: save result into \fBFILE\fR\. Note that this operation is in conflict with \fB\-c\fR\. If both operations are present on the command line, the last expressed one wins\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\.
|
\fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-[no\-]pass\-through\fR enable / disable passing through uncompressed files as\-is\. During decompression when pass\-through is enabled, unrecognized formats will be copied as\-is from the input to the output\. By default, pass\-through will occur when the output destination is stdout and the force (\fB\-f\fR) option is set\.
|
\fB\-\-[no\-]pass\-through\fR enable / disable passing through uncompressed files as\-is\. During decompression when pass\-through is enabled, unrecognized formats will be copied as\-is from the input to the output\. By default, pass\-through will occur when the output destination is stdout and the force (\fB\-f\fR) option is set\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. This command is silently ignored if output is \fBstdout\fR\. If used in combination with \fB\-o\fR, triggers a confirmation prompt (which can be silenced with \fB\-f\fR), as this is a destructive operation\.
|
\fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. This command is silently ignored if output is \fBstdout\fR\. If used in combination with \fB\-o\fR, triggers a confirmation prompt (which can be silenced with \fB\-f\fR), as this is a destructive operation\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\.
|
\fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-r\fR: operate recursively on directories\. It selects all files in the named directory and all its subdirectories\. This can be useful both to reduce command line typing, and to circumvent shell expansion limitations, when there are a lot of files and naming breaks the maximum size of a command line\.
|
\fB\-r\fR: operate recursively on directories\. It selects all files in the named directory and all its subdirectories\. This can be useful both to reduce command line typing, and to circumvent shell expansion limitations, when there are a lot of files and naming breaks the maximum size of a command line\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-filelist FILE\fR read a list of files to process as content from \fBFILE\fR\. Format is compatible with \fBls\fR output, with one file per line\.
|
\fB\-\-filelist FILE\fR read a list of files to process as content from \fBFILE\fR\. Format is compatible with \fBls\fR output, with one file per line\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-output\-dir\-flat DIR\fR: resulting files are stored into target \fBDIR\fR directory, instead of same directory as origin file\. Be aware that this command can introduce name collision issues, if multiple files, from different directories, end up having the same name\. Collision resolution ensures first file with a given name will be present in \fBDIR\fR, while in combination with \fB\-f\fR, the last file will be present instead\.
|
\fB\-\-output\-dir\-flat DIR\fR: resulting files are stored into target \fBDIR\fR directory, instead of same directory as origin file\. Be aware that this command can introduce name collision issues, if multiple files, from different directories, end up having the same name\. Collision resolution ensures first file with a given name will be present in \fBDIR\fR, while in combination with \fB\-f\fR, the last file will be present instead\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-output\-dir\-mirror DIR\fR: similar to \fB\-\-output\-dir\-flat\fR, the output files are stored underneath target \fBDIR\fR directory, but this option will replicate input directory hierarchy into output \fBDIR\fR\.
|
\fB\-\-output\-dir\-mirror DIR\fR: similar to \fB\-\-output\-dir\-flat\fR, the output files are stored underneath target \fBDIR\fR directory, but this option will replicate input directory hierarchy into output \fBDIR\fR\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
If input directory contains "\.\.", the files in this directory will be ignored\. If input directory is an absolute directory (i\.e\. "/var/tmp/abc"), it will be stored into the "output\-dir/var/tmp/abc"\. If there are multiple input files or directories, name collision resolution will follow the same rules as \fB\-\-output\-dir\-flat\fR\.
|
If input directory contains "\.\.", the files in this directory will be ignored\. If input directory is an absolute directory (i\.e\. "/var/tmp/abc"), it will be stored into the "output\-dir/var/tmp/abc"\. If there are multiple input files or directories, name collision resolution will follow the same rules as \fB\-\-output\-dir\-flat\fR\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-format=FORMAT\fR: compress and decompress in other formats\. If compiled with support, zstd can compress to or decompress from other compression algorithm formats\. Possibly available options are \fBzstd\fR, \fBgzip\fR, \fBxz\fR, \fBlzma\fR, and \fBlz4\fR\. If no such format is provided, \fBzstd\fR is the default\.
|
\fB\-\-format=FORMAT\fR: compress and decompress in other formats\. If compiled with support, zstd can compress to or decompress from other compression algorithm formats\. Possibly available options are \fBzstd\fR, \fBgzip\fR, \fBxz\fR, \fBlzma\fR, and \fBlz4\fR\. If no such format is provided, \fBzstd\fR is the default\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit
|
\fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-V\fR, \fB\-\-version\fR: display version number and immediately exit\. note that, since it exits, flags specified after \fB\-V\fR are effectively ignored\. Advanced: \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-qV\fR will only display the version number, suitable for machine reading\.
|
\fB\-V\fR, \fB\-\-version\fR: display version number and immediately exit\. note that, since it exits, flags specified after \fB\-V\fR are effectively ignored\. Advanced: \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-qV\fR will only display the version number, suitable for machine reading\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information
|
\fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-q\fR, \fB\-\-quiet\fR: suppress warnings, interactivity, and notifications\. specify twice to suppress errors too\.
|
\fB\-q\fR, \fB\-\-quiet\fR: suppress warnings, interactivity, and notifications\. specify twice to suppress errors too\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\.
|
\fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-show\-default\-cparams\fR: shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size\. If the provided file is not a regular file (e\.g\. a pipe), this flag will output the parameters used for inputs of unknown size\.
|
\fB\-\-show\-default\-cparams\fR: shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size\. If the provided file is not a regular file (e\.g\. a pipe), this flag will output the parameters used for inputs of unknown size\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-exclude\-compressed\fR: only compress files that are not already compressed\.
|
\fB\-\-exclude\-compressed\fR: only compress files that are not already compressed\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files
|
\fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files
|
||||||
|
.
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
|
.
|
||||||
.SS "gzip Operation Modifiers"
|
.SS "gzip Operation Modifiers"
|
||||||
When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior:
|
When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior:
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-n\fR, \fB\-\-no\-name\fR
|
\fB\-n\fR, \fB\-\-no\-name\fR
|
||||||
do not store the original filename and timestamps when compressing a file\. This is the default behavior and hence a no\-op\.
|
do not store the original filename and timestamps when compressing a file\. This is the default behavior and hence a no\-op\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-best\fR
|
\fB\-\-best\fR
|
||||||
alias to the option \fB\-9\fR\.
|
alias to the option \fB\-9\fR\.
|
||||||
|
.
|
||||||
.SS "Environment Variables"
|
.SS "Environment Variables"
|
||||||
Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the default compression level and number of threads to use during compression, respectively\.
|
Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the default compression level and number of threads to use during compression, respectively\.
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\.
|
\fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\.
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of (\fB1\fR), and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this variable to have any effect\.
|
\fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of \fBmax(1, min(4, nbCores/4))\fR, and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this variable to have any effect\.
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
They can both be overridden by corresponding command line arguments: \fB\-#\fR for compression level and \fB\-T#\fR for number of compression threads\.
|
They can both be overridden by corresponding command line arguments: \fB\-#\fR for compression level and \fB\-T#\fR for number of compression threads\.
|
||||||
|
.
|
||||||
.SH "ADVANCED COMPRESSION OPTIONS"
|
.SH "ADVANCED COMPRESSION OPTIONS"
|
||||||
\fBzstd\fR provides 22 predefined regular compression levels plus the fast levels\. A compression level is translated internally into multiple advanced parameters that control the behavior of the compressor (one can observe the result of this translation with \fB\-\-show\-default\-cparams\fR)\. These advanced parameters can be overridden using advanced compression options\.
|
\fBzstd\fR provides 22 predefined regular compression levels plus the fast levels\. A compression level is translated internally into multiple advanced parameters that control the behavior of the compressor (one can observe the result of this translation with \fB\-\-show\-default\-cparams\fR)\. These advanced parameters can be overridden using advanced compression options\.
|
||||||
|
.
|
||||||
.SS "\-\-zstd[=options]:"
|
.SS "\-\-zstd[=options]:"
|
||||||
The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR:
|
The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR:
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR
|
\fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR
|
||||||
Specify a strategy used by a match finder\.
|
Specify a strategy used by a match finder\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
There are 9 strategies numbered from 1 to 9, from fastest to strongest: 1=\fBZSTD_fast\fR, 2=\fBZSTD_dfast\fR, 3=\fBZSTD_greedy\fR, 4=\fBZSTD_lazy\fR, 5=\fBZSTD_lazy2\fR, 6=\fBZSTD_btlazy2\fR, 7=\fBZSTD_btopt\fR, 8=\fBZSTD_btultra\fR, 9=\fBZSTD_btultra2\fR\.
|
There are 9 strategies numbered from 1 to 9, from fastest to strongest: 1=\fBZSTD_fast\fR, 2=\fBZSTD_dfast\fR, 3=\fBZSTD_greedy\fR, 4=\fBZSTD_lazy\fR, 5=\fBZSTD_lazy2\fR, 6=\fBZSTD_btlazy2\fR, 7=\fBZSTD_btopt\fR, 8=\fBZSTD_btultra\fR, 9=\fBZSTD_btultra2\fR\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR
|
\fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR
|
||||||
Specify the maximum number of bits for a match distance\.
|
Specify the maximum number of bits for a match distance\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The higher number of increases the chance to find a match which usually improves compression ratio\. It also increases memory requirements for the compressor and decompressor\. The minimum \fIwlog\fR is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32\-bit platforms and 31 (2 GiB) on 64\-bit platforms\.
|
The higher number of increases the chance to find a match which usually improves compression ratio\. It also increases memory requirements for the compressor and decompressor\. The minimum \fIwlog\fR is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32\-bit platforms and 31 (2 GiB) on 64\-bit platforms\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\.
|
Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBhashLog\fR=\fIhlog\fR, \fBhlog\fR=\fIhlog\fR
|
\fBhashLog\fR=\fIhlog\fR, \fBhlog\fR=\fIhlog\fR
|
||||||
Specify the maximum number of bits for a hash table\.
|
Specify the maximum number of bits for a hash table\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Bigger hash tables cause fewer collisions which usually makes compression faster, but requires more memory during compression\.
|
Bigger hash tables cause fewer collisions which usually makes compression faster, but requires more memory during compression\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The minimum \fIhlog\fR is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB)\.
|
The minimum \fIhlog\fR is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB)\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR
|
\fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR
|
||||||
Specify the maximum number of bits for the secondary search structure, whose form depends on the selected \fBstrategy\fR\.
|
Specify the maximum number of bits for the secondary search structure, whose form depends on the selected \fBstrategy\fR\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the \fBZSTD_fast\fR \fBstrategy\fR, which only has the primary hash table\.
|
Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the \fBZSTD_fast\fR \fBstrategy\fR, which only has the primary hash table\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The minimum \fIclog\fR is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32\-bit platforms and 30 (1B entries / 4 GiB) on 64\-bit platforms\.
|
The minimum \fIclog\fR is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32\-bit platforms and 30 (1B entries / 4 GiB) on 64\-bit platforms\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR
|
\fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR
|
||||||
Specify the maximum number of searches in a hash chain or a binary tree using logarithmic scale\.
|
Specify the maximum number of searches in a hash chain or a binary tree using logarithmic scale\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
More searches increases the chance to find a match which usually increases compression ratio but decreases compression speed\.
|
More searches increases the chance to find a match which usually increases compression ratio but decreases compression speed\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The minimum \fIslog\fR is 1 and the maximum is 'windowLog' \- 1\.
|
The minimum \fIslog\fR is 1 and the maximum is \'windowLog\' \- 1\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBminMatch\fR=\fImml\fR, \fBmml\fR=\fImml\fR
|
\fBminMatch\fR=\fImml\fR, \fBmml\fR=\fImml\fR
|
||||||
Specify the minimum searched length of a match in a hash table\.
|
Specify the minimum searched length of a match in a hash table\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Larger search lengths usually decrease compression ratio but improve decompression speed\.
|
Larger search lengths usually decrease compression ratio but improve decompression speed\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The minimum \fImml\fR is 3 and the maximum is 7\.
|
The minimum \fImml\fR is 3 and the maximum is 7\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBtargetLength\fR=\fItlen\fR, \fBtlen\fR=\fItlen\fR
|
\fBtargetLength\fR=\fItlen\fR, \fBtlen\fR=\fItlen\fR
|
||||||
The impact of this field vary depending on selected strategy\.
|
The impact of this field vary depending on selected strategy\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
For \fBZSTD_btopt\fR, \fBZSTD_btultra\fR and \fBZSTD_btultra2\fR, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\.
|
For \fBZSTD_btopt\fR, \fBZSTD_btultra\fR and \fBZSTD_btultra2\fR, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
For \fBZSTD_fast\fR, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed: a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\.
|
For \fBZSTD_fast\fR, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed: a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
For all other strategies, this field has no impact\.
|
For all other strategies, this field has no impact\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The minimum \fItlen\fR is 0 and the maximum is 128 KiB\.
|
The minimum \fItlen\fR is 0 and the maximum is 128 KiB\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR
|
\fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR
|
||||||
Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\.
|
Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default": \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\.
|
The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default": \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\.
|
||||||
.TP
|
.
|
||||||
\fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR
|
|
||||||
Specify the maximum size for a hash table used for long distance matching\.
|
|
||||||
.IP
|
|
||||||
This option is ignored unless long distance matching is enabled\.
|
|
||||||
.IP
|
|
||||||
Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\.
|
|
||||||
.IP
|
|
||||||
The minimum \fIlhlog\fR is 6 and the maximum is 30 (default: 20)\.
|
|
||||||
.TP
|
|
||||||
\fBldmMinMatch\fR=\fIlmml\fR, \fBlmml\fR=\fIlmml\fR
|
|
||||||
Specify the minimum searched length of a match for long distance matching\.
|
|
||||||
.IP
|
|
||||||
This option is ignored unless long distance matching is enabled\.
|
|
||||||
.IP
|
|
||||||
Larger/very small values usually decrease compression ratio\.
|
|
||||||
.IP
|
|
||||||
The minimum \fIlmml\fR is 4 and the maximum is 4096 (default: 64)\.
|
|
||||||
.TP
|
|
||||||
\fBldmBucketSizeLog\fR=\fIlblog\fR, \fBlblog\fR=\fIlblog\fR
|
|
||||||
Specify the size of each bucket for the hash table used for long distance matching\.
|
|
||||||
.IP
|
|
||||||
This option is ignored unless long distance matching is enabled\.
|
|
||||||
.IP
|
|
||||||
Larger bucket sizes improve collision resolution but decrease compression speed\.
|
|
||||||
.IP
|
|
||||||
The minimum \fIlblog\fR is 1 and the maximum is 8 (default: 3)\.
|
|
||||||
.TP
|
.TP
|
||||||
\fBldmHashRateLog\fR=\fIlhrlog\fR, \fBlhrlog\fR=\fIlhrlog\fR
|
\fBldmHashRateLog\fR=\fIlhrlog\fR, \fBlhrlog\fR=\fIlhrlog\fR
|
||||||
Specify the frequency of inserting entries into the long distance matching hash table\.
|
Specify the frequency of inserting entries into the long distance matching hash table\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
This option is ignored unless long distance matching is enabled\.
|
This option is ignored unless long distance matching is enabled\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\.
|
Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
The default value is \fBwlog \- lhlog\fR\.
|
The default value varies between 4 and 7, depending on \fBstrategy\fR\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR
|
||||||
|
Specify the maximum size for a hash table used for long distance matching\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
This option is ignored unless long distance matching is enabled\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
The minimum \fIlhlog\fR is 6 and the maximum is 30 (default: \fBwindowLog \- ldmHashRateLog\fR)\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBldmMinMatch\fR=\fIlmml\fR, \fBlmml\fR=\fIlmml\fR
|
||||||
|
Specify the minimum searched length of a match for long distance matching\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
This option is ignored unless long distance matching is enabled\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
Larger/very small values usually decrease compression ratio\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
The minimum \fIlmml\fR is 4 and the maximum is 4096 (default: 32 to 64, depending on \fBstrategy\fR)\.
|
||||||
|
.
|
||||||
|
.TP
|
||||||
|
\fBldmBucketSizeLog\fR=\fIlblog\fR, \fBlblog\fR=\fIlblog\fR
|
||||||
|
Specify the size of each bucket for the hash table used for long distance matching\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
This option is ignored unless long distance matching is enabled\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
Larger bucket sizes improve collision resolution but decrease compression speed\.
|
||||||
|
.
|
||||||
|
.IP
|
||||||
|
The minimum \fIlblog\fR is 1 and the maximum is 8 (default: 4 to 8, depending on \fBstrategy\fR)\.
|
||||||
|
.
|
||||||
.SS "Example"
|
.SS "Example"
|
||||||
The following parameters sets advanced compression options to something similar to predefined level 19 for files bigger than 256 KB:
|
The following parameters sets advanced compression options to something similar to predefined level 19 for files bigger than 256 KB:
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
|
\fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
|
||||||
|
.
|
||||||
.SS "\-B#:"
|
.SS "\-B#:"
|
||||||
Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\.
|
Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\.
|
||||||
|
.
|
||||||
.SH "DICTIONARY BUILDER"
|
.SH "DICTIONARY BUILDER"
|
||||||
\fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It's possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then, during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\.
|
\fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It\'s possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then, during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-train FILEs\fR
|
\fB\-\-train FILEs\fR
|
||||||
Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\.
|
Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KiB of these samples will be used for training\.
|
Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KiB of these samples will be used for training\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\.
|
\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-o FILE\fR
|
\fB\-o FILE\fR
|
||||||
Dictionary saved into \fBFILE\fR (default name: dictionary)\.
|
Dictionary saved into \fBFILE\fR (default name: dictionary)\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-maxdict=#\fR
|
\fB\-\-maxdict=#\fR
|
||||||
Limit dictionary to specified size (default: 112640 bytes)\. As usual, quantities are expressed in bytes by default, and it's possible to employ suffixes (like \fBKB\fR or \fBMB\fR) to specify larger values\.
|
Limit dictionary to specified size (default: 112640 bytes)\. As usual, quantities are expressed in bytes by default, and it\'s possible to employ suffixes (like \fBKB\fR or \fBMB\fR) to specify larger values\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-#\fR
|
\fB\-#\fR
|
||||||
Use \fB#\fR compression level during training (optional)\. Will generate statistics more tuned for selected compression level, resulting in a \fIsmall\fR compression ratio improvement for this level\.
|
Use \fB#\fR compression level during training (optional)\. Will generate statistics more tuned for selected compression level, resulting in a \fIsmall\fR compression ratio improvement for this level\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-B#\fR
|
\fB\-B#\fR
|
||||||
Split input files into blocks of size # (default: no split)
|
Split input files into blocks of size # (default: no split)
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-M#\fR, \fB\-\-memory=#\fR
|
\fB\-M#\fR, \fB\-\-memory=#\fR
|
||||||
Limit the amount of sample data loaded for training (default: 2 GB)\. Note that the default (2 GB) is also the maximum\. This parameter can be useful in situations where the training set size is not well controlled and could be potentially very large\. Since speed of the training process is directly correlated to the size of the training sample set, a smaller sample set leads to faster training\.
|
Limit the amount of sample data loaded for training (default: 2 GB)\. Note that the default (2 GB) is also the maximum\. This parameter can be useful in situations where the training set size is not well controlled and could be potentially very large\. Since speed of the training process is directly correlated to the size of the training sample set, a smaller sample set leads to faster training\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
In situations where the training set is larger than maximum memory, the CLI will randomly select samples among the available ones, up to the maximum allowed memory budget\. This is meant to improve dictionary relevance by mitigating the potential impact of clustering, such as selecting only files from the beginning of a list sorted by modification date, or sorted by alphabetical order\. The randomization process is deterministic, so training of the same list of files with the same parameters will lead to the creation of the same dictionary\.
|
In situations where the training set is larger than maximum memory, the CLI will randomly select samples among the available ones, up to the maximum allowed memory budget\. This is meant to improve dictionary relevance by mitigating the potential impact of clustering, such as selecting only files from the beginning of a list sorted by modification date, or sorted by alphabetical order\. The randomization process is deterministic, so training of the same list of files with the same parameters will lead to the creation of the same dictionary\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-dictID=#\fR
|
\fB\-\-dictID=#\fR
|
||||||
A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It's possible to provide an explicit number ID instead\. It's up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage: an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\.
|
A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It\'s possible to provide an explicit number ID instead\. It\'s up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage: an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2\e^31, so they should not be used in public\.
|
Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2^31, so they should not be used in public\.
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR
|
\fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR
|
||||||
Select parameters for the default dictionary builder algorithm named cover\. If \fId\fR is not specified, then it tries \fId\fR = 6 and \fId\fR = 8\. If \fIk\fR is not specified, then it tries \fIsteps\fR values in the range [50, 2000]\. If \fIsteps\fR is not specified, then the default value of 40 is used\. If \fIsplit\fR is not specified or split <= 0, then the default value of 100 is used\. Requires that \fId\fR <= \fIk\fR\. If \fIshrink\fR flag is not used, then the default value for \fIshrinkDict\fR of 0 is used\. If \fIshrink\fR is not specified, then the default value for \fIshrinkDictMaxRegression\fR of 1 is used\.
|
Select parameters for the default dictionary builder algorithm named cover\. If \fId\fR is not specified, then it tries \fId\fR = 6 and \fId\fR = 8\. If \fIk\fR is not specified, then it tries \fIsteps\fR values in the range [50, 2000]\. If \fIsteps\fR is not specified, then the default value of 40 is used\. If \fIsplit\fR is not specified or split <= 0, then the default value of 100 is used\. Requires that \fId\fR <= \fIk\fR\. If \fIshrink\fR flag is not used, then the default value for \fIshrinkDict\fR of 0 is used\. If \fIshrink\fR is not specified, then the default value for \fIshrinkDictMaxRegression\fR of 1 is used\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Selects segments of size \fIk\fR with highest score to put in the dictionary\. The score of a segment is computed by the sum of the frequencies of all the subsegments of size \fId\fR\. Generally \fId\fR should be in the range [6, 8], occasionally up to 16, but the algorithm will run faster with d <= \fI8\fR\. Good values for \fIk\fR vary widely based on the input data, but a safe range is [2 * \fId\fR, 2000]\. If \fIsplit\fR is 100, all input samples are used for both training and testing to find optimal \fId\fR and \fIk\fR to build dictionary\. Supports multithreading if \fBzstd\fR is compiled with threading support\. Having \fIshrink\fR enabled takes a truncated dictionary of minimum size and doubles in size until compression ratio of the truncated dictionary is at most \fIshrinkDictMaxRegression%\fR worse than the compression ratio of the largest dictionary\.
|
Selects segments of size \fIk\fR with highest score to put in the dictionary\. The score of a segment is computed by the sum of the frequencies of all the subsegments of size \fId\fR\. Generally \fId\fR should be in the range [6, 8], occasionally up to 16, but the algorithm will run faster with d <= \fI8\fR\. Good values for \fIk\fR vary widely based on the input data, but a safe range is [2 * \fId\fR, 2000]\. If \fIsplit\fR is 100, all input samples are used for both training and testing to find optimal \fId\fR and \fIk\fR to build dictionary\. Supports multithreading if \fBzstd\fR is compiled with threading support\. Having \fIshrink\fR enabled takes a truncated dictionary of minimum size and doubles in size until compression ratio of the truncated dictionary is at most \fIshrinkDictMaxRegression%\fR worse than the compression ratio of the largest dictionary\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Examples:
|
Examples:
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover FILEs\fR
|
\fBzstd \-\-train\-cover FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover=k=50,d=8 FILEs\fR
|
\fBzstd \-\-train\-cover=k=50,d=8 FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover=d=8,steps=500 FILEs\fR
|
\fBzstd \-\-train\-cover=d=8,steps=500 FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover=k=50 FILEs\fR
|
\fBzstd \-\-train\-cover=k=50 FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover=k=50,split=60 FILEs\fR
|
\fBzstd \-\-train\-cover=k=50,split=60 FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover=shrink FILEs\fR
|
\fBzstd \-\-train\-cover=shrink FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-cover=shrink=2 FILEs\fR
|
\fBzstd \-\-train\-cover=shrink=2 FILEs\fR
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-train\-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]\fR
|
\fB\-\-train\-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]\fR
|
||||||
Same as cover but with extra parameters \fIf\fR and \fIaccel\fR and different default value of split If \fIsplit\fR is not specified, then it tries \fIsplit\fR = 75\. If \fIf\fR is not specified, then it tries \fIf\fR = 20\. Requires that 0 < \fIf\fR < 32\. If \fIaccel\fR is not specified, then it tries \fIaccel\fR = 1\. Requires that 0 < \fIaccel\fR <= 10\. Requires that \fId\fR = 6 or \fId\fR = 8\.
|
Same as cover but with extra parameters \fIf\fR and \fIaccel\fR and different default value of split If \fIsplit\fR is not specified, then it tries \fIsplit\fR = 75\. If \fIf\fR is not specified, then it tries \fIf\fR = 20\. Requires that 0 < \fIf\fR < 32\. If \fIaccel\fR is not specified, then it tries \fIaccel\fR = 1\. Requires that 0 < \fIaccel\fR <= 10\. Requires that \fId\fR = 6 or \fId\fR = 8\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fIf\fR is log of size of array that keeps track of frequency of subsegments of size \fId\fR\. The subsegment is hashed to an index in the range [0,2^\fIf\fR \- 1]\. It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency\. Using a higher \fIf\fR reduces collision but takes longer\.
|
\fIf\fR is log of size of array that keeps track of frequency of subsegments of size \fId\fR\. The subsegment is hashed to an index in the range [0,2^\fIf\fR \- 1]\. It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency\. Using a higher \fIf\fR reduces collision but takes longer\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Examples:
|
Examples:
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-fastcover FILEs\fR
|
\fBzstd \-\-train\-fastcover FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-fastcover=d=8,f=15,accel=2 FILEs\fR
|
\fBzstd \-\-train\-fastcover=d=8,f=15,accel=2 FILEs\fR
|
||||||
|
.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-train\-legacy[=selectivity=#]\fR
|
\fB\-\-train\-legacy[=selectivity=#]\fR
|
||||||
Use legacy dictionary builder algorithm with the given dictionary \fIselectivity\fR (default: 9)\. The smaller the \fIselectivity\fR value, the denser the dictionary, improving its efficiency but reducing its achievable maximum size\. \fB\-\-train\-legacy=s=#\fR is also accepted\.
|
Use legacy dictionary builder algorithm with the given dictionary \fIselectivity\fR (default: 9)\. The smaller the \fIselectivity\fR value, the denser the dictionary, improving its efficiency but reducing its achievable maximum size\. \fB\-\-train\-legacy=s=#\fR is also accepted\.
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
Examples:
|
Examples:
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-legacy FILEs\fR
|
\fBzstd \-\-train\-legacy FILEs\fR
|
||||||
|
.
|
||||||
.IP
|
.IP
|
||||||
\fBzstd \-\-train\-legacy=selectivity=8 FILEs\fR
|
\fBzstd \-\-train\-legacy=selectivity=8 FILEs\fR
|
||||||
|
.
|
||||||
.SH "BENCHMARK"
|
.SH "BENCHMARK"
|
||||||
The \fBzstd\fR CLI provides a benchmarking mode that can be used to easily find suitable compression parameters, or alternatively to benchmark a computer's performance\. \fBzstd \-b [FILE(s)]\fR will benchmark \fBzstd\fR for both compression and decompression using default compression level\. Note that results are very dependent on the content being compressed\. It's possible to pass multiple files to the benchmark, and even a directory with \fB\-r DIRECTORY\fR\. When no \fBFILE\fR is provided, the benchmark will use a procedurally generated \fBlorem ipsum\fR text\.
|
The \fBzstd\fR CLI provides a benchmarking mode that can be used to easily find suitable compression parameters, or alternatively to benchmark a computer\'s performance\. \fBzstd \-b [FILE(s)]\fR will benchmark \fBzstd\fR for both compression and decompression using default compression level\. Note that results are very dependent on the content being compressed\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
It\'s possible to pass multiple files to the benchmark, and even a directory with \fB\-r DIRECTORY\fR\. When no \fBFILE\fR is provided, the benchmark will use a procedurally generated \fBlorem ipsum\fR text\.
|
||||||
|
.
|
||||||
|
.P
|
||||||
|
Benchmarking will employ \fBmax(1, min(4, nbCores/4))\fR worker threads by default in order to match the behavior of the normal CLI I/O\.
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-b#\fR: benchmark file(s) using compression level #
|
\fB\-b#\fR: benchmark file(s) using compression level #
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-e#\fR: benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\fR (inclusive)
|
\fB\-e#\fR: benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\fR (inclusive)
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-d\fR: benchmark decompression speed only (requires providing a zstd\-compressed content)
|
\fB\-d\fR: benchmark decompression speed only (requires providing a zstd\-compressed content)
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-i#\fR: minimum evaluation time, in seconds (default: 3s), benchmark mode only
|
\fB\-i#\fR: minimum evaluation time, in seconds (default: 3s), benchmark mode only
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-B#\fR, \fB\-\-block\-size=#\fR: cut file(s) into independent chunks of size # (default: no chunking)
|
\fB\-B#\fR, \fB\-\-block\-size=#\fR: cut file(s) into independent chunks of size # (default: no chunking)
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-S\fR: output one benchmark result per input file (default: consolidated result)
|
\fB\-S\fR: output one benchmark result per input file (default: consolidated result)
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-D dictionary\fR benchmark using dictionary
|
\fB\-D dictionary\fR benchmark using dictionary
|
||||||
|
.
|
||||||
.IP "\(bu" 4
|
.IP "\(bu" 4
|
||||||
\fB\-\-priority=rt\fR: set process priority to real\-time (Windows)
|
\fB\-\-priority=rt\fR: set process priority to real\-time (Windows)
|
||||||
|
.
|
||||||
.IP "" 0
|
.IP "" 0
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
Beyond compression levels, benchmarking is also compatible with other parameters, such as number of threads (\fB\-T#\fR), advanced compression parameters (\fB\-\-zstd=###\fR), dictionary compression (\fB\-D dictionary\fR), or even disabling checksum verification for example\.
|
Beyond compression levels, benchmarking is also compatible with other parameters, such as number of threads (\fB\-T#\fR), advanced compression parameters (\fB\-\-zstd=###\fR), dictionary compression (\fB\-D dictionary\fR), or even disabling checksum verification for example\.
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBOutput Format:\fR CompressionLevel#Filename: InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed
|
\fBOutput Format:\fR CompressionLevel#Filename: InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
\fBMethodology:\fR For speed measurement, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\.
|
\fBMethodology:\fR For speed measurement, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\.
|
||||||
|
.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
\fBzstdgrep\fR(1), \fBzstdless\fR(1), \fBgzip\fR(1), \fBxz\fR(1)
|
\fBzstdgrep\fR(1), \fBzstdless\fR(1), \fBgzip\fR(1), \fBxz\fR(1)
|
||||||
|
.
|
||||||
.P
|
.P
|
||||||
The \fIzstandard\fR format is specified in Y\. Collet, "Zstandard Compression and the 'application/zstd' Media Type", https://www\.ietf\.org/rfc/rfc8878\.txt, Internet RFC 8878 (February 2021)\.
|
The \fIzstandard\fR format is specified in Y\. Collet, "Zstandard Compression and the \'application/zstd\' Media Type", https://www\.ietf\.org/rfc/rfc8878\.txt, Internet RFC 8878 (February 2021)\.
|
||||||
|
.
|
||||||
.SH "BUGS"
|
.SH "BUGS"
|
||||||
Report bugs at: https://github\.com/facebook/zstd/issues
|
Report bugs at: https://github\.com/facebook/zstd/issues
|
||||||
|
.
|
||||||
.SH "AUTHOR"
|
.SH "AUTHOR"
|
||||||
Yann Collet
|
Yann Collet
|
||||||
|
|||||||
+16
-15
@@ -113,7 +113,11 @@ the last one takes effect.
|
|||||||
Because the compressor's behavior highly depends on the content to compress, there's no guarantee of a smooth progression from one level to another.
|
Because the compressor's behavior highly depends on the content to compress, there's no guarantee of a smooth progression from one level to another.
|
||||||
* `--ultra`:
|
* `--ultra`:
|
||||||
unlocks high compression levels 20+ (maximum 22), using a lot more memory.
|
unlocks high compression levels 20+ (maximum 22), using a lot more memory.
|
||||||
Note that decompression will also require more memory when using these levels.
|
Decompression will also need more memory when using these levels.
|
||||||
|
* `--max`:
|
||||||
|
set advanced parameters to reach maximum compression.
|
||||||
|
warning: this setting is very slow and uses a lot of resources.
|
||||||
|
It's inappropriate for 32-bit mode and therefore disabled in this mode.
|
||||||
* `--fast[=#]`:
|
* `--fast[=#]`:
|
||||||
switch to ultra-fast compression levels.
|
switch to ultra-fast compression levels.
|
||||||
If `=#` is not present, it defaults to `1`.
|
If `=#` is not present, it defaults to `1`.
|
||||||
@@ -122,11 +126,12 @@ the last one takes effect.
|
|||||||
This setting overwrites compression level if one was set previously.
|
This setting overwrites compression level if one was set previously.
|
||||||
Similarly, if a compression level is set after `--fast`, it overrides it.
|
Similarly, if a compression level is set after `--fast`, it overrides it.
|
||||||
* `-T#`, `--threads=#`:
|
* `-T#`, `--threads=#`:
|
||||||
Compress using `#` working threads (default: 1).
|
Compress using `#` working threads (default: between 1 and 4 depending on physical CPU cores; see `ZSTD_NBTHREADS` below).
|
||||||
If `#` is 0, attempt to detect and use the number of physical CPU cores.
|
If `#` is 0, attempt to detect and use the number of physical CPU cores.
|
||||||
In all cases, the nb of threads is capped to `ZSTDMT_NBWORKERS_MAX`,
|
In all cases, the nb of threads is capped to `ZSTDMT_NBWORKERS_MAX`,
|
||||||
which is either 64 in 32-bit mode, or 256 for 64-bit environments.
|
which is either 64 in 32-bit mode, or 256 for 64-bit environments.
|
||||||
This modifier does nothing if `zstd` is compiled without multithread support.
|
This modifier does nothing if `zstd` is compiled without multithread support.
|
||||||
|
Note that memory usage increases with each thread.
|
||||||
* `--single-thread`:
|
* `--single-thread`:
|
||||||
Use a single thread for both I/O and compression.
|
Use a single thread for both I/O and compression.
|
||||||
As compression is serialized with I/O, this can be slightly slower.
|
As compression is serialized with I/O, this can be slightly slower.
|
||||||
@@ -153,7 +158,7 @@ the last one takes effect.
|
|||||||
when combined with multiple worker threads (>=2).
|
when combined with multiple worker threads (>=2).
|
||||||
* `--long[=#]`:
|
* `--long[=#]`:
|
||||||
enables long distance matching with `#` `windowLog`, if `#` is not
|
enables long distance matching with `#` `windowLog`, if `#` is not
|
||||||
present it defaults to `27`.
|
present it defaults to `27`. The highest possible value is 31.
|
||||||
This increases the window size (`windowLog`) and memory usage for both the
|
This increases the window size (`windowLog`) and memory usage for both the
|
||||||
compressor and decompressor.
|
compressor and decompressor.
|
||||||
This setting is designed to improve the compression ratio for files with
|
This setting is designed to improve the compression ratio for files with
|
||||||
@@ -161,10 +166,6 @@ the last one takes effect.
|
|||||||
|
|
||||||
Note: If `windowLog` is set to larger than 27, `--long=windowLog` or
|
Note: If `windowLog` is set to larger than 27, `--long=windowLog` or
|
||||||
`--memory=windowSize` needs to be passed to the decompressor.
|
`--memory=windowSize` needs to be passed to the decompressor.
|
||||||
* `--max`:
|
|
||||||
set advanced parameters to maximum compression.
|
|
||||||
warning: this setting is very slow and uses a lot of resources.
|
|
||||||
It's inappropriate for 32-bit mode and therefore disabled in this mode.
|
|
||||||
* `-D DICT`:
|
* `-D DICT`:
|
||||||
use `DICT` as Dictionary to compress or decompress FILE(s)
|
use `DICT` as Dictionary to compress or decompress FILE(s)
|
||||||
* `--patch-from FILE`:
|
* `--patch-from FILE`:
|
||||||
@@ -503,12 +504,12 @@ similar to predefined level 19 for files bigger than 256 KB:
|
|||||||
|
|
||||||
`--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
|
`--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
|
||||||
|
|
||||||
### -B#:
|
### --jobsize=#:
|
||||||
Specify the size of each compression job.
|
Specify the size of each compression job.
|
||||||
This parameter is only available when multi-threading is enabled.
|
This parameter is only meaningful when multi-threading is enabled.
|
||||||
Each compression job is run in parallel, so this value indirectly impacts the nb of active threads.
|
Each compression job is run in parallel, so this value can indirectly impact the nb of active threads.
|
||||||
Default job size varies depending on compression level (generally `4 * windowSize`).
|
Default job size varies depending on compression level (generally `4 * windowSize`).
|
||||||
`-B#` makes it possible to manually select a custom size.
|
`--jobsize=#` makes it possible to manually select a custom size.
|
||||||
Note that job size must respect a minimum value which is enforced transparently.
|
Note that job size must respect a minimum value which is enforced transparently.
|
||||||
This minimum is either 512 KB, or `overlapSize`, whichever is largest.
|
This minimum is either 512 KB, or `overlapSize`, whichever is largest.
|
||||||
Different job sizes will lead to non-identical compressed frames.
|
Different job sizes will lead to non-identical compressed frames.
|
||||||
@@ -554,8 +555,8 @@ Compression of small files similar to the sample set will be greatly improved.
|
|||||||
Use `#` compression level during training (optional).
|
Use `#` compression level during training (optional).
|
||||||
Will generate statistics more tuned for selected compression level,
|
Will generate statistics more tuned for selected compression level,
|
||||||
resulting in a _small_ compression ratio improvement for this level.
|
resulting in a _small_ compression ratio improvement for this level.
|
||||||
* `-B#`:
|
* `--split=#`:
|
||||||
Split input files into blocks of size # (default: no split)
|
Split input files into independent chunks of size # (default: no split)
|
||||||
* `-M#`, `--memory=#`:
|
* `-M#`, `--memory=#`:
|
||||||
Limit the amount of sample data loaded for training (default: 2 GB).
|
Limit the amount of sample data loaded for training (default: 2 GB).
|
||||||
Note that the default (2 GB) is also the maximum.
|
Note that the default (2 GB) is also the maximum.
|
||||||
@@ -683,8 +684,8 @@ Benchmarking will employ `max(1, min(4, nbCores/4))` worker threads by default i
|
|||||||
benchmark decompression speed only (requires providing a zstd-compressed content)
|
benchmark decompression speed only (requires providing a zstd-compressed content)
|
||||||
* `-i#`:
|
* `-i#`:
|
||||||
minimum evaluation time, in seconds (default: 3s), benchmark mode only
|
minimum evaluation time, in seconds (default: 3s), benchmark mode only
|
||||||
* `-B#`, `--block-size=#`:
|
* `--split=#`:
|
||||||
cut file(s) into independent chunks of size # (default: no chunking)
|
split input file(s) into independent chunks of size # (default: no chunking)
|
||||||
* `-S`:
|
* `-S`:
|
||||||
output one benchmark result per input file (default: consolidated result)
|
output one benchmark result per input file (default: consolidated result)
|
||||||
* `-D dictionary`
|
* `-D dictionary`
|
||||||
|
|||||||
+132
-94
@@ -44,10 +44,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ZSTDCLI_NBTHREADS_DEFAULT
|
#ifndef ZSTDCLI_NBTHREADS_DEFAULT
|
||||||
#define ZSTDCLI_NBTHREADS_DEFAULT MAX(1, MIN(4, UTIL_countLogicalCores() / 4))
|
#define ZSTDCLI_NBTHREADS_DEFAULT (unsigned)(MAX(1, MIN(4, UTIL_countLogicalCores() / 4)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static unsigned init_nbWorkers(unsigned defaultNbWorkers);
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
* Constants
|
* Constants
|
||||||
@@ -77,7 +77,9 @@
|
|||||||
#define MB *(1 <<20)
|
#define MB *(1 <<20)
|
||||||
#define GB *(1U<<30)
|
#define GB *(1U<<30)
|
||||||
|
|
||||||
#define DISPLAY_LEVEL_DEFAULT 2
|
#ifndef ZSTD_DISPLAY_LEVEL_DEFAULT
|
||||||
|
# define ZSTD_DISPLAY_LEVEL_DEFAULT 2
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* g_defaultDictName = "dictionary";
|
static const char* g_defaultDictName = "dictionary";
|
||||||
static const unsigned g_defaultMaxDictSize = 110 KB;
|
static const unsigned g_defaultMaxDictSize = 110 KB;
|
||||||
@@ -94,6 +96,8 @@ static U32 g_ldmBucketSizeLog = LDM_PARAM_DEFAULT;
|
|||||||
|
|
||||||
|
|
||||||
#define DEFAULT_ACCEL 1
|
#define DEFAULT_ACCEL 1
|
||||||
|
#define NBWORKERS_AUTOCPU 0
|
||||||
|
#define NBWORKERS_UNSET UINT_MAX
|
||||||
|
|
||||||
typedef enum { cover, fastCover, legacy } dictType;
|
typedef enum { cover, fastCover, legacy } dictType;
|
||||||
|
|
||||||
@@ -102,7 +106,7 @@ typedef enum { cover, fastCover, legacy } dictType;
|
|||||||
**************************************/
|
**************************************/
|
||||||
#undef DISPLAYLEVEL
|
#undef DISPLAYLEVEL
|
||||||
#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
|
#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
|
||||||
static int g_displayLevel = DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
|
static int g_displayLevel = ZSTD_DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
@@ -145,8 +149,9 @@ static void usage(FILE* f, const char* programName)
|
|||||||
DISPLAY_F(f, "Usage: %s [OPTIONS...] [INPUT... | -] [-o OUTPUT]\n\n", programName);
|
DISPLAY_F(f, "Usage: %s [OPTIONS...] [INPUT... | -] [-o OUTPUT]\n\n", programName);
|
||||||
DISPLAY_F(f, "Options:\n");
|
DISPLAY_F(f, "Options:\n");
|
||||||
DISPLAY_F(f, " -o OUTPUT Write output to a single file, OUTPUT.\n");
|
DISPLAY_F(f, " -o OUTPUT Write output to a single file, OUTPUT.\n");
|
||||||
|
DISPLAY_F(f, " -c, --stdout Write to STDOUT (even if it is a console) and keep the INPUT file(s).\n");
|
||||||
DISPLAY_F(f, " -k, --keep Preserve INPUT file(s). [Default] \n");
|
DISPLAY_F(f, " -k, --keep Preserve INPUT file(s). [Default] \n");
|
||||||
DISPLAY_F(f, " --rm Remove INPUT file(s) after successful (de)compression.\n");
|
DISPLAY_F(f, " --rm Remove INPUT file(s) after successful (de)compression to file.\n");
|
||||||
#ifdef ZSTD_GZCOMPRESS
|
#ifdef ZSTD_GZCOMPRESS
|
||||||
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
|
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
|
||||||
DISPLAY_F(f, " -n, --no-name Do not store original filename when compressing.\n\n");
|
DISPLAY_F(f, " -n, --no-name Do not store original filename when compressing.\n\n");
|
||||||
@@ -179,7 +184,6 @@ static void usageAdvanced(const char* programName)
|
|||||||
DISPLAYOUT("\n");
|
DISPLAYOUT("\n");
|
||||||
usage(stdout, programName);
|
usage(stdout, programName);
|
||||||
DISPLAYOUT("Advanced options:\n");
|
DISPLAYOUT("Advanced options:\n");
|
||||||
DISPLAYOUT(" -c, --stdout Write to STDOUT (even if it is a console) and keep the INPUT file(s).\n\n");
|
|
||||||
|
|
||||||
DISPLAYOUT(" -v, --verbose Enable verbose output; pass multiple times to increase verbosity.\n");
|
DISPLAYOUT(" -v, --verbose Enable verbose output; pass multiple times to increase verbosity.\n");
|
||||||
DISPLAYOUT(" -q, --quiet Suppress warnings; pass twice to suppress errors.\n");
|
DISPLAYOUT(" -q, --quiet Suppress warnings; pass twice to suppress errors.\n");
|
||||||
@@ -229,14 +233,15 @@ static void usageAdvanced(const char* programName)
|
|||||||
#endif
|
#endif
|
||||||
DISPLAYOUT(" --adapt Dynamically adapt compression level to I/O conditions.\n");
|
DISPLAYOUT(" --adapt Dynamically adapt compression level to I/O conditions.\n");
|
||||||
DISPLAYOUT(" --long[=#] Enable long distance matching with window log #. [Default: %u]\n", g_defaultMaxWindowLog);
|
DISPLAYOUT(" --long[=#] Enable long distance matching with window log #. [Default: %u]\n", g_defaultMaxWindowLog);
|
||||||
DISPLAYOUT(" --patch-from=REF Use REF as the reference point for Zstandard's diff engine. \n\n");
|
DISPLAYOUT(" --patch-from=REF Use REF as the reference point for Zstandard's diff engine. \n");
|
||||||
|
DISPLAYOUT(" --patch-apply Equivalent for `-d --patch-from` \n\n");
|
||||||
# ifdef ZSTD_MULTITHREAD
|
# ifdef ZSTD_MULTITHREAD
|
||||||
DISPLAYOUT(" -T# Spawn # compression threads. [Default: 1; pass 0 for core count.]\n");
|
DISPLAYOUT(" -T# Spawn # compression threads. [Default: %u; pass 0 for core count.]\n", init_nbWorkers(ZSTDCLI_NBTHREADS_DEFAULT));
|
||||||
DISPLAYOUT(" --single-thread Share a single thread for I/O and compression (slightly different than `-T1`).\n");
|
DISPLAYOUT(" --single-thread Share a single thread for I/O and compression (slightly different than `-T1`).\n");
|
||||||
DISPLAYOUT(" --auto-threads={physical|logical}\n");
|
DISPLAYOUT(" --auto-threads={physical|logical}\n");
|
||||||
DISPLAYOUT(" Use physical/logical cores when using `-T0`. [Default: Physical]\n\n");
|
DISPLAYOUT(" Use physical/logical cores when using `-T0`. [Default: Physical]\n\n");
|
||||||
DISPLAYOUT(" -B# Set job size to #. [Default: 0 (automatic)]\n");
|
DISPLAYOUT(" --jobsize=# Set job size to #. [Default: 0 (automatic)]\n");
|
||||||
DISPLAYOUT(" --rsyncable Compress using a rsync-friendly method (`-B` sets block size). \n");
|
DISPLAYOUT(" --rsyncable Compress using a rsync-friendly method (`--jobsize=#` sets unit size). \n");
|
||||||
DISPLAYOUT("\n");
|
DISPLAYOUT("\n");
|
||||||
# endif
|
# endif
|
||||||
DISPLAYOUT(" --exclude-compressed Only compress files that are not already compressed.\n\n");
|
DISPLAYOUT(" --exclude-compressed Only compress files that are not already compressed.\n\n");
|
||||||
@@ -261,7 +266,7 @@ static void usageAdvanced(const char* programName)
|
|||||||
DISPLAYOUT(" --format=lzma Compress files to the `.lzma` format.\n");
|
DISPLAYOUT(" --format=lzma Compress files to the `.lzma` format.\n");
|
||||||
#endif
|
#endif
|
||||||
#ifdef ZSTD_LZ4COMPRESS
|
#ifdef ZSTD_LZ4COMPRESS
|
||||||
DISPLAYOUT( " --format=lz4 Compress files to the `.lz4` format.\n");
|
DISPLAYOUT( " --format=lz4 Compress files to the `.lz4` format.\n");
|
||||||
#endif
|
#endif
|
||||||
#endif /* !ZSTD_NOCOMPRESS */
|
#endif /* !ZSTD_NOCOMPRESS */
|
||||||
|
|
||||||
@@ -307,7 +312,7 @@ static void usageAdvanced(const char* programName)
|
|||||||
DISPLAYOUT(" -b# Perform benchmarking with compression level #. [Default: %d]\n", ZSTDCLI_CLEVEL_DEFAULT);
|
DISPLAYOUT(" -b# Perform benchmarking with compression level #. [Default: %d]\n", ZSTDCLI_CLEVEL_DEFAULT);
|
||||||
DISPLAYOUT(" -e# Test all compression levels up to #; starting level is `-b#`. [Default: 1]\n");
|
DISPLAYOUT(" -e# Test all compression levels up to #; starting level is `-b#`. [Default: 1]\n");
|
||||||
DISPLAYOUT(" -i# Set the minimum evaluation to time # seconds. [Default: 3]\n");
|
DISPLAYOUT(" -i# Set the minimum evaluation to time # seconds. [Default: 3]\n");
|
||||||
DISPLAYOUT(" -B# Cut file into independent chunks of size #. [Default: No chunking]\n");
|
DISPLAYOUT(" --split=# Split input into independent chunks of size #. [Default: No chunking]\n");
|
||||||
DISPLAYOUT(" -S Output one benchmark result per input file. [Default: Consolidated result]\n");
|
DISPLAYOUT(" -S Output one benchmark result per input file. [Default: Consolidated result]\n");
|
||||||
DISPLAYOUT(" -D dictionary Benchmark using dictionary \n");
|
DISPLAYOUT(" -D dictionary Benchmark using dictionary \n");
|
||||||
DISPLAYOUT(" --priority=rt Set process priority to real-time.\n");
|
DISPLAYOUT(" --priority=rt Set process priority to real-time.\n");
|
||||||
@@ -344,7 +349,7 @@ static void errorOut(const char* msg)
|
|||||||
|
|
||||||
/*! readU32FromCharChecked() :
|
/*! readU32FromCharChecked() :
|
||||||
* @return 0 if success, and store the result in *value.
|
* @return 0 if success, and store the result in *value.
|
||||||
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
|
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
|
||||||
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
* @return 1 if an overflow error occurs */
|
* @return 1 if an overflow error occurs */
|
||||||
static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
|
static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
|
||||||
@@ -359,15 +364,22 @@ static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
|
|||||||
if (result < last) return 1; /* overflow error */
|
if (result < last) return 1; /* overflow error */
|
||||||
(*stringPtr)++ ;
|
(*stringPtr)++ ;
|
||||||
}
|
}
|
||||||
if ((**stringPtr=='K') || (**stringPtr=='M')) {
|
if ((**stringPtr=='K') || (**stringPtr=='M') || (**stringPtr=='G')) {
|
||||||
unsigned const maxK = ((unsigned)(-1)) >> 10;
|
switch (**stringPtr) {
|
||||||
if (result > maxK) return 1; /* overflow error */
|
case 'K':
|
||||||
result <<= 10;
|
if (result > (((unsigned)-1) >> 10)) return 1; /* overflow error */
|
||||||
if (**stringPtr=='M') {
|
result <<= 10;
|
||||||
if (result > maxK) return 1; /* overflow error */
|
break;
|
||||||
result <<= 10;
|
case 'M':
|
||||||
|
if (result > (((unsigned)-1) >> 20)) return 1; /* overflow error */
|
||||||
|
result <<= 20;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
if (result > (((unsigned)-1) >> 30)) return 1; /* overflow error */
|
||||||
|
result <<= 30;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
(*stringPtr)++; /* skip `K` or `M` */
|
(*stringPtr)++; /* skip `K`, `M` or `G` */
|
||||||
if (**stringPtr=='i') (*stringPtr)++;
|
if (**stringPtr=='i') (*stringPtr)++;
|
||||||
if (**stringPtr=='B') (*stringPtr)++;
|
if (**stringPtr=='B') (*stringPtr)++;
|
||||||
}
|
}
|
||||||
@@ -377,7 +389,7 @@ static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
|
|||||||
|
|
||||||
/*! readU32FromChar() :
|
/*! readU32FromChar() :
|
||||||
* @return : unsigned integer value read from input in `char` format.
|
* @return : unsigned integer value read from input in `char` format.
|
||||||
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
|
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
|
||||||
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
* Note : function will exit() program if digit sequence overflows */
|
* Note : function will exit() program if digit sequence overflows */
|
||||||
static unsigned readU32FromChar(const char** stringPtr) {
|
static unsigned readU32FromChar(const char** stringPtr) {
|
||||||
@@ -389,7 +401,7 @@ static unsigned readU32FromChar(const char** stringPtr) {
|
|||||||
|
|
||||||
/*! readIntFromChar() :
|
/*! readIntFromChar() :
|
||||||
* @return : signed integer value read from input in `char` format.
|
* @return : signed integer value read from input in `char` format.
|
||||||
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
|
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
|
||||||
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
* Note : function will exit() program if digit sequence overflows */
|
* Note : function will exit() program if digit sequence overflows */
|
||||||
static int readIntFromChar(const char** stringPtr) {
|
static int readIntFromChar(const char** stringPtr) {
|
||||||
@@ -406,7 +418,7 @@ static int readIntFromChar(const char** stringPtr) {
|
|||||||
|
|
||||||
/*! readSizeTFromCharChecked() :
|
/*! readSizeTFromCharChecked() :
|
||||||
* @return 0 if success, and store the result in *value.
|
* @return 0 if success, and store the result in *value.
|
||||||
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
|
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
|
||||||
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
* @return 1 if an overflow error occurs */
|
* @return 1 if an overflow error occurs */
|
||||||
static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
|
static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
|
||||||
@@ -421,15 +433,22 @@ static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
|
|||||||
if (result < last) return 1; /* overflow error */
|
if (result < last) return 1; /* overflow error */
|
||||||
(*stringPtr)++ ;
|
(*stringPtr)++ ;
|
||||||
}
|
}
|
||||||
if ((**stringPtr=='K') || (**stringPtr=='M')) {
|
if ((**stringPtr=='K') || (**stringPtr=='M') || (**stringPtr=='G')) {
|
||||||
size_t const maxK = ((size_t)(-1)) >> 10;
|
switch (**stringPtr) {
|
||||||
if (result > maxK) return 1; /* overflow error */
|
case 'K':
|
||||||
result <<= 10;
|
if (result > (((size_t)-1) >> 10)) return 1; /* overflow error */
|
||||||
if (**stringPtr=='M') {
|
result <<= 10;
|
||||||
if (result > maxK) return 1; /* overflow error */
|
break;
|
||||||
result <<= 10;
|
case 'M':
|
||||||
|
if (result > (((size_t)-1) >> 20)) return 1; /* overflow error */
|
||||||
|
result <<= 20;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
if (result > (((size_t)-1) >> 30)) return 1; /* overflow error */
|
||||||
|
result <<= 30;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
(*stringPtr)++; /* skip `K` or `M` */
|
(*stringPtr)++; /* skip `K`, `M` or `G` */
|
||||||
if (**stringPtr=='i') (*stringPtr)++;
|
if (**stringPtr=='i') (*stringPtr)++;
|
||||||
if (**stringPtr=='B') (*stringPtr)++;
|
if (**stringPtr=='B') (*stringPtr)++;
|
||||||
}
|
}
|
||||||
@@ -439,7 +458,7 @@ static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
|
|||||||
|
|
||||||
/*! readSizeTFromChar() :
|
/*! readSizeTFromChar() :
|
||||||
* @return : size_t value read from input in `char` format.
|
* @return : size_t value read from input in `char` format.
|
||||||
* allows and interprets K, KB, KiB, M, MB and MiB suffix.
|
* allows and interprets K, KB, KiB, M, MB, MiB, G, GB and GiB suffix.
|
||||||
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
* Will also modify `*stringPtr`, advancing it to position where it stopped reading.
|
||||||
* Note : function will exit() program if digit sequence overflows */
|
* Note : function will exit() program if digit sequence overflows */
|
||||||
static size_t readSizeTFromChar(const char** stringPtr) {
|
static size_t readSizeTFromChar(const char** stringPtr) {
|
||||||
@@ -657,7 +676,7 @@ static void setMaxCompression(ZSTD_compressionParameters* params)
|
|||||||
|
|
||||||
static void printVersion(void)
|
static void printVersion(void)
|
||||||
{
|
{
|
||||||
if (g_displayLevel < DISPLAY_LEVEL_DEFAULT) {
|
if (g_displayLevel < ZSTD_DISPLAY_LEVEL_DEFAULT) {
|
||||||
DISPLAYOUT("%s\n", ZSTD_VERSION_STRING);
|
DISPLAYOUT("%s\n", ZSTD_VERSION_STRING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -685,6 +704,12 @@ static void printVersion(void)
|
|||||||
DISPLAYOUT("lz4 version %s\n", FIO_lz4Version());
|
DISPLAYOUT("lz4 version %s\n", FIO_lz4Version());
|
||||||
DISPLAYOUT("lzma version %s\n", FIO_lzmaVersion());
|
DISPLAYOUT("lzma version %s\n", FIO_lzmaVersion());
|
||||||
|
|
||||||
|
#ifdef ZSTD_MULTITHREAD
|
||||||
|
DISPLAYOUT("supports Multithreading \n");
|
||||||
|
#else
|
||||||
|
DISPLAYOUT("single-thread operations only \n");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* posix support */
|
/* posix support */
|
||||||
#ifdef _POSIX_C_SOURCE
|
#ifdef _POSIX_C_SOURCE
|
||||||
DISPLAYOUT("_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
|
DISPLAYOUT("_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
|
||||||
@@ -695,7 +720,10 @@ static void printVersion(void)
|
|||||||
#ifdef PLATFORM_POSIX_VERSION
|
#ifdef PLATFORM_POSIX_VERSION
|
||||||
DISPLAYOUT("PLATFORM_POSIX_VERSION defined: %ldL\n", (long) PLATFORM_POSIX_VERSION);
|
DISPLAYOUT("PLATFORM_POSIX_VERSION defined: %ldL\n", (long) PLATFORM_POSIX_VERSION);
|
||||||
#endif
|
#endif
|
||||||
} }
|
|
||||||
|
if (!ZSTD_isDeterministicBuild()) {
|
||||||
|
DISPLAYOUT("non-deterministic build\n");
|
||||||
|
} } }
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ZSTD_NB_STRATEGIES 9
|
#define ZSTD_NB_STRATEGIES 9
|
||||||
@@ -742,7 +770,7 @@ static void printActualCParams(const char* filename, const char* dictFileName, i
|
|||||||
|
|
||||||
/* Environment variables for parameter setting */
|
/* Environment variables for parameter setting */
|
||||||
#define ENV_CLEVEL "ZSTD_CLEVEL"
|
#define ENV_CLEVEL "ZSTD_CLEVEL"
|
||||||
#define ENV_NBTHREADS "ZSTD_NBTHREADS" /* takes lower precedence than directly specifying -T# in the CLI */
|
#define ENV_NBWORKERS "ZSTD_NBTHREADS" /* takes lower precedence than directly specifying -T# in the CLI */
|
||||||
|
|
||||||
/* pick up environment variable */
|
/* pick up environment variable */
|
||||||
static int init_cLevel(void) {
|
static int init_cLevel(void) {
|
||||||
@@ -772,26 +800,29 @@ static int init_cLevel(void) {
|
|||||||
return ZSTDCLI_CLEVEL_DEFAULT;
|
return ZSTDCLI_CLEVEL_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned init_nbWorkers(unsigned defaultNbWorkers) {
|
||||||
#ifdef ZSTD_MULTITHREAD
|
#ifdef ZSTD_MULTITHREAD
|
||||||
static unsigned default_nbThreads(void) {
|
const char* const env = getenv(ENV_NBWORKERS);
|
||||||
const char* const env = getenv(ENV_NBTHREADS);
|
|
||||||
if (env != NULL) {
|
if (env != NULL) {
|
||||||
const char* ptr = env;
|
const char* ptr = env;
|
||||||
if ((*ptr>='0') && (*ptr<='9')) {
|
if ((*ptr>='0') && (*ptr<='9')) {
|
||||||
unsigned nbThreads;
|
unsigned nbThreads;
|
||||||
if (readU32FromCharChecked(&ptr, &nbThreads)) {
|
if (readU32FromCharChecked(&ptr, &nbThreads)) {
|
||||||
DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: numeric value too large \n", ENV_NBTHREADS, env);
|
DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: numeric value too large \n", ENV_NBWORKERS, env);
|
||||||
return ZSTDCLI_NBTHREADS_DEFAULT;
|
return defaultNbWorkers;
|
||||||
} else if (*ptr == 0) {
|
} else if (*ptr == 0) {
|
||||||
return nbThreads;
|
return nbThreads;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid unsigned value \n", ENV_NBTHREADS, env);
|
DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid unsigned value \n", ENV_NBWORKERS, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZSTDCLI_NBTHREADS_DEFAULT;
|
return defaultNbWorkers;
|
||||||
}
|
#else
|
||||||
|
(void)defaultNbWorkers;
|
||||||
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#define NEXT_FIELD(ptr) { \
|
#define NEXT_FIELD(ptr) { \
|
||||||
if (*argument == '=') { \
|
if (*argument == '=') { \
|
||||||
@@ -810,22 +841,22 @@ static unsigned default_nbThreads(void) {
|
|||||||
CLEAN_RETURN(1); \
|
CLEAN_RETURN(1); \
|
||||||
} } }
|
} } }
|
||||||
|
|
||||||
#define NEXT_UINT32(val32) { \
|
#define NEXT_UINT32(_varu32) { \
|
||||||
const char* __nb; \
|
const char* __nb; \
|
||||||
NEXT_FIELD(__nb); \
|
NEXT_FIELD(__nb); \
|
||||||
val32 = readU32FromChar(&__nb); \
|
_varu32 = readU32FromChar(&__nb); \
|
||||||
if(*__nb != 0) { \
|
if(*__nb != 0) { \
|
||||||
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed"); \
|
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed"); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NEXT_TSIZE(valTsize) { \
|
#define NEXT_TSIZE(_varTsize) { \
|
||||||
const char* __nb; \
|
const char* __nb; \
|
||||||
NEXT_FIELD(__nb); \
|
NEXT_FIELD(__nb); \
|
||||||
valTsize = readSizeTFromChar(&__nb); \
|
_varTsize = readSizeTFromChar(&__nb); \
|
||||||
if(*__nb != 0) { \
|
if(*__nb != 0) { \
|
||||||
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed"); \
|
errorOut("error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed"); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom_list } zstd_operation_mode;
|
typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom_list } zstd_operation_mode;
|
||||||
@@ -862,24 +893,25 @@ int main(int argCount, const char* argv[])
|
|||||||
singleThread = 0,
|
singleThread = 0,
|
||||||
defaultLogicalCores = 0,
|
defaultLogicalCores = 0,
|
||||||
showDefaultCParams = 0,
|
showDefaultCParams = 0,
|
||||||
ultra=0,
|
contentSize = 1,
|
||||||
contentSize=1,
|
removeSrcFile = 0,
|
||||||
removeSrcFile=0;
|
cLevel = init_cLevel(),
|
||||||
ZSTD_ParamSwitch_e mmapDict=ZSTD_ps_auto;
|
ultra = 0,
|
||||||
|
cLevelLast = MINCLEVEL - 1, /* for benchmark range */
|
||||||
|
setThreads_non1 = 0;
|
||||||
|
unsigned nbWorkers = init_nbWorkers(NBWORKERS_UNSET);
|
||||||
|
ZSTD_ParamSwitch_e mmapDict = ZSTD_ps_auto;
|
||||||
ZSTD_ParamSwitch_e useRowMatchFinder = ZSTD_ps_auto;
|
ZSTD_ParamSwitch_e useRowMatchFinder = ZSTD_ps_auto;
|
||||||
FIO_compressionType_t cType = FIO_zstdCompression;
|
FIO_compressionType_t cType = FIO_zstdCompression;
|
||||||
int nbWorkers = -1; /* -1 means unset */
|
|
||||||
double compressibility = -1.0; /* lorem ipsum generator */
|
double compressibility = -1.0; /* lorem ipsum generator */
|
||||||
unsigned bench_nbSeconds = 3; /* would be better if this value was synchronized from bench */
|
unsigned bench_nbSeconds = 3; /* would be better if this value was synchronized from bench */
|
||||||
size_t blockSize = 0;
|
size_t chunkSize = 0;
|
||||||
|
|
||||||
FIO_prefs_t* const prefs = FIO_createPreferences();
|
FIO_prefs_t* const prefs = FIO_createPreferences();
|
||||||
FIO_ctx_t* const fCtx = FIO_createContext();
|
FIO_ctx_t* const fCtx = FIO_createContext();
|
||||||
FIO_progressSetting_e progress = FIO_ps_auto;
|
FIO_progressSetting_e progress = FIO_ps_auto;
|
||||||
zstd_operation_mode operation = zom_compress;
|
zstd_operation_mode operation = zom_compress;
|
||||||
ZSTD_compressionParameters compressionParams;
|
ZSTD_compressionParameters compressionParams;
|
||||||
int cLevel = init_cLevel();
|
|
||||||
int cLevelLast = MINCLEVEL - 1; /* lower than minimum */
|
|
||||||
unsigned recursive = 0;
|
unsigned recursive = 0;
|
||||||
unsigned memLimit = 0;
|
unsigned memLimit = 0;
|
||||||
FileNamesTable* filenames = UTIL_allocateFileNamesTable((size_t)argCount); /* argCount >= 1 */
|
FileNamesTable* filenames = UTIL_allocateFileNamesTable((size_t)argCount); /* argCount >= 1 */
|
||||||
@@ -918,7 +950,7 @@ int main(int argCount, const char* argv[])
|
|||||||
programName = lastNameFromPath(programName);
|
programName = lastNameFromPath(programName);
|
||||||
|
|
||||||
/* preset behaviors */
|
/* preset behaviors */
|
||||||
if (exeNameMatch(programName, ZSTD_ZSTDMT)) nbWorkers=0, singleThread=0;
|
if (exeNameMatch(programName, ZSTD_ZSTDMT)) nbWorkers=NBWORKERS_AUTOCPU, singleThread=0;
|
||||||
if (exeNameMatch(programName, ZSTD_UNZSTD)) operation=zom_decompress;
|
if (exeNameMatch(programName, ZSTD_UNZSTD)) operation=zom_decompress;
|
||||||
if (exeNameMatch(programName, ZSTD_CAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; FIO_setPassThroughFlag(prefs, 1); outFileName=stdoutmark; g_displayLevel=1; } /* supports multiple formats */
|
if (exeNameMatch(programName, ZSTD_CAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; FIO_setPassThroughFlag(prefs, 1); outFileName=stdoutmark; g_displayLevel=1; } /* supports multiple formats */
|
||||||
if (exeNameMatch(programName, ZSTD_ZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; FIO_setPassThroughFlag(prefs, 1); outFileName=stdoutmark; g_displayLevel=1; } /* behave like zcat, also supports multiple formats */
|
if (exeNameMatch(programName, ZSTD_ZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; FIO_setPassThroughFlag(prefs, 1); outFileName=stdoutmark; g_displayLevel=1; } /* behave like zcat, also supports multiple formats */
|
||||||
@@ -926,7 +958,7 @@ int main(int argCount, const char* argv[])
|
|||||||
suffix = GZ_EXTENSION; cType = FIO_gzipCompression; removeSrcFile=1;
|
suffix = GZ_EXTENSION; cType = FIO_gzipCompression; removeSrcFile=1;
|
||||||
dictCLevel = cLevel = 6; /* gzip default is -6 */
|
dictCLevel = cLevel = 6; /* gzip default is -6 */
|
||||||
}
|
}
|
||||||
if (exeNameMatch(programName, ZSTD_GUNZIP)) { operation=zom_decompress; removeSrcFile=1; } /* behave like gunzip, also supports multiple formats */
|
if (exeNameMatch(programName, ZSTD_GUNZIP)) { operation=zom_decompress; removeSrcFile=1; } /* behave like gunzip, also supports multiple formats */
|
||||||
if (exeNameMatch(programName, ZSTD_GZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; FIO_setPassThroughFlag(prefs, 1); outFileName=stdoutmark; g_displayLevel=1; } /* behave like gzcat, also supports multiple formats */
|
if (exeNameMatch(programName, ZSTD_GZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; FIO_setPassThroughFlag(prefs, 1); outFileName=stdoutmark; g_displayLevel=1; } /* behave like gzcat, also supports multiple formats */
|
||||||
if (exeNameMatch(programName, ZSTD_LZMA)) { suffix = LZMA_EXTENSION; cType = FIO_lzmaCompression; removeSrcFile=1; } /* behave like lzma */
|
if (exeNameMatch(programName, ZSTD_LZMA)) { suffix = LZMA_EXTENSION; cType = FIO_lzmaCompression; removeSrcFile=1; } /* behave like lzma */
|
||||||
if (exeNameMatch(programName, ZSTD_UNLZMA)) { operation=zom_decompress; cType = FIO_lzmaCompression; removeSrcFile=1; } /* behave like unlzma, also supports multiple formats */
|
if (exeNameMatch(programName, ZSTD_UNLZMA)) { operation=zom_decompress; cType = FIO_lzmaCompression; removeSrcFile=1; } /* behave like unlzma, also supports multiple formats */
|
||||||
@@ -1069,11 +1101,13 @@ int main(int argCount, const char* argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (longCommandWArg(&argument, "--threads")) { NEXT_UINT32(nbWorkers); continue; }
|
if (longCommandWArg(&argument, "--threads")) { NEXT_UINT32(nbWorkers); setThreads_non1 = (nbWorkers != 1); continue; }
|
||||||
if (longCommandWArg(&argument, "--memlimit")) { NEXT_UINT32(memLimit); continue; }
|
if (longCommandWArg(&argument, "--memlimit")) { NEXT_UINT32(memLimit); continue; }
|
||||||
if (longCommandWArg(&argument, "--memory")) { NEXT_UINT32(memLimit); continue; }
|
if (longCommandWArg(&argument, "--memory")) { NEXT_UINT32(memLimit); continue; }
|
||||||
if (longCommandWArg(&argument, "--memlimit-decompress")) { NEXT_UINT32(memLimit); continue; }
|
if (longCommandWArg(&argument, "--memlimit-decompress")) { NEXT_UINT32(memLimit); continue; }
|
||||||
if (longCommandWArg(&argument, "--block-size")) { NEXT_TSIZE(blockSize); continue; }
|
if (longCommandWArg(&argument, "--block-size")) { NEXT_TSIZE(chunkSize); continue; } /* hidden command, prefer --split below */
|
||||||
|
if (longCommandWArg(&argument, "--split")) { NEXT_TSIZE(chunkSize); continue; }
|
||||||
|
if (longCommandWArg(&argument, "--jobsize")) { NEXT_TSIZE(chunkSize); continue; } /* note: overloaded variable */
|
||||||
if (longCommandWArg(&argument, "--maxdict")) { NEXT_UINT32(maxDictSize); continue; }
|
if (longCommandWArg(&argument, "--maxdict")) { NEXT_UINT32(maxDictSize); continue; }
|
||||||
if (longCommandWArg(&argument, "--dictID")) { NEXT_UINT32(dictID); continue; }
|
if (longCommandWArg(&argument, "--dictID")) { NEXT_UINT32(dictID); continue; }
|
||||||
if (longCommandWArg(&argument, "--zstd=")) { if (!parseCompressionParameters(argument, &compressionParams)) { badUsage(programName, originalArgument); CLEAN_RETURN(1); } ; cType = FIO_zstdCompression; continue; }
|
if (longCommandWArg(&argument, "--zstd=")) { if (!parseCompressionParameters(argument, &compressionParams)) { badUsage(programName, originalArgument); CLEAN_RETURN(1); } ; cType = FIO_zstdCompression; continue; }
|
||||||
@@ -1109,6 +1143,7 @@ int main(int argCount, const char* argv[])
|
|||||||
if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; }
|
if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; }
|
||||||
#endif
|
#endif
|
||||||
if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); ultra = 1; continue; }
|
if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); ultra = 1; continue; }
|
||||||
|
if (longCommandWArg(&argument, "--patch-apply")) { operation=zom_decompress; NEXT_FIELD(patchFromDictFileName); memLimit= 1U << ZSTD_WINDOWLOG_MAX; continue; }
|
||||||
if (longCommandWArg(&argument, "--long")) {
|
if (longCommandWArg(&argument, "--long")) {
|
||||||
unsigned ldmWindowLog = 0;
|
unsigned ldmWindowLog = 0;
|
||||||
ldmFlag = 1;
|
ldmFlag = 1;
|
||||||
@@ -1256,10 +1291,10 @@ int main(int argCount, const char* argv[])
|
|||||||
bench_nbSeconds = readU32FromChar(&argument);
|
bench_nbSeconds = readU32FromChar(&argument);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* cut input into blocks (benchmark only) */
|
/* hidden shortcut for --split=# and --jobsize=# */
|
||||||
case 'B':
|
case 'B':
|
||||||
argument++;
|
argument++;
|
||||||
blockSize = readU32FromChar(&argument);
|
chunkSize = readU32FromChar(&argument);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* benchmark files separately (hidden option) */
|
/* benchmark files separately (hidden option) */
|
||||||
@@ -1274,6 +1309,7 @@ int main(int argCount, const char* argv[])
|
|||||||
case 'T':
|
case 'T':
|
||||||
argument++;
|
argument++;
|
||||||
nbWorkers = readU32FromChar(&argument);
|
nbWorkers = readU32FromChar(&argument);
|
||||||
|
setThreads_non1 = (nbWorkers != 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Dictionary Selection level */
|
/* Dictionary Selection level */
|
||||||
@@ -1318,11 +1354,11 @@ int main(int argCount, const char* argv[])
|
|||||||
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
DISPLAYLEVEL(3, WELCOME_MESSAGE);
|
||||||
|
|
||||||
#ifdef ZSTD_MULTITHREAD
|
#ifdef ZSTD_MULTITHREAD
|
||||||
if ((operation==zom_decompress) && (nbWorkers > 1)) {
|
if ((operation==zom_decompress) && (setThreads_non1)) {
|
||||||
DISPLAYLEVEL(2, "Warning : decompression does not support multi-threading\n");
|
DISPLAYLEVEL(2, "Warning : decompression does not support multi-threading\n");
|
||||||
}
|
}
|
||||||
if ((nbWorkers==0) && (!singleThread)) {
|
if ((nbWorkers==NBWORKERS_AUTOCPU) && (!singleThread)) {
|
||||||
/* automatically set # workers based on # of reported cpus */
|
/* automatically set # workers based on # of reported cpu cores */
|
||||||
if (defaultLogicalCores) {
|
if (defaultLogicalCores) {
|
||||||
nbWorkers = (unsigned)UTIL_countLogicalCores();
|
nbWorkers = (unsigned)UTIL_countLogicalCores();
|
||||||
DISPLAYLEVEL(3, "Note: %d logical core(s) detected \n", nbWorkers);
|
DISPLAYLEVEL(3, "Note: %d logical core(s) detected \n", nbWorkers);
|
||||||
@@ -1331,18 +1367,10 @@ int main(int argCount, const char* argv[])
|
|||||||
DISPLAYLEVEL(3, "Note: %d physical core(s) detected \n", nbWorkers);
|
DISPLAYLEVEL(3, "Note: %d physical core(s) detected \n", nbWorkers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Resolve to default if nbWorkers is still unset */
|
if (operation == zom_compress)
|
||||||
if (nbWorkers == -1) {
|
|
||||||
if (operation == zom_decompress) {
|
|
||||||
nbWorkers = 1;
|
|
||||||
} else {
|
|
||||||
nbWorkers = default_nbThreads();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (operation != zom_bench)
|
|
||||||
DISPLAYLEVEL(4, "Compressing with %u worker threads \n", nbWorkers);
|
DISPLAYLEVEL(4, "Compressing with %u worker threads \n", nbWorkers);
|
||||||
#else
|
#else
|
||||||
(void)singleThread; (void)nbWorkers; (void)defaultLogicalCores;
|
(void)singleThread; (void)nbWorkers; (void)defaultLogicalCores; (void)setThreads_non1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_utilDisplayLevel = g_displayLevel;
|
g_utilDisplayLevel = g_displayLevel;
|
||||||
@@ -1369,7 +1397,7 @@ int main(int argCount, const char* argv[])
|
|||||||
size_t const nbFileLists = file_of_names->tableSize;
|
size_t const nbFileLists = file_of_names->tableSize;
|
||||||
size_t flNb;
|
size_t flNb;
|
||||||
for (flNb=0; flNb < nbFileLists; flNb++) {
|
for (flNb=0; flNb < nbFileLists; flNb++) {
|
||||||
FileNamesTable* const fnt = UTIL_createFileNamesTable_fromFileName(file_of_names->fileNames[flNb]);
|
FileNamesTable* const fnt = UTIL_createFileNamesTable_fromFileList(file_of_names->fileNames[flNb]);
|
||||||
if (fnt==NULL) {
|
if (fnt==NULL) {
|
||||||
DISPLAYLEVEL(1, "zstd: error reading %s \n", file_of_names->fileNames[flNb]);
|
DISPLAYLEVEL(1, "zstd: error reading %s \n", file_of_names->fileNames[flNb]);
|
||||||
CLEAN_RETURN(1);
|
CLEAN_RETURN(1);
|
||||||
@@ -1400,11 +1428,14 @@ int main(int argCount, const char* argv[])
|
|||||||
/* Check if benchmark is selected */
|
/* Check if benchmark is selected */
|
||||||
if (operation==zom_bench) {
|
if (operation==zom_bench) {
|
||||||
#ifndef ZSTD_NOBENCH
|
#ifndef ZSTD_NOBENCH
|
||||||
|
int benchThreadsMsgLevel = 2;
|
||||||
|
if (nbWorkers == NBWORKERS_UNSET) nbWorkers = 1;
|
||||||
|
if (nbWorkers <= 1) benchThreadsMsgLevel = 3;
|
||||||
if (cType != FIO_zstdCompression) {
|
if (cType != FIO_zstdCompression) {
|
||||||
DISPLAYLEVEL(1, "benchmark mode is only compatible with zstd format \n");
|
DISPLAYLEVEL(1, "benchmark mode is only compatible with zstd format \n");
|
||||||
CLEAN_RETURN(1);
|
CLEAN_RETURN(1);
|
||||||
}
|
}
|
||||||
benchParams.blockSize = blockSize;
|
benchParams.chunkSizeMax = chunkSize;
|
||||||
benchParams.targetCBlockSize = targetCBlockSize;
|
benchParams.targetCBlockSize = targetCBlockSize;
|
||||||
benchParams.nbWorkers = (int)nbWorkers;
|
benchParams.nbWorkers = (int)nbWorkers;
|
||||||
benchParams.realTime = (unsigned)setRealTimePrio;
|
benchParams.realTime = (unsigned)setRealTimePrio;
|
||||||
@@ -1425,7 +1456,7 @@ int main(int argCount, const char* argv[])
|
|||||||
if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
|
if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
|
||||||
if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel();
|
if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel();
|
||||||
if (cLevelLast < cLevel) cLevelLast = cLevel;
|
if (cLevelLast < cLevel) cLevelLast = cLevel;
|
||||||
DISPLAYLEVEL(3, "Benchmarking ");
|
DISPLAYLEVEL(benchThreadsMsgLevel, "Benchmarking ");
|
||||||
if (filenames->tableSize > 1)
|
if (filenames->tableSize > 1)
|
||||||
DISPLAYLEVEL(3, "%u files ", (unsigned)filenames->tableSize);
|
DISPLAYLEVEL(3, "%u files ", (unsigned)filenames->tableSize);
|
||||||
if (cLevelLast > cLevel) {
|
if (cLevelLast > cLevel) {
|
||||||
@@ -1433,7 +1464,7 @@ int main(int argCount, const char* argv[])
|
|||||||
} else {
|
} else {
|
||||||
DISPLAYLEVEL(3, "at level %d ", cLevel);
|
DISPLAYLEVEL(3, "at level %d ", cLevel);
|
||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "using %i threads \n", nbWorkers);
|
DISPLAYLEVEL(benchThreadsMsgLevel, "using %i threads \n", nbWorkers);
|
||||||
if (filenames->tableSize > 0) {
|
if (filenames->tableSize > 0) {
|
||||||
if(separateFiles) {
|
if(separateFiles) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -1448,7 +1479,7 @@ int main(int argCount, const char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
(void)bench_nbSeconds; (void)blockSize; (void)setRealTimePrio; (void)separateFiles; (void)compressibility;
|
(void)bench_nbSeconds; (void)chunkSize; (void)setRealTimePrio; (void)separateFiles; (void)compressibility;
|
||||||
#endif
|
#endif
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
@@ -1460,22 +1491,23 @@ int main(int argCount, const char* argv[])
|
|||||||
zParams.compressionLevel = dictCLevel;
|
zParams.compressionLevel = dictCLevel;
|
||||||
zParams.notificationLevel = (unsigned)g_displayLevel;
|
zParams.notificationLevel = (unsigned)g_displayLevel;
|
||||||
zParams.dictID = dictID;
|
zParams.dictID = dictID;
|
||||||
|
if (nbWorkers == NBWORKERS_UNSET) nbWorkers = init_nbWorkers(ZSTDCLI_NBTHREADS_DEFAULT);
|
||||||
if (dict == cover) {
|
if (dict == cover) {
|
||||||
int const optimize = !coverParams.k || !coverParams.d;
|
int const optimize = !coverParams.k || !coverParams.d;
|
||||||
coverParams.nbThreads = (unsigned)nbWorkers;
|
coverParams.nbThreads = (unsigned)nbWorkers;
|
||||||
coverParams.zParams = zParams;
|
coverParams.zParams = zParams;
|
||||||
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, &coverParams, NULL, optimize, memLimit);
|
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, chunkSize, NULL, &coverParams, NULL, optimize, memLimit);
|
||||||
} else if (dict == fastCover) {
|
} else if (dict == fastCover) {
|
||||||
int const optimize = !fastCoverParams.k || !fastCoverParams.d;
|
int const optimize = !fastCoverParams.k || !fastCoverParams.d;
|
||||||
fastCoverParams.nbThreads = (unsigned)nbWorkers;
|
fastCoverParams.nbThreads = (unsigned)nbWorkers;
|
||||||
fastCoverParams.zParams = zParams;
|
fastCoverParams.zParams = zParams;
|
||||||
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, NULL, &fastCoverParams, optimize, memLimit);
|
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, chunkSize, NULL, NULL, &fastCoverParams, optimize, memLimit);
|
||||||
} else {
|
} else {
|
||||||
ZDICT_legacy_params_t dictParams;
|
ZDICT_legacy_params_t dictParams;
|
||||||
memset(&dictParams, 0, sizeof(dictParams));
|
memset(&dictParams, 0, sizeof(dictParams));
|
||||||
dictParams.selectivityLevel = dictSelect;
|
dictParams.selectivityLevel = dictSelect;
|
||||||
dictParams.zParams = zParams;
|
dictParams.zParams = zParams;
|
||||||
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, &dictParams, NULL, NULL, 0, memLimit);
|
operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, chunkSize, &dictParams, NULL, NULL, 0, memLimit);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)dictCLevel; (void)dictSelect; (void)dictID; (void)maxDictSize; /* not used when ZSTD_NODICT set */
|
(void)dictCLevel; (void)dictSelect; (void)dictID; (void)maxDictSize; /* not used when ZSTD_NODICT set */
|
||||||
@@ -1524,7 +1556,12 @@ int main(int argCount, const char* argv[])
|
|||||||
/* check compression level limits */
|
/* check compression level limits */
|
||||||
{ int const maxCLevel = ultra ? ZSTD_maxCLevel() : ZSTDCLI_CLEVEL_MAX;
|
{ int const maxCLevel = ultra ? ZSTD_maxCLevel() : ZSTDCLI_CLEVEL_MAX;
|
||||||
if (cLevel > maxCLevel) {
|
if (cLevel > maxCLevel) {
|
||||||
DISPLAYLEVEL(2, "Warning : compression level higher than max, reduced to %i \n", maxCLevel);
|
DISPLAYLEVEL(2, "Warning : compression level higher than max, reduced to %i. ", maxCLevel);
|
||||||
|
DISPLAYLEVEL(2, "Specify --ultra to raise the limit to 22 and use "
|
||||||
|
"--long=31 for maximum compression. Note that this "
|
||||||
|
"requires high amounts of memory, and the resulting data "
|
||||||
|
"might be rejected by third-party decoders and is "
|
||||||
|
"therefore only recommended for archival purposes. \n");
|
||||||
cLevel = maxCLevel;
|
cLevel = maxCLevel;
|
||||||
} }
|
} }
|
||||||
#endif
|
#endif
|
||||||
@@ -1582,8 +1619,9 @@ int main(int argCount, const char* argv[])
|
|||||||
#ifndef ZSTD_NOCOMPRESS
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
FIO_setCompressionType(prefs, cType);
|
FIO_setCompressionType(prefs, cType);
|
||||||
FIO_setContentSize(prefs, contentSize);
|
FIO_setContentSize(prefs, contentSize);
|
||||||
|
if (nbWorkers == NBWORKERS_UNSET) nbWorkers = init_nbWorkers(ZSTDCLI_NBTHREADS_DEFAULT);
|
||||||
FIO_setNbWorkers(prefs, (int)nbWorkers);
|
FIO_setNbWorkers(prefs, (int)nbWorkers);
|
||||||
FIO_setBlockSize(prefs, (int)blockSize);
|
FIO_setJobSize(prefs, (int)chunkSize);
|
||||||
if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(prefs, (int)g_overlapLog);
|
if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(prefs, (int)g_overlapLog);
|
||||||
FIO_setLdmFlag(prefs, (unsigned)ldmFlag);
|
FIO_setLdmFlag(prefs, (unsigned)ldmFlag);
|
||||||
FIO_setLdmHashLog(prefs, (int)g_ldmHashLog);
|
FIO_setLdmHashLog(prefs, (int)g_ldmHashLog);
|
||||||
|
|||||||
@@ -81,8 +81,9 @@ static void TRACE_log(char const* method, PTime duration, ZSTD_Trace const* trac
|
|||||||
{
|
{
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int workers = 0;
|
int workers = 0;
|
||||||
|
double const durationAsDouble = duration ? (double)duration : .1;
|
||||||
double const ratio = (double)trace->uncompressedSize / (double)trace->compressedSize;
|
double const ratio = (double)trace->uncompressedSize / (double)trace->compressedSize;
|
||||||
double const speed = ((double)trace->uncompressedSize * 1000) / (double)duration;
|
double const speed = ((double)trace->uncompressedSize * 1000) / durationAsDouble;
|
||||||
if (trace->params) {
|
if (trace->params) {
|
||||||
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_compressionLevel, &level);
|
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_compressionLevel, &level);
|
||||||
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_nbWorkers, &workers);
|
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_nbWorkers, &workers);
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
.
|
.
|
||||||
.TH "ZSTDGREP" "1" "March 2024" "zstd 1.5.6" "User Commands"
|
.TH "ZSTDGREP" "1" "February 2025" "zstd 1.5.7" "User Commands"
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files
|
\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
.
|
.
|
||||||
.TH "ZSTDLESS" "1" "March 2024" "zstd 1.5.6" "User Commands"
|
.TH "ZSTDLESS" "1" "February 2025" "zstd 1.5.7" "User Commands"
|
||||||
.
|
.
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
\fBzstdless\fR \- view zstandard\-compressed files
|
\fBzstdless\fR \- view zstandard\-compressed files
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ fullbench-lib
|
|||||||
fuzzer
|
fuzzer
|
||||||
fuzzer32
|
fuzzer32
|
||||||
fuzzer-dll
|
fuzzer-dll
|
||||||
|
largeDictionary
|
||||||
zbufftest
|
zbufftest
|
||||||
zbufftest32
|
zbufftest32
|
||||||
zbufftest-dll
|
zbufftest-dll
|
||||||
|
|||||||
+10
-6
@@ -20,7 +20,7 @@
|
|||||||
# zstreamtest32: Same as zstreamtest, but forced to compile in 32-bits mode
|
# zstreamtest32: Same as zstreamtest, but forced to compile in 32-bits mode
|
||||||
# ##########################################################################
|
# ##########################################################################
|
||||||
|
|
||||||
ZSTD_LEGACY_SUPPORT ?= 5
|
ZSTD_LEGACY_SUPPORT ?= 0
|
||||||
export ZSTD_LEGACY_SUPPORT
|
export ZSTD_LEGACY_SUPPORT
|
||||||
|
|
||||||
DEBUGLEVEL ?= 2
|
DEBUGLEVEL ?= 2
|
||||||
@@ -281,7 +281,7 @@ test-valgrind: VALGRIND = valgrind --leak-check=full --show-leak-kinds=all --err
|
|||||||
test-valgrind: zstd datagen fuzzer fullbench
|
test-valgrind: zstd datagen fuzzer fullbench
|
||||||
@echo "\n ---- valgrind tests : memory analyzer ----"
|
@echo "\n ---- valgrind tests : memory analyzer ----"
|
||||||
$(VALGRIND) ./datagen -g50M > $(VOID)
|
$(VALGRIND) ./datagen -g50M > $(VOID)
|
||||||
$(VALGRIND) $(PRGDIR)/zstd ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi
|
$(VALGRIND) $(PRGDIR)/zstd --fake-stdin-is-console ; if [ $$? -eq 0 ] ; then echo "zstd without argument should have failed"; false; fi
|
||||||
./datagen -g80 | $(VALGRIND) $(PRGDIR)/zstd - -c > $(VOID)
|
./datagen -g80 | $(VALGRIND) $(PRGDIR)/zstd - -c > $(VOID)
|
||||||
./datagen -g16KB | $(VALGRIND) $(PRGDIR)/zstd -vf - -c > $(VOID)
|
./datagen -g16KB | $(VALGRIND) $(PRGDIR)/zstd -vf - -c > $(VOID)
|
||||||
./datagen -g2930KB | $(VALGRIND) $(PRGDIR)/zstd -5 -vf - -o tmp
|
./datagen -g2930KB | $(VALGRIND) $(PRGDIR)/zstd -5 -vf - -o tmp
|
||||||
@@ -359,7 +359,11 @@ test-zstd test-zstd32 test-zstd-nolegacy test-zstd-dll: datagen
|
|||||||
test-cli-tests: ZSTD = $(PRGDIR)/zstd
|
test-cli-tests: ZSTD = $(PRGDIR)/zstd
|
||||||
test-cli-tests: zstd datagen
|
test-cli-tests: zstd datagen
|
||||||
file $(ZSTD)
|
file $(ZSTD)
|
||||||
./cli-tests/run.py --exec-prefix="$(QEMU_SYS)" --zstd="$(ZSTD)" --datagen=./datagen
|
./cli-tests/run.py --exec-prefix="$(QEMU_SYS)" --zstd="$(ZSTD)" --datagen=./datagen $(CLI_TEST_ARGS)
|
||||||
|
|
||||||
|
.PHONY: update-cli-tests
|
||||||
|
update-cli-tests: CLI_TEST_ARGS = --set-exact-output
|
||||||
|
update-cli-tests: test-cli-tests
|
||||||
|
|
||||||
.PHONY: test-fullbench
|
.PHONY: test-fullbench
|
||||||
test-fullbench: fullbench datagen
|
test-fullbench: fullbench datagen
|
||||||
@@ -443,9 +447,9 @@ test-decodecorpus-cli: decodecorpus
|
|||||||
test-pool: poolTests
|
test-pool: poolTests
|
||||||
$(QEMU_SYS) ./poolTests
|
$(QEMU_SYS) ./poolTests
|
||||||
|
|
||||||
test-lz4: ZSTD = LD_LIBRARY_PATH=/usr/local/lib $(PRGDIR)/zstd
|
test-lz4: ZSTD = $(PRGDIR)/zstd
|
||||||
test-lz4: ZSTD_LZ4 = LD_LIBRARY_PATH=/usr/local/lib ./lz4
|
test-lz4: ZSTD_LZ4 = ./lz4
|
||||||
test-lz4: ZSTD_UNLZ4 = LD_LIBRARY_PATH=/usr/local/lib ./unlz4
|
test-lz4: ZSTD_UNLZ4 = ./unlz4
|
||||||
test-lz4: zstd decodecorpus datagen
|
test-lz4: zstd decodecorpus datagen
|
||||||
[ -f lz4 ] || ln -s $(PRGDIR)/zstd lz4
|
[ -f lz4 ] || ln -s $(PRGDIR)/zstd lz4
|
||||||
[ -f unlz4 ] || ln -s $(PRGDIR)/zstd unlz4
|
[ -f unlz4 ] || ln -s $(PRGDIR)/zstd unlz4
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ def get_regressions_dictionary(baseline_build, test_build, filenames_directory,
|
|||||||
for j, level in enumerate(levels):
|
for j, level in enumerate(levels):
|
||||||
old_cspeed, old_dspeed = old[j]
|
old_cspeed, old_dspeed = old[j]
|
||||||
new_cspeed, new_dspeed = new[j]
|
new_cspeed, new_dspeed = new[j]
|
||||||
cspeed_reg, dspeed_reg, baesline_label, test_label = parse_regressions_and_labels(
|
cspeed_reg, dspeed_reg, baseline_label, test_label = parse_regressions_and_labels(
|
||||||
old_cspeed, new_cspeed, old_dspeed, new_dspeed, baseline_build, test_build
|
old_cspeed, new_cspeed, old_dspeed, new_dspeed, baseline_build, test_build
|
||||||
)
|
)
|
||||||
if cspeed_reg > CSPEED_REGRESSION_TOLERANCE:
|
if cspeed_reg > CSPEED_REGRESSION_TOLERANCE:
|
||||||
@@ -315,7 +315,7 @@ if __name__ == "__main__":
|
|||||||
quit()
|
quit()
|
||||||
|
|
||||||
if mode == "onetime":
|
if mode == "onetime":
|
||||||
main(filenames, levels, iterations, frequency=frequenc, dictionary_filename=dictionary_filename)
|
main(filenames, levels, iterations, frequency=frequency, dictionary_filename=dictionary_filename)
|
||||||
elif mode == "current":
|
elif mode == "current":
|
||||||
builds = [{"user": None, "branch": "None", "hash": None}]
|
builds = [{"user": None, "branch": "None", "hash": None}]
|
||||||
main(filenames, levels, iterations, builds, frequency=frequency, dictionary_filename=dictionary_filename)
|
main(filenames, levels, iterations, builds, frequency=frequency, dictionary_filename=dictionary_filename)
|
||||||
|
|||||||
-133
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under both the BSD-style license (found in the
|
|
||||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
||||||
* in the COPYING file in the root directory of this source tree).
|
|
||||||
* You may select, at your option, one of the above-listed licenses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "datagen.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#define ZSTD_STATIC_LINKING_ONLY
|
|
||||||
#include "zstd.h"
|
|
||||||
|
|
||||||
static int
|
|
||||||
compress(ZSTD_CCtx* cctx, ZSTD_DCtx* dctx,
|
|
||||||
void* dst, size_t dstCapacity,
|
|
||||||
void const* src, size_t srcSize,
|
|
||||||
void* roundtrip, ZSTD_EndDirective end)
|
|
||||||
{
|
|
||||||
ZSTD_inBuffer in = {src, srcSize, 0};
|
|
||||||
ZSTD_outBuffer out = {dst, dstCapacity, 0};
|
|
||||||
int ended = 0;
|
|
||||||
|
|
||||||
while (!ended && (in.pos < in.size || out.pos > 0)) {
|
|
||||||
size_t rc;
|
|
||||||
out.pos = 0;
|
|
||||||
rc = ZSTD_compressStream2(cctx, &out, &in, end);
|
|
||||||
if (ZSTD_isError(rc))
|
|
||||||
return 1;
|
|
||||||
if (end == ZSTD_e_end && rc == 0)
|
|
||||||
ended = 1;
|
|
||||||
{
|
|
||||||
ZSTD_inBuffer rtIn = {dst, out.pos, 0};
|
|
||||||
ZSTD_outBuffer rtOut = {roundtrip, srcSize, 0};
|
|
||||||
rc = 1;
|
|
||||||
while (rtIn.pos < rtIn.size || rtOut.pos > 0) {
|
|
||||||
rtOut.pos = 0;
|
|
||||||
rc = ZSTD_decompressStream(dctx, &rtOut, &rtIn);
|
|
||||||
if (ZSTD_isError(rc)) {
|
|
||||||
fprintf(stderr, "Decompression error: %s\n", ZSTD_getErrorName(rc));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (rc == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ended && rc != 0) {
|
|
||||||
fprintf(stderr, "Frame not finished!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char** argv)
|
|
||||||
{
|
|
||||||
ZSTD_CCtx* cctx = ZSTD_createCCtx();
|
|
||||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
|
||||||
const size_t dataSize = (size_t)1 << 30;
|
|
||||||
const size_t outSize = ZSTD_compressBound(dataSize);
|
|
||||||
const size_t bufferSize = (size_t)1 << 31;
|
|
||||||
char* buffer = (char*)malloc(bufferSize);
|
|
||||||
void* out = malloc(outSize);
|
|
||||||
void* roundtrip = malloc(dataSize);
|
|
||||||
int _exit_code = 0;
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
|
|
||||||
if (!buffer || !out || !roundtrip || !cctx || !dctx) {
|
|
||||||
fprintf(stderr, "Allocation failure\n");
|
|
||||||
_exit_code = 1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 31)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_overlapLog, 9)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, ZSTD_btopt)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, 7)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 7)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, 1)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, 10)))
|
|
||||||
return 1;
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, 10)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (ZSTD_isError(ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 31)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
RDG_genBuffer(buffer, bufferSize, 1.0, 0.0, 0xbeefcafe);
|
|
||||||
|
|
||||||
/* Compress 30 GB */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 10; ++i) {
|
|
||||||
fprintf(stderr, "Compressing 1 GB\n");
|
|
||||||
if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_continue))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(stderr, "Compressing 1 GB\n");
|
|
||||||
if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_end))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
fprintf(stderr, "Success!\n");
|
|
||||||
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
free(roundtrip);
|
|
||||||
free(out);
|
|
||||||
free(buffer);
|
|
||||||
ZSTD_freeCCtx(cctx);
|
|
||||||
ZSTD_freeDCtx(dctx);
|
|
||||||
return _exit_code;
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,9 @@ Usage: zstd *OPTIONS...* *INPUT... | -* *-o OUTPUT*
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
-o OUTPUT Write output to a single file, OUTPUT.
|
-o OUTPUT Write output to a single file, OUTPUT.
|
||||||
|
-c, --stdout Write to STDOUT (even if it is a console) and keep the INPUT file(s).
|
||||||
-k, --keep Preserve INPUT file(s). *Default*
|
-k, --keep Preserve INPUT file(s). *Default*
|
||||||
--rm Remove INPUT file(s) after successful (de)compression.
|
--rm Remove INPUT file(s) after successful (de)compression to file.
|
||||||
|
|
||||||
-# Desired compression level, where `#` is a number between 1 and 19;
|
-# Desired compression level, where `#` is a number between 1 and 19;
|
||||||
lower numbers provide faster compression, higher numbers yield
|
lower numbers provide faster compression, higher numbers yield
|
||||||
|
|||||||
@@ -35,6 +35,30 @@ rm file.zst
|
|||||||
println "+ zstd --memory=1MiB file"
|
println "+ zstd --memory=1MiB file"
|
||||||
zstd -q --memory=1MiB file && die "Should allow numeric parameter with expected suffix"
|
zstd -q --memory=1MiB file && die "Should allow numeric parameter with expected suffix"
|
||||||
rm file.zst
|
rm file.zst
|
||||||
|
println "+ zstd --memory=1G file"
|
||||||
|
zstd -q --memory=1G file && die "Should allow numeric parameter with expected suffix"
|
||||||
|
rm file.zst
|
||||||
|
println "+ zstd --memory=1GB file"
|
||||||
|
zstd -q --memory=1GB file && die "Should allow numeric parameter with expected suffix"
|
||||||
|
rm file.zst
|
||||||
|
println "+ zstd --memory=1GiB file"
|
||||||
|
zstd -q --memory=1GiB file && die "Should allow numeric parameter with expected suffix"
|
||||||
|
rm file.zst
|
||||||
|
println "+ zstd --memory=3G file"
|
||||||
|
zstd -q --memory=3G file && die "Should allow numeric parameter with expected suffix"
|
||||||
|
rm file.zst
|
||||||
|
println "+ zstd --memory=3GB file"
|
||||||
|
zstd -q --memory=3GB file && die "Should allow numeric parameter with expected suffix"
|
||||||
|
rm file.zst
|
||||||
|
println "+ zstd --memory=3GiB file"
|
||||||
|
zstd -q --memory=3GiB file && die "Should allow numeric parameter with expected suffix"
|
||||||
|
rm file.zst
|
||||||
|
println "+ zstd --memory=4G file"
|
||||||
|
zstd --memory=4G file && die "Should not allow out-of-bound numeric parameter"
|
||||||
|
println "+ zstd --memory=4GB file"
|
||||||
|
zstd --memory=4GB file && die "Should not allow out-of-bound numeric parameter"
|
||||||
|
println "+ zstd --memory=4GiB file"
|
||||||
|
zstd --memory=4GiB file && die "Should not allow out-of-bound numeric parameter"
|
||||||
|
|
||||||
rm file
|
rm file
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
|
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
|
||||||
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
|
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
|
||||||
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
|
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
|
||||||
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
|
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
|
||||||
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
|
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
|
||||||
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB are allowed
|
error: only numeric values with optional suffixes K, KB, KiB, M, MB, MiB, G, GB, GiB are allowed
|
||||||
Should allow numeric parameter without suffix
|
Should allow numeric parameter without suffix
|
||||||
Should allow numeric parameter with expected suffix
|
Should allow numeric parameter with expected suffix
|
||||||
Should allow numeric parameter with expected suffix
|
Should allow numeric parameter with expected suffix
|
||||||
@@ -11,3 +11,12 @@ Should allow numeric parameter with expected suffix
|
|||||||
Should allow numeric parameter with expected suffix
|
Should allow numeric parameter with expected suffix
|
||||||
Should allow numeric parameter with expected suffix
|
Should allow numeric parameter with expected suffix
|
||||||
Should allow numeric parameter with expected suffix
|
Should allow numeric parameter with expected suffix
|
||||||
|
Should allow numeric parameter with expected suffix
|
||||||
|
Should allow numeric parameter with expected suffix
|
||||||
|
Should allow numeric parameter with expected suffix
|
||||||
|
Should allow numeric parameter with expected suffix
|
||||||
|
Should allow numeric parameter with expected suffix
|
||||||
|
Should allow numeric parameter with expected suffix
|
||||||
|
error: numeric value overflows 32-bit unsigned int
|
||||||
|
error: numeric value overflows 32-bit unsigned int
|
||||||
|
error: numeric value overflows 32-bit unsigned int
|
||||||
|
|||||||
@@ -11,3 +11,12 @@
|
|||||||
+ zstd --memory=1M file
|
+ zstd --memory=1M file
|
||||||
+ zstd --memory=1MB file
|
+ zstd --memory=1MB file
|
||||||
+ zstd --memory=1MiB file
|
+ zstd --memory=1MiB file
|
||||||
|
+ zstd --memory=1G file
|
||||||
|
+ zstd --memory=1GB file
|
||||||
|
+ zstd --memory=1GiB file
|
||||||
|
+ zstd --memory=3G file
|
||||||
|
+ zstd --memory=3GB file
|
||||||
|
+ zstd --memory=3GiB file
|
||||||
|
+ zstd --memory=4G file
|
||||||
|
+ zstd --memory=4GB file
|
||||||
|
+ zstd --memory=4GiB file
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ case "$UNAME" in
|
|||||||
*) MD5SUM="md5sum" ;;
|
*) MD5SUM="md5sum" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
md5hash() {
|
||||||
|
$MD5SUM | dd bs=1 count=32 status=none
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
DIFF="diff"
|
DIFF="diff"
|
||||||
case "$UNAME" in
|
case "$UNAME" in
|
||||||
SunOS) DIFF="gdiff" ;;
|
SunOS) DIFF="gdiff" ;;
|
||||||
@@ -34,3 +39,9 @@ then
|
|||||||
else
|
else
|
||||||
hasMT="true"
|
hasMT="true"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if zstd -vv --version | grep -q 'non-deterministic'; then
|
||||||
|
NON_DETERMINISTIC="true"
|
||||||
|
else
|
||||||
|
NON_DETERMINISTIC=""
|
||||||
|
fi
|
||||||
|
|||||||
@@ -9,7 +9,14 @@ zstd --rsyncable -f file -q ; zstd -t file.zst
|
|||||||
zstd -T0 -f file -q ; zstd -t file.zst
|
zstd -T0 -f file -q ; zstd -t file.zst
|
||||||
zstd -T0 --auto-threads=logical -f file -q ; zstd -t file.zst
|
zstd -T0 --auto-threads=logical -f file -q ; zstd -t file.zst
|
||||||
zstd -T0 --auto-threads=physical -f file -q ; zstd -t file.zst
|
zstd -T0 --auto-threads=physical -f file -q ; zstd -t file.zst
|
||||||
|
zstd -T0 --jobsize=1M -f file -q ; zstd -t file.zst
|
||||||
|
|
||||||
# multi-thread decompression warning test
|
# multi-thread decompression warning test
|
||||||
zstd -T0 -f file -q ; zstd -t file.zst; zstd -T0 -d file.zst -o file3
|
zstd -T0 -f file -q ; zstd -t file.zst; zstd -T0 -d file.zst -o file3
|
||||||
zstd -T0 -f file -q ; zstd -t file.zst; zstd -T2 -d file.zst -o file4
|
zstd -T0 -f file -q ; zstd -t file.zst; zstd -T2 -d file.zst -o file4
|
||||||
|
# setting multi-thread via environment variable does not trigger decompression warning
|
||||||
|
zstd -T0 -f file -q ; zstd -t file.zst; ZSTD_NBTHREADS=0 zstd -df file.zst -o file3
|
||||||
|
zstd -T0 -f file -q ; zstd -t file.zst; ZSTD_NBTHREADS=2 zstd -df file.zst -o file4
|
||||||
|
# setting nbThreads==1 does not trigger decompression warning
|
||||||
|
zstd -T0 -f file -q ; zstd -t file.zst; zstd -T1 -df file.zst -o file3
|
||||||
|
zstd -T0 -f file -q ; zstd -t file.zst; zstd -T2 -T1 -df file.zst -o file4
|
||||||
|
|||||||
@@ -6,6 +6,16 @@ file.zst : 65537 bytes
|
|||||||
file.zst : 65537 bytes
|
file.zst : 65537 bytes
|
||||||
file.zst : 65537 bytes
|
file.zst : 65537 bytes
|
||||||
file.zst : 65537 bytes
|
file.zst : 65537 bytes
|
||||||
file.zst : 65537 bytes
|
|
||||||
Warning : decompression does not support multi-threading
|
Warning : decompression does not support multi-threading
|
||||||
file.zst : 65537 bytes
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
Warning : decompression does not support multi-threading
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
file.zst : 65537 bytes
|
||||||
|
|||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. "$COMMON/platform.sh"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# To update checksums on version change run this from the tests/ directory
|
||||||
|
# make update-cli-tests
|
||||||
|
|
||||||
|
if [ -n "$NON_DETERMINISTIC" ]; then
|
||||||
|
# Skip tests if we have a non-deterministic build
|
||||||
|
cat "$CLI_TESTS/determinism/basic.sh.stdout.exact"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for level in $(seq 1 19); do
|
||||||
|
for file in $(ls files/); do
|
||||||
|
file="files/$file"
|
||||||
|
echo "level $level, file $file"
|
||||||
|
zstd --single-thread -q -$level $file -c | md5hash
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
for file in $(ls files/); do
|
||||||
|
file="files/$file"
|
||||||
|
echo "level 1, long=18, file $file"
|
||||||
|
zstd --long=18 --single-thread -q -1 $file -c | md5hash
|
||||||
|
echo "level 19, long=18, file $file"
|
||||||
|
zstd --long=18 --single-thread -q -19 $file -c | md5hash
|
||||||
|
done
|
||||||
|
|
||||||
|
for file in $(ls files/); do
|
||||||
|
file="files/$file"
|
||||||
|
echo "level -1, file $file"
|
||||||
|
zstd -q --single-thread --fast=1 $file -c | md5hash
|
||||||
|
done
|
||||||
@@ -0,0 +1,880 @@
|
|||||||
|
level 1, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 1, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 1, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 1, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 1, file files/g1000
|
||||||
|
6bf2f4b179864fd8db4676037465feed
|
||||||
|
level 1, file files/g10000
|
||||||
|
2ae44c4053b2b47724c8f612dfb60d24
|
||||||
|
level 1, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 1, file files/g10000-P10
|
||||||
|
2d0eeab6a966098583a1dfeafb5090c1
|
||||||
|
level 1, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 1, file files/g10000-P25
|
||||||
|
c64b5f512c44b6a647da81753791b9a7
|
||||||
|
level 1, file files/g10000-P50
|
||||||
|
3982325490d90c8307e734c1b25790df
|
||||||
|
level 1, file files/g10000-P75
|
||||||
|
b7504f80fee16b5ba6a0f46571eb563a
|
||||||
|
level 1, file files/g10000-P90
|
||||||
|
350892bec7f7ad6a7d6af01c5d8b07c7
|
||||||
|
level 1, file files/g100000
|
||||||
|
daa38a869130494c077290cf54f2d895
|
||||||
|
level 1, file files/g1000000
|
||||||
|
a1d548531221d408b95dc5d9c600b3f0
|
||||||
|
level 1, file files/g20000
|
||||||
|
1da5b56511e8693867c0cdd962c521aa
|
||||||
|
level 1, file files/g200000
|
||||||
|
41fb3b3d46d4221f2f0b072c65dd6e0a
|
||||||
|
level 1, file files/g30000
|
||||||
|
788bc5abca5e33d79bb79a4eca98b9cd
|
||||||
|
level 1, file files/g50000
|
||||||
|
0bf9fafd84a2d56a788a9159f1f23f26
|
||||||
|
level 1, file files/g500000
|
||||||
|
73401d6df0657e091de20468f32579a9
|
||||||
|
level 2, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 2, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 2, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 2, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 2, file files/g1000
|
||||||
|
a14988fb331bc6f8b33d9eba3a0416dc
|
||||||
|
level 2, file files/g10000
|
||||||
|
a8656ebab20efa8a3fb281327aab5d58
|
||||||
|
level 2, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 2, file files/g10000-P10
|
||||||
|
9db9877242632964c232ebd4485dba07
|
||||||
|
level 2, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 2, file files/g10000-P25
|
||||||
|
d7a7223240a607fe28a2e8fd641a969d
|
||||||
|
level 2, file files/g10000-P50
|
||||||
|
86478908f9caa5ca4029454005063078
|
||||||
|
level 2, file files/g10000-P75
|
||||||
|
14f5dcdb347e87790d49c1eb99ac5069
|
||||||
|
level 2, file files/g10000-P90
|
||||||
|
05bdb42a2eeb5788d6288dc241cde12c
|
||||||
|
level 2, file files/g100000
|
||||||
|
12c6a4c50fad3e479e0f0ffe1d4df324
|
||||||
|
level 2, file files/g1000000
|
||||||
|
4f9cdc0de37b22d657fd9d3c61ec5b44
|
||||||
|
level 2, file files/g20000
|
||||||
|
1e70c3fe429c1af41e9cb8a536fb6df1
|
||||||
|
level 2, file files/g200000
|
||||||
|
bb1cc37142783345db29c3fd5838ce4e
|
||||||
|
level 2, file files/g30000
|
||||||
|
52528017fe0eec85b6c3244e6fceb4ed
|
||||||
|
level 2, file files/g50000
|
||||||
|
a38bdd671b6d3bd76b479dfc01d1c7fb
|
||||||
|
level 2, file files/g500000
|
||||||
|
cd2090a38bbd677b385238355c996c01
|
||||||
|
level 3, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 3, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 3, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 3, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 3, file files/g1000
|
||||||
|
3ec47dcb2d606b9fdef3f19b1304f8fe
|
||||||
|
level 3, file files/g10000
|
||||||
|
69a9d518b84fe2a66b57dfb4ab8905ae
|
||||||
|
level 3, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 3, file files/g10000-P10
|
||||||
|
ac9866ac355c4ed8939deb9fbeec1aef
|
||||||
|
level 3, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 3, file files/g10000-P25
|
||||||
|
5e1fe7a3831f6632bc8c9873ab8b633d
|
||||||
|
level 3, file files/g10000-P50
|
||||||
|
76295f181396a98565eb9cc69b96dc75
|
||||||
|
level 3, file files/g10000-P75
|
||||||
|
1f751dc70508e81fef197311e8583e99
|
||||||
|
level 3, file files/g10000-P90
|
||||||
|
47c7b061c299dc253c6aaaf489e936cb
|
||||||
|
level 3, file files/g100000
|
||||||
|
4b30b2be3394f03f1cf1f37a08dcec12
|
||||||
|
level 3, file files/g1000000
|
||||||
|
4301dea72cc4dd6162e46caa59788a09
|
||||||
|
level 3, file files/g20000
|
||||||
|
30456361833d27c0962c2faaa254e615
|
||||||
|
level 3, file files/g200000
|
||||||
|
0f01c07c57d60298dd54c6b6b197c3d3
|
||||||
|
level 3, file files/g30000
|
||||||
|
0b3c506a1b1b6ccbb54a852c370f5cdc
|
||||||
|
level 3, file files/g50000
|
||||||
|
81368c0b96bf1a2f318940b836b46074
|
||||||
|
level 3, file files/g500000
|
||||||
|
0c1ef9c6d3d75bfa0dd5d893f65da47c
|
||||||
|
level 4, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 4, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 4, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 4, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 4, file files/g1000
|
||||||
|
6a1214c19ab13d15934244a4655fa327
|
||||||
|
level 4, file files/g10000
|
||||||
|
09bbd556d9ee9f74f36b36bfa6b17325
|
||||||
|
level 4, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 4, file files/g10000-P10
|
||||||
|
1adb177b7a441c3585ffd781654758ba
|
||||||
|
level 4, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 4, file files/g10000-P25
|
||||||
|
3a62170477d7f17d64dc49b971388ff7
|
||||||
|
level 4, file files/g10000-P50
|
||||||
|
de93403eafd68786410fa52a95752514
|
||||||
|
level 4, file files/g10000-P75
|
||||||
|
f5466b3cfc3ba1e5afecb8d8bb91250f
|
||||||
|
level 4, file files/g10000-P90
|
||||||
|
132869db4091a9b9bdbc5236435a1d98
|
||||||
|
level 4, file files/g100000
|
||||||
|
dd92f22c593f40e0ccd6b31ad09d9d18
|
||||||
|
level 4, file files/g1000000
|
||||||
|
cfe7c063909c635f22438f83eb824082
|
||||||
|
level 4, file files/g20000
|
||||||
|
f8be159b057c6ee827f36cdd2ee5c43f
|
||||||
|
level 4, file files/g200000
|
||||||
|
71362cc7c28dcc730b591e3002fe888c
|
||||||
|
level 4, file files/g30000
|
||||||
|
f0b899995c6ba86066bd7f407fc708ef
|
||||||
|
level 4, file files/g50000
|
||||||
|
2f293e665d5161e68d8e1f86ac6841be
|
||||||
|
level 4, file files/g500000
|
||||||
|
42c5c45c595af60d5cf28f4cdd8ab392
|
||||||
|
level 5, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 5, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 5, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 5, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 5, file files/g1000
|
||||||
|
d47284586e181d455017d821bd3de1ef
|
||||||
|
level 5, file files/g10000
|
||||||
|
d6cd223f1c215d332654ca241a376549
|
||||||
|
level 5, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 5, file files/g10000-P10
|
||||||
|
66b935a7666ae668ac990d5c9aaac652
|
||||||
|
level 5, file files/g10000-P100
|
||||||
|
15fede9faa3d7c484dead66071fb8c5d
|
||||||
|
level 5, file files/g10000-P25
|
||||||
|
b292339cacea797a184554a2de3c1ed3
|
||||||
|
level 5, file files/g10000-P50
|
||||||
|
10b65af5125bf21a6810b8fb7a30b8b1
|
||||||
|
level 5, file files/g10000-P75
|
||||||
|
04fc60ea83db4b6101778f91a73d6040
|
||||||
|
level 5, file files/g10000-P90
|
||||||
|
302c8c7355082a7f40efe4ea40912411
|
||||||
|
level 5, file files/g100000
|
||||||
|
338f5e822a469774462f144d7ae371a0
|
||||||
|
level 5, file files/g1000000
|
||||||
|
46b8608a1f833477387e2fc844a817d5
|
||||||
|
level 5, file files/g20000
|
||||||
|
b7a468d363a7797d3d7a48577cd20213
|
||||||
|
level 5, file files/g200000
|
||||||
|
5ed09b3fd58ba540128319c02f9259cb
|
||||||
|
level 5, file files/g30000
|
||||||
|
fd4c0e5acb85271c101fd8ae1f411232
|
||||||
|
level 5, file files/g50000
|
||||||
|
2a14c76d629615bd50a370e587d13eb8
|
||||||
|
level 5, file files/g500000
|
||||||
|
cb1122167d4a747f3f8e0dd18bce6fa3
|
||||||
|
level 6, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 6, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 6, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 6, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 6, file files/g1000
|
||||||
|
19187f900e7540efdcab3735f489f718
|
||||||
|
level 6, file files/g10000
|
||||||
|
70c03e642fb98b896f2d96c0fa0eca74
|
||||||
|
level 6, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 6, file files/g10000-P10
|
||||||
|
70e2df33337095c818051d86ea68f188
|
||||||
|
level 6, file files/g10000-P100
|
||||||
|
15fede9faa3d7c484dead66071fb8c5d
|
||||||
|
level 6, file files/g10000-P25
|
||||||
|
dd4ed2ced4ae48672d5c8c0d4a7d58a5
|
||||||
|
level 6, file files/g10000-P50
|
||||||
|
9182b845f45f4990c8993e1c54e1e2e6
|
||||||
|
level 6, file files/g10000-P75
|
||||||
|
d3e6bb5a8e9790d23dda0a38b3def532
|
||||||
|
level 6, file files/g10000-P90
|
||||||
|
21da6c8aefa00b3e16f7674c642aa043
|
||||||
|
level 6, file files/g100000
|
||||||
|
350a0f07d7ddbcd0c629da0bcf734f02
|
||||||
|
level 6, file files/g1000000
|
||||||
|
d40c700beee149ab272b94c7ef0f3811
|
||||||
|
level 6, file files/g20000
|
||||||
|
335bc3f5767a7d4ad479408b0e289459
|
||||||
|
level 6, file files/g200000
|
||||||
|
032e3313ca247a8f4687059fa708284c
|
||||||
|
level 6, file files/g30000
|
||||||
|
a4b9fed2e1005298617125ee3b00cb06
|
||||||
|
level 6, file files/g50000
|
||||||
|
d7b3dab8d19fb992795c440d5f953c94
|
||||||
|
level 6, file files/g500000
|
||||||
|
44e59ccbf7a9794d4ea03f3f59f61ffd
|
||||||
|
level 7, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 7, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 7, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 7, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 7, file files/g1000
|
||||||
|
19187f900e7540efdcab3735f489f718
|
||||||
|
level 7, file files/g10000
|
||||||
|
495f1e5d30de3b34c5a76301875fa231
|
||||||
|
level 7, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 7, file files/g10000-P10
|
||||||
|
8a91fa2460ec9bd0387baa31beb81060
|
||||||
|
level 7, file files/g10000-P100
|
||||||
|
15fede9faa3d7c484dead66071fb8c5d
|
||||||
|
level 7, file files/g10000-P25
|
||||||
|
7dc0563f2e66a2e57c0f119e4d5e636e
|
||||||
|
level 7, file files/g10000-P50
|
||||||
|
e93a6eb179f7b26daa896328b2583b04
|
||||||
|
level 7, file files/g10000-P75
|
||||||
|
cb1e5facfc34fca7323000c6188ad657
|
||||||
|
level 7, file files/g10000-P90
|
||||||
|
e9984c6557f5a392f16e5c139dbe4994
|
||||||
|
level 7, file files/g100000
|
||||||
|
6e493dbe2985fec69860ef34728ac01a
|
||||||
|
level 7, file files/g1000000
|
||||||
|
455023a055f3a4de76c7295408ce3c8f
|
||||||
|
level 7, file files/g20000
|
||||||
|
2359efcd587e36ac9b74a8344bbf0e53
|
||||||
|
level 7, file files/g200000
|
||||||
|
ca80dbc88183a5aabb4aae955c449dff
|
||||||
|
level 7, file files/g30000
|
||||||
|
7e1be7e841c9fddd776dbe94b50db0ab
|
||||||
|
level 7, file files/g50000
|
||||||
|
09b80b58d70622de6f2354a06c15cb2a
|
||||||
|
level 7, file files/g500000
|
||||||
|
c90609f0558f0979eccb572ce0af4aa3
|
||||||
|
level 8, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 8, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 8, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 8, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 8, file files/g1000
|
||||||
|
19187f900e7540efdcab3735f489f718
|
||||||
|
level 8, file files/g10000
|
||||||
|
495f1e5d30de3b34c5a76301875fa231
|
||||||
|
level 8, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 8, file files/g10000-P10
|
||||||
|
8a91fa2460ec9bd0387baa31beb81060
|
||||||
|
level 8, file files/g10000-P100
|
||||||
|
15fede9faa3d7c484dead66071fb8c5d
|
||||||
|
level 8, file files/g10000-P25
|
||||||
|
526c95fd77cbcc2079720bb1b5515a54
|
||||||
|
level 8, file files/g10000-P50
|
||||||
|
50d4e0154067af438e56729716c3eda7
|
||||||
|
level 8, file files/g10000-P75
|
||||||
|
c94a94cce795566b065f2d3dca554c28
|
||||||
|
level 8, file files/g10000-P90
|
||||||
|
8f83ce03eb280cba48bafafbd066b752
|
||||||
|
level 8, file files/g100000
|
||||||
|
dbc4c43d9dc0937e67e92a908688a51e
|
||||||
|
level 8, file files/g1000000
|
||||||
|
5a4e6e44c89c3538fdb09823e649c8f6
|
||||||
|
level 8, file files/g20000
|
||||||
|
3653750b7ea2e8dc97d1d24ccec72153
|
||||||
|
level 8, file files/g200000
|
||||||
|
e978eb15e94cf221f1c7c55a059bbc4a
|
||||||
|
level 8, file files/g30000
|
||||||
|
9668f8c1292931955e14b81d67c2c648
|
||||||
|
level 8, file files/g50000
|
||||||
|
36a864d5bb5d9167d19ac237ce3bef51
|
||||||
|
level 8, file files/g500000
|
||||||
|
eaaac1f3c4861d4d501d9c92fa67cc08
|
||||||
|
level 9, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 9, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 9, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 9, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 9, file files/g1000
|
||||||
|
42d1f8aa9ee42135013077f09b77fd1a
|
||||||
|
level 9, file files/g10000
|
||||||
|
ae4166250554922e9ed27e436c13bf6b
|
||||||
|
level 9, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 9, file files/g10000-P10
|
||||||
|
bd9ede6738524ef732c9516146536acd
|
||||||
|
level 9, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 9, file files/g10000-P25
|
||||||
|
526c95fd77cbcc2079720bb1b5515a54
|
||||||
|
level 9, file files/g10000-P50
|
||||||
|
af6f029bd0d9baee1a78b8f7ffef5df3
|
||||||
|
level 9, file files/g10000-P75
|
||||||
|
f56895eec07a63269ea3eaeb59e87f40
|
||||||
|
level 9, file files/g10000-P90
|
||||||
|
c5cef2890886bfaf2d747b37ededc261
|
||||||
|
level 9, file files/g100000
|
||||||
|
f11c301dcf8c791e4f2db29e1b388eba
|
||||||
|
level 9, file files/g1000000
|
||||||
|
f90563e0d0962955d31af45fc8f2b19d
|
||||||
|
level 9, file files/g20000
|
||||||
|
49820710f3fbc6627b60071e91dba56d
|
||||||
|
level 9, file files/g200000
|
||||||
|
4689b0eb28c34619d8a9087cfa33fc88
|
||||||
|
level 9, file files/g30000
|
||||||
|
c14b029711fa6abc627ed3a051902b4c
|
||||||
|
level 9, file files/g50000
|
||||||
|
2d1cde6271f46081fbeaaba10f1c48bb
|
||||||
|
level 9, file files/g500000
|
||||||
|
eaaac1f3c4861d4d501d9c92fa67cc08
|
||||||
|
level 10, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 10, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 10, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 10, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 10, file files/g1000
|
||||||
|
42d1f8aa9ee42135013077f09b77fd1a
|
||||||
|
level 10, file files/g10000
|
||||||
|
ae4166250554922e9ed27e436c13bf6b
|
||||||
|
level 10, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 10, file files/g10000-P10
|
||||||
|
bd9ede6738524ef732c9516146536acd
|
||||||
|
level 10, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 10, file files/g10000-P25
|
||||||
|
526c95fd77cbcc2079720bb1b5515a54
|
||||||
|
level 10, file files/g10000-P50
|
||||||
|
6f821eef670933208d85daad6a9a2791
|
||||||
|
level 10, file files/g10000-P75
|
||||||
|
9c944c50c800d72294bdc9a9a452dc90
|
||||||
|
level 10, file files/g10000-P90
|
||||||
|
838a22c0731a67d185cac135b2bac5c7
|
||||||
|
level 10, file files/g100000
|
||||||
|
bbb2e91bdee192ae6f23404542a35bfb
|
||||||
|
level 10, file files/g1000000
|
||||||
|
1e52803b3311c2d4428c56d059901721
|
||||||
|
level 10, file files/g20000
|
||||||
|
939b50f472cf67c6dfbc4d3074e04011
|
||||||
|
level 10, file files/g200000
|
||||||
|
adc5f0c58c75e79e4bc4800c015d2401
|
||||||
|
level 10, file files/g30000
|
||||||
|
43e46ec5aae76c55c890a18f49b0163b
|
||||||
|
level 10, file files/g50000
|
||||||
|
65c57573aef37a38bd6c587ef4388800
|
||||||
|
level 10, file files/g500000
|
||||||
|
d3c45fce79c26bce889c3fa6a5480200
|
||||||
|
level 11, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 11, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 11, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 11, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 11, file files/g1000
|
||||||
|
4aa08662527d6d7f996705929e0dd8e0
|
||||||
|
level 11, file files/g10000
|
||||||
|
330f75029558d7cb6fa2756d85a998bd
|
||||||
|
level 11, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 11, file files/g10000-P10
|
||||||
|
990879c5b3d1c99aa5ef39f6049cebc9
|
||||||
|
level 11, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 11, file files/g10000-P25
|
||||||
|
26a10f96c2008608a33a731ff39cd9c8
|
||||||
|
level 11, file files/g10000-P50
|
||||||
|
129c6082daea0da5f52358c71b252750
|
||||||
|
level 11, file files/g10000-P75
|
||||||
|
7ff21b2c10548b9fc8ec5b61f86b9db0
|
||||||
|
level 11, file files/g10000-P90
|
||||||
|
0def9775620838420b295c07fd50a196
|
||||||
|
level 11, file files/g100000
|
||||||
|
c115057c51f9bb603a7d0c6bdf76e422
|
||||||
|
level 11, file files/g1000000
|
||||||
|
d28d3aed914ba7368dd004a9431c0173
|
||||||
|
level 11, file files/g20000
|
||||||
|
650cf27ffca49ed98f0e5dbb8997d7eb
|
||||||
|
level 11, file files/g200000
|
||||||
|
3210b89239e35e559be0ccd842577bb4
|
||||||
|
level 11, file files/g30000
|
||||||
|
09fe5a276e3fec09490c85962263fb26
|
||||||
|
level 11, file files/g50000
|
||||||
|
a9fa2677e4faab0eaa2334f278b3ec7d
|
||||||
|
level 11, file files/g500000
|
||||||
|
86815b1a35a46312a081f1af4946a62e
|
||||||
|
level 12, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 12, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 12, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 12, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 12, file files/g1000
|
||||||
|
6cb98f0115baf96a720638cf92b7803b
|
||||||
|
level 12, file files/g10000
|
||||||
|
b73485abce0df9802dcfeee652c45a8d
|
||||||
|
level 12, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 12, file files/g10000-P10
|
||||||
|
d00ac554fefc8a0f40420f908ff6fe69
|
||||||
|
level 12, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 12, file files/g10000-P25
|
||||||
|
9e20110ea128e4201c9a09eb48ad16c8
|
||||||
|
level 12, file files/g10000-P50
|
||||||
|
07287871c8b4ec3b5a925563a97451ce
|
||||||
|
level 12, file files/g10000-P75
|
||||||
|
2a47bb2eb7fb84a157f4525da9f78a77
|
||||||
|
level 12, file files/g10000-P90
|
||||||
|
d9c87f3f0faf212ec2d60cb611dac8a9
|
||||||
|
level 12, file files/g100000
|
||||||
|
d5d45068ded1319342ac3b7867d8c8fd
|
||||||
|
level 12, file files/g1000000
|
||||||
|
d28d3aed914ba7368dd004a9431c0173
|
||||||
|
level 12, file files/g20000
|
||||||
|
650cf27ffca49ed98f0e5dbb8997d7eb
|
||||||
|
level 12, file files/g200000
|
||||||
|
077d0f0ef9e9af86b1a298624fc70062
|
||||||
|
level 12, file files/g30000
|
||||||
|
09fe5a276e3fec09490c85962263fb26
|
||||||
|
level 12, file files/g50000
|
||||||
|
a9fa2677e4faab0eaa2334f278b3ec7d
|
||||||
|
level 12, file files/g500000
|
||||||
|
86815b1a35a46312a081f1af4946a62e
|
||||||
|
level 13, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 13, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 13, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 13, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 13, file files/g1000
|
||||||
|
773b6b59d472db0932b5ad1ad75eac64
|
||||||
|
level 13, file files/g10000
|
||||||
|
dfd1e66b36c80b191c338d0b14813920
|
||||||
|
level 13, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 13, file files/g10000-P10
|
||||||
|
40b5f47e143e235198f6408a099208e8
|
||||||
|
level 13, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 13, file files/g10000-P25
|
||||||
|
deaa99c2458ca8ea661b358ef837ef58
|
||||||
|
level 13, file files/g10000-P50
|
||||||
|
dd575cdc1ac009a7f2407013063d02e3
|
||||||
|
level 13, file files/g10000-P75
|
||||||
|
0d411eb9beee65c6f5dd7764b639097b
|
||||||
|
level 13, file files/g10000-P90
|
||||||
|
61db327f8fdd9a735e68259f05f71f0d
|
||||||
|
level 13, file files/g100000
|
||||||
|
dece3af6a1b7ef4ab80cad69119a3b61
|
||||||
|
level 13, file files/g1000000
|
||||||
|
916989f734410afce6b3ae72a3352e68
|
||||||
|
level 13, file files/g20000
|
||||||
|
7ce4e5c10392cbae28ed79b0707f627f
|
||||||
|
level 13, file files/g200000
|
||||||
|
ab3d3f2a0fb5d4e54f8e799213d7e995
|
||||||
|
level 13, file files/g30000
|
||||||
|
61f3ce2b87a584169e92791fa54c7361
|
||||||
|
level 13, file files/g50000
|
||||||
|
aba34c68e1d812fab8ce9863169e050b
|
||||||
|
level 13, file files/g500000
|
||||||
|
9f16a159f5fa88b875e5c1e0574a999c
|
||||||
|
level 14, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 14, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 14, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 14, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 14, file files/g1000
|
||||||
|
773b6b59d472db0932b5ad1ad75eac64
|
||||||
|
level 14, file files/g10000
|
||||||
|
dfd1e66b36c80b191c338d0b14813920
|
||||||
|
level 14, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 14, file files/g10000-P10
|
||||||
|
40b5f47e143e235198f6408a099208e8
|
||||||
|
level 14, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 14, file files/g10000-P25
|
||||||
|
deaa99c2458ca8ea661b358ef837ef58
|
||||||
|
level 14, file files/g10000-P50
|
||||||
|
246b1782db44f4226d32c8718e39ac8c
|
||||||
|
level 14, file files/g10000-P75
|
||||||
|
023a4c9c041fbcd4f584d5e65f9b4444
|
||||||
|
level 14, file files/g10000-P90
|
||||||
|
d57d3ce213e81d7ce80930115afc9f71
|
||||||
|
level 14, file files/g100000
|
||||||
|
29c1d79c3dc1dc51ec4ee3fd19fdbd10
|
||||||
|
level 14, file files/g1000000
|
||||||
|
7721785c341760a66ac9e2fb39cfeb33
|
||||||
|
level 14, file files/g20000
|
||||||
|
1055a0a808598d1eedf0442fceff44e0
|
||||||
|
level 14, file files/g200000
|
||||||
|
87df6235943fd09ba3f6a1f24cbc3a3a
|
||||||
|
level 14, file files/g30000
|
||||||
|
74c32e0cd8bcd62bd4e1cf599c193abf
|
||||||
|
level 14, file files/g50000
|
||||||
|
10d3bbb5e9822fa5c31fc2e79aeae7e9
|
||||||
|
level 14, file files/g500000
|
||||||
|
f8865d65f1790f723184007b2f940127
|
||||||
|
level 15, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 15, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 15, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 15, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 15, file files/g1000
|
||||||
|
773b6b59d472db0932b5ad1ad75eac64
|
||||||
|
level 15, file files/g10000
|
||||||
|
dfd1e66b36c80b191c338d0b14813920
|
||||||
|
level 15, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 15, file files/g10000-P10
|
||||||
|
40b5f47e143e235198f6408a099208e8
|
||||||
|
level 15, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 15, file files/g10000-P25
|
||||||
|
deaa99c2458ca8ea661b358ef837ef58
|
||||||
|
level 15, file files/g10000-P50
|
||||||
|
91cc04148eef18ae4222038ad05f0586
|
||||||
|
level 15, file files/g10000-P75
|
||||||
|
aa5e9e619fe89644098c9ad17a8b9ad4
|
||||||
|
level 15, file files/g10000-P90
|
||||||
|
28d6d71a33f507d1e7acd56d586e3981
|
||||||
|
level 15, file files/g100000
|
||||||
|
29c1d79c3dc1dc51ec4ee3fd19fdbd10
|
||||||
|
level 15, file files/g1000000
|
||||||
|
de1091b6021db006820019edfcb1384c
|
||||||
|
level 15, file files/g20000
|
||||||
|
1055a0a808598d1eedf0442fceff44e0
|
||||||
|
level 15, file files/g200000
|
||||||
|
0096718cf88b77da67fc2211bf85e3ca
|
||||||
|
level 15, file files/g30000
|
||||||
|
74c32e0cd8bcd62bd4e1cf599c193abf
|
||||||
|
level 15, file files/g50000
|
||||||
|
10d3bbb5e9822fa5c31fc2e79aeae7e9
|
||||||
|
level 15, file files/g500000
|
||||||
|
53aa49e42ffac4621397b88d4749c9c0
|
||||||
|
level 16, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 16, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 16, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 16, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 16, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 16, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 16, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 16, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 16, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 16, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 16, file files/g10000-P50
|
||||||
|
9af82247b7fe18900592ae4fd5f1890a
|
||||||
|
level 16, file files/g10000-P75
|
||||||
|
d44f2305f023fbff3d1a872ab740958a
|
||||||
|
level 16, file files/g10000-P90
|
||||||
|
517f98319c717526b5e211079f073fbc
|
||||||
|
level 16, file files/g100000
|
||||||
|
95ec61667f371a3621b34a042f1f4a0a
|
||||||
|
level 16, file files/g1000000
|
||||||
|
b71641629b58754f1961ac394f177d7c
|
||||||
|
level 16, file files/g20000
|
||||||
|
7bd4e03d703ead21e15fddd4423ef79e
|
||||||
|
level 16, file files/g200000
|
||||||
|
fd1c701e9872f304a71f0e7f7aa9f918
|
||||||
|
level 16, file files/g30000
|
||||||
|
bc2211b250b5f4ed0a7bd97d447132e0
|
||||||
|
level 16, file files/g50000
|
||||||
|
a6d98ebd2ed96688482c7d1181dded42
|
||||||
|
level 16, file files/g500000
|
||||||
|
44e339bb9e57842b77476f6d75ff3fbd
|
||||||
|
level 17, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 17, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 17, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 17, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 17, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 17, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 17, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 17, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 17, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 17, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 17, file files/g10000-P50
|
||||||
|
607968cd37d41631312307f6c8a37ab4
|
||||||
|
level 17, file files/g10000-P75
|
||||||
|
818c2b0124e0dad26f9d95d753b11140
|
||||||
|
level 17, file files/g10000-P90
|
||||||
|
2d01bb79185ec88e5d7e684d3983eff8
|
||||||
|
level 17, file files/g100000
|
||||||
|
95ec61667f371a3621b34a042f1f4a0a
|
||||||
|
level 17, file files/g1000000
|
||||||
|
cbd03f012664a02441271c50ba1330bf
|
||||||
|
level 17, file files/g20000
|
||||||
|
7bd4e03d703ead21e15fddd4423ef79e
|
||||||
|
level 17, file files/g200000
|
||||||
|
fd1c701e9872f304a71f0e7f7aa9f918
|
||||||
|
level 17, file files/g30000
|
||||||
|
bc2211b250b5f4ed0a7bd97d447132e0
|
||||||
|
level 17, file files/g50000
|
||||||
|
a6d98ebd2ed96688482c7d1181dded42
|
||||||
|
level 17, file files/g500000
|
||||||
|
01223076923dc7e3e06eeb3d71c467d2
|
||||||
|
level 18, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 18, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 18, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 18, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 18, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 18, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 18, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 18, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 18, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 18, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 18, file files/g10000-P50
|
||||||
|
c61ad9309da86f7229498e46daacd6d9
|
||||||
|
level 18, file files/g10000-P75
|
||||||
|
8bf1c42a6a1f46ff8549e87f7b6daa54
|
||||||
|
level 18, file files/g10000-P90
|
||||||
|
29077b7a282975006c20701bca0d439d
|
||||||
|
level 18, file files/g100000
|
||||||
|
95ec61667f371a3621b34a042f1f4a0a
|
||||||
|
level 18, file files/g1000000
|
||||||
|
1e598049810de86924756bcda8941085
|
||||||
|
level 18, file files/g20000
|
||||||
|
7bd4e03d703ead21e15fddd4423ef79e
|
||||||
|
level 18, file files/g200000
|
||||||
|
ab03b5ab84b6ebe79fa325118a895c6b
|
||||||
|
level 18, file files/g30000
|
||||||
|
bc2211b250b5f4ed0a7bd97d447132e0
|
||||||
|
level 18, file files/g50000
|
||||||
|
a6d98ebd2ed96688482c7d1181dded42
|
||||||
|
level 18, file files/g500000
|
||||||
|
1b5374095c0bdc676655fe4db94286d1
|
||||||
|
level 19, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 19, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 19, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 19, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 19, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 19, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 19, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 19, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 19, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 19, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 19, file files/g10000-P50
|
||||||
|
c61ad9309da86f7229498e46daacd6d9
|
||||||
|
level 19, file files/g10000-P75
|
||||||
|
d3171f297dfd08e444d481b30b1bbefa
|
||||||
|
level 19, file files/g10000-P90
|
||||||
|
87c4a59ec6e15f6da86b26969044a8a4
|
||||||
|
level 19, file files/g100000
|
||||||
|
7ae11dc1919d94e80979d41d12a0b578
|
||||||
|
level 19, file files/g1000000
|
||||||
|
d4b9ee8879d7f30bed3ec9e70520ca67
|
||||||
|
level 19, file files/g20000
|
||||||
|
70028792166e24282f5497592b632192
|
||||||
|
level 19, file files/g200000
|
||||||
|
ab03b5ab84b6ebe79fa325118a895c6b
|
||||||
|
level 19, file files/g30000
|
||||||
|
d698feea5119e141a08656439c4c1508
|
||||||
|
level 19, file files/g50000
|
||||||
|
b81384753f0db76004ac97681f6ef757
|
||||||
|
level 19, file files/g500000
|
||||||
|
0a25ba39483255a2c16899ab80a3ed8f
|
||||||
|
level 1, long=18, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 19, long=18, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 1, long=18, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 19, long=18, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 1, long=18, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 19, long=18, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 1, long=18, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 19, long=18, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 1, long=18, file files/g1000
|
||||||
|
6bf2f4b179864fd8db4676037465feed
|
||||||
|
level 19, long=18, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 1, long=18, file files/g10000
|
||||||
|
2ae44c4053b2b47724c8f612dfb60d24
|
||||||
|
level 19, long=18, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 1, long=18, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 19, long=18, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 1, long=18, file files/g10000-P10
|
||||||
|
6a8f6e75ab538eb08a422febc8b68006
|
||||||
|
level 19, long=18, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 1, long=18, file files/g10000-P100
|
||||||
|
5db6fbe04a2de772ad4e49f5357d0543
|
||||||
|
level 19, long=18, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 1, long=18, file files/g10000-P25
|
||||||
|
6fd603b31365845346faab9cd64fd647
|
||||||
|
level 19, long=18, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 1, long=18, file files/g10000-P50
|
||||||
|
d1de679e9a8c962ed1cc668a96bf930a
|
||||||
|
level 19, long=18, file files/g10000-P50
|
||||||
|
c61ad9309da86f7229498e46daacd6d9
|
||||||
|
level 1, long=18, file files/g10000-P75
|
||||||
|
dcf9822423e2ad42a569985707cd5ab4
|
||||||
|
level 19, long=18, file files/g10000-P75
|
||||||
|
f0ea19930e3866ff7a1932931346e0ac
|
||||||
|
level 1, long=18, file files/g10000-P90
|
||||||
|
87d249fd8c1ad0064d067a1e5ad97647
|
||||||
|
level 19, long=18, file files/g10000-P90
|
||||||
|
582e2c4c5a06e452d8dae22e7210c070
|
||||||
|
level 1, long=18, file files/g100000
|
||||||
|
daa38a869130494c077290cf54f2d895
|
||||||
|
level 19, long=18, file files/g100000
|
||||||
|
7ae11dc1919d94e80979d41d12a0b578
|
||||||
|
level 1, long=18, file files/g1000000
|
||||||
|
81b9ffd138f3b25254a7078b06950e5f
|
||||||
|
level 19, long=18, file files/g1000000
|
||||||
|
db54f06bf3abdbfd57892ab3aad18233
|
||||||
|
level 1, long=18, file files/g20000
|
||||||
|
1da5b56511e8693867c0cdd962c521aa
|
||||||
|
level 19, long=18, file files/g20000
|
||||||
|
70028792166e24282f5497592b632192
|
||||||
|
level 1, long=18, file files/g200000
|
||||||
|
17eb9ff8d912da9c445def85cb748e54
|
||||||
|
level 19, long=18, file files/g200000
|
||||||
|
ab03b5ab84b6ebe79fa325118a895c6b
|
||||||
|
level 1, long=18, file files/g30000
|
||||||
|
788bc5abca5e33d79bb79a4eca98b9cd
|
||||||
|
level 19, long=18, file files/g30000
|
||||||
|
d698feea5119e141a08656439c4c1508
|
||||||
|
level 1, long=18, file files/g50000
|
||||||
|
0bf9fafd84a2d56a788a9159f1f23f26
|
||||||
|
level 19, long=18, file files/g50000
|
||||||
|
b81384753f0db76004ac97681f6ef757
|
||||||
|
level 1, long=18, file files/g500000
|
||||||
|
f035223dc02f581daf5dd79773c4dc2b
|
||||||
|
level 19, long=18, file files/g500000
|
||||||
|
97093f718faf7b9094e27ea822fd1a29
|
||||||
|
level -1, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level -1, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level -1, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level -1, file files/g100
|
||||||
|
eb805e7fdb95bc42231b20d0e12e2a53
|
||||||
|
level -1, file files/g1000
|
||||||
|
ac7c900e31b9e4fe37b7846a898c7d48
|
||||||
|
level -1, file files/g10000
|
||||||
|
55e1e6ed7fcf5581a17f72f3a32e0834
|
||||||
|
level -1, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level -1, file files/g10000-P10
|
||||||
|
0bf549bdfc20b644c37901918de0d0eb
|
||||||
|
level -1, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level -1, file files/g10000-P25
|
||||||
|
b65475ee206e480b3adc9fcc7b79c54b
|
||||||
|
level -1, file files/g10000-P50
|
||||||
|
ae4bf85c8343052ecb1d666bd9766fbc
|
||||||
|
level -1, file files/g10000-P75
|
||||||
|
b0674333f519e71708f226f935ae63d5
|
||||||
|
level -1, file files/g10000-P90
|
||||||
|
2daa80aa34a8259fed7e04ae41397d6c
|
||||||
|
level -1, file files/g100000
|
||||||
|
586e12a3aa574f35aedf0afadee3040c
|
||||||
|
level -1, file files/g1000000
|
||||||
|
1cc8eb9ee1e4c20373fe3c1b0aa1a982
|
||||||
|
level -1, file files/g20000
|
||||||
|
b220e6387b1f5036c203f8be5f1a571c
|
||||||
|
level -1, file files/g200000
|
||||||
|
fc42db710c19a4f4a27f004fb4678d9c
|
||||||
|
level -1, file files/g30000
|
||||||
|
5350a7346d815f4ad42216b91ba8749a
|
||||||
|
level -1, file files/g50000
|
||||||
|
4f00a5a94e8f98c6972053057f6ac971
|
||||||
|
level -1, file files/g500000
|
||||||
|
4abb2e46c936c273955778c00f3eb492
|
||||||
Executable
+45
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. "$COMMON/platform.sh"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# To update checksums on version change run this from the tests/ directory
|
||||||
|
# make update-cli-tests
|
||||||
|
|
||||||
|
if [ -n "$NON_DETERMINISTIC" ] || [ -z "$hasMT" ]; then
|
||||||
|
# Skip tests if we have a non-deterministic build
|
||||||
|
cat "$CLI_TESTS/determinism/multithread.sh.stdout.exact"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for level in 1 3 7 19; do
|
||||||
|
for file in $(ls files/); do
|
||||||
|
file="files/$file"
|
||||||
|
echo "level $level, file $file"
|
||||||
|
zstd -T2 -q -$level $file -c | md5hash
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
for file in $(ls files/); do
|
||||||
|
file="files/$file"
|
||||||
|
echo "level 1, long=18, file $file"
|
||||||
|
zstd --long=18 -T2 -q -1 $file -c | md5hash
|
||||||
|
echo "level 19, long=18, file $file"
|
||||||
|
zstd --long=18 -T2 -q -19 $file -c | md5hash
|
||||||
|
done
|
||||||
|
|
||||||
|
for file in $(ls files/); do
|
||||||
|
file="files/$file"
|
||||||
|
echo "Vary number of threads on $file"
|
||||||
|
zstd -qf -1 $file -o $file.zst.good
|
||||||
|
|
||||||
|
zstd -qf -T1 -1 $file
|
||||||
|
$DIFF $file.zst $file.zst.good
|
||||||
|
|
||||||
|
zstd -qf -T2 -1 $file
|
||||||
|
$DIFF $file.zst $file.zst.good
|
||||||
|
|
||||||
|
zstd -qf -T4 -1 $file
|
||||||
|
$DIFF $file.zst $file.zst.good
|
||||||
|
done
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
level 1, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 1, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 1, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 1, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 1, file files/g1000
|
||||||
|
6bf2f4b179864fd8db4676037465feed
|
||||||
|
level 1, file files/g10000
|
||||||
|
2ae44c4053b2b47724c8f612dfb60d24
|
||||||
|
level 1, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 1, file files/g10000-P10
|
||||||
|
2d0eeab6a966098583a1dfeafb5090c1
|
||||||
|
level 1, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 1, file files/g10000-P25
|
||||||
|
c64b5f512c44b6a647da81753791b9a7
|
||||||
|
level 1, file files/g10000-P50
|
||||||
|
3982325490d90c8307e734c1b25790df
|
||||||
|
level 1, file files/g10000-P75
|
||||||
|
b7504f80fee16b5ba6a0f46571eb563a
|
||||||
|
level 1, file files/g10000-P90
|
||||||
|
350892bec7f7ad6a7d6af01c5d8b07c7
|
||||||
|
level 1, file files/g100000
|
||||||
|
daa38a869130494c077290cf54f2d895
|
||||||
|
level 1, file files/g1000000
|
||||||
|
a1d548531221d408b95dc5d9c600b3f0
|
||||||
|
level 1, file files/g20000
|
||||||
|
1da5b56511e8693867c0cdd962c521aa
|
||||||
|
level 1, file files/g200000
|
||||||
|
41fb3b3d46d4221f2f0b072c65dd6e0a
|
||||||
|
level 1, file files/g30000
|
||||||
|
788bc5abca5e33d79bb79a4eca98b9cd
|
||||||
|
level 1, file files/g50000
|
||||||
|
0bf9fafd84a2d56a788a9159f1f23f26
|
||||||
|
level 1, file files/g500000
|
||||||
|
73401d6df0657e091de20468f32579a9
|
||||||
|
level 3, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 3, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 3, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 3, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 3, file files/g1000
|
||||||
|
3ec47dcb2d606b9fdef3f19b1304f8fe
|
||||||
|
level 3, file files/g10000
|
||||||
|
69a9d518b84fe2a66b57dfb4ab8905ae
|
||||||
|
level 3, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 3, file files/g10000-P10
|
||||||
|
ac9866ac355c4ed8939deb9fbeec1aef
|
||||||
|
level 3, file files/g10000-P100
|
||||||
|
93436482b4da30ce2300d356448c8990
|
||||||
|
level 3, file files/g10000-P25
|
||||||
|
5e1fe7a3831f6632bc8c9873ab8b633d
|
||||||
|
level 3, file files/g10000-P50
|
||||||
|
76295f181396a98565eb9cc69b96dc75
|
||||||
|
level 3, file files/g10000-P75
|
||||||
|
1f751dc70508e81fef197311e8583e99
|
||||||
|
level 3, file files/g10000-P90
|
||||||
|
47c7b061c299dc253c6aaaf489e936cb
|
||||||
|
level 3, file files/g100000
|
||||||
|
4b30b2be3394f03f1cf1f37a08dcec12
|
||||||
|
level 3, file files/g1000000
|
||||||
|
4301dea72cc4dd6162e46caa59788a09
|
||||||
|
level 3, file files/g20000
|
||||||
|
30456361833d27c0962c2faaa254e615
|
||||||
|
level 3, file files/g200000
|
||||||
|
0f01c07c57d60298dd54c6b6b197c3d3
|
||||||
|
level 3, file files/g30000
|
||||||
|
0b3c506a1b1b6ccbb54a852c370f5cdc
|
||||||
|
level 3, file files/g50000
|
||||||
|
81368c0b96bf1a2f318940b836b46074
|
||||||
|
level 3, file files/g500000
|
||||||
|
0c1ef9c6d3d75bfa0dd5d893f65da47c
|
||||||
|
level 7, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 7, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 7, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 7, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 7, file files/g1000
|
||||||
|
19187f900e7540efdcab3735f489f718
|
||||||
|
level 7, file files/g10000
|
||||||
|
495f1e5d30de3b34c5a76301875fa231
|
||||||
|
level 7, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 7, file files/g10000-P10
|
||||||
|
8a91fa2460ec9bd0387baa31beb81060
|
||||||
|
level 7, file files/g10000-P100
|
||||||
|
15fede9faa3d7c484dead66071fb8c5d
|
||||||
|
level 7, file files/g10000-P25
|
||||||
|
7dc0563f2e66a2e57c0f119e4d5e636e
|
||||||
|
level 7, file files/g10000-P50
|
||||||
|
e93a6eb179f7b26daa896328b2583b04
|
||||||
|
level 7, file files/g10000-P75
|
||||||
|
cb1e5facfc34fca7323000c6188ad657
|
||||||
|
level 7, file files/g10000-P90
|
||||||
|
e9984c6557f5a392f16e5c139dbe4994
|
||||||
|
level 7, file files/g100000
|
||||||
|
6e493dbe2985fec69860ef34728ac01a
|
||||||
|
level 7, file files/g1000000
|
||||||
|
455023a055f3a4de76c7295408ce3c8f
|
||||||
|
level 7, file files/g20000
|
||||||
|
2359efcd587e36ac9b74a8344bbf0e53
|
||||||
|
level 7, file files/g200000
|
||||||
|
ca80dbc88183a5aabb4aae955c449dff
|
||||||
|
level 7, file files/g30000
|
||||||
|
7e1be7e841c9fddd776dbe94b50db0ab
|
||||||
|
level 7, file files/g50000
|
||||||
|
09b80b58d70622de6f2354a06c15cb2a
|
||||||
|
level 7, file files/g500000
|
||||||
|
c90609f0558f0979eccb572ce0af4aa3
|
||||||
|
level 19, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 19, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 19, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 19, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 19, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 19, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 19, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 19, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 19, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 19, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 19, file files/g10000-P50
|
||||||
|
c61ad9309da86f7229498e46daacd6d9
|
||||||
|
level 19, file files/g10000-P75
|
||||||
|
d3171f297dfd08e444d481b30b1bbefa
|
||||||
|
level 19, file files/g10000-P90
|
||||||
|
87c4a59ec6e15f6da86b26969044a8a4
|
||||||
|
level 19, file files/g100000
|
||||||
|
7ae11dc1919d94e80979d41d12a0b578
|
||||||
|
level 19, file files/g1000000
|
||||||
|
d4b9ee8879d7f30bed3ec9e70520ca67
|
||||||
|
level 19, file files/g20000
|
||||||
|
70028792166e24282f5497592b632192
|
||||||
|
level 19, file files/g200000
|
||||||
|
ab03b5ab84b6ebe79fa325118a895c6b
|
||||||
|
level 19, file files/g30000
|
||||||
|
d698feea5119e141a08656439c4c1508
|
||||||
|
level 19, file files/g50000
|
||||||
|
b81384753f0db76004ac97681f6ef757
|
||||||
|
level 19, file files/g500000
|
||||||
|
0a25ba39483255a2c16899ab80a3ed8f
|
||||||
|
level 1, long=18, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 19, long=18, file files/g0
|
||||||
|
5d80401e01d33084c65e94f93351e94c
|
||||||
|
level 1, long=18, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 19, long=18, file files/g1
|
||||||
|
8436b07a7eb916ac9c48af847b7e612f
|
||||||
|
level 1, long=18, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 19, long=18, file files/g10
|
||||||
|
6cf177a3e6494ac3c76c857df6a9b31d
|
||||||
|
level 1, long=18, file files/g100
|
||||||
|
c94d1ef6bbec8b4899486b06207ee829
|
||||||
|
level 19, long=18, file files/g100
|
||||||
|
e6e88e42b891fbc82c87a60928d88e97
|
||||||
|
level 1, long=18, file files/g1000
|
||||||
|
6bf2f4b179864fd8db4676037465feed
|
||||||
|
level 19, long=18, file files/g1000
|
||||||
|
f3eeeae11e293292fe1810d8745d0ae1
|
||||||
|
level 1, long=18, file files/g10000
|
||||||
|
2ae44c4053b2b47724c8f612dfb60d24
|
||||||
|
level 19, long=18, file files/g10000
|
||||||
|
23c5d58cca20ab65ff8a5d780f09e075
|
||||||
|
level 1, long=18, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 19, long=18, file files/g10000-P0
|
||||||
|
6c2641d3b83775c50b766793b39967c4
|
||||||
|
level 1, long=18, file files/g10000-P10
|
||||||
|
6a8f6e75ab538eb08a422febc8b68006
|
||||||
|
level 19, long=18, file files/g10000-P10
|
||||||
|
cced9c0f5709262da932fc8540bb72f4
|
||||||
|
level 1, long=18, file files/g10000-P100
|
||||||
|
5db6fbe04a2de772ad4e49f5357d0543
|
||||||
|
level 19, long=18, file files/g10000-P100
|
||||||
|
049015191cf579b24653c8730fcc10f5
|
||||||
|
level 1, long=18, file files/g10000-P25
|
||||||
|
6fd603b31365845346faab9cd64fd647
|
||||||
|
level 19, long=18, file files/g10000-P25
|
||||||
|
6676c9b599408491f7abc00947782054
|
||||||
|
level 1, long=18, file files/g10000-P50
|
||||||
|
d1de679e9a8c962ed1cc668a96bf930a
|
||||||
|
level 19, long=18, file files/g10000-P50
|
||||||
|
c61ad9309da86f7229498e46daacd6d9
|
||||||
|
level 1, long=18, file files/g10000-P75
|
||||||
|
dcf9822423e2ad42a569985707cd5ab4
|
||||||
|
level 19, long=18, file files/g10000-P75
|
||||||
|
f0ea19930e3866ff7a1932931346e0ac
|
||||||
|
level 1, long=18, file files/g10000-P90
|
||||||
|
87d249fd8c1ad0064d067a1e5ad97647
|
||||||
|
level 19, long=18, file files/g10000-P90
|
||||||
|
582e2c4c5a06e452d8dae22e7210c070
|
||||||
|
level 1, long=18, file files/g100000
|
||||||
|
daa38a869130494c077290cf54f2d895
|
||||||
|
level 19, long=18, file files/g100000
|
||||||
|
7ae11dc1919d94e80979d41d12a0b578
|
||||||
|
level 1, long=18, file files/g1000000
|
||||||
|
2c410773bb02367d20d20569393faf1e
|
||||||
|
level 19, long=18, file files/g1000000
|
||||||
|
e3f5ef0204aedbac03e80d4300b3afc7
|
||||||
|
level 1, long=18, file files/g20000
|
||||||
|
1da5b56511e8693867c0cdd962c521aa
|
||||||
|
level 19, long=18, file files/g20000
|
||||||
|
70028792166e24282f5497592b632192
|
||||||
|
level 1, long=18, file files/g200000
|
||||||
|
17eb9ff8d912da9c445def85cb748e54
|
||||||
|
level 19, long=18, file files/g200000
|
||||||
|
ab03b5ab84b6ebe79fa325118a895c6b
|
||||||
|
level 1, long=18, file files/g30000
|
||||||
|
788bc5abca5e33d79bb79a4eca98b9cd
|
||||||
|
level 19, long=18, file files/g30000
|
||||||
|
d698feea5119e141a08656439c4c1508
|
||||||
|
level 1, long=18, file files/g50000
|
||||||
|
0bf9fafd84a2d56a788a9159f1f23f26
|
||||||
|
level 19, long=18, file files/g50000
|
||||||
|
b81384753f0db76004ac97681f6ef757
|
||||||
|
level 1, long=18, file files/g500000
|
||||||
|
f035223dc02f581daf5dd79773c4dc2b
|
||||||
|
level 19, long=18, file files/g500000
|
||||||
|
97093f718faf7b9094e27ea822fd1a29
|
||||||
|
Vary number of threads on files/g0
|
||||||
|
Vary number of threads on files/g1
|
||||||
|
Vary number of threads on files/g10
|
||||||
|
Vary number of threads on files/g100
|
||||||
|
Vary number of threads on files/g1000
|
||||||
|
Vary number of threads on files/g10000
|
||||||
|
Vary number of threads on files/g10000-P0
|
||||||
|
Vary number of threads on files/g10000-P10
|
||||||
|
Vary number of threads on files/g10000-P100
|
||||||
|
Vary number of threads on files/g10000-P25
|
||||||
|
Vary number of threads on files/g10000-P50
|
||||||
|
Vary number of threads on files/g10000-P75
|
||||||
|
Vary number of threads on files/g10000-P90
|
||||||
|
Vary number of threads on files/g100000
|
||||||
|
Vary number of threads on files/g1000000
|
||||||
|
Vary number of threads on files/g20000
|
||||||
|
Vary number of threads on files/g200000
|
||||||
|
Vary number of threads on files/g30000
|
||||||
|
Vary number of threads on files/g50000
|
||||||
|
Vary number of threads on files/g500000
|
||||||
Executable
+44
@@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
. "$COMMON/platform.sh"
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# To update checksums on version change run this from the tests/ directory
|
||||||
|
# make update-cli-tests
|
||||||
|
|
||||||
|
if [ -n "$NON_DETERMINISTIC" ]; then
|
||||||
|
# Skip tests if we have a non-deterministic build
|
||||||
|
cat "$CLI_TESTS/determinism/reuse.sh.stdout.exact"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
datagen -g0 > file0
|
||||||
|
datagen -g1 > file1
|
||||||
|
datagen -g1000 > file1000
|
||||||
|
datagen -g100000 > file100000
|
||||||
|
|
||||||
|
validate() {
|
||||||
|
$DIFF file0.zst file0.zst.good
|
||||||
|
$DIFF file1.zst file1.zst.good
|
||||||
|
$DIFF file1000.zst file1000.zst.good
|
||||||
|
$DIFF file100000.zst file100000.zst.good
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check that context reuse doesn't impact determinism
|
||||||
|
for level in $(seq 1 19); do
|
||||||
|
echo $level
|
||||||
|
zstd -qf --single-thread -$level file0 -o file0.zst.good
|
||||||
|
zstd -qf --single-thread -$level file1 -o file1.zst.good
|
||||||
|
zstd -qf --single-thread -$level file1000 -o file1000.zst.good
|
||||||
|
zstd -qf --single-thread -$level file100000 -o file100000.zst.good
|
||||||
|
|
||||||
|
zstd -qf --single-thread -$level file0 file1 file1000 file100000
|
||||||
|
validate
|
||||||
|
zstd -qf --single-thread -$level file1 file0 file1000 file100000
|
||||||
|
validate
|
||||||
|
zstd -qf --single-thread -$level file1000 file1 file0 file100000
|
||||||
|
validate
|
||||||
|
zstd -qf --single-thread -$level file100000 file1000 file1 file0
|
||||||
|
validate
|
||||||
|
done
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
||||||
|
7
|
||||||
|
8
|
||||||
|
9
|
||||||
|
10
|
||||||
|
11
|
||||||
|
12
|
||||||
|
13
|
||||||
|
14
|
||||||
|
15
|
||||||
|
16
|
||||||
|
17
|
||||||
|
18
|
||||||
|
19
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cp -r ../files .
|
||||||
Executable
+30
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
. "$COMMON/platform.sh"
|
||||||
|
|
||||||
|
|
||||||
|
mkdir files/
|
||||||
|
|
||||||
|
datagen -g0 > files/g0
|
||||||
|
datagen -g1 > files/g1
|
||||||
|
datagen -g10 > files/g10
|
||||||
|
datagen -g100 > files/g100
|
||||||
|
datagen -g1000 > files/g1000
|
||||||
|
datagen -g10000 > files/g10000
|
||||||
|
datagen -g20000 > files/g20000
|
||||||
|
datagen -g30000 > files/g30000
|
||||||
|
datagen -g50000 > files/g50000
|
||||||
|
datagen -g100000 > files/g100000
|
||||||
|
datagen -g200000 > files/g200000
|
||||||
|
datagen -g500000 > files/g500000
|
||||||
|
datagen -g1000000 > files/g1000000
|
||||||
|
|
||||||
|
datagen -g10000 -P0 > files/g10000-P0
|
||||||
|
datagen -g10000 -P10 > files/g10000-P10
|
||||||
|
datagen -g10000 -P25 > files/g10000-P25
|
||||||
|
datagen -g10000 -P50 > files/g10000-P50
|
||||||
|
datagen -g10000 -P75 > files/g10000-P75
|
||||||
|
datagen -g10000 -P90 > files/g10000-P90
|
||||||
|
datagen -g10000 -P100 > files/g10000-P100
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
zstd --train
|
zstd --train
|
||||||
! Warning : nb of samples too low for proper processing !
|
! Warning : nb of samples too low for proper processing !
|
||||||
! Please provide _one file per sample_.
|
! Please provide _one file per sample_.
|
||||||
! Alternatively, split files into fixed-size blocks representative of samples, with -B#
|
! Alternatively, split file(s) into fixed-size samples, with --split=#
|
||||||
Error 14 : nb of samples too low
|
Error 14 : nb of samples too low
|
||||||
|
|||||||
@@ -22,5 +22,9 @@ Trace:FileStat: > UTIL_isRegularFile(out/file.zst)
|
|||||||
Trace:FileStat: > UTIL_stat(-1, out/file.zst)
|
Trace:FileStat: > UTIL_stat(-1, out/file.zst)
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isFdRegularFile(-1)
|
||||||
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isFileDescriptorPipe(out/file.zst)
|
||||||
|
Trace:FileStat: < 0
|
||||||
zstd: out/file.zst: Permission denied
|
zstd: out/file.zst: Permission denied
|
||||||
zstd: can't stat out/file.zst : Permission denied -- ignored
|
zstd: can't stat out/file.zst : Permission denied -- ignored
|
||||||
|
|||||||
+4
@@ -22,6 +22,10 @@ Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
|||||||
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isFdRegularFile(*)
|
||||||
|
Trace:FileStat: > UTIL_stat(*, )
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
||||||
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
||||||
Trace:FileStat: < 1
|
Trace:FileStat: < 1
|
||||||
+4
@@ -14,6 +14,10 @@ Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
|||||||
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isFdRegularFile(*)
|
||||||
|
Trace:FileStat: > UTIL_stat(*, )
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
Trace:FileStat: > UTIL_isRegularFile(file.zst)
|
||||||
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
Trace:FileStat: > UTIL_stat(-1, file.zst)
|
||||||
Trace:FileStat: < 1
|
Trace:FileStat: < 1
|
||||||
+4
@@ -22,6 +22,10 @@ Trace:FileStat: > UTIL_isRegularFile(file)
|
|||||||
Trace:FileStat: > UTIL_stat(-1, file)
|
Trace:FileStat: > UTIL_stat(-1, file)
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isFdRegularFile(*)
|
||||||
|
Trace:FileStat: > UTIL_stat(*, )
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
Trace:FileStat: > UTIL_isRegularFile(file)
|
Trace:FileStat: > UTIL_isRegularFile(file)
|
||||||
Trace:FileStat: > UTIL_stat(-1, file)
|
Trace:FileStat: > UTIL_stat(-1, file)
|
||||||
Trace:FileStat: < 1
|
Trace:FileStat: < 1
|
||||||
+4
@@ -14,6 +14,10 @@ Trace:FileStat: > UTIL_isRegularFile(file)
|
|||||||
Trace:FileStat: > UTIL_stat(-1, file)
|
Trace:FileStat: > UTIL_stat(-1, file)
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
Trace:FileStat: < 0
|
Trace:FileStat: < 0
|
||||||
|
Trace:FileStat: > UTIL_isFdRegularFile(*)
|
||||||
|
Trace:FileStat: > UTIL_stat(*, )
|
||||||
|
Trace:FileStat: < 1
|
||||||
|
Trace:FileStat: < 1
|
||||||
Trace:FileStat: > UTIL_isRegularFile(file)
|
Trace:FileStat: > UTIL_isRegularFile(file)
|
||||||
Trace:FileStat: > UTIL_stat(-1, file)
|
Trace:FileStat: > UTIL_stat(-1, file)
|
||||||
Trace:FileStat: < 1
|
Trace:FileStat: < 1
|
||||||
@@ -640,7 +640,7 @@ if __name__ == "__main__":
|
|||||||
help="Preserve the scratch directory TEST_DIR/scratch/ for debugging purposes."
|
help="Preserve the scratch directory TEST_DIR/scratch/ for debugging purposes."
|
||||||
)
|
)
|
||||||
parser.add_argument("--verbose", action="store_true", help="Verbose test output.")
|
parser.add_argument("--verbose", action="store_true", help="Verbose test output.")
|
||||||
parser.add_argument("--timeout", default=200, type=int, help="Test case timeout in seconds. Set to 0 to disable timeouts.")
|
parser.add_argument("--timeout", default=800, type=int, help="Test case timeout in seconds. Set to 0 to disable timeouts.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--exec-prefix",
|
"--exec-prefix",
|
||||||
default=None,
|
default=None,
|
||||||
@@ -705,6 +705,7 @@ if __name__ == "__main__":
|
|||||||
env["DATAGEN_BIN"] = os.path.abspath(args.datagen)
|
env["DATAGEN_BIN"] = os.path.abspath(args.datagen)
|
||||||
env["ZSTDGREP_BIN"] = os.path.abspath(args.zstdgrep)
|
env["ZSTDGREP_BIN"] = os.path.abspath(args.zstdgrep)
|
||||||
env["ZSTDLESS_BIN"] = os.path.abspath(args.zstdless)
|
env["ZSTDLESS_BIN"] = os.path.abspath(args.zstdless)
|
||||||
|
env["CLI_TESTS"] = os.path.abspath(args.test_dir)
|
||||||
env["COMMON"] = os.path.abspath(os.path.join(args.test_dir, "common"))
|
env["COMMON"] = os.path.abspath(os.path.join(args.test_dir, "common"))
|
||||||
env["PATH"] = bin_dir + ":" + os.getenv("PATH", "")
|
env["PATH"] = bin_dir + ":" + os.getenv("PATH", "")
|
||||||
env["LC_ALL"] = "C"
|
env["LC_ALL"] = "C"
|
||||||
|
|||||||
@@ -890,6 +890,7 @@ static int benchMem(unsigned scenarioID,
|
|||||||
if (!BMK_isSuccessful_runOutcome(bOutcome)) {
|
if (!BMK_isSuccessful_runOutcome(bOutcome)) {
|
||||||
DISPLAY("ERROR: Scenario %u: %s \n", scenarioID, ZSTD_getErrorName(BMK_extract_errorResult(bOutcome)));
|
DISPLAY("ERROR: Scenario %u: %s \n", scenarioID, ZSTD_getErrorName(BMK_extract_errorResult(bOutcome)));
|
||||||
errorcode = 1;
|
errorcode = 1;
|
||||||
|
BMK_freeTimedFnState(tfs);
|
||||||
goto _cleanOut;
|
goto _cleanOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,11 @@ void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer)
|
|||||||
return mem;
|
return mem;
|
||||||
} else {
|
} else {
|
||||||
uintptr_t ptr = 0;
|
uintptr_t ptr = 0;
|
||||||
/* Add +- 1M 50% of the time */
|
/* Return junk pointer 50% of the time */
|
||||||
if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
|
if (FUZZ_dataProducer_uint32Range(producer, 0, 1))
|
||||||
FUZZ_dataProducer_int32Range(producer, -1000000, 1000000);
|
ptr += FUZZ_dataProducer_int32Range(producer, -1000000, 1000000);
|
||||||
return (void*)ptr;
|
return (void*)ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size)
|
int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ void* FUZZ_malloc(size_t size);
|
|||||||
/**
|
/**
|
||||||
* malloc except returns random pointer for zero sized data and FUZZ_ASSERT
|
* malloc except returns random pointer for zero sized data and FUZZ_ASSERT
|
||||||
* that malloc doesn't fail.
|
* that malloc doesn't fail.
|
||||||
|
* WARNING: Only free the returned pointer if size > 0!
|
||||||
*/
|
*/
|
||||||
void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer);
|
void* FUZZ_malloc_rand(size_t size, FUZZ_dataProducer_t *producer);
|
||||||
|
|
||||||
|
|||||||
+385
@@ -44,6 +44,14 @@
|
|||||||
/* must be included after util.h, due to ERROR macro redefinition issue on Visual Studio */
|
/* must be included after util.h, due to ERROR macro redefinition issue on Visual Studio */
|
||||||
#include "zstd_internal.h" /* ZSTD_WORKSPACETOOLARGE_MAXDURATION, ZSTD_WORKSPACETOOLARGE_FACTOR, KB, MB */
|
#include "zstd_internal.h" /* ZSTD_WORKSPACETOOLARGE_MAXDURATION, ZSTD_WORKSPACETOOLARGE_FACTOR, KB, MB */
|
||||||
#include "threading.h" /* ZSTD_pthread_create, ZSTD_pthread_join */
|
#include "threading.h" /* ZSTD_pthread_create, ZSTD_pthread_join */
|
||||||
|
#include "compress/hist.h" /* HIST_count_wksp */
|
||||||
|
#include "compress/zstd_compress_internal.h" /* ZSTD_get1BlockSummary */
|
||||||
|
|
||||||
|
|
||||||
|
/*-************************************
|
||||||
|
* Macros
|
||||||
|
**************************************/
|
||||||
|
#define COUNTOF(array) (sizeof(array) / sizeof(*(array)))
|
||||||
|
|
||||||
|
|
||||||
/*-************************************
|
/*-************************************
|
||||||
@@ -567,6 +575,123 @@ static void test_decompressBound(unsigned tnb)
|
|||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned test_histCountWksp(unsigned seed, unsigned testNb)
|
||||||
|
{
|
||||||
|
static const unsigned symLowLimits[] = { 0, 27, 0, 0, 27, 42, 0, 0, 27, 42, 27, 42 };
|
||||||
|
static const unsigned symHighLimits[] = { 255, 255, 210, 110, 42, 42, 210, 110, 42, 42, 42, 42 };
|
||||||
|
static const unsigned symMaxLimits[] = { 255, 255, 255, 255, 255, 255, 230, 130, 99, 99, 42, 42 };
|
||||||
|
static const size_t inputSizes[] = { 3367, 1761, 893, 117 };
|
||||||
|
unsigned workspace[HIST_WKSP_SIZE_U32];
|
||||||
|
size_t res, i, is, il;
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : HIST_count_wksp with empty source : ", testNb++);
|
||||||
|
{
|
||||||
|
/* With NULL source UBSan of older Clang could fail: applying zero offset to null pointer. */
|
||||||
|
static const unsigned char source[4] = { 0 };
|
||||||
|
unsigned count[1] = { 0 };
|
||||||
|
unsigned maxSym = 0;
|
||||||
|
res = HIST_count_wksp(count, &maxSym, source, 0, workspace, sizeof(workspace));
|
||||||
|
CHECK_EQ(res, 0);
|
||||||
|
CHECK_EQ(maxSym, 0);
|
||||||
|
CHECK_EQ(count[0], 0);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
#if HIST_WKSP_SIZE_U32
|
||||||
|
DISPLAYLEVEL(3, "test%3u : HIST_count_wksp with small workspace : ", testNb++);
|
||||||
|
{
|
||||||
|
unsigned count[1] = { 0 };
|
||||||
|
unsigned maxSym = 0;
|
||||||
|
res = HIST_count_wksp(count, &maxSym, NULL, 0, workspace, sizeof(workspace) - 1);
|
||||||
|
CHECK_EQ(res, ERROR(workSpace_tooSmall));
|
||||||
|
CHECK_EQ(maxSym, 0);
|
||||||
|
CHECK_EQ(count[0], 0);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : HIST_count_wksp with wrong workspace alignment : ", testNb++);
|
||||||
|
{
|
||||||
|
unsigned count[1] = { 0 };
|
||||||
|
unsigned maxSym = 0;
|
||||||
|
res = HIST_count_wksp(count, &maxSym, NULL, 0, (unsigned*)(void*)((char*)workspace + 1), sizeof(workspace));
|
||||||
|
CHECK_EQ(res, ERROR(GENERIC));
|
||||||
|
CHECK_EQ(maxSym, 0);
|
||||||
|
CHECK_EQ(count[0], 0);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : HIST_count_wksp with symbol out of range, small size : ", testNb++);
|
||||||
|
{
|
||||||
|
/* For less elements HIST_count_parallel_wksp would fail. */
|
||||||
|
static const unsigned char source[4] = { 1, 4, 0, 2 };
|
||||||
|
static const unsigned expected[6] = { 0 };
|
||||||
|
unsigned count[6] = { 0 };
|
||||||
|
unsigned maxSym = 2;
|
||||||
|
res = HIST_count_wksp(count, &maxSym, source, sizeof(source), workspace, sizeof(workspace));
|
||||||
|
CHECK_EQ(res, ERROR(maxSymbolValue_tooSmall));
|
||||||
|
CHECK_EQ(maxSym, 2);
|
||||||
|
for (i = 0; i < COUNTOF(expected); ++i) CHECK_EQ(count[i], expected[i]);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : HIST_count_wksp with symbol out of range, medium size : ", testNb++);
|
||||||
|
{
|
||||||
|
unsigned char source[3407];
|
||||||
|
unsigned count[6] = { 0 };
|
||||||
|
unsigned maxSym = 2;
|
||||||
|
for (i = 0; i < COUNTOF(source); ++i) {
|
||||||
|
source[i] = (48271 * (i + 1)) & 3;
|
||||||
|
}
|
||||||
|
res = HIST_count_wksp(count, &maxSym, source, sizeof(source), workspace, sizeof(workspace));
|
||||||
|
CHECK_EQ(res, ERROR(maxSymbolValue_tooSmall));
|
||||||
|
CHECK_EQ(maxSym, 2);
|
||||||
|
for (i = 0; i < COUNTOF(count); ++i) CHECK_EQ(count[i], 0);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
for (il = 0; il < COUNTOF(symMaxLimits); ++il) {
|
||||||
|
unsigned symMax = symMaxLimits[il];
|
||||||
|
unsigned symLow = symLowLimits[il];
|
||||||
|
unsigned symHigh = symHighLimits[il];
|
||||||
|
unsigned symRange = symHigh - symLow + 1;
|
||||||
|
|
||||||
|
for (is = 0; is < COUNTOF(inputSizes); ++is) {
|
||||||
|
unsigned char source[4000];
|
||||||
|
size_t inputSize = inputSizes[is];
|
||||||
|
assert(inputSize <= sizeof(source));
|
||||||
|
DISPLAYLEVEL(3, "test%3u : HIST_count_wksp test in [%u..%u], symMax: %u, inputSize: %u : ",
|
||||||
|
testNb++, symLow, symHigh, symMax, (unsigned)inputSize);
|
||||||
|
{
|
||||||
|
unsigned count[260] = { 0 };
|
||||||
|
unsigned expected[COUNTOF(count)] = { 0 };
|
||||||
|
unsigned maxSym = symMax;
|
||||||
|
unsigned realMaxSym = symMax;
|
||||||
|
unsigned maxCount = 0;
|
||||||
|
for (i = 0; i < inputSize; ++i) {
|
||||||
|
unsigned prng = (48271 * (i + seed)) % symRange + symLow;
|
||||||
|
source[i] = (unsigned char)prng;
|
||||||
|
++expected[prng];
|
||||||
|
}
|
||||||
|
/* for basic buffer overwrite checks */
|
||||||
|
for (i = maxSym + 1; i < COUNTOF(count); ++i) expected[i] = count[i] = ~0u;
|
||||||
|
for (i = 0; i <= maxSym; ++i) maxCount = MAX(maxCount, expected[i]);
|
||||||
|
for (i = realMaxSym; i > 0; --i) {
|
||||||
|
if (expected[i]) break;
|
||||||
|
--realMaxSym;
|
||||||
|
}
|
||||||
|
res = HIST_count_wksp(count, &maxSym, source, inputSize, workspace, sizeof(workspace));
|
||||||
|
CHECK_EQ(res, maxCount);
|
||||||
|
CHECK_EQ(maxSym, realMaxSym);
|
||||||
|
for (i = 0; i < COUNTOF(expected); ++i) CHECK_EQ(count[i], expected[i]);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return testNb;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_setCParams(unsigned tnb)
|
static void test_setCParams(unsigned tnb)
|
||||||
{
|
{
|
||||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
@@ -645,6 +770,210 @@ static void test_blockSplitter_incompressibleExpansionProtection(unsigned testNb
|
|||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t convertSequences_noRepcodes(SeqDef* dstSeqs, const ZSTD_Sequence* inSeqs,
|
||||||
|
size_t nbSequences);
|
||||||
|
|
||||||
|
static size_t convertSequences_noRepcodes_ref(
|
||||||
|
SeqDef* dstSeqs,
|
||||||
|
const ZSTD_Sequence* inSeqs,
|
||||||
|
size_t nbSequences)
|
||||||
|
{
|
||||||
|
size_t longLen = 0;
|
||||||
|
size_t n;
|
||||||
|
for (n=0; n<nbSequences; n++) {
|
||||||
|
dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
|
||||||
|
dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
|
||||||
|
dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
|
||||||
|
/* Check for long length > 65535. */
|
||||||
|
if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = n + 1;
|
||||||
|
}
|
||||||
|
if (UNLIKELY(inSeqs[n].litLength > 65535)) {
|
||||||
|
assert(longLen == 0);
|
||||||
|
longLen = n + nbSequences + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return longLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned test_convertSequences_noRepcodes(unsigned seed, unsigned testNb)
|
||||||
|
{
|
||||||
|
ZSTD_Sequence nsrc[12];
|
||||||
|
SeqDef ndst[12], rdst[12];
|
||||||
|
size_t ref, ret, i, j;
|
||||||
|
|
||||||
|
seed += 0xDEADBEEF;
|
||||||
|
for (i = 0; i < COUNTOF(nsrc); ++i) {
|
||||||
|
seed = 48271 * ((unsigned)i + seed);
|
||||||
|
nsrc[i].offset = (seed & 0xFFFF) | 1; /* Offset shall not be zero. */
|
||||||
|
seed = 48271 * ((unsigned)i + seed);
|
||||||
|
nsrc[i].litLength = seed & 0xFFFF;
|
||||||
|
seed = 48271 * ((unsigned)i + seed);
|
||||||
|
nsrc[i].matchLength = (seed & 0xFFFFFF) % (65536 + MINMATCH);
|
||||||
|
seed = 48271 * ((unsigned)i + seed);
|
||||||
|
nsrc[i].rep = seed & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For near overflow and proper negative value handling. */
|
||||||
|
nsrc[5].matchLength = 65535 + MINMATCH;
|
||||||
|
nsrc[6].litLength = 65535;
|
||||||
|
nsrc[6].matchLength = 0;
|
||||||
|
nsrc[7].litLength = 0;
|
||||||
|
nsrc[7].matchLength = MINMATCH;
|
||||||
|
|
||||||
|
for (i = 0; i <= COUNTOF(nsrc); ++i) {
|
||||||
|
DISPLAYLEVEL(3, "test%3u : convertSequences_noRepcodes with %u inputs : ",
|
||||||
|
testNb++, (unsigned)i);
|
||||||
|
memset(ndst, 0, sizeof(ndst));
|
||||||
|
memset(rdst, 0, sizeof(rdst));
|
||||||
|
ref = convertSequences_noRepcodes_ref(rdst, nsrc, i);
|
||||||
|
ret = convertSequences_noRepcodes(ndst, nsrc, i);
|
||||||
|
CHECK_EQ(ret, ref);
|
||||||
|
CHECK_EQ(memcmp(rdst, ndst, sizeof(ndst)), 0);
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
nsrc[7].matchLength = 65536 + MINMATCH;
|
||||||
|
for (i = 8; i <= COUNTOF(nsrc); ++i) {
|
||||||
|
DISPLAYLEVEL(3, "test%3u : convertSequences_noRepcodes with %u inputs and "
|
||||||
|
"matchLength overflow : ",
|
||||||
|
testNb++, (unsigned)i);
|
||||||
|
memset(ndst, 0, sizeof(ndst));
|
||||||
|
memset(rdst, 0, sizeof(rdst));
|
||||||
|
ref = convertSequences_noRepcodes_ref(rdst, nsrc, i);
|
||||||
|
ret = convertSequences_noRepcodes(ndst, nsrc, i);
|
||||||
|
CHECK_EQ(ret, ref);
|
||||||
|
CHECK_EQ(memcmp(rdst, ndst, sizeof(ndst)), 0);
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
assert(COUNTOF(nsrc) > 8);
|
||||||
|
for (j = 4; j < 8; ++j) {
|
||||||
|
DISPLAYLEVEL(3, "test%3u : convertSequences_noRepcodes with %u inputs and "
|
||||||
|
"matchLength overflow #%u : ",
|
||||||
|
testNb++, (unsigned)i, (unsigned)(i - j));
|
||||||
|
memset(ndst, 0, sizeof(ndst));
|
||||||
|
memset(rdst, 0, sizeof(rdst));
|
||||||
|
ref = convertSequences_noRepcodes_ref(rdst, nsrc + j, i - j);
|
||||||
|
ret = convertSequences_noRepcodes(ndst, nsrc + j, i - j);
|
||||||
|
CHECK_EQ(ret, ref);
|
||||||
|
CHECK_EQ(memcmp(rdst, ndst, sizeof(ndst)), 0);
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nsrc[7].matchLength = 1;
|
||||||
|
|
||||||
|
nsrc[7].litLength = 65536;
|
||||||
|
for (i = 8; i <= COUNTOF(nsrc); ++i) {
|
||||||
|
DISPLAYLEVEL(3, "test%3u : convertSequences_noRepcodes with %u inputs and "
|
||||||
|
"litLength overflow: ",
|
||||||
|
testNb++, (unsigned)i);
|
||||||
|
memset(ndst, 0, sizeof(ndst));
|
||||||
|
memset(rdst, 0, sizeof(rdst));
|
||||||
|
ref = convertSequences_noRepcodes_ref(rdst, nsrc, i);
|
||||||
|
ret = convertSequences_noRepcodes(ndst, nsrc, i);
|
||||||
|
CHECK_EQ(ret, ref);
|
||||||
|
CHECK_EQ(memcmp(rdst, ndst, sizeof(ndst)), 0);
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
assert(COUNTOF(nsrc) > 8);
|
||||||
|
for (j = 4; j < 8; ++j) {
|
||||||
|
DISPLAYLEVEL(3, "test%3u : convertSequences_noRepcodes with %u inputs and "
|
||||||
|
"litLength overflow #%u: ",
|
||||||
|
testNb++, (unsigned)i, (unsigned)(i - j));
|
||||||
|
memset(ndst, 0, sizeof(ndst));
|
||||||
|
memset(rdst, 0, sizeof(rdst));
|
||||||
|
ref = convertSequences_noRepcodes_ref(rdst, nsrc + j, i - j);
|
||||||
|
ret = convertSequences_noRepcodes(ndst, nsrc + j, i - j);
|
||||||
|
CHECK_EQ(ret, ref);
|
||||||
|
CHECK_EQ(memcmp(rdst, ndst, sizeof(ndst)), 0);
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return testNb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned test_get1BlockSummary(unsigned testNb)
|
||||||
|
{
|
||||||
|
static const ZSTD_Sequence nseqs[] = {
|
||||||
|
{ 10, 2, 4, 1 },
|
||||||
|
{ 20, 3, 5, 2 },
|
||||||
|
{ 30, 6, 8, 3 },
|
||||||
|
{ 40, 7, 9, 4 },
|
||||||
|
{ 50, 10, 12, 5 },
|
||||||
|
{ 60, 11, 13, 6 },
|
||||||
|
{ 0, 14, 0, 7 },
|
||||||
|
{ 70, 15, 17, 8 },
|
||||||
|
{ 80, 16, 18, 9 },
|
||||||
|
{ 90, 19, 21, 1 },
|
||||||
|
{ 99, 20, 22, 2 },
|
||||||
|
};
|
||||||
|
static const BlockSummary blocks[] = {
|
||||||
|
{ 7, 104, 53 },
|
||||||
|
{ 6, 98, 51 },
|
||||||
|
{ 5, 90, 48 },
|
||||||
|
{ 4, 76, 42 },
|
||||||
|
{ 3, 60, 35 },
|
||||||
|
{ 2, 38, 25 },
|
||||||
|
{ 1, 14, 14 },
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : ZSTD_get1BlockSummary with empty array : ", testNb++);
|
||||||
|
{
|
||||||
|
BlockSummary bs = ZSTD_get1BlockSummary(nseqs, 0);
|
||||||
|
CHECK_EQ(bs.nbSequences, ERROR(externalSequences_invalid));
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : ZSTD_get1BlockSummary with 1 literal only : ", testNb++);
|
||||||
|
{
|
||||||
|
static const ZSTD_Sequence seqs[] = { { 0, 5, 0, 0 } };
|
||||||
|
BlockSummary bs = ZSTD_get1BlockSummary(seqs, 1);
|
||||||
|
CHECK_EQ(bs.nbSequences, 1);
|
||||||
|
CHECK_EQ(bs.litSize, 5);
|
||||||
|
CHECK_EQ(bs.blockSize, 5);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : ZSTD_get1BlockSummary with no terminator : ", testNb++);
|
||||||
|
{
|
||||||
|
static const ZSTD_Sequence seqs[] = { { 10, 2, 4, 0 }, { 20, 3, 5, 0 } };
|
||||||
|
BlockSummary bs = ZSTD_get1BlockSummary(seqs, 2);
|
||||||
|
CHECK_EQ(bs.nbSequences, ERROR(externalSequences_invalid));
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3u : ZSTD_get1BlockSummary with rep ignored : ", testNb++);
|
||||||
|
{
|
||||||
|
static const ZSTD_Sequence seqs[] = {
|
||||||
|
{ 10, 2, 4, 2 },
|
||||||
|
{ 10, 3, 5, 2 },
|
||||||
|
{ 0, 7, 0, 3 },
|
||||||
|
};
|
||||||
|
BlockSummary bs = ZSTD_get1BlockSummary(seqs, 3);
|
||||||
|
CHECK_EQ(bs.nbSequences, 3);
|
||||||
|
CHECK_EQ(bs.litSize, 2 + 3 + 7);
|
||||||
|
CHECK_EQ(bs.blockSize, (4 + 5) + (2 + 3 + 7));
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
assert(COUNTOF(nseqs) > COUNTOF(blocks));
|
||||||
|
for (i = 0; i < COUNTOF(blocks); ++i) {
|
||||||
|
BlockSummary bs;
|
||||||
|
DISPLAYLEVEL(3, "test%3u : ZSTD_get1BlockSummary with %u inputs : ",
|
||||||
|
testNb++, (unsigned)(COUNTOF(nseqs) - i));
|
||||||
|
bs = ZSTD_get1BlockSummary(nseqs + i, COUNTOF(nseqs) - i);
|
||||||
|
CHECK_EQ(bs.nbSequences, blocks[i].nbSequences);
|
||||||
|
CHECK_EQ(bs.litSize, blocks[i].litSize);
|
||||||
|
CHECK_EQ(bs.blockSize, blocks[i].blockSize);
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return testNb;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================================= */
|
/* ============================================================= */
|
||||||
|
|
||||||
static int basicUnitTests(U32 const seed, double compressibility)
|
static int basicUnitTests(U32 const seed, double compressibility)
|
||||||
@@ -712,6 +1041,8 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
|||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
testNb = test_histCountWksp(seed, testNb);
|
||||||
|
|
||||||
DISPLAYLEVEL(3, "test%3u : compress %u bytes : ", testNb++, (unsigned)CNBuffSize);
|
DISPLAYLEVEL(3, "test%3u : compress %u bytes : ", testNb++, (unsigned)CNBuffSize);
|
||||||
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
{ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
if (cctx==NULL) goto _output_error;
|
if (cctx==NULL) goto _output_error;
|
||||||
@@ -1083,6 +1414,37 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
|||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3i : ldm hashRateLog > windowLog underflow check : ", testNb++);
|
||||||
|
{
|
||||||
|
/* Test that when windowLog < hashRateLog, we don't get excessive memory usage
|
||||||
|
* due to underflow in hashLog calculation (windowLog - hashRateLog). */
|
||||||
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
|
|
||||||
|
size_t const size = (1U << 10); // 1 KB
|
||||||
|
size_t const dstCapacity = ZSTD_compressBound(size);
|
||||||
|
void* src = (void*)malloc(size);
|
||||||
|
void* dst = (void*)malloc(dstCapacity);
|
||||||
|
|
||||||
|
RDG_genBuffer(src, size, 0.5, 0.5, seed);
|
||||||
|
|
||||||
|
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable));
|
||||||
|
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_ldmHashLog, 0));
|
||||||
|
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 12));
|
||||||
|
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_ldmHashRateLog, 13));
|
||||||
|
|
||||||
|
CHECK_Z(ZSTD_compress2(cctx, dst, dstCapacity, src, size));
|
||||||
|
|
||||||
|
{ size_t const cctxSize = ZSTD_sizeof_CCtx(cctx);
|
||||||
|
DISPLAYLEVEL(3, "CCtx size: %u bytes ", (unsigned)cctxSize);
|
||||||
|
CHECK_LT(cctxSize, 50 MB);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZSTD_freeCCtx(cctx);
|
||||||
|
free(src);
|
||||||
|
free(dst);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
DISPLAYLEVEL(3, "test%3i : testing dict compression with enableLdm and forceMaxWindow : ", testNb++);
|
DISPLAYLEVEL(3, "test%3i : testing dict compression with enableLdm and forceMaxWindow : ", testNb++);
|
||||||
{
|
{
|
||||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||||
@@ -2184,6 +2546,25 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
DISPLAYLEVEL(3, "test%3i : estimation functions with LDM enabled (issue #4590) : ", testNb++);
|
||||||
|
{
|
||||||
|
/* ZSTD_estimateCCtxSize_usingCCtxParams must adjust zeroed-out
|
||||||
|
* LDM parameters when LDM is enabled, to avoid division by zero
|
||||||
|
* in ZSTD_ldm_getMaxNbSeq. */
|
||||||
|
ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
|
||||||
|
size_t cctxSize;
|
||||||
|
CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_compressionLevel, 22));
|
||||||
|
CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_enableLongDistanceMatching, ZSTD_ps_enable));
|
||||||
|
cctxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
|
||||||
|
if (ZSTD_isError(cctxSize)) goto _output_error;
|
||||||
|
if (cctxSize == 0) goto _output_error;
|
||||||
|
cctxSize = ZSTD_estimateCStreamSize_usingCCtxParams(params);
|
||||||
|
if (ZSTD_isError(cctxSize)) goto _output_error;
|
||||||
|
if (cctxSize == 0) goto _output_error;
|
||||||
|
ZSTD_freeCCtxParams(params);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
}
|
}
|
||||||
free(staticCCtxBuffer);
|
free(staticCCtxBuffer);
|
||||||
free(staticDCtxBuffer);
|
free(staticDCtxBuffer);
|
||||||
@@ -3878,6 +4259,10 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
|||||||
}
|
}
|
||||||
DISPLAYLEVEL(3, "OK \n");
|
DISPLAYLEVEL(3, "OK \n");
|
||||||
|
|
||||||
|
testNb = test_convertSequences_noRepcodes(seed, testNb);
|
||||||
|
|
||||||
|
testNb = test_get1BlockSummary(testNb);
|
||||||
|
|
||||||
DISPLAYLEVEL(3, "test%3i : ZSTD_compressSequencesAndLiterals : ", testNb++);
|
DISPLAYLEVEL(3, "test%3i : ZSTD_compressSequencesAndLiterals : ", testNb++);
|
||||||
{
|
{
|
||||||
const size_t srcSize = 497000;
|
const size_t srcSize = 497000;
|
||||||
|
|||||||
+18
-15
@@ -70,37 +70,38 @@ int main(int argc, const char** argv)
|
|||||||
char* buffer = (char*)malloc(bufferSize);
|
char* buffer = (char*)malloc(bufferSize);
|
||||||
void* out = malloc(outSize);
|
void* out = malloc(outSize);
|
||||||
void* roundtrip = malloc(dataSize);
|
void* roundtrip = malloc(dataSize);
|
||||||
|
int _exit_code = 1;
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
if (!buffer || !out || !roundtrip || !cctx || !dctx) {
|
if (!buffer || !out || !roundtrip || !cctx || !dctx) {
|
||||||
fprintf(stderr, "Allocation failure\n");
|
fprintf(stderr, "Allocation failure\n");
|
||||||
return 1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 31)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 31)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_overlapLog, 9)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_overlapLog, 9)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, ZSTD_btopt)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, ZSTD_btopt)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, 7)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, 7)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 7)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 7)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, 1)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, 1)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, 10)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, 10)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, 10)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, 10)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
|
|
||||||
if (ZSTD_isError(ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 31)))
|
if (ZSTD_isError(ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 31)))
|
||||||
return 1;
|
goto cleanup;
|
||||||
|
|
||||||
RDG_genBuffer(buffer, bufferSize, 1.0, 0.0, 0xbeefcafe);
|
RDG_genBuffer(buffer, bufferSize, 1.0, 0.0, 0xbeefcafe);
|
||||||
|
|
||||||
@@ -110,19 +111,21 @@ int main(int argc, const char** argv)
|
|||||||
for (i = 0; i < 10; ++i) {
|
for (i = 0; i < 10; ++i) {
|
||||||
fprintf(stderr, "Compressing 1 GB\n");
|
fprintf(stderr, "Compressing 1 GB\n");
|
||||||
if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_continue))
|
if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_continue))
|
||||||
return 1;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Compressing 1 GB\n");
|
fprintf(stderr, "Compressing 1 GB\n");
|
||||||
if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_end))
|
if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_end))
|
||||||
return 1;
|
goto cleanup;
|
||||||
|
|
||||||
|
_exit_code = 0;
|
||||||
fprintf(stderr, "Success!\n");
|
fprintf(stderr, "Success!\n");
|
||||||
|
|
||||||
|
cleanup:
|
||||||
free(roundtrip);
|
free(roundtrip);
|
||||||
free(out);
|
free(out);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
ZSTD_freeDCtx(dctx);
|
ZSTD_freeDCtx(dctx);
|
||||||
ZSTD_freeCCtx(cctx);
|
ZSTD_freeCCtx(cctx);
|
||||||
return 0;
|
return _exit_code;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ static int testSimpleAPI(void)
|
|||||||
} else {
|
} else {
|
||||||
DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret));
|
DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret));
|
||||||
}
|
}
|
||||||
|
free(output);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ret != size) {
|
if (ret != size) {
|
||||||
@@ -64,6 +65,7 @@ static int testSimpleAPI(void)
|
|||||||
}
|
}
|
||||||
if (memcmp(EXPECTED, output, size) != 0) {
|
if (memcmp(EXPECTED, output, size) != 0) {
|
||||||
DISPLAY("ERROR: Wrong decoded output produced\n");
|
DISPLAY("ERROR: Wrong decoded output produced\n");
|
||||||
|
free(output);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-6
@@ -21,14 +21,14 @@ mustBeAbsent() {
|
|||||||
$ECHO "$@ correctly not present" # for some reason, this $ECHO must exist, otherwise mustBeAbsent() always fails (??)
|
$ECHO "$@ correctly not present" # for some reason, this $ECHO must exist, otherwise mustBeAbsent() always fails (??)
|
||||||
}
|
}
|
||||||
|
|
||||||
# default compilation : all features enabled - no zbuff
|
# default compilation : all features enabled - no zbuff, no legacy
|
||||||
$ECHO "testing default library compilation"
|
$ECHO "testing default library compilation"
|
||||||
CFLAGS= make -C $DIR/../lib libzstd libzstd.a > $INTOVOID
|
CFLAGS= make -C $DIR/../lib libzstd libzstd.a > $INTOVOID
|
||||||
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
||||||
isPresent "zstd_compress.o"
|
isPresent "zstd_compress.o"
|
||||||
isPresent "zstd_decompress.o"
|
isPresent "zstd_decompress.o"
|
||||||
isPresent "zdict.o"
|
isPresent "zdict.o"
|
||||||
isPresent "zstd_v07.o"
|
mustBeAbsent "zstd_v07.o"
|
||||||
mustBeAbsent "zbuff_compress.o"
|
mustBeAbsent "zbuff_compress.o"
|
||||||
$RM tmplog
|
$RM tmplog
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
|||||||
mustBeAbsent "zstd_compress.o"
|
mustBeAbsent "zstd_compress.o"
|
||||||
isPresent "zstd_decompress.o"
|
isPresent "zstd_decompress.o"
|
||||||
mustBeAbsent "zdict.o"
|
mustBeAbsent "zdict.o"
|
||||||
isPresent "zstd_v07.o"
|
mustBeAbsent "zstd_v07.o"
|
||||||
mustBeAbsent "zbuff_compress.o"
|
mustBeAbsent "zbuff_compress.o"
|
||||||
$RM $DIR/../lib/libzstd.a tmplog
|
$RM $DIR/../lib/libzstd.a tmplog
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
|||||||
isPresent "zstd_compress.o"
|
isPresent "zstd_compress.o"
|
||||||
isPresent "zstd_decompress.o"
|
isPresent "zstd_decompress.o"
|
||||||
isPresent "zdict.o"
|
isPresent "zdict.o"
|
||||||
isPresent "zstd_v07.o"
|
mustBeAbsent "zstd_v07.o"
|
||||||
mustBeAbsent "zbuff_compress.o"
|
mustBeAbsent "zbuff_compress.o"
|
||||||
$RM $DIR/../lib/libzstd.a tmplog
|
$RM $DIR/../lib/libzstd.a tmplog
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
|||||||
isPresent "zstd_compress.o"
|
isPresent "zstd_compress.o"
|
||||||
isPresent "zstd_decompress.o"
|
isPresent "zstd_decompress.o"
|
||||||
isPresent "zdict.o"
|
isPresent "zdict.o"
|
||||||
isPresent "zstd_v07.o"
|
mustBeAbsent "zstd_v07.o"
|
||||||
isPresent "zbuff_compress.o"
|
isPresent "zbuff_compress.o"
|
||||||
$RM $DIR/../lib/libzstd.a tmplog
|
$RM $DIR/../lib/libzstd.a tmplog
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
|||||||
isPresent "zstd_compress.o"
|
isPresent "zstd_compress.o"
|
||||||
isPresent "zstd_decompress.o"
|
isPresent "zstd_decompress.o"
|
||||||
mustBeAbsent "zdict.o"
|
mustBeAbsent "zdict.o"
|
||||||
isPresent "zstd_v07.o"
|
mustBeAbsent "zstd_v07.o"
|
||||||
mustBeAbsent "zbuff_compress.o"
|
mustBeAbsent "zbuff_compress.o"
|
||||||
$RM $DIR/../lib/libzstd.a tmplog
|
$RM $DIR/../lib/libzstd.a tmplog
|
||||||
|
|
||||||
@@ -102,3 +102,14 @@ mustBeAbsent "zdict.o"
|
|||||||
mustBeAbsent "zstd_v07.o"
|
mustBeAbsent "zstd_v07.o"
|
||||||
mustBeAbsent "zbuff_compress.o"
|
mustBeAbsent "zbuff_compress.o"
|
||||||
$RM $DIR/../lib/libzstd.a tmplog
|
$RM $DIR/../lib/libzstd.a tmplog
|
||||||
|
|
||||||
|
# legacy support explicitly enabled
|
||||||
|
$ECHO "testing with legacy support explicitly enabled"
|
||||||
|
ZSTD_LEGACY_SUPPORT=5 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID
|
||||||
|
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
|
||||||
|
isPresent "zstd_compress.o"
|
||||||
|
isPresent "zstd_decompress.o"
|
||||||
|
isPresent "zdict.o"
|
||||||
|
isPresent "zstd_v07.o"
|
||||||
|
mustBeAbsent "zbuff_compress.o"
|
||||||
|
$RM $DIR/../lib/libzstd.a tmplog
|
||||||
|
|||||||
+38
-17
@@ -39,24 +39,39 @@ int main(int argc, const char** argv)
|
|||||||
unsigned windowLog = 18;
|
unsigned windowLog = 18;
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
int _exit_code = 0;
|
||||||
/* Create stream */
|
/* Create stream */
|
||||||
ctx = ZSTD_createCCtx();
|
ctx = ZSTD_createCCtx();
|
||||||
if (!ctx) { return 1; }
|
if (!ctx) { return 1; }
|
||||||
/* Set parameters */
|
/* Set parameters */
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, windowLog)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_windowLog, windowLog))) {
|
||||||
return 2;
|
_exit_code = 2;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, 13)))
|
goto _clean_ctx;
|
||||||
return 2;
|
}
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, 14)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_chainLog, 13))) {
|
||||||
return 2;
|
_exit_code = 2;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, 1)))
|
goto _clean_ctx;
|
||||||
return 2;
|
}
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, 7)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_hashLog, 14))) {
|
||||||
return 2;
|
_exit_code = 2;
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, 16)))
|
goto _clean_ctx;
|
||||||
return 2;
|
}
|
||||||
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, ZSTD_fast)))
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_searchLog, 1))) {
|
||||||
return 2;
|
_exit_code = 2;
|
||||||
|
goto _clean_ctx;
|
||||||
|
}
|
||||||
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, 7))) {
|
||||||
|
_exit_code = 2;
|
||||||
|
goto _clean_ctx;
|
||||||
|
}
|
||||||
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, 16))) {
|
||||||
|
_exit_code = 2;
|
||||||
|
goto _clean_ctx;
|
||||||
|
}
|
||||||
|
if (ZSTD_isError(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, ZSTD_fast))) {
|
||||||
|
_exit_code = 2;
|
||||||
|
goto _clean_ctx;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
U64 compressed = 0;
|
U64 compressed = 0;
|
||||||
const U64 toCompress = ((U64)1) << 33;
|
const U64 toCompress = ((U64)1) << 33;
|
||||||
@@ -81,22 +96,28 @@ int main(int argc, const char** argv)
|
|||||||
}
|
}
|
||||||
printf("Compressing, trying to generate a segfault \n");
|
printf("Compressing, trying to generate a segfault \n");
|
||||||
if (compress(ctx, out, srcBuffer, size)) {
|
if (compress(ctx, out, srcBuffer, size)) {
|
||||||
return 1;
|
_exit_code = 1;
|
||||||
|
goto _clean_buffer;
|
||||||
}
|
}
|
||||||
compressed += size;
|
compressed += size;
|
||||||
while (compressed < toCompress) {
|
while (compressed < toCompress) {
|
||||||
const size_t block = rand() % (size - pos + 1);
|
const size_t block = rand() % (size - pos + 1);
|
||||||
if (pos == size) { pos = 0; }
|
if (pos == size) { pos = 0; }
|
||||||
if (compress(ctx, out, srcBuffer + pos, block)) {
|
if (compress(ctx, out, srcBuffer + pos, block)) {
|
||||||
return 1;
|
_exit_code = 1;
|
||||||
|
goto _clean_buffer;
|
||||||
}
|
}
|
||||||
pos += block;
|
pos += block;
|
||||||
compressed += block;
|
compressed += block;
|
||||||
}
|
}
|
||||||
printf("Compression completed successfully (no error triggered)\n");
|
printf("Compression completed successfully (no error triggered)\n");
|
||||||
|
|
||||||
|
_clean_buffer:
|
||||||
free(srcBuffer);
|
free(srcBuffer);
|
||||||
free(dstBuffer);
|
free(dstBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_clean_ctx:
|
||||||
ZSTD_freeCCtx(ctx);
|
ZSTD_freeCCtx(ctx);
|
||||||
return 0;
|
return _exit_code;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1242,7 +1242,7 @@ static int createBuffers(buffers_t* buff, const char* const * const fileNamesTab
|
|||||||
size_t n;
|
size_t n;
|
||||||
size_t totalSizeToLoad = (size_t)UTIL_getTotalFileSize(fileNamesTable, (U32)nbFiles);
|
size_t totalSizeToLoad = (size_t)UTIL_getTotalFileSize(fileNamesTable, (U32)nbFiles);
|
||||||
size_t benchedSize = MIN(BMK_findMaxMem(totalSizeToLoad * 3) / 3, totalSizeToLoad);
|
size_t benchedSize = MIN(BMK_findMaxMem(totalSizeToLoad * 3) / 3, totalSizeToLoad);
|
||||||
size_t* fileSizes = calloc(sizeof(size_t), nbFiles);
|
size_t* fileSizes = calloc(nbFiles, sizeof(size_t));
|
||||||
void* srcBuffer = NULL;
|
void* srcBuffer = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -1457,7 +1457,7 @@ createMemoTableArray(const paramValues_t p,
|
|||||||
const size_t varyLen,
|
const size_t varyLen,
|
||||||
const U32 memoTableLog)
|
const U32 memoTableLog)
|
||||||
{
|
{
|
||||||
memoTable_t* const mtAll = (memoTable_t*)calloc(sizeof(memoTable_t),(ZSTD_STRATEGY_MAX + 1));
|
memoTable_t* const mtAll = (memoTable_t*)calloc((ZSTD_STRATEGY_MAX + 1), sizeof(memoTable_t));
|
||||||
ZSTD_strategy i, stratMin = ZSTD_STRATEGY_MIN, stratMax = ZSTD_STRATEGY_MAX;
|
ZSTD_strategy i, stratMin = ZSTD_STRATEGY_MIN, stratMax = ZSTD_STRATEGY_MAX;
|
||||||
|
|
||||||
if(mtAll == NULL) {
|
if(mtAll == NULL) {
|
||||||
@@ -1494,7 +1494,7 @@ createMemoTableArray(const paramValues_t p,
|
|||||||
mtl = ((size_t)1 << memoTableLog);
|
mtl = ((size_t)1 << memoTableLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtAll[i].table = (BYTE*)calloc(sizeof(BYTE), mtl);
|
mtAll[i].table = (BYTE*)calloc(mtl, sizeof(BYTE));
|
||||||
mtAll[i].tableLen = mtl;
|
mtAll[i].tableLen = mtl;
|
||||||
|
|
||||||
if(mtAll[i].table == NULL) {
|
if(mtAll[i].table == NULL) {
|
||||||
|
|||||||
+44
-35
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
set -e # exit immediately on error
|
set -e # exit immediately on error
|
||||||
# set -x # print commands before execution (debug)
|
set -x # print commands before execution (debug)
|
||||||
|
|
||||||
unset ZSTD_CLEVEL
|
unset ZSTD_CLEVEL
|
||||||
unset ZSTD_NBTHREADS
|
unset ZSTD_NBTHREADS
|
||||||
@@ -16,13 +16,7 @@ datagen() {
|
|||||||
"$DATAGEN_BIN" "$@"
|
"$DATAGEN_BIN" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
zstd() {
|
alias zstd='$EXE_PREFIX $ZSTD_BIN'
|
||||||
if [ -z "$EXE_PREFIX" ]; then
|
|
||||||
"$ZSTD_BIN" "$@"
|
|
||||||
else
|
|
||||||
"$EXE_PREFIX" "$ZSTD_BIN" "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
sudoZstd() {
|
sudoZstd() {
|
||||||
if [ -z "$EXE_PREFIX" ]; then
|
if [ -z "$EXE_PREFIX" ]; then
|
||||||
@@ -49,7 +43,7 @@ roundTripTest() {
|
|||||||
rm -f tmp1 tmp2
|
rm -f tmp1 tmp2
|
||||||
println "roundTripTest: datagen $1 $proba | zstd -v$cLevel | zstd -d$dLevel"
|
println "roundTripTest: datagen $1 $proba | zstd -v$cLevel | zstd -d$dLevel"
|
||||||
datagen $1 $proba | $MD5SUM > tmp1
|
datagen $1 $proba | $MD5SUM > tmp1
|
||||||
datagen $1 $proba | zstd --ultra -v$cLevel | zstd -d$dLevel | $MD5SUM > tmp2
|
datagen $1 $proba | zstd -T0 --ultra -v$cLevel | zstd -d$dLevel | $MD5SUM > tmp2
|
||||||
$DIFF -q tmp1 tmp2
|
$DIFF -q tmp1 tmp2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +65,7 @@ fileRoundTripTest() {
|
|||||||
println "fileRoundTripTest: datagen $1 $local_p > tmp && zstd -v$local_c -c tmp | zstd -d$local_d"
|
println "fileRoundTripTest: datagen $1 $local_p > tmp && zstd -v$local_c -c tmp | zstd -d$local_d"
|
||||||
datagen $1 $local_p > tmp
|
datagen $1 $local_p > tmp
|
||||||
< tmp $MD5SUM > tmp.md5.1
|
< tmp $MD5SUM > tmp.md5.1
|
||||||
zstd --ultra -v$local_c -c tmp | zstd -d$local_d | $MD5SUM > tmp.md5.2
|
zstd -T0 --ultra -v$local_c -c tmp | zstd -d$local_d | $MD5SUM > tmp.md5.2
|
||||||
$DIFF -q tmp.md5.1 tmp.md5.2
|
$DIFF -q tmp.md5.1 tmp.md5.2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,6 +848,7 @@ ls tmp* > tmpList
|
|||||||
zstd -f tmp1 --filelist=tmpList --filelist=tmpList tmp2 tmp3 # can trigger an overflow of internal file list
|
zstd -f tmp1 --filelist=tmpList --filelist=tmpList tmp2 tmp3 # can trigger an overflow of internal file list
|
||||||
rm -rf tmp*
|
rm -rf tmp*
|
||||||
|
|
||||||
|
|
||||||
println "\n===> --[no-]content-size tests"
|
println "\n===> --[no-]content-size tests"
|
||||||
|
|
||||||
datagen > tmp_contentsize
|
datagen > tmp_contentsize
|
||||||
@@ -1080,21 +1075,27 @@ cat tmp | zstd -14 -f --size-hint=11050 | zstd -t # slightly too high
|
|||||||
cat tmp | zstd -14 -f --size-hint=10950 | zstd -t # slightly too low
|
cat tmp | zstd -14 -f --size-hint=10950 | zstd -t # slightly too low
|
||||||
cat tmp | zstd -14 -f --size-hint=22000 | zstd -t # considerably too high
|
cat tmp | zstd -14 -f --size-hint=22000 | zstd -t # considerably too high
|
||||||
cat tmp | zstd -14 -f --size-hint=5500 | zstd -t # considerably too low
|
cat tmp | zstd -14 -f --size-hint=5500 | zstd -t # considerably too low
|
||||||
println "test : allows and interprets K,KB,KiB,M,MB and MiB suffix"
|
println "test : allows and interprets K,KB,KiB,M,MB,MiB,G,GB and GiB suffix"
|
||||||
cat tmp | zstd -14 -f --size-hint=11K | zstd -t
|
cat tmp | zstd -14 -f --size-hint=11K | zstd -t
|
||||||
cat tmp | zstd -14 -f --size-hint=11KB | zstd -t
|
cat tmp | zstd -14 -f --size-hint=11KB | zstd -t
|
||||||
cat tmp | zstd -14 -f --size-hint=11KiB | zstd -t
|
cat tmp | zstd -14 -f --size-hint=11KiB | zstd -t
|
||||||
cat tmp | zstd -14 -f --size-hint=1M | zstd -t
|
cat tmp | zstd -14 -f --size-hint=1M | zstd -t
|
||||||
cat tmp | zstd -14 -f --size-hint=1MB | zstd -t
|
cat tmp | zstd -14 -f --size-hint=1MB | zstd -t
|
||||||
cat tmp | zstd -14 -f --size-hint=1MiB | zstd -t
|
cat tmp | zstd -14 -f --size-hint=1MiB | zstd -t
|
||||||
|
cat tmp | zstd -14 -f --size-hint=1G | zstd -t
|
||||||
|
cat tmp | zstd -14 -f --size-hint=1GB | zstd -t
|
||||||
|
cat tmp | zstd -14 -f --size-hint=1GiB | zstd -t
|
||||||
|
cat tmp | zstd -14 -f --size-hint=3G | zstd -t
|
||||||
|
cat tmp | zstd -14 -f --size-hint=3GB | zstd -t
|
||||||
|
cat tmp | zstd -14 -f --size-hint=3GiB | zstd -t
|
||||||
|
|
||||||
|
|
||||||
println "\n===> dictionary tests "
|
println "\n===> dictionary tests "
|
||||||
println "- Test high/low compressibility corpus training"
|
println "- Test high/low compressibility corpus training"
|
||||||
datagen -g12M -P90 > tmpCorpusHighCompress
|
datagen -g12M -P90 > tmpCorpusHighCompress
|
||||||
datagen -g12M -P5 > tmpCorpusLowCompress
|
datagen -g12M -P5 > tmpCorpusLowCompress
|
||||||
zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress
|
zstd --train --split=2K tmpCorpusHighCompress -o tmpDictHighCompress
|
||||||
zstd --train -B2K tmpCorpusLowCompress -o tmpDictLowCompress
|
zstd --train --split=2K tmpCorpusLowCompress -o tmpDictLowCompress
|
||||||
rm -f tmpCorpusHighCompress tmpCorpusLowCompress tmpDictHighCompress tmpDictLowCompress
|
rm -f tmpCorpusHighCompress tmpCorpusLowCompress tmpDictHighCompress tmpDictLowCompress
|
||||||
println "- Test with raw dict (content only) "
|
println "- Test with raw dict (content only) "
|
||||||
datagen > tmpDict
|
datagen > tmpDict
|
||||||
@@ -1179,8 +1180,8 @@ rm -f tmp* dictionary
|
|||||||
|
|
||||||
println "- Test --memory for dictionary compression"
|
println "- Test --memory for dictionary compression"
|
||||||
datagen -g12M -P90 > tmpCorpusHighCompress
|
datagen -g12M -P90 > tmpCorpusHighCompress
|
||||||
zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=10K && die "Dictionary training should fail : --memory too low (10K)"
|
zstd --train --split=2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=10K && die "Dictionary training should fail : --memory too low (10K)"
|
||||||
zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=5MB 2> zstTrainWithMemLimitStdErr
|
zstd --train --split=2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=5MB 2> zstTrainWithMemLimitStdErr
|
||||||
cat zstTrainWithMemLimitStdErr | $GREP "setting manual memory limit for dictionary training data at 5 MB"
|
cat zstTrainWithMemLimitStdErr | $GREP "setting manual memory limit for dictionary training data at 5 MB"
|
||||||
cat zstTrainWithMemLimitStdErr | $GREP "Training samples set too large (12 MB); training on 5 MB only..."
|
cat zstTrainWithMemLimitStdErr | $GREP "Training samples set too large (12 MB); training on 5 MB only..."
|
||||||
rm zstTrainWithMemLimitStdErr
|
rm zstTrainWithMemLimitStdErr
|
||||||
@@ -1555,7 +1556,7 @@ then
|
|||||||
roundTripTest -g4M "1 -T0 --auto-threads=logical"
|
roundTripTest -g4M "1 -T0 --auto-threads=logical"
|
||||||
roundTripTest -g8M "3 -T2"
|
roundTripTest -g8M "3 -T2"
|
||||||
roundTripTest -g8000K "2 --threads=2"
|
roundTripTest -g8000K "2 --threads=2"
|
||||||
fileRoundTripTest -g4M "19 -T2 -B1M"
|
fileRoundTripTest -g4M "19 -T2 --split=1M"
|
||||||
|
|
||||||
println "\n===> zstdmt long distance matching round-trip tests "
|
println "\n===> zstdmt long distance matching round-trip tests "
|
||||||
roundTripTest -g8M "3 --long=24 -T2"
|
roundTripTest -g8M "3 --long=24 -T2"
|
||||||
@@ -1563,14 +1564,16 @@ then
|
|||||||
println "\n===> zstdmt environment variable tests "
|
println "\n===> zstdmt environment variable tests "
|
||||||
echo "multifoo" >> mt_tmp
|
echo "multifoo" >> mt_tmp
|
||||||
ZSTD_NBTHREADS=-3 zstd -f mt_tmp # negative value, warn and revert to default setting
|
ZSTD_NBTHREADS=-3 zstd -f mt_tmp # negative value, warn and revert to default setting
|
||||||
ZSTD_NBTHREADS='' zstd -f mt_tmp # empty env var, warn and revert to default setting
|
ZSTD_NBTHREADS='' zstd -f mt_tmp # empty env var, warn and revert to default setting
|
||||||
ZSTD_NBTHREADS=- zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
ZSTD_NBTHREADS=- zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
||||||
ZSTD_NBTHREADS=a zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
ZSTD_NBTHREADS=a zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
||||||
ZSTD_NBTHREADS=+a zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
ZSTD_NBTHREADS=+a zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
||||||
ZSTD_NBTHREADS=3a7 zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
ZSTD_NBTHREADS=3a7 zstd -f mt_tmp # malformed env var, warn and revert to default setting
|
||||||
ZSTD_NBTHREADS=50000000000 zstd -f mt_tmp # numeric value too large, warn and revert to default setting=
|
ZSTD_NBTHREADS=50000000000 zstd -f mt_tmp # numeric value too large, warn and revert to default setting=
|
||||||
ZSTD_NBTHREADS=2 zstd -f mt_tmp # correct usage
|
ZSTD_NBTHREADS=2 zstd -f mt_tmp # correct usage
|
||||||
ZSTD_NBTHREADS=1 zstd -f mt_tmp # correct usage: single thread
|
ZSTD_NBTHREADS=1 zstd -f mt_tmp # correct usage: single worker
|
||||||
|
ZSTD_NBTHREADS=4 zstd -f mt_tmp -vv 2>&1 | $GREP "4 worker threads" # check message
|
||||||
|
ZSTD_NBTHREADS=0 zstd -f mt_tmp -vv 2>&1 | $GREP "core(s) detected" # check core count autodetection is triggered
|
||||||
# temporary envvar changes in the above tests would actually persist in macos /bin/sh
|
# temporary envvar changes in the above tests would actually persist in macos /bin/sh
|
||||||
unset ZSTD_NBTHREADS
|
unset ZSTD_NBTHREADS
|
||||||
rm -f mt_tmp*
|
rm -f mt_tmp*
|
||||||
@@ -1687,6 +1690,8 @@ roundTripTest -g1M -P50 "1 --single-thread --long=29" " --memory=512MB"
|
|||||||
roundTripTest -g1M -P50 "1 --single-thread --long=29 --zstd=wlog=28" " --memory=256MB"
|
roundTripTest -g1M -P50 "1 --single-thread --long=29 --zstd=wlog=28" " --memory=256MB"
|
||||||
roundTripTest -g1M -P50 "1 --single-thread --long=29" " --long=28 --memory=512MB"
|
roundTripTest -g1M -P50 "1 --single-thread --long=29" " --long=28 --memory=512MB"
|
||||||
roundTripTest -g1M -P50 "1 --single-thread --long=29" " --zstd=wlog=28 --memory=512MB"
|
roundTripTest -g1M -P50 "1 --single-thread --long=29" " --zstd=wlog=28 --memory=512MB"
|
||||||
|
roundTripTest -g1M -P50 "1 --single-thread --long=30" " --memory=1GB"
|
||||||
|
roundTripTest -g1M -P50 "1 --single-thread --long=30" " --zstd=wlog=29 --memory=1GB"
|
||||||
|
|
||||||
|
|
||||||
if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -ne "1" ]; then
|
if [ "$ZSTD_LIB_EXCLUDE_COMPRESSORS_DFAST_AND_UP" -ne "1" ]; then
|
||||||
@@ -1770,7 +1775,7 @@ then
|
|||||||
|
|
||||||
println "\n===> rsyncable mode "
|
println "\n===> rsyncable mode "
|
||||||
roundTripTest -g10M " --rsyncable"
|
roundTripTest -g10M " --rsyncable"
|
||||||
roundTripTest -g10M " --rsyncable -B100K"
|
roundTripTest -g10M " --rsyncable --split=100K"
|
||||||
println "===> test: --rsyncable must fail with --single-thread"
|
println "===> test: --rsyncable must fail with --single-thread"
|
||||||
zstd -f -vv --rsyncable --single-thread tmp && die "--rsyncable must fail with --single-thread"
|
zstd -f -vv --rsyncable --single-thread tmp && die "--rsyncable must fail with --single-thread"
|
||||||
fi
|
fi
|
||||||
@@ -1781,11 +1786,15 @@ datagen -g1000 -P10 > tmp_patch
|
|||||||
zstd --patch-from=tmp_dict tmp_patch -o tmp_patch_diff
|
zstd --patch-from=tmp_dict tmp_patch -o tmp_patch_diff
|
||||||
zstd -d --patch-from=tmp_dict tmp_patch_diff -o tmp_patch_recon
|
zstd -d --patch-from=tmp_dict tmp_patch_diff -o tmp_patch_recon
|
||||||
$DIFF -s tmp_patch_recon tmp_patch
|
$DIFF -s tmp_patch_recon tmp_patch
|
||||||
|
zstd -f --patch-apply=tmp_dict tmp_patch_diff -o tmp_patch_recon
|
||||||
|
$DIFF -s tmp_patch_recon tmp_patch
|
||||||
|
|
||||||
println "\n===> alternate syntax: patch-from origin"
|
println "\n===> alternate syntax: patch-from origin"
|
||||||
zstd -f --patch-from tmp_dict tmp_patch -o tmp_patch_diff
|
zstd -f --patch-from tmp_dict tmp_patch -o tmp_patch_diff
|
||||||
zstd -df --patch-from tmp_dict tmp_patch_diff -o tmp_patch_recon
|
zstd -df --patch-from tmp_dict tmp_patch_diff -o tmp_patch_recon
|
||||||
$DIFF -s tmp_patch_recon tmp_patch
|
$DIFF -s tmp_patch_recon tmp_patch
|
||||||
|
zstd -f --patch-apply tmp_dict tmp_patch_diff -o tmp_patch_recon
|
||||||
|
$DIFF -s tmp_patch_recon tmp_patch
|
||||||
rm -rf tmp_*
|
rm -rf tmp_*
|
||||||
|
|
||||||
println "\n===> patch-from recursive tests"
|
println "\n===> patch-from recursive tests"
|
||||||
@@ -1889,36 +1898,36 @@ println "\n===> cover dictionary builder : advanced options "
|
|||||||
TESTFILE="$PRGDIR"/zstdcli.c
|
TESTFILE="$PRGDIR"/zstdcli.c
|
||||||
datagen > tmpDict
|
datagen > tmpDict
|
||||||
println "- Create first dictionary"
|
println "- Create first dictionary"
|
||||||
zstd --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict
|
zstd -T0 --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict
|
||||||
cp "$TESTFILE" tmp
|
cp "$TESTFILE" tmp
|
||||||
zstd -f tmp -D tmpDict
|
zstd -f tmp -D tmpDict
|
||||||
zstd -f tmp -D tmpDict --patch-from=tmpDict && die "error: can't use -D and --patch-from=#at the same time"
|
zstd -f tmp -D tmpDict --patch-from=tmpDict && die "error: can't use -D and --patch-from=#at the same time"
|
||||||
zstd -d tmp.zst -D tmpDict -fo result
|
zstd -d tmp.zst -D tmpDict -fo result
|
||||||
$DIFF "$TESTFILE" result
|
$DIFF "$TESTFILE" result
|
||||||
zstd --train-cover=k=56,d=8 && die "Create dictionary without input file (should error)"
|
zstd -T0 --train-cover=k=56,d=8 && die "Create dictionary without input file (should error)"
|
||||||
println "- Create second (different) dictionary"
|
println "- Create second (different) dictionary"
|
||||||
zstd --train-cover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c "$PRGDIR"/*.h -o tmpDictC
|
zstd -T0 --train-cover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c "$PRGDIR"/*.h -o tmpDictC
|
||||||
zstd -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!"
|
zstd -d tmp.zst -D tmpDictC -fo result && die "wrong dictionary not detected!"
|
||||||
println "- Create dictionary using shrink-dict flag"
|
println "- Create dictionary using shrink-dict flag"
|
||||||
zstd --train-cover=steps=256,shrink "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict
|
zstd -T0 --train-cover=steps=256,shrink "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict
|
||||||
zstd --train-cover=steps=256,shrink=1 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict1
|
zstd -T0 --train-cover=steps=256,shrink=1 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict1
|
||||||
zstd --train-cover=steps=256,shrink=5 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict2
|
zstd -T0 --train-cover=steps=256,shrink=5 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict2
|
||||||
zstd --train-cover=shrink=5,steps=256 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict3
|
zstd -T0 --train-cover=shrink=5,steps=256 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict3
|
||||||
println "- Create dictionary with short dictID"
|
println "- Create dictionary with short dictID"
|
||||||
zstd --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1
|
zstd -T0 --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1
|
||||||
cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"
|
cmp tmpDict tmpDict1 && die "dictionaries should have different ID !"
|
||||||
println "- Create dictionary with size limit"
|
println "- Create dictionary with size limit"
|
||||||
zstd --train-cover=steps=8 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K
|
zstd -T0 --train-cover=steps=8 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K
|
||||||
println "- Compare size of dictionary from 90% training samples with 80% training samples"
|
println "- Compare size of dictionary from 90% training samples with 80% training samples"
|
||||||
zstd --train-cover=split=90 -r "$TESTDIR"/*.c "$PRGDIR"/*.c
|
zstd -T0 --train-cover=split=90 -r "$TESTDIR"/*.c "$PRGDIR"/*.c
|
||||||
zstd --train-cover=split=80 -r "$TESTDIR"/*.c "$PRGDIR"/*.c
|
zstd -T0 --train-cover=split=80 -r "$TESTDIR"/*.c "$PRGDIR"/*.c
|
||||||
println "- Create dictionary using all samples for both training and testing"
|
println "- Create dictionary using all samples for both training and testing"
|
||||||
zstd --train-cover=split=100 -r "$TESTDIR"/*.c "$PRGDIR"/*.c
|
zstd -T0 --train-cover=split=100 -r "$TESTDIR"/*.c "$PRGDIR"/*.c
|
||||||
println "- Test -o before --train-cover"
|
println "- Test -o before --train-cover"
|
||||||
rm -f tmpDict dictionary
|
rm -f tmpDict dictionary
|
||||||
zstd -o tmpDict --train-cover "$TESTDIR"/*.c "$PRGDIR"/*.c
|
zstd -o tmpDict --train-cover "$TESTDIR"/*.c "$PRGDIR"/*.c
|
||||||
test -f tmpDict
|
test -f tmpDict
|
||||||
zstd --train-cover "$TESTDIR"/*.c "$PRGDIR"/*.c
|
zstd -T0 --train-cover "$TESTDIR"/*.c "$PRGDIR"/*.c
|
||||||
test -f dictionary
|
test -f dictionary
|
||||||
rm -f tmp* dictionary
|
rm -f tmp* dictionary
|
||||||
|
|
||||||
|
|||||||
@@ -159,15 +159,15 @@ static result_t compress_cctx_compress(
|
|||||||
return result_error(result_error_skip);
|
return result_error(result_error_skip);
|
||||||
|
|
||||||
int const level = config_get_level(config);
|
int const level = config_get_level(config);
|
||||||
|
result_t result;
|
||||||
ZSTD_CCtx* cctx = ZSTD_createCCtx();
|
ZSTD_CCtx* cctx = ZSTD_createCCtx();
|
||||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
||||||
if (cctx == NULL || dctx == NULL) {
|
if (cctx == NULL || dctx == NULL) {
|
||||||
fprintf(stderr, "context creation failed\n");
|
fprintf(stderr, "context creation failed\n");
|
||||||
return result_error(result_error_system_error);
|
result = result_error(result_error_system_error);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
result_t result;
|
|
||||||
result_data_t data = {.total_size = 0};
|
result_data_t data = {.total_size = 0};
|
||||||
for (size_t i = 0; i < state->inputs.size; ++i) {
|
for (size_t i = 0; i < state->inputs.size; ++i) {
|
||||||
data_buffer_t const input = state->inputs.buffers[i];
|
data_buffer_t const input = state->inputs.buffers[i];
|
||||||
|
|||||||
@@ -259,13 +259,23 @@ if __name__ == '__main__':
|
|||||||
shutil.copy2('dictBuilder', '{}/dictBuilder.{}'.format(tmp_dir, tag))
|
shutil.copy2('dictBuilder', '{}/dictBuilder.{}'.format(tmp_dir, tag))
|
||||||
os.chdir(r_dir + '/programs') # /path/to/zstd/tests/versionsTest/<TAG>/programs
|
os.chdir(r_dir + '/programs') # /path/to/zstd/tests/versionsTest/<TAG>/programs
|
||||||
make(['clean'], False) # separate 'clean' target to allow parallel build
|
make(['clean'], False) # separate 'clean' target to allow parallel build
|
||||||
make(['zstd'], False)
|
# Enable legacy support for cross-version compatibility testing.
|
||||||
|
# Use ZSTD_LEGACY_SUPPORT=1 for v0.6.x due to a bug where headers
|
||||||
|
# check for ==1 but code checks for >=1.
|
||||||
|
# Use ZSTD_LEGACY_SUPPORT=5 for v1.2.0+ because =1 includes old
|
||||||
|
# legacy files (v01-v04) that have missing includes in newer versions.
|
||||||
|
if tag < 'v1.2.0':
|
||||||
|
make(['zstd', 'ZSTD_LEGACY_SUPPORT=1'], False)
|
||||||
|
else:
|
||||||
|
make(['zstd', 'ZSTD_LEGACY_SUPPORT=5'], False)
|
||||||
else:
|
else:
|
||||||
os.chdir(programs_dir)
|
os.chdir(programs_dir)
|
||||||
print('-----------------------------------------------')
|
print('-----------------------------------------------')
|
||||||
print('compiling head')
|
print('compiling head')
|
||||||
print('-----------------------------------------------')
|
print('-----------------------------------------------')
|
||||||
make(['zstd'], False)
|
# Enable legacy support for head to test cross-version compatibility
|
||||||
|
# (legacy support is disabled by default since v1.6.0)
|
||||||
|
make(['zstd', 'ZSTD_LEGACY_SUPPORT=5'], False)
|
||||||
shutil.copy2('zstd', dst_zstd)
|
shutil.copy2('zstd', dst_zstd)
|
||||||
|
|
||||||
# remove any remaining *.zst and *.dec from previous test
|
# remove any remaining *.zst and *.dec from previous test
|
||||||
|
|||||||
Executable
+92
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# test_process_substitution.bash
|
||||||
|
# Test zstd's support for process substitution with --filelist
|
||||||
|
|
||||||
|
# Process arguments
|
||||||
|
ZSTD_PATH="zstd" # Default to using zstd from PATH
|
||||||
|
if [ $# -ge 1 ]; then
|
||||||
|
ZSTD_PATH="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using zstd executable: $ZSTD_PATH"
|
||||||
|
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
# Set up test directory and files
|
||||||
|
echo "Setting up test environment..."
|
||||||
|
TEST_DIR="tmp_process_substit"
|
||||||
|
rm -rf "$TEST_DIR"
|
||||||
|
mkdir -p "$TEST_DIR"
|
||||||
|
echo "Content of file 1" > "$TEST_DIR/file1.txt"
|
||||||
|
echo "Content of file 2" > "$TEST_DIR/file2.txt"
|
||||||
|
echo "Content of file 3" > "$TEST_DIR/file3.txt"
|
||||||
|
|
||||||
|
# Clean up any previous test artifacts
|
||||||
|
rm -f "$TEST_DIR/output.zst" "$TEST_DIR/output_echo.zst" "$TEST_DIR/output_cat.zst"
|
||||||
|
rm -rf "$TEST_DIR/extracted"
|
||||||
|
mkdir -p "$TEST_DIR/extracted"
|
||||||
|
|
||||||
|
echo "=== Testing process substitution with --filelist ==="
|
||||||
|
|
||||||
|
# Test 1: Basic process substitution with find
|
||||||
|
echo "Test 1: Basic process substitution (find command)"
|
||||||
|
"$ZSTD_PATH" --filelist=<(find "$TEST_DIR" -name "*.txt" | sort) -c > "$TEST_DIR/output.zst"
|
||||||
|
|
||||||
|
if [ -f "$TEST_DIR/output.zst" ]; then
|
||||||
|
echo "✓ Test 1 PASSED: Output file was created"
|
||||||
|
else
|
||||||
|
echo "✗ Test 1 FAILED: Output file was not created"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test 2: Process substitution with echo
|
||||||
|
echo "Test 2: Process substitution (echo command)"
|
||||||
|
"$ZSTD_PATH" --filelist=<(echo -e "$TEST_DIR/file1.txt\n$TEST_DIR/file2.txt") -c > "$TEST_DIR/output_echo.zst"
|
||||||
|
|
||||||
|
if [ -f "$TEST_DIR/output_echo.zst" ]; then
|
||||||
|
echo "✓ Test 2 PASSED: Output file was created"
|
||||||
|
else
|
||||||
|
echo "✗ Test 2 FAILED: Output file was not created"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test 3: Process substitution with cat
|
||||||
|
echo "Test 3: Process substitution (cat command)"
|
||||||
|
echo -e "$TEST_DIR/file1.txt\n$TEST_DIR/file3.txt" > "$TEST_DIR/filelist.txt"
|
||||||
|
"$ZSTD_PATH" --filelist=<(cat "$TEST_DIR/filelist.txt") -c > "$TEST_DIR/output_cat.zst"
|
||||||
|
|
||||||
|
if [ -f "$TEST_DIR/output_cat.zst" ]; then
|
||||||
|
echo "✓ Test 3 PASSED: Output file was created"
|
||||||
|
else
|
||||||
|
echo "✗ Test 3 FAILED: Output file was not created"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test 4: Verify contents of archives
|
||||||
|
echo "Test 4: Verifying archive contents"
|
||||||
|
"$ZSTD_PATH" -d "$TEST_DIR/output.zst" -o "$TEST_DIR/extracted/combined.out"
|
||||||
|
|
||||||
|
if grep -q "Content of file 1" "$TEST_DIR/extracted/combined.out" &&
|
||||||
|
grep -q "Content of file 2" "$TEST_DIR/extracted/combined.out" &&
|
||||||
|
grep -q "Content of file 3" "$TEST_DIR/extracted/combined.out"; then
|
||||||
|
echo "✓ Test 4 PASSED: All files were correctly archived and extracted"
|
||||||
|
else
|
||||||
|
echo "✗ Test 4 FAILED: Not all expected content was found in the extracted file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test 5: Edge case with empty list
|
||||||
|
echo "Test 5: Process substitution with empty input"
|
||||||
|
"$ZSTD_PATH" --filelist=<(echo "") -c > "$TEST_DIR/output_empty.zst" 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -f "$TEST_DIR/output_empty.zst" ]; then
|
||||||
|
echo "✓ Test 5 PASSED: Handled empty input gracefully"
|
||||||
|
else
|
||||||
|
echo "✓ Test 5 PASSED: Properly rejected empty input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
rm -rf "$TEST_DIR"
|
||||||
|
|
||||||
|
echo "All tests completed successfully!"
|
||||||
|
|
||||||
+1
-1
@@ -1896,7 +1896,7 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests)
|
|||||||
CHECK_Z(ZSTD_CCtx_setParameter(zc, ZSTD_c_checksumFlag, 1));
|
CHECK_Z(ZSTD_CCtx_setParameter(zc, ZSTD_c_checksumFlag, 1));
|
||||||
/* Write a bunch of 6 byte blocks */
|
/* Write a bunch of 6 byte blocks */
|
||||||
while (remainingInput > 0) {
|
while (remainingInput > 0) {
|
||||||
char testBuffer[6] = "\xAA\xAA\xAA\xAA\xAA\xAA";
|
char testBuffer[6] = { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 };
|
||||||
const size_t kSmallBlockSize = sizeof(testBuffer);
|
const size_t kSmallBlockSize = sizeof(testBuffer);
|
||||||
ZSTD_inBuffer in = {testBuffer, kSmallBlockSize, 0};
|
ZSTD_inBuffer in = {testBuffer, kSmallBlockSize, 0};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user