mirror of
https://github.com/facebook/zstd
synced 2026-08-22 22:32:07 -04:00
Compare commits
367 commits
v1.5.7-ker
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82d322c497 | ||
|
|
1345d2008d | ||
|
|
8223abf92f | ||
|
|
af48fb967f | ||
|
|
e076449205 | ||
|
|
a1ddcdae2d | ||
|
|
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 |
152 changed files with 6276 additions and 1882 deletions
|
|
@ -2,7 +2,7 @@ task:
|
|||
name: FreeBSD (make check)
|
||||
freebsd_instance:
|
||||
matrix:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-15-0-amd64-zfs
|
||||
install_script: pkg install -y gmake coreutils
|
||||
script: |
|
||||
MOREFLAGS="-Werror" gmake -j all
|
||||
|
|
|
|||
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
|
|
@ -3,4 +3,4 @@ updates:
|
|||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
interval: "monthly"
|
||||
|
|
|
|||
17
.github/workflows/android-ndk-build.yml
vendored
17
.github/workflows/android-ndk-build.yml
vendored
|
|
@ -13,16 +13,16 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
- 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
|
||||
run: |
|
||||
|
|
@ -37,3 +37,14 @@ jobs:
|
|||
RANLIB=llvm-ranlib \
|
||||
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
|
||||
|
|
|
|||
168
.github/workflows/cmake-tests.yml
vendored
Normal file
168
.github/workflows/cmake-tests.yml
vendored
Normal file
|
|
@ -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
|
||||
10
.github/workflows/commit.yml
vendored
10
.github/workflows/commit.yml
vendored
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
image: fbopensource/zstd-circleci-primary:0.0.1
|
||||
options: --entrypoint /bin/bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6.0.2
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
|
@ -40,7 +40,7 @@ jobs:
|
|||
image: fbopensource/zstd-circleci-primary:0.0.1
|
||||
options: --entrypoint /bin/bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6.0.2
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
|
@ -73,9 +73,9 @@ jobs:
|
|||
env:
|
||||
CIRCLE_ARTIFACTS: "/tmp/circleci-artifacts"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6.0.2
|
||||
- name: restore_cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
key: regression-cache-{{ checksum "tests/regression/data.c" }}-v0
|
||||
path: tests/regression/cache
|
||||
|
|
@ -99,6 +99,6 @@ jobs:
|
|||
echo " are still good, copy it into the repo and commit it."
|
||||
echo "> diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv"
|
||||
diff tests/regression/results.csv $CIRCLE_ARTIFACTS/results.csv
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v7.0.1
|
||||
with:
|
||||
path: "/tmp/circleci-artifacts"
|
||||
|
|
|
|||
91
.github/workflows/dev-long-tests.yml
vendored
91
.github/workflows/dev-long-tests.yml
vendored
|
|
@ -1,5 +1,5 @@
|
|||
name: dev-long-tests
|
||||
# Tests longer than 10mn
|
||||
# Tests generally longer than 10mn
|
||||
|
||||
concurrency:
|
||||
group: long-${{ github.ref }}
|
||||
|
|
@ -12,40 +12,44 @@ on:
|
|||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
# lasts ~7mn
|
||||
make-all:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: make all
|
||||
run: make all
|
||||
|
||||
# lasts ~24mn
|
||||
# lasts ~19mn
|
||||
make-test:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DEVNULLRIGHTS: 1
|
||||
READFROMBLOCKDEVICE: 1
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- 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:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: make test on macos
|
||||
run: make test
|
||||
|
||||
# lasts ~24mn
|
||||
# lasts ~10mn
|
||||
make-test-32bit:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DEVNULLRIGHTS: 1
|
||||
READFROMBLOCKDEVICE: 1
|
||||
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
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -53,51 +57,61 @@ jobs:
|
|||
make clean
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: no intrinsics fuzztest
|
||||
run: MOREFLAGS="-DZSTD_NO_INTRINSICS" make -C tests fuzztest
|
||||
|
||||
# lasts ~8mn
|
||||
tsan-zstreamtest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: thread sanitizer zstreamtest
|
||||
run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream
|
||||
|
||||
uasan-zstreamtest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: ub + address sanitizer on zstreamtest
|
||||
run: CC=clang make uasan-test-zstream
|
||||
|
||||
# lasts ~15mn
|
||||
# lasts ~11mn
|
||||
tsan-fuzztest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: thread sanitizer fuzztest
|
||||
run: CC=clang make tsan-fuzztest
|
||||
|
||||
|
||||
big-tests-zstreamtest32:
|
||||
runs-on: ubuntu-latest
|
||||
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
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
make libc6install
|
||||
CC=clang make -C tests test-zstream32 FUZZER_FLAGS="--big-tests"
|
||||
|
||||
# lasts ~23mn
|
||||
# lasts ~13mn
|
||||
gcc-8-asan-ubsan-testzstd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: gcc-8 + ASan + UBSan + Test Zstd
|
||||
# See https://askubuntu.com/a/1428822
|
||||
run: |
|
||||
|
|
@ -109,14 +123,14 @@ jobs:
|
|||
clang-asan-ubsan-testzstd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + ASan + UBSan + Test Zstd
|
||||
run: CC=clang make -j uasan-test-zstd </dev/null V=1
|
||||
|
||||
gcc-asan-ubsan-testzstd-32bit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: ASan + UBSan + Test Zstd, 32bit mode
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -130,7 +144,7 @@ jobs:
|
|||
gcc-8-asan-ubsan-fuzz:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: gcc-8 + ASan + UBSan + Fuzz Test
|
||||
# See https://askubuntu.com/a/1428822
|
||||
run: |
|
||||
|
|
@ -142,14 +156,14 @@ jobs:
|
|||
clang-asan-ubsan-fuzz:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + ASan + UBSan + Fuzz Test
|
||||
run: CC=clang FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest
|
||||
|
||||
gcc-asan-ubsan-fuzz32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: ASan + UBSan + Fuzz Test 32bit
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -159,7 +173,7 @@ jobs:
|
|||
clang-asan-fuzz32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + ASan + Fuzz Test 32bit
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -174,7 +188,7 @@ jobs:
|
|||
# clang-asan-ubsan-fuzz32:
|
||||
# runs-on: ubuntu-20.04
|
||||
# steps:
|
||||
# - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
# - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
# - name: clang + ASan + UBSan + Fuzz Test 32bit
|
||||
# run: |
|
||||
# sudo apt-get -qqq update
|
||||
|
|
@ -184,28 +198,28 @@ jobs:
|
|||
asan-ubsan-regression:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: ASan + UBSan + Regression Test
|
||||
run: make -j uasanregressiontest
|
||||
|
||||
clang-asan-ubsan-regression:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + ASan + UBSan + Regression Test
|
||||
run: CC=clang make -j uasanregressiontest
|
||||
|
||||
msan-regression:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: MSan + Regression Test
|
||||
run: make -j msanregressiontest
|
||||
|
||||
clang-msan-fuzz-unoptimized:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + MSan + Fuzz Test
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -215,28 +229,25 @@ jobs:
|
|||
clang-msan-fuzz:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + MSan + Fuzz Test
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
sudo apt-get install clang
|
||||
CC=clang FUZZER_FLAGS="--long-tests" make clean msan-fuzztest
|
||||
|
||||
# lasts ~24mn
|
||||
clang-msan-testzstd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: clang + MSan + Test Zstd
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang
|
||||
CC=clang make msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0 V=1
|
||||
CC=clang make -j msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0 V=1
|
||||
|
||||
armfuzz:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Qemu ARM emulation + Fuzz Test
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -246,7 +257,7 @@ jobs:
|
|||
valgrind-fuzz-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: valgrind + fuzz test stack mode # ~ 7mn
|
||||
shell: 'script -q -e -c "bash {0}"'
|
||||
run: |
|
||||
|
|
@ -262,8 +273,8 @@ jobs:
|
|||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # tag=v2.32.0
|
||||
with:
|
||||
msystem: MINGW64
|
||||
install: make
|
||||
|
|
@ -306,7 +317,7 @@ jobs:
|
|||
dry-run: false
|
||||
sanitizer: ${{ matrix.sanitizer }}
|
||||
- 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'
|
||||
with:
|
||||
name: ${{ matrix.sanitizer }}-artifacts
|
||||
|
|
|
|||
171
.github/workflows/dev-short-tests.yml
vendored
171
.github/workflows/dev-short-tests.yml
vendored
|
|
@ -16,39 +16,40 @@ jobs:
|
|||
linux-kernel:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: linux kernel, library + build + test
|
||||
run: make -C contrib/linux-kernel test CFLAGS="-Werror -Wunused-const-variable -Wunused-but-set-variable"
|
||||
|
||||
benchmarking:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: make benchmarking
|
||||
run: make benchmarking
|
||||
|
||||
check-32bit: # designed to catch https://github.com/facebook/zstd/issues/2428
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: make check on 32-bit
|
||||
run: |
|
||||
sudo apt update
|
||||
APT_PACKAGES="gcc-multilib" make apt-install
|
||||
CFLAGS="-m32 -O1 -fstack-protector" make check V=1
|
||||
CFLAGS="-m32 -O1 -fstack-protector" make V=1 -C tests test-cli-tests
|
||||
|
||||
build-c89:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- name: ensure zstd can be build with c89/c90 compilers (+ long long support + variadic macros)
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: ensure zstd can be built with c89/c90 compilers (+ long long support + variadic macros)
|
||||
run: |
|
||||
make c89build V=1
|
||||
|
||||
build-zstd-dll:
|
||||
runs-on: ubuntu-latest
|
||||
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)
|
||||
run: |
|
||||
make -C lib lib-mt-release
|
||||
|
|
@ -57,7 +58,7 @@ jobs:
|
|||
gcc-7-libzstd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: gcc-7 + libzstdmt compilation
|
||||
# See https://askubuntu.com/a/1428822
|
||||
run: |
|
||||
|
|
@ -71,44 +72,10 @@ jobs:
|
|||
# candidate test (for discussion) : underlink test
|
||||
# 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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: C++, gnu90 and c99 compatibility
|
||||
run: |
|
||||
make cxxtest
|
||||
|
|
@ -122,7 +89,7 @@ jobs:
|
|||
mingw-cross-compilation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: mingw cross-compilation
|
||||
run: |
|
||||
# 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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: ARM Build Test
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -143,7 +110,7 @@ jobs:
|
|||
bourne-shell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Bourne shell compatibility (shellcheck)
|
||||
run: |
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: install valgrind
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -166,10 +133,9 @@ jobs:
|
|||
lz4-threadpool-libs:
|
||||
runs-on: ubuntu-latest
|
||||
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
|
||||
run: |
|
||||
make lz4install
|
||||
make -C tests test-lz4
|
||||
make check < /dev/null | tee # mess with lz4 console detection
|
||||
make clean
|
||||
|
|
@ -180,7 +146,7 @@ jobs:
|
|||
gcc-make-all-avx2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Make all, with AVX2
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -190,7 +156,7 @@ jobs:
|
|||
gcc-make-all-32bit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Make all, 32bit mode
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -200,7 +166,7 @@ jobs:
|
|||
gcc-make-all-32bit-avx2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Make all, 32bit + AVX2 mode
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -211,7 +177,7 @@ jobs:
|
|||
gcc-8-make:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: gcc-8 build
|
||||
# See https://askubuntu.com/a/1428822
|
||||
run: |
|
||||
|
|
@ -234,7 +200,7 @@ jobs:
|
|||
flags: "HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=1"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Build with ${{matrix.name}}
|
||||
run: |
|
||||
sudo apt install liblzma-dev
|
||||
|
|
@ -244,7 +210,7 @@ jobs:
|
|||
implicit-fall-through:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: -Wimplicit-fallthrough build
|
||||
run: |
|
||||
make clean
|
||||
|
|
@ -255,7 +221,7 @@ jobs:
|
|||
meson-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
|
@ -279,7 +245,7 @@ jobs:
|
|||
meson-mingw-cross-compilation:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt-get -qqq update
|
||||
|
|
@ -323,7 +289,7 @@ jobs:
|
|||
meson-windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Install packages
|
||||
run: pip install --pre meson
|
||||
- name: Configure with Meson
|
||||
|
|
@ -339,34 +305,6 @@ jobs:
|
|||
run: |
|
||||
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:
|
||||
strategy:
|
||||
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 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 2019 x64 Release", platform: Win32, configuration: Release, toolset: v142, runner: "windows-2019", arch: ""},
|
||||
{ name: "VS 2019 Win32 Release", platform: x64, 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 2022 x64 Release AVX2", platform: x64, configuration: Release, toolset: v143, runner: "windows-2022", arch: "AdvancedVectorExtensions2" },
|
||||
]
|
||||
runs-on: ${{matrix.runner}}
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- 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}}
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
# See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference
|
||||
|
|
@ -407,7 +344,7 @@ jobs:
|
|||
libzstd-size:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: libzstd size test
|
||||
run: |
|
||||
make clean && make -j -C lib libzstd && ./tests/check_size.py lib/libzstd.so 1100000
|
||||
|
|
@ -418,7 +355,7 @@ jobs:
|
|||
minimal-decompressor-macros:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: minimal decompressor macros
|
||||
run: |
|
||||
make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror"
|
||||
|
|
@ -435,7 +372,7 @@ jobs:
|
|||
dynamic-bmi2:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: dynamic bmi2 tests
|
||||
run: |
|
||||
make clean && make -j check MOREFLAGS="-O0 -Werror -mbmi2"
|
||||
|
|
@ -447,7 +384,7 @@ jobs:
|
|||
test-variants:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: make all variants & validate
|
||||
run: |
|
||||
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: 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: 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: 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 }}
|
||||
XEMU: ${{ matrix.xemu }}
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: apt update & install
|
||||
run: |
|
||||
sudo apt-get update
|
||||
|
|
@ -496,6 +433,9 @@ jobs:
|
|||
run: |
|
||||
make clean
|
||||
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).
|
||||
# Unfortunately, the standard library provided on Ubuntu 24.04 does not have this feature enabled.
|
||||
# make clean
|
||||
|
|
@ -520,6 +460,9 @@ jobs:
|
|||
if: ${{ matrix.name == 'RISC-V' }}
|
||||
run: |
|
||||
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
|
||||
if: ${{ matrix.name == 'M68K' }}
|
||||
run: |
|
||||
|
|
@ -543,8 +486,8 @@ jobs:
|
|||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # tag=v2.32.0
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
install: make diffutils
|
||||
|
|
@ -579,9 +522,9 @@ jobs:
|
|||
platform: [x64, Win32]
|
||||
configuration: [Release]
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- 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
|
||||
working-directory: ${{env.GITHUB_WORKSPACE}}
|
||||
env:
|
||||
|
|
@ -600,8 +543,8 @@ jobs:
|
|||
runs-on: windows-latest
|
||||
steps:
|
||||
- run: git config --global core.autocrlf input
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: cygwin/cygwin-install-action@f61179d72284ceddc397ed07ddb444d82bf9e559 # tag=v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- uses: cygwin/cygwin-install-action@3f0a3f9f988f7e96b8c18098ae05eaec175f5b52 # tag=v6
|
||||
with:
|
||||
platform: x86_64
|
||||
packages: >-
|
||||
|
|
@ -632,7 +575,7 @@ jobs:
|
|||
container:
|
||||
image: debian:testing
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt -y update
|
||||
|
|
@ -647,7 +590,7 @@ jobs:
|
|||
versions-compatibility:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Versions Compatibility Test
|
||||
run: |
|
||||
make -C tests versionsTest
|
||||
|
|
@ -655,7 +598,7 @@ jobs:
|
|||
clangbuild:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: make clangbuild
|
||||
run: |
|
||||
make clangbuild
|
||||
|
|
@ -663,7 +606,7 @@ jobs:
|
|||
gcc-pgo:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Build PGO Zstd with GCC
|
||||
env:
|
||||
CC: gcc
|
||||
|
|
@ -674,7 +617,7 @@ jobs:
|
|||
clang-pgo:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Build PGO Zstd with Clang
|
||||
env:
|
||||
CC: clang
|
||||
|
|
@ -684,10 +627,21 @@ jobs:
|
|||
make -C programs zstd-pgo
|
||||
./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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v4.1.1
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
- name: Build Zstd
|
||||
run: |
|
||||
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
|
||||
sudo apt-get update
|
||||
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
|
||||
run: |
|
||||
source /opt/intel/oneapi/setvars.sh
|
||||
make CC=icx check
|
||||
make CC=icx -C tests test-cli-tests
|
||||
|
|
|
|||
2
.github/workflows/nightly.yml
vendored
2
.github/workflows/nightly.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
regression-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6.0.2
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev
|
||||
- name: Regression Test
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
|
||||
- name: Archive
|
||||
env:
|
||||
|
|
|
|||
64
.github/workflows/release_check.yml
vendored
Normal file
64
.github/workflows/release_check.yml
vendored
Normal file
|
|
@ -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
|
||||
8
.github/workflows/scorecards.yml
vendored
8
.github/workflows/scorecards.yml
vendored
|
|
@ -27,12 +27,12 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # tag=v2.4.0
|
||||
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # tag=v2.4.1
|
||||
with:
|
||||
results_file: results.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
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # tag=v7.0.1
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
|
|
@ -59,6 +59,6 @@ jobs:
|
|||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- 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:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
105
.github/workflows/windows-artifacts.yml
vendored
105
.github/workflows/windows-artifacts.yml
vendored
|
|
@ -2,7 +2,7 @@ name: windows-artifacts
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [ test_artifacts, win_artifacts ]
|
||||
branches: [ test_artifacts, win_artifacts, release ]
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
|
@ -11,48 +11,109 @@ permissions: read-all
|
|||
|
||||
jobs:
|
||||
windows-artifacts:
|
||||
# see https://ariya.io/2020/07/on-github-actions-with-msys2
|
||||
runs-on: windows-latest
|
||||
# see https://github.com/msys2/setup-msys2
|
||||
permissions:
|
||||
contents: write # to fetch code and upload artifacts
|
||||
# For msys2, see https://ariya.io/2020/07/on-github-actions-with-msys2
|
||||
runs-on: ${{ matrix.shell == 'cmake' && 'windows-11-arm' || 'windows-latest' }}
|
||||
strategy:
|
||||
# For msys2, see https://github.com/msys2/setup-msys2
|
||||
matrix:
|
||||
include:
|
||||
- { msystem: mingw64, env: x86_64, ziparch: win64 }
|
||||
- { msystem: mingw32, env: i686, ziparch: win32 }
|
||||
- { msystem: mingw64, env: x86_64, ziparch: win64, shell: msys2 }
|
||||
- { msystem: mingw32, env: i686, ziparch: win32, shell: msys2 }
|
||||
- { msystem: null, env: arm64, ziparch: win-arm64, shell: cmake }
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
shell: ${{ matrix.shell == 'cmake' && 'pwsh' || 'msys2 {0}' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # tag=v3
|
||||
- uses: msys2/setup-msys2@d44ca8e88d8b43d56cf5670f91747359d5537f97 # tag=v2.26.0
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # tag=v6.0.2
|
||||
|
||||
# MSYS2 setup
|
||||
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # tag=v2.32.0
|
||||
if: matrix.shell == 'msys2'
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
install: make zlib git p7zip mingw-w64-${{matrix.env}}-gcc
|
||||
install: make p7zip git mingw-w64-${{matrix.env}}-gcc
|
||||
update: true
|
||||
|
||||
- name: display versions
|
||||
- name: display versions (MSYS2)
|
||||
if: matrix.shell == 'msys2'
|
||||
run: |
|
||||
make -v
|
||||
cc -v
|
||||
|
||||
- name: Building zlib to static link
|
||||
- name: display versions (CMake)
|
||||
if: matrix.shell == 'cmake'
|
||||
run: |
|
||||
git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib
|
||||
cmake --version
|
||||
|
||||
# Build dependencies (MSYS2 only)
|
||||
- name: Building zlib to static link
|
||||
if: matrix.shell == 'msys2'
|
||||
run: |
|
||||
git clone --depth 1 --branch v1.3.1 https://github.com/madler/zlib
|
||||
make -C zlib -f win32/Makefile.gcc libz.a
|
||||
|
||||
- name: Building lz4 to static link
|
||||
if: matrix.shell == 'msys2'
|
||||
run: |
|
||||
git clone --depth 1 --branch v1.10.0 https://github.com/lz4/lz4
|
||||
# ensure both libraries use the same version of libxxhash
|
||||
cp lib/common/xxhash.* lz4/lib
|
||||
CPPFLAGS=-DXXH_NAMESPACE=LZ4_ make -C lz4/lib liblz4.a V=1
|
||||
|
||||
# Build zstd
|
||||
- name: Building zstd programs
|
||||
if: matrix.shell == 'msys2'
|
||||
run: |
|
||||
CPPFLAGS=-I../zlib LDFLAGS=../zlib/libz.a make -j allzstd MOREFLAGS=-static V=1
|
||||
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: Create artifacts
|
||||
- name: Build zstd (CMake ARM64)
|
||||
if: matrix.shell == 'cmake'
|
||||
run: |
|
||||
./lib/dll/example/build_package.bat
|
||||
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}}/
|
||||
7z a -tzip -mx9 zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip zstd-${{ github.ref_name }}-${{matrix.ziparch}}/
|
||||
cd ..
|
||||
|
||||
- name: Publish zstd-$VERSION-${{matrix.ziparch}}.zip
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # tag=v4.3.1
|
||||
- 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:
|
||||
path: ${{ github.workspace }}/zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip
|
||||
name: zstd-${{ github.ref_name }}-${{matrix.ziparch}}.zip
|
||||
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
|
||||
21
.gitignore
vendored
21
.gitignore
vendored
|
|
@ -22,16 +22,6 @@ zstdmt
|
|||
*.out
|
||||
*.app
|
||||
|
||||
# Test artefacts
|
||||
tmp*
|
||||
*.zst
|
||||
*.zstd
|
||||
dictionary.
|
||||
dictionary
|
||||
NUL
|
||||
cmakebuild/
|
||||
install/
|
||||
|
||||
# Build artefacts
|
||||
contrib/linux-kernel/linux/
|
||||
projects/
|
||||
|
|
@ -40,6 +30,17 @@ bin/
|
|||
buck-out/
|
||||
build-*
|
||||
*.gcda
|
||||
cmakebuild/
|
||||
cmake-build/
|
||||
|
||||
# Test artefacts
|
||||
tmp*
|
||||
*.zst
|
||||
*.zstd
|
||||
dictionary.
|
||||
dictionary
|
||||
NUL
|
||||
install/
|
||||
|
||||
# IDE
|
||||
.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)
|
||||
fix: compression bug in 32-bit mode associated with long-lasting sessions
|
||||
api: new method `ZSTD_compressSequencesAndLiterals()` (#4217, #4232)
|
||||
|
|
|
|||
11
CMakeLists.txt
Normal file
11
CMakeLists.txt
Normal file
|
|
@ -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)
|
||||
|
|
@ -373,7 +373,12 @@ counter `L1-dcache-load-misses`
|
|||
|
||||
#### 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
|
||||
We use GitHub issues to track public bugs. Please ensure your description is
|
||||
|
|
|
|||
11
Makefile
11
Makefile
|
|
@ -144,10 +144,13 @@ clean:
|
|||
$(Q)$(RM) -r lz4 cmakebuild mesonbuild install
|
||||
@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
|
||||
#------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
|
@ -351,7 +354,7 @@ apt-add-repo:
|
|||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
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:
|
||||
APT_PACKAGES="qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu" $(MAKE) apt-install
|
||||
|
||||
|
|
@ -379,10 +382,6 @@ gpp6install: apt-add-repo
|
|||
clang38install:
|
||||
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
|
||||
|
||||
|
||||
|
|
|
|||
77
README.md
77
README.md
|
|
@ -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
|
||||
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
|
||||
compiled with [gcc] 9.4.0,
|
||||
compiled with [gcc] 14.2.0,
|
||||
on the [Silesia compression corpus].
|
||||
|
||||
[lzbench]: https://github.com/inikep/lzbench
|
||||
|
|
@ -41,16 +41,16 @@ on the [Silesia compression corpus].
|
|||
|
||||
| Compressor name | Ratio | Compression| Decompress.|
|
||||
| --------------- | ------| -----------| ---------- |
|
||||
| **zstd 1.5.6 -1** | 2.887 | 510 MB/s | 1580 MB/s |
|
||||
| [zlib] 1.2.11 -1 | 2.743 | 95 MB/s | 400 MB/s |
|
||||
| brotli 1.0.9 -0 | 2.702 | 395 MB/s | 430 MB/s |
|
||||
| **zstd 1.5.6 --fast=1** | 2.437 | 545 MB/s | 1890 MB/s |
|
||||
| **zstd 1.5.6 --fast=3** | 2.239 | 650 MB/s | 2000 MB/s |
|
||||
| quicklz 1.5.0 -1 | 2.238 | 525 MB/s | 750 MB/s |
|
||||
| lzo1x 2.10 -1 | 2.106 | 650 MB/s | 825 MB/s |
|
||||
| [lz4] 1.9.4 | 2.101 | 700 MB/s | 4000 MB/s |
|
||||
| lzf 3.6 -1 | 2.077 | 420 MB/s | 830 MB/s |
|
||||
| snappy 1.1.9 | 2.073 | 530 MB/s | 1660 MB/s |
|
||||
| **zstd 1.5.7 -1** | 2.896 | 510 MB/s | 1550 MB/s |
|
||||
| brotli 1.1.0 -1 | 2.883 | 290 MB/s | 425 MB/s |
|
||||
| [zlib] 1.3.1 -1 | 2.743 | 105 MB/s | 390 MB/s |
|
||||
| **zstd 1.5.7 --fast=1** | 2.439 | 545 MB/s | 1850 MB/s |
|
||||
| quicklz 1.5.0 -1 | 2.238 | 520 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 | 780 MB/s |
|
||||
| [lz4] 1.10.0 | 2.101 | 675 MB/s | 3850 MB/s |
|
||||
| snappy 1.2.1 | 2.089 | 520 MB/s | 1500 MB/s |
|
||||
| lzf 3.6 -1 | 2.077 | 410 MB/s | 820 MB/s |
|
||||
|
||||
[zlib]: https://www.zlib.net/
|
||||
[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
|
||||
|
||||
`make` is the officially maintained build system of this project.
|
||||
All other build systems are "compatible" and 3rd-party maintained,
|
||||
they may feature small differences in advanced options.
|
||||
When your system allows it, prefer using `make` to build `zstd` and `libzstd`.
|
||||
`make` is the main build system of this project.
|
||||
It is the reference, and other build systems are periodically updated to stay compatible.
|
||||
However, small drifts and feature differences can be present, since perfect synchronization is difficult.
|
||||
For this reason, when your build system allows it, prefer employing `make`.
|
||||
|
||||
### Makefile
|
||||
|
||||
If your system is compatible with standard `make` (or `gmake`),
|
||||
invoking `make` in root directory will generate `zstd` cli in root directory.
|
||||
It will also create `libzstd` into `lib/`.
|
||||
Assuming your system supports standard `make` (or `gmake`),
|
||||
just invoking `make` in root directory generates `zstd` cli at root,
|
||||
and also generates `libzstd` into `lib/`.
|
||||
|
||||
Other available options include:
|
||||
- `make install` : create and install zstd cli, library and man pages
|
||||
- `make check` : create and run `zstd`, test its behavior on local platform
|
||||
Other standard targets include:
|
||||
- `make install` : install zstd cli, library and man pages
|
||||
- `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),
|
||||
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
|
||||
are documented in [`lib/README.md`](lib/README.md#modular-build) for the `libzstd` library
|
||||
For advanced use cases, specialized flags which control binary generation and installation paths are documented
|
||||
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.
|
||||
|
||||
### cmake
|
||||
|
||||
A `cmake` project generator is provided within `build/cmake`.
|
||||
It can generate Makefiles or other build scripts
|
||||
to create `zstd` binary, and `libzstd` dynamic and static libraries.
|
||||
A `cmake` project generator is available for generating Makefiles or other build scripts
|
||||
to create the `zstd` binary as well as `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`.
|
||||
|
||||
|
|
@ -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:
|
||||
|
||||
```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
|
||||
ninja
|
||||
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)
|
||||
|
||||
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.
|
||||
- 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.
|
||||
- It is now recommended to generate Visual Studio solutions from `cmake`
|
||||
|
||||
### Buck
|
||||
|
||||
|
|
@ -210,7 +218,7 @@ The output binary will be in `buck-out/gen/programs/`.
|
|||
|
||||
### 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
|
||||
|
||||
|
|
@ -221,9 +229,9 @@ For information on CI testing, please refer to `TESTING.md`.
|
|||
|
||||
## Status
|
||||
|
||||
Zstandard is currently deployed within Facebook and many other large cloud infrastructures.
|
||||
It is run continuously to compress large amounts of data in multiple formats and use cases.
|
||||
Zstandard is considered safe for production environments.
|
||||
Zstandard is deployed within Meta and many other large cloud infrastructures,
|
||||
to compress humongous amounts of data in various formats and use cases.
|
||||
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
|
||||
|
||||
|
|
@ -232,6 +240,5 @@ Zstandard is dual-licensed under [BSD](LICENSE) OR [GPLv2](COPYING).
|
|||
## Contributing
|
||||
|
||||
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.
|
||||
For more information, please read [CONTRIBUTING](CONTRIBUTING.md).
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
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"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
|
|
@ -122,7 +122,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
OmitFramePointers="true"
|
||||
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"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
|
|
@ -197,7 +197,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
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"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
|
|
@ -275,7 +275,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
OmitFramePointers="true"
|
||||
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"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
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"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
OmitFramePointers="true"
|
||||
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"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
|
|
@ -195,7 +195,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
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"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
|
|
@ -272,7 +272,7 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
OmitFramePointers="true"
|
||||
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"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<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>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
|
|
@ -188,7 +188,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<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>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
|
|
@ -208,7 +208,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<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>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
|
|
@ -229,7 +229,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<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>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<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>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<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>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<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>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
|
|
@ -222,7 +222,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<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>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<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>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<EnableEnhancedInstructionSet>$(InstructionSet)</EnableEnhancedInstructionSet>
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<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>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<EnableEnhancedInstructionSet>$(InstructionSet)</EnableEnhancedInstructionSet>
|
||||
|
|
@ -223,7 +223,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<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>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
|
|
@ -245,7 +245,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<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>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
|
|
|
|||
|
|
@ -9,220 +9,73 @@
|
|||
|
||||
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
|
||||
set(ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION "3")
|
||||
set(ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION "13") #Policies never changed at PATCH level
|
||||
if("${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}" EQUAL "${CMAKE_MAJOR_VERSION}" AND
|
||||
"${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}" GREATER "${CMAKE_MINOR_VERSION}")
|
||||
set(ZSTD_CMAKE_POLICY_VERSION "${CMAKE_VERSION}")
|
||||
else()
|
||||
set(ZSTD_CMAKE_POLICY_VERSION "${ZSTD_MAX_VALIDATED_CMAKE_MAJOR_VERSION}.${ZSTD_MAX_VALIDATED_CMAKE_MINOR_VERSION}.0")
|
||||
endif()
|
||||
cmake_policy(VERSION ${ZSTD_CMAKE_POLICY_VERSION})
|
||||
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH on)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Setup CMake environment
|
||||
#-----------------------------------------------------------------------------
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||
|
||||
# Define project paths
|
||||
set(ZSTD_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
|
||||
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
|
||||
VERSION "${ZSTD_FULL_VERSION}"
|
||||
LANGUAGES C # Main library is in C
|
||||
ASM # And ASM
|
||||
CXX # Testing contributed code also utilizes CXX
|
||||
LANGUAGES C # Main library is in C and ASM, ASM is enabled conditionally
|
||||
HOMEPAGE_URL "${zstd_HOMEPAGE_URL}"
|
||||
DESCRIPTION "${zstd_DESCRIPTION}"
|
||||
)
|
||||
|
||||
message(STATUS "ZSTD VERSION: ${zstd_VERSION}")
|
||||
set(zstd_HOMEPAGE_URL "https://facebook.github.io/zstd")
|
||||
set(zstd_DESCRIPTION "Zstandard is a real-time compression algorithm, providing high compression ratios.")
|
||||
|
||||
# Set a default build type if none was specified
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build type configuration
|
||||
#-----------------------------------------------------------------------------
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
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 the possible values of build type for cmake-gui
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Include standard modules
|
||||
#-----------------------------------------------------------------------------
|
||||
include(GNUInstallDirs)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Add extra compilation flags
|
||||
#-----------------------------------------------------------------------------
|
||||
include(AddZstdCompilationFlags)
|
||||
ADD_ZSTD_COMPILATION_FLAGS()
|
||||
|
||||
# Always hide XXHash symbols
|
||||
add_definitions(-DXXH_NAMESPACE=ZSTD_)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Installation variables
|
||||
# Display installation information
|
||||
#-----------------------------------------------------------------------------
|
||||
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
||||
message(STATUS "CMAKE_INSTALL_LIBDIR: ${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Options
|
||||
# Configure build options
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# 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 ()
|
||||
include(ZstdOptions)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# External dependencies
|
||||
# Configure compilation flags
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define a function to handle special thread settings for HP-UX
|
||||
# See https://github.com/facebook/zstd/pull/3862 for details.
|
||||
function(setup_hpux_threads)
|
||||
find_package(Threads)
|
||||
if (NOT Threads_FOUND)
|
||||
set(CMAKE_USE_PTHREADS_INIT 1 PARENT_SCOPE)
|
||||
set(CMAKE_THREAD_LIBS_INIT -lpthread PARENT_SCOPE)
|
||||
set(CMAKE_HAVE_THREADS_LIBRARY 1 PARENT_SCOPE)
|
||||
set(Threads_FOUND TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if (ZSTD_MULTITHREAD_SUPPORT AND UNIX)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
|
||||
setup_hpux_threads()
|
||||
else()
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
endif()
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(THREADS_LIBS "${CMAKE_THREAD_LIBS_INIT}")
|
||||
else()
|
||||
message(SEND_ERROR "ZSTD currently does not support thread libraries other than pthreads")
|
||||
endif()
|
||||
endif ()
|
||||
include(AddZstdCompilationFlags)
|
||||
ADD_ZSTD_COMPILATION_FLAGS(ON ZSTD_ENABLE_CXX ON)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Add source directories
|
||||
# Configure dependencies
|
||||
#-----------------------------------------------------------------------------
|
||||
add_subdirectory(lib)
|
||||
|
||||
option(ZSTD_PROGRAMS_LINK_SHARED "PROGRAMS LINK SHARED" OFF)
|
||||
|
||||
if (ZSTD_BUILD_PROGRAMS)
|
||||
if (NOT ZSTD_BUILD_STATIC AND NOT ZSTD_PROGRAMS_LINK_SHARED)
|
||||
message(SEND_ERROR "You need to build static library to build zstd CLI")
|
||||
elseif(NOT ZSTD_BUILD_SHARED AND ZSTD_PROGRAMS_LINK_SHARED)
|
||||
message(SEND_ERROR "You need to build shared library to build zstd CLI")
|
||||
endif ()
|
||||
|
||||
add_subdirectory(programs)
|
||||
endif ()
|
||||
|
||||
if (ZSTD_BUILD_TESTS)
|
||||
enable_testing()
|
||||
if (NOT ZSTD_BUILD_STATIC)
|
||||
message(SEND_ERROR "You need to build static library to build tests")
|
||||
endif ()
|
||||
|
||||
add_subdirectory(tests)
|
||||
endif ()
|
||||
|
||||
if (ZSTD_BUILD_CONTRIB)
|
||||
add_subdirectory(contrib)
|
||||
endif ()
|
||||
include(ZstdDependencies)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Add clean-all target
|
||||
# Configure build targets
|
||||
#-----------------------------------------------------------------------------
|
||||
add_custom_target(clean-all
|
||||
COMMAND ${CMAKE_BUILD_TOOL} clean
|
||||
COMMAND rm -rf ${CMAKE_BINARY_DIR}/
|
||||
)
|
||||
include(ZstdBuild)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Generate Package Config files
|
||||
#
|
||||
# This section is based on the boiler plate code from:
|
||||
# https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-packages
|
||||
# Configure package generation
|
||||
#-----------------------------------------------------------------------------
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
|
||||
VERSION ${zstd_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
# A Package Config file that works from the build directory
|
||||
export(EXPORT zstdExports
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/zstdTargets.cmake"
|
||||
NAMESPACE zstd::
|
||||
)
|
||||
|
||||
# A Package Config file that works from the installation directory
|
||||
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/zstd)
|
||||
install(EXPORT zstdExports
|
||||
FILE zstdTargets.cmake
|
||||
NAMESPACE zstd::
|
||||
DESTINATION ${ConfigPackageLocation}
|
||||
)
|
||||
configure_package_config_file(
|
||||
zstdConfig.cmake.in
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake"
|
||||
INSTALL_DESTINATION ${ConfigPackageLocation}
|
||||
)
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/zstdConfigVersion.cmake"
|
||||
DESTINATION ${ConfigPackageLocation}
|
||||
)
|
||||
include(ZstdPackage)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCCompilerFlag)
|
||||
if(CMAKE_CXX_COMPILER)
|
||||
include(CheckCXXCompilerFlag)
|
||||
endif()
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
|
||||
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)
|
||||
endif ()
|
||||
endif ()
|
||||
if (_CXX)
|
||||
if (_CXX AND CMAKE_CXX_COMPILER)
|
||||
CHECK_CXX_COMPILER_FLAG(${_flag} CXX_FLAG_${varname})
|
||||
if (CXX_FLAG_${varname})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_flag}" PARENT_SCOPE)
|
||||
|
|
@ -49,7 +51,7 @@ function(EnableCompilerFlag _flag _C _CXX _LD)
|
|||
endif ()
|
||||
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
|
||||
# compiler flags to mark the stack as non-executable.
|
||||
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
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC)
|
||||
# clang-cl normally maps -Wall to -Weverything.
|
||||
EnableCompilerFlag("/clang:-Wall" true true false)
|
||||
EnableCompilerFlag("/clang:-Wall" _C _CXX false)
|
||||
else ()
|
||||
EnableCompilerFlag("-Wall" true true false)
|
||||
EnableCompilerFlag("-Wall" _C _CXX false)
|
||||
endif ()
|
||||
EnableCompilerFlag("-Wextra" true true false)
|
||||
EnableCompilerFlag("-Wundef" true true false)
|
||||
EnableCompilerFlag("-Wshadow" true true false)
|
||||
EnableCompilerFlag("-Wcast-align" true true false)
|
||||
EnableCompilerFlag("-Wcast-qual" true true false)
|
||||
EnableCompilerFlag("-Wstrict-prototypes" true false false)
|
||||
EnableCompilerFlag("-Wextra" _C _CXX false)
|
||||
EnableCompilerFlag("-Wundef" _C _CXX false)
|
||||
EnableCompilerFlag("-Wshadow" _C _CXX false)
|
||||
EnableCompilerFlag("-Wcast-align" _C _CXX false)
|
||||
EnableCompilerFlag("-Wcast-qual" _C _CXX false)
|
||||
EnableCompilerFlag("-Wstrict-prototypes" _C false false)
|
||||
# Enable asserts in Debug mode
|
||||
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
EnableCompilerFlag("-DDEBUGLEVEL=1" true true false)
|
||||
EnableCompilerFlag("-DDEBUGLEVEL=1" _C _CXX false)
|
||||
endif ()
|
||||
# Add noexecstack flags
|
||||
# LDFLAGS
|
||||
EnableCompilerFlag("-Wl,-z,noexecstack" false false true)
|
||||
EnableCompilerFlag("-Wl,-z,noexecstack" false false _LD)
|
||||
# CFLAGS & CXXFLAGS
|
||||
EnableCompilerFlag("-Qunused-arguments" true true false)
|
||||
EnableCompilerFlag("-Wa,--noexecstack" true true false)
|
||||
EnableCompilerFlag("-Qunused-arguments" _C _CXX false)
|
||||
EnableCompilerFlag("-Wa,--noexecstack" _C _CXX false)
|
||||
# NOTE: Using 3 nested ifs because the variables are sometimes
|
||||
# empty if the condition is false, and sometimes equal to false.
|
||||
# This implicitly converts them to truthy values. There may be
|
||||
|
|
@ -99,15 +101,15 @@ macro(ADD_ZSTD_COMPILATION_FLAGS)
|
|||
|
||||
set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)")
|
||||
if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION)
|
||||
EnableCompilerFlag("/MP" true true false)
|
||||
EnableCompilerFlag("/MP" _C _CXX false)
|
||||
endif ()
|
||||
|
||||
# UNICODE SUPPORT
|
||||
EnableCompilerFlag("/D_UNICODE" true true false)
|
||||
EnableCompilerFlag("/DUNICODE" true true false)
|
||||
EnableCompilerFlag("/D_UNICODE" _C _CXX false)
|
||||
EnableCompilerFlag("/DUNICODE" _C _CXX false)
|
||||
# Enable asserts in Debug mode
|
||||
if (CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
EnableCompilerFlag("/DDEBUGLEVEL=1" true true false)
|
||||
EnableCompilerFlag("/DDEBUGLEVEL=1" _C _CXX false)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
|
|
|||
42
build/cmake/CMakeModules/ZstdBuild.cmake
Normal file
42
build/cmake/CMakeModules/ZstdBuild.cmake
Normal file
|
|
@ -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"
|
||||
)
|
||||
30
build/cmake/CMakeModules/ZstdDependencies.cmake
Normal file
30
build/cmake/CMakeModules/ZstdDependencies.cmake
Normal file
|
|
@ -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()
|
||||
68
build/cmake/CMakeModules/ZstdOptions.cmake
Normal file
68
build/cmake/CMakeModules/ZstdOptions.cmake
Normal file
|
|
@ -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_)
|
||||
45
build/cmake/CMakeModules/ZstdPackage.cmake
Normal file
45
build/cmake/CMakeModules/ZstdPackage.cmake
Normal file
|
|
@ -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}
|
||||
)
|
||||
31
build/cmake/CMakeModules/ZstdVersion.cmake
Normal file
31
build/cmake/CMakeModules/ZstdVersion.cmake
Normal file
|
|
@ -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
|
||||
|
||||
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".
|
||||
To do this, you can create a new directory and build in it:
|
||||
```sh
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
# 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)
|
||||
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
|
||||
|
|
@ -40,6 +40,7 @@ if (MSVC)
|
|||
add_compile_options(-DZSTD_DISABLE_ASM)
|
||||
else ()
|
||||
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)
|
||||
else()
|
||||
add_compile_options(-DZSTD_DISABLE_ASM)
|
||||
|
|
@ -97,9 +98,11 @@ if (ZSTD_LEGACY_SUPPORT)
|
|||
${LIBRARY_LEGACY_DIR}/zstd_v07.h)
|
||||
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(PlatformDependResources ${MSVC_RESOURCE_DIR}/libzstd-dll.rc)
|
||||
else()
|
||||
set(PlatformDependResources)
|
||||
endif ()
|
||||
|
||||
# Explicitly set the language to C for all files, including ASM files.
|
||||
|
|
@ -112,7 +115,7 @@ endif()
|
|||
|
||||
macro (add_definition target var)
|
||||
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 ()
|
||||
endmacro ()
|
||||
|
||||
|
|
@ -120,13 +123,11 @@ endmacro ()
|
|||
set(PUBLIC_INCLUDE_DIRS ${LIBRARY_DIR})
|
||||
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} /I \"${LIBRARY_DIR}\"")
|
||||
# Split project to static and shared libraries build
|
||||
set(library_targets)
|
||||
if (ZSTD_BUILD_SHARED)
|
||||
add_library(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources})
|
||||
target_include_directories(libzstd_shared INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>)
|
||||
list(APPEND library_targets libzstd_shared)
|
||||
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)
|
||||
target_link_libraries(libzstd_shared ${THREADS_LIBS})
|
||||
endif ()
|
||||
|
|
@ -138,9 +139,8 @@ endif ()
|
|||
if (ZSTD_BUILD_STATIC)
|
||||
add_library(libzstd_static STATIC ${Sources} ${Headers})
|
||||
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS}>)
|
||||
list(APPEND library_targets libzstd_static)
|
||||
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)
|
||||
target_link_libraries(libzstd_static ${THREADS_LIBS})
|
||||
endif ()
|
||||
|
|
@ -157,7 +157,6 @@ if (ZSTD_BUILD_SHARED AND NOT ZSTD_BUILD_STATIC)
|
|||
endif ()
|
||||
add_library(libzstd INTERFACE)
|
||||
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
||||
list(APPEND library_targets libzstd)
|
||||
endif ()
|
||||
if (ZSTD_BUILD_STATIC AND NOT ZSTD_BUILD_SHARED)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
|
|
@ -165,7 +164,6 @@ if (ZSTD_BUILD_STATIC AND NOT ZSTD_BUILD_SHARED)
|
|||
endif ()
|
||||
add_library(libzstd INTERFACE)
|
||||
target_link_libraries(libzstd INTERFACE libzstd_static)
|
||||
list(APPEND library_targets libzstd)
|
||||
endif ()
|
||||
if (ZSTD_BUILD_SHARED AND ZSTD_BUILD_STATIC)
|
||||
# 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)
|
||||
add_library(libzstd INTERFACE)
|
||||
target_link_libraries(libzstd INTERFACE libzstd_shared)
|
||||
list(APPEND library_targets libzstd)
|
||||
else ()
|
||||
add_library(libzstd INTERFACE)
|
||||
target_link_libraries(libzstd INTERFACE libzstd_static)
|
||||
list(APPEND library_targets libzstd)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
|
@ -272,8 +268,10 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" DESTINATION "${CMAKE_INST
|
|||
# install target
|
||||
install(FILES ${PublicHeaders} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
|
||||
install(TARGETS ${library_targets}
|
||||
EXPORT zstdExports
|
||||
foreach(target_suffix IN ITEMS "_shared" "_static" "")
|
||||
if(TARGET "libzstd${target_suffix}")
|
||||
install(TARGETS "libzstd${target_suffix}"
|
||||
EXPORT "zstdExports${target_suffix}"
|
||||
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
|
|
@ -282,6 +280,8 @@ install(TARGETS ${library_targets}
|
|||
FRAMEWORK DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT runtime OPTIONAL
|
||||
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# uninstall target
|
||||
if (NOT TARGET uninstall)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ if(@ZSTD_MULTITHREAD_SUPPORT@ AND "@UNIX@")
|
|||
find_dependency(Threads)
|
||||
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")
|
||||
|
||||
check_required_components("zstd")
|
||||
|
|
|
|||
|
|
@ -127,6 +127,10 @@ libzstd = library('zstd',
|
|||
libzstd_dep = declare_dependency(link_with: libzstd,
|
||||
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:
|
||||
# - the shared library (for public symbols)
|
||||
# - the static library (for private symbols)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
project('zstd',
|
||||
['c', 'cpp'],
|
||||
license: ['BSD', 'GPLv2'],
|
||||
license: 'BSD-3-Clause OR GPL-2.0-only',
|
||||
default_options : [
|
||||
# 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.
|
||||
|
|
@ -65,7 +65,6 @@ zstd_docdir = join_paths(zstd_datadir, 'doc', meson.project_name())
|
|||
|
||||
# Built-in options
|
||||
use_debug = get_option('debug')
|
||||
buildtype = get_option('buildtype')
|
||||
default_library_type = get_option('default_library')
|
||||
|
||||
# Custom options
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
# Read guidelines from https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting
|
||||
|
||||
option('legacy_level', type: 'integer', min: 0, max: 7, value: 5,
|
||||
description: 'Support any legacy format: 7 to 1 for v0.7+ to v0.1+')
|
||||
option('legacy_level', type: 'integer', min: 0, max: 7, value: 0,
|
||||
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,
|
||||
description: 'Enable run-time debug. See lib/common/debug.h')
|
||||
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)
|
||||
|
||||
if subprocess.call([*VALGRIND_ARGS, zstd],
|
||||
if subprocess.call([*VALGRIND_ARGS, zstd, '--fake-stdin-is-console'],
|
||||
stdout=subprocess.DEVNULL) == 0:
|
||||
raise subprocess.SubprocessError('zstd without argument should have failed')
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ do { \
|
|||
} while (0) \
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int retn = 0;
|
||||
if (argc != 2) {
|
||||
printf("Usage: externalSequenceProducer <file>\n");
|
||||
return 1;
|
||||
|
|
@ -96,12 +97,12 @@ int main(int argc, char *argv[]) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
retn = 1;
|
||||
}
|
||||
|
||||
ZSTD_freeCCtx(zc);
|
||||
free(src);
|
||||
free(dst);
|
||||
free(val);
|
||||
return 0;
|
||||
return retn;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@
|
|||
#define RUN_TIME_DEFAULT_MS 1000
|
||||
#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)
|
||||
|
||||
|
|
@ -61,7 +63,7 @@
|
|||
|
||||
#define DISPLAY(...) fprintf(stdout, __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 ---*/
|
||||
|
|
@ -739,6 +741,8 @@ static int benchMem(slice_collection_t dstBlocks, slice_collection_t srcBlocks,
|
|||
/* BMK_benchTimedFn may not run exactly nbRounds iterations */
|
||||
double speedAggregated =
|
||||
aggregateData(speedPerRound, roundNb + 1, metricAggregatePref);
|
||||
free(speedPerRound);
|
||||
|
||||
if (metricAggregatePref == fastest)
|
||||
DISPLAY("Fastest Speed : %.1f MB/s \n", speedAggregated);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -77,6 +77,30 @@ int zstd_min_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 ====== */
|
||||
|
||||
/**
|
||||
|
|
@ -136,6 +160,18 @@ typedef ZSTD_parameters zstd_parameters;
|
|||
zstd_parameters zstd_get_params(int level,
|
||||
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_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,
|
||||
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 ====== */
|
||||
|
||||
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,
|
||||
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 ====== */
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ int zstd_max_clevel(void)
|
|||
}
|
||||
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)
|
||||
{
|
||||
return ZSTD_compressBound(src_size);
|
||||
|
|
@ -80,6 +86,13 @@ zstd_parameters zstd_get_params(int level,
|
|||
}
|
||||
EXPORT_SYMBOL(zstd_get_params);
|
||||
|
||||
zstd_compression_parameters zstd_get_cparams(int level,
|
||||
unsigned long long estimated_src_size, size_t dict_size)
|
||||
{
|
||||
return ZSTD_getCParams(level, estimated_src_size, dict_size);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_get_cparams);
|
||||
|
||||
size_t zstd_cctx_set_param(zstd_cctx *cctx, ZSTD_cParameter param, int value)
|
||||
{
|
||||
return ZSTD_CCtx_setParameter(cctx, param, value);
|
||||
|
|
@ -146,6 +159,33 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size)
|
|||
}
|
||||
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,
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
return ZSTD_estimateCStreamSize_usingCParams(*cparams);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,33 @@ size_t zstd_dctx_workspace_bound(void)
|
|||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
return ZSTD_estimateDStreamSize(max_window_size);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
-- Basic usage: project_zstd(ZSTD_DIR)
|
||||
|
||||
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 decompression == nil then decompression = true end
|
||||
if deprecated == nil then deprecated = false end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <cstdio>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
|
||||
namespace pzstd {
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
ZSTDLIB_PATH = ../../../lib
|
||||
ZSTDLIB_NAME = libzstd.a
|
||||
# Parallel tools only make sense against multi-threaded libzstd
|
||||
ZSTDLIB_TARGET = $(ZSTDLIB_NAME)-mt
|
||||
ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME)
|
||||
|
||||
CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I../../../lib -I../../../lib/common
|
||||
|
|
@ -28,7 +30,7 @@ all: seekable_compression seekable_decompression seekable_decompression_mem \
|
|||
parallel_processing
|
||||
|
||||
$(ZSTDLIB):
|
||||
make -C $(ZSTDLIB_PATH) $(ZSTDLIB_NAME)
|
||||
$(MAKE) -C $(ZSTDLIB_PATH) $(ZSTDLIB_TARGET)
|
||||
|
||||
seekable_compression : seekable_compression.c $(SEEKABLE_OBJS)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "xxhash.h"
|
||||
|
||||
#define ZSTD_MULTITHREAD 1
|
||||
#include "threading.h"
|
||||
#include "pool.h" // use zstd thread pool for demo
|
||||
|
||||
#include "../zstd_seekable.h"
|
||||
|
|
@ -72,114 +74,87 @@ static size_t fclose_orDie(FILE* file)
|
|||
exit(6);
|
||||
}
|
||||
|
||||
static void fseek_orDie(FILE* file, long int offset, int origin)
|
||||
{
|
||||
if (!fseek(file, offset, origin)) {
|
||||
if (!fflush(file)) return;
|
||||
}
|
||||
/* error */
|
||||
perror("fseek");
|
||||
exit(7);
|
||||
}
|
||||
|
||||
static long int ftell_orDie(FILE* file)
|
||||
{
|
||||
long int off = ftell(file);
|
||||
if (off != -1) return off;
|
||||
/* error */
|
||||
perror("ftell");
|
||||
exit(8);
|
||||
}
|
||||
struct state {
|
||||
FILE* fout;
|
||||
ZSTD_pthread_mutex_t mutex;
|
||||
size_t nextID;
|
||||
struct job* pending;
|
||||
ZSTD_frameLog* frameLog;
|
||||
const int compressionLevel;
|
||||
};
|
||||
|
||||
struct job {
|
||||
const void* src;
|
||||
size_t id;
|
||||
struct job* next;
|
||||
struct state* state;
|
||||
|
||||
void* src;
|
||||
size_t srcSize;
|
||||
void* dst;
|
||||
size_t dstSize;
|
||||
|
||||
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)
|
||||
{
|
||||
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)) {
|
||||
fprintf(stderr, "ZSTD_compress() error : %s \n", ZSTD_getErrorName(ret));
|
||||
exit(20);
|
||||
}
|
||||
|
||||
job->dstSize = ret;
|
||||
job->done = 1;
|
||||
}
|
||||
|
||||
static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize, int nbThreads)
|
||||
{
|
||||
POOL_ctx* pool = POOL_create(nbThreads, nbThreads);
|
||||
if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); }
|
||||
// No longer need
|
||||
free(job->src);
|
||||
job->src = NULL;
|
||||
|
||||
FILE* const fin = fopen_orDie(fname, "rb");
|
||||
FILE* const fout = fopen_orDie(outName, "wb");
|
||||
|
||||
if (ZSTD_compressBound(frameSize) > 0xFFFFFFFFU) { fprintf(stderr, "Frame size too large \n"); exit(10); }
|
||||
unsigned dstSize = ZSTD_compressBound(frameSize);
|
||||
|
||||
|
||||
fseek_orDie(fin, 0, SEEK_END);
|
||||
long int length = ftell_orDie(fin);
|
||||
fseek_orDie(fin, 0, SEEK_SET);
|
||||
|
||||
size_t numFrames = (length + frameSize - 1) / frameSize;
|
||||
|
||||
struct job* jobs = malloc_orDie(sizeof(struct job) * numFrames);
|
||||
|
||||
size_t i;
|
||||
for(i = 0; i < numFrames; i++) {
|
||||
void* in = malloc_orDie(frameSize);
|
||||
void* out = malloc_orDie(dstSize);
|
||||
|
||||
size_t inSize = fread_orDie(in, frameSize, fin);
|
||||
|
||||
jobs[i].src = in;
|
||||
jobs[i].srcSize = inSize;
|
||||
jobs[i].dst = out;
|
||||
jobs[i].dstSize = dstSize;
|
||||
jobs[i].compressionLevel = cLevel;
|
||||
jobs[i].done = 0;
|
||||
POOL_add(pool, compressFrame, &jobs[i]);
|
||||
}
|
||||
|
||||
ZSTD_frameLog* fl = ZSTD_seekable_createFrameLog(1);
|
||||
if (fl == NULL) { fprintf(stderr, "ZSTD_seekable_createFrameLog() failed \n"); exit(11); }
|
||||
for (i = 0; i < numFrames; i++) {
|
||||
while (!jobs[i].done) SLEEP(5); /* wake up every 5 milliseconds to check */
|
||||
fwrite_orDie(jobs[i].dst, jobs[i].dstSize, fout);
|
||||
free((void*)jobs[i].src);
|
||||
free(jobs[i].dst);
|
||||
|
||||
size_t ret = ZSTD_seekable_logFrame(fl, jobs[i].dstSize, jobs[i].srcSize, jobs[i].checksum);
|
||||
if (ZSTD_isError(ret)) { fprintf(stderr, "ZSTD_seekable_logFrame() error : %s \n", ZSTD_getErrorName(ret)); }
|
||||
}
|
||||
|
||||
{ unsigned char seekTableBuff[1024];
|
||||
ZSTD_outBuffer out = {seekTableBuff, 1024, 0};
|
||||
while (ZSTD_seekable_writeSeekTable(fl, &out) != 0) {
|
||||
fwrite_orDie(seekTableBuff, out.pos, fout);
|
||||
out.pos = 0;
|
||||
}
|
||||
fwrite_orDie(seekTableBuff, out.pos, fout);
|
||||
}
|
||||
|
||||
ZSTD_seekable_freeFrameLog(fl);
|
||||
free(jobs);
|
||||
fclose_orDie(fout);
|
||||
fclose_orDie(fin);
|
||||
finishFrame(job);
|
||||
}
|
||||
|
||||
static const char* createOutFilename_orDie(const char* filename)
|
||||
|
|
@ -193,6 +168,72 @@ static const char* createOutFilename_orDie(const char* filename)
|
|||
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) {
|
||||
const char* const exeName = argv[0];
|
||||
if (argc!=4) {
|
||||
|
|
@ -204,10 +245,9 @@ int main(int argc, const char** argv) {
|
|||
|
||||
{ const char* const inFileName = argv[1];
|
||||
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, outFileName, 5, frameSize, nbThreads);
|
||||
compressFile_orDie(inFileName, 5, frameSize, nbThreads);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -100,13 +100,11 @@ struct sum_job {
|
|||
const char* fname;
|
||||
unsigned long long sum;
|
||||
unsigned frameNb;
|
||||
int done;
|
||||
};
|
||||
|
||||
static void sumFrame(void* opaque)
|
||||
{
|
||||
struct sum_job* job = (struct sum_job*)opaque;
|
||||
job->done = 0;
|
||||
|
||||
FILE* const fin = fopen_orDie(job->fname, "rb");
|
||||
|
||||
|
|
@ -128,7 +126,6 @@ static void sumFrame(void* opaque)
|
|||
sum += data[i];
|
||||
}
|
||||
job->sum = sum;
|
||||
job->done = 1;
|
||||
|
||||
fclose(fin);
|
||||
ZSTD_seekable_free(seekable);
|
||||
|
|
@ -153,14 +150,14 @@ static void sumFile_orDie(const char* fname, int nbThreads)
|
|||
|
||||
unsigned 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_joinJobs(pool);
|
||||
|
||||
unsigned long long total = 0;
|
||||
|
||||
for (fnb = 0; fnb < numFrames; fnb++) {
|
||||
while (!jobs[fnb].done) SLEEP(5); /* wake up every 5 milliseconds to check */
|
||||
total += jobs[fnb].sum;
|
||||
}
|
||||
|
||||
|
|
|
|||
1
contrib/seekable_format/tests/.gitignore
vendored
1
contrib/seekable_format/tests/.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
seekable_tests
|
||||
data.txt
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c $(ZSTDLIB)
|
|||
.PHONY: default clean test
|
||||
default: test
|
||||
|
||||
test: seekable_tests
|
||||
test: seekable_tests parallel_compression_test
|
||||
./seekable_tests
|
||||
|
||||
$(ZSTDLIB):
|
||||
|
|
@ -32,7 +32,27 @@ $(ZSTDLIB):
|
|||
|
||||
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:
|
||||
@$(RM) core *.o tmp* result* *.zst \
|
||||
seekable_tests
|
||||
seekable_tests data.txt
|
||||
@echo Cleaning completed
|
||||
|
|
|
|||
|
|
@ -316,6 +316,10 @@ int main(int argc, const char** argv)
|
|||
for (pos = 0; pos < inSize; pos += 2) {
|
||||
size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, 1, pos);
|
||||
if (decStatus != 1 || outBuffer[0] != inBuffer[pos]) {
|
||||
free(seekBuffer);
|
||||
free(outBuffer);
|
||||
ZSTD_seekable_freeCStream(zscs);
|
||||
ZSTD_seekable_free(stream);
|
||||
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.
|
||||
This is unneeded because we only seeked forward. */
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -342,6 +350,10 @@ int main(int argc, const char** argv)
|
|||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Distribution of this document is unlimited.
|
|||
|
||||
### Version
|
||||
|
||||
0.4.3 (2024-10-07)
|
||||
0.4.5 (2026-05-14)
|
||||
|
||||
|
||||
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`__
|
||||
|
||||
The size of `Block_Content` is limited by `Block_Maximum_Size`,
|
||||
which is the smallest of:
|
||||
The size of `Block_Content` is limited by `Block_Maximum_Size`, which is
|
||||
determined once for a given frame and is the smallest of:
|
||||
- `Window_Size`
|
||||
- 128 KB
|
||||
- 128 KiB (131.072 bytes)
|
||||
|
||||
`Block_Maximum_Size` is constant for a given frame.
|
||||
This maximum is applicable to both the decompressed size
|
||||
and the compressed size of any block in the frame.
|
||||
Both the `Block_Content` and the decompressed size of any block in the frame must
|
||||
be no larger than `Block_Maximum_Size`.
|
||||
|
||||
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.
|
||||
The guarantees on the size of blocks ensure that
|
||||
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
|
||||
-----------------
|
||||
|
|
@ -1742,6 +1746,8 @@ or at least provide a meaningful error code explaining for which reason it canno
|
|||
|
||||
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.2 : refactor FSE table construction process, inspired by Donald Pian
|
||||
- 0.4.1 : clarifications on a few error scenarios, by Eric Lasota
|
||||
|
|
|
|||
|
|
@ -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_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".
|
||||
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).
|
||||
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.
|
||||
|
|
@ -128,9 +129,8 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
|
|||
</p></pre><BR>
|
||||
|
||||
<pre><b>ZSTD_DEPRECATED("Replaced by ZSTD_getFrameContentSize")
|
||||
ZSTDLIB_API
|
||||
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
|
||||
"empty", "unknown" and "error" results to the same return value (0),
|
||||
while ZSTD_getFrameContentSize() gives them separate return values.
|
||||
|
|
@ -143,6 +143,11 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
|
|||
@return : the compressed size of the first frame starting at `src`,
|
||||
suitable to pass as `srcSize` to `ZSTD_decompress` or similar,
|
||||
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>
|
||||
|
||||
<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>
|
||||
|
||||
<h3>Error helper functions</h3><pre></pre><b><pre>#include "zstd_errors.h" </b>/* list of errors */<b>
|
||||
</b>/* ZSTD_isError() :<b>
|
||||
<h3>Error helper functions</h3><pre></pre><b><pre></b>/* ZSTD_isError() :<b>
|
||||
* Most ZSTD_* functions returning a size_t value can be tested for error,
|
||||
* using ZSTD_isError().
|
||||
* @return 1 if error, 0 otherwise
|
||||
|
|
@ -1239,7 +1243,7 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
|||
</p></pre><BR>
|
||||
|
||||
<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,
|
||||
or an error code (if srcSize is too small)
|
||||
</p></pre><BR>
|
||||
|
|
@ -1252,20 +1256,20 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
|||
unsigned blockSizeMax;
|
||||
ZSTD_FrameType_e frameType; </b>/* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */<b>
|
||||
unsigned headerSize;
|
||||
unsigned dictID;
|
||||
unsigned dictID; </b>/* for ZSTD_skippableFrame, contains the skippable magic variant [0-15] */<b>
|
||||
unsigned checksumFlag;
|
||||
unsigned _reserved1;
|
||||
unsigned _reserved2;
|
||||
} ZSTD_frameHeader;
|
||||
} ZSTD_FrameHeader;
|
||||
</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>
|
||||
* same as ZSTD_getFrameHeader(),
|
||||
* 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);
|
||||
</b><p> decode Frame Header, or requires larger `srcSize`.
|
||||
@return : 0, `zfhPtr` is correctly filled,
|
||||
>0, `srcSize` is too small, value is wanted `srcSize` amount,
|
||||
</b><p> decode Frame Header into `zfhPtr`, or requires larger `srcSize`.
|
||||
@return : 0 => header is complete, `zfhPtr` is correctly filled,
|
||||
>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()
|
||||
</p></pre><BR>
|
||||
|
||||
|
|
@ -1421,7 +1425,7 @@ ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|||
ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const ZSTD_Sequence* inSeqs, size_t nbSequences,
|
||||
const void* literals, size_t litSize, size_t litCapacity,
|
||||
const void* literals, size_t litSize, size_t litBufCapacity,
|
||||
size_t decompressedSize);
|
||||
</b><p> This is a variant of ZSTD_compressSequences() which,
|
||||
instead of receiving (src,srcSize) as input parameter, receives (literals,litSize),
|
||||
|
|
@ -1435,20 +1439,22 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
|||
- Not compatible with frame checksum, which must be disabled
|
||||
- If any block is incompressible, will fail and return an error
|
||||
- @litSize must be == sum of all @.litLength fields in @inSeqs. Any discrepancy will generate an error.
|
||||
- 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.
|
||||
@return : final compressed size, or a ZSTD error code.
|
||||
|
||||
</p></pre><BR>
|
||||
|
||||
<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.
|
||||
|
||||
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.
|
||||
As such, the parameter magicVariant controls the exact skippable frame magic number variant used, so
|
||||
the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant.
|
||||
As such, the parameter magicVariant controls the exact skippable frame magic number variant used,
|
||||
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
|
||||
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>
|
||||
|
||||
<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,
|
||||
unsigned* magicVariant,
|
||||
const void* src, size_t srcSize);
|
||||
</b><p> Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
|
||||
</b><p> Retrieves the content of a zstd skippable frame starting at @src, and writes it to @dst buffer.
|
||||
|
||||
The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
|
||||
i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
|
||||
in the magicVariant.
|
||||
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 in the magicVariant.
|
||||
|
||||
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>
|
||||
|
||||
<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.
|
||||
|
||||
</p></pre><BR>
|
||||
|
|
|
|||
2
lib/BUCK
2
lib/BUCK
|
|
@ -57,7 +57,7 @@ cxx_library(
|
|||
srcs=glob(['legacy/*.c']),
|
||||
deps=[':common'],
|
||||
exported_preprocessor_flags=[
|
||||
'-DZSTD_LEGACY_SUPPORT=4',
|
||||
'-DZSTD_LEGACY_SUPPORT=0',
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
18
lib/Makefile
18
lib/Makefile
|
|
@ -128,7 +128,7 @@ $(ZSTD_STATICLIB): $(ZSTD_STATICLIB_OBJ)
|
|||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
libzstd.a: $(ZSTD_STATICLIB)
|
||||
cp -f $< $@
|
||||
$(CP) $< $@
|
||||
|
||||
endif
|
||||
|
||||
|
|
@ -166,13 +166,13 @@ $(ZSTD_DYNLIB): $(ZSTD_DYNLIB_OBJ)
|
|||
$(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\
|
||||
@echo compiling multi-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
|
||||
ln -sf $@ libzstd.$(SHARED_EXT_MAJOR)
|
||||
ln -sf $@ libzstd.$(SHARED_EXT)
|
||||
$(LN) -sf $@ libzstd.$(SHARED_EXT_MAJOR)
|
||||
$(LN) -sf $@ libzstd.$(SHARED_EXT)
|
||||
|
||||
$(LIBZSTD): $(ZSTD_DYNLIB)
|
||||
cp -f $< $@
|
||||
$(CP) $< $@
|
||||
|
||||
endif # ifndef BUILD_DIR
|
||||
endif # if windows
|
||||
|
|
@ -255,7 +255,7 @@ libzstd-nomt: $(ZSTD_NOMT_FILES)
|
|||
echo "Error: Found zstdmt in list."; \
|
||||
exit 1; \
|
||||
fi
|
||||
$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
|
||||
$(CC) $(FLAGS) $^ $(SONAME_FLAGS) -o $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
|
@ -268,7 +268,7 @@ clean:
|
|||
#-----------------------------------------------------------------------------
|
||||
# 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
|
||||
|
||||
|
|
@ -363,8 +363,8 @@ install-shared:
|
|||
[ -e $(DESTDIR)$(LIBDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(LIBDIR)/
|
||||
@echo Installing shared library
|
||||
$(INSTALL_PROGRAM) $(LIBZSTD) $(DESTDIR)$(LIBDIR)
|
||||
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_MAJOR)
|
||||
$(LN) -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
|
||||
|
||||
.PHONY: install-includes
|
||||
install-includes:
|
||||
|
|
|
|||
|
|
@ -7,15 +7,30 @@ in order to make it easier to select or exclude features.
|
|||
|
||||
#### 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.
|
||||
- `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,
|
||||
and support for decoding legacy formats >= v0.5.0.
|
||||
`libzstd` default scope includes compression, decompression, and dictionary builder.
|
||||
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_).
|
||||
|
||||
#### 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
|
||||
|
||||
|
|
@ -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.
|
||||
For example, `ZSTD_LEGACY_SUPPORT=2` means : "support legacy formats >= v0.2.0".
|
||||
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.
|
||||
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.
|
||||
|
|
@ -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
|
||||
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
|
||||
|
||||
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)
|
||||
{
|
||||
if (customMem.customAlloc) {
|
||||
/* calloc implemented as malloc+memset;
|
||||
* not as efficient as calloc, but next best guess for custom malloc */
|
||||
/* calloc implemented as malloc+memset */
|
||||
void* const ptr = customMem.customAlloc(customMem.opaque, size);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZSTD_memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
|
|||
30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7,
|
||||
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() */
|
||||
|
||||
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
|
||||
MEM_STATIC BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
|
||||
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
|
||||
FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
|
||||
FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
|
||||
MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -218,6 +218,18 @@
|
|||
# if defined(__ARM_NEON) || defined(_M_ARM64)
|
||||
# define ZSTD_ARCH_ARM_NEON
|
||||
# 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)
|
||||
# include <immintrin.h>
|
||||
|
|
@ -227,6 +239,12 @@
|
|||
# elif defined(ZSTD_ARCH_ARM_NEON)
|
||||
# include <arm_neon.h>
|
||||
# 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
|
||||
|
||||
/* 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
|
||||
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
|
||||
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`.
|
||||
*/
|
||||
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
|
||||
|
|
|
|||
|
|
@ -142,19 +142,17 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
|
|||
/* Allocate space for the thread handles */
|
||||
ctx->threads = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
|
||||
ctx->threadCapacity = 0;
|
||||
ctx->threadLimit = numThreads;
|
||||
ctx->customMem = customMem;
|
||||
/* Check for errors */
|
||||
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
|
||||
/* Initialize the threads */
|
||||
{ size_t i;
|
||||
for (i = 0; i < numThreads; ++i) {
|
||||
if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
|
||||
ctx->threadCapacity = i;
|
||||
while (ctx->threadCapacity < numThreads) {
|
||||
if (ZSTD_pthread_create(&ctx->threads[ctx->threadCapacity++], NULL, &POOL_thread, ctx)) {
|
||||
--ctx->threadCapacity;
|
||||
POOL_free(ctx);
|
||||
return NULL;
|
||||
} }
|
||||
ctx->threadCapacity = numThreads;
|
||||
ctx->threadLimit = numThreads;
|
||||
}
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
|
@ -220,23 +218,22 @@ static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
|
|||
return 0;
|
||||
}
|
||||
/* numThreads > threadCapacity */
|
||||
ctx->threadLimit = numThreads;
|
||||
{ ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
|
||||
if (!threadPool) return 1;
|
||||
/* replace existing thread pool */
|
||||
/* extend existing thread pool */
|
||||
ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(ZSTD_pthread_t));
|
||||
ZSTD_customFree(ctx->threads, ctx->customMem);
|
||||
ctx->threads = threadPool;
|
||||
/* Initialize additional threads */
|
||||
{ size_t threadId;
|
||||
for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
|
||||
if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
|
||||
ctx->threadCapacity = threadId;
|
||||
while (ctx->threadCapacity < numThreads) {
|
||||
if (ZSTD_pthread_create(&threadPool[ctx->threadCapacity++], NULL, &POOL_thread, ctx)) {
|
||||
--ctx->threadCapacity;
|
||||
return 1;
|
||||
} }
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
/* successfully expanded */
|
||||
ctx->threadCapacity = numThreads;
|
||||
ctx->threadLimit = numThreads;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,4 +168,23 @@
|
|||
# define ZSTD_CET_ENDBRANCH
|
||||
#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 */
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
if (!*mutex)
|
||||
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)
|
||||
|
|
@ -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));
|
||||
if (!*cond)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -46,3 +46,12 @@ ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
|
|||
/*! ZSTD_getErrorString() :
|
||||
* provides error code string from enum */
|
||||
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
|
||||
*********************************************/
|
||||
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));
|
||||
#else
|
||||
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));
|
||||
#elif defined(ZSTD_ARCH_X86_SSE2)
|
||||
_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__)
|
||||
ZSTD_memmove(dst, src, 16);
|
||||
#else
|
||||
|
|
@ -213,7 +215,7 @@ typedef enum {
|
|||
* The src buffer must be before the dst buffer.
|
||||
*/
|
||||
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;
|
||||
const BYTE* ip = (const BYTE*)src;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@
|
|||
#include "../common/error_private.h" /* ERROR */
|
||||
#include "hist.h"
|
||||
|
||||
#if defined(ZSTD_ARCH_ARM_SVE2)
|
||||
#define HIST_FAST_THRESHOLD 500
|
||||
#else
|
||||
#define HIST_FAST_THRESHOLD 1500
|
||||
#endif
|
||||
|
||||
|
||||
/* --- Error management --- */
|
||||
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;
|
||||
|
||||
#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() :
|
||||
* store histogram into 4 intermediate tables, recombined at the end.
|
||||
* 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.
|
||||
* @return : largest histogram frequency,
|
||||
* or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */
|
||||
static size_t HIST_count_parallel_wksp(
|
||||
unsigned* count, unsigned* maxSymbolValuePtr,
|
||||
static UNUSED_ATTR
|
||||
size_t HIST_count_parallel_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
||||
const void* source, size_t sourceSize,
|
||||
HIST_checkInput_e check,
|
||||
U32* const workSpace)
|
||||
|
|
@ -151,11 +395,17 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
|||
const void* source, size_t sourceSize,
|
||||
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);
|
||||
#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 (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
|
||||
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* HIST_count_wksp() :
|
||||
|
|
@ -165,10 +415,15 @@ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
|||
const void* source, size_t sourceSize,
|
||||
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 (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
|
||||
if (*maxSymbolValuePtr < 255)
|
||||
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace);
|
||||
#endif
|
||||
*maxSymbolValuePtr = 255;
|
||||
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 --- */
|
||||
|
||||
#if defined(__ARM_FEATURE_SVE2)
|
||||
#define HIST_WKSP_SIZE_U32 0
|
||||
#else
|
||||
#define HIST_WKSP_SIZE_U32 1024
|
||||
#endif
|
||||
#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned))
|
||||
/** HIST_count_wksp() :
|
||||
* 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.
|
||||
*/
|
||||
U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1;
|
||||
assert(nBitsToDecrease <= HUF_TABLELOG_MAX+1);
|
||||
for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
|
||||
U32 const highPos = rankLast[nBitsToDecrease];
|
||||
U32 const lowPos = rankLast[nBitsToDecrease-1];
|
||||
|
|
|
|||
|
|
@ -56,6 +56,14 @@
|
|||
# define ZSTD_HASHLOG3_MAX 17
|
||||
#endif
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Forward declarations
|
||||
***************************************/
|
||||
size_t convertSequences_noRepcodes(SeqDef* dstSeqs, const ZSTD_Sequence* inSeqs,
|
||||
size_t nbSequences);
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* 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 */
|
||||
static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode,
|
||||
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 */
|
||||
mode = ZSTD_ps_disable;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1755,15 +1771,19 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|||
{
|
||||
ZSTD_compressionParameters const cParams =
|
||||
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
||||
ldmParams_t ldmParams = params->ldmParams;
|
||||
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
|
||||
&cParams);
|
||||
|
||||
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
|
||||
* be needed. However, we still allocate two 0-sized buffers, which can
|
||||
* take space under ASAN. */
|
||||
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)
|
||||
|
|
@ -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.");
|
||||
{ ZSTD_compressionParameters const cParams =
|
||||
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 inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
|
||||
? ((size_t)1 << cParams.windowLog) + blockSize
|
||||
|
|
@ -1822,8 +1843,11 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|||
: 0;
|
||||
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(
|
||||
&cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
|
||||
&cParams, &ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
|
||||
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 */
|
||||
|
||||
|
|
@ -7130,7 +7154,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|||
* @returns > 0 if there is one long length (> 65535),
|
||||
* indicating the position, and type.
|
||||
*/
|
||||
static size_t convertSequences_noRepcodes(
|
||||
size_t convertSequences_noRepcodes(
|
||||
SeqDef* dstSeqs,
|
||||
const ZSTD_Sequence* inSeqs,
|
||||
size_t nbSequences)
|
||||
|
|
@ -7276,13 +7300,378 @@ static size_t convertSequences_noRepcodes(
|
|||
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,
|
||||
* but since this implementation is targeting modern systems (>= Sapphire Rapid),
|
||||
* 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,
|
||||
const ZSTD_Sequence* inSeqs,
|
||||
size_t nbSequences)
|
||||
|
|
@ -7293,7 +7682,7 @@ static size_t convertSequences_noRepcodes(
|
|||
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 */
|
||||
/* Check for long length > 65535. */
|
||||
if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
|
||||
assert(longLen == 0);
|
||||
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)
|
||||
{
|
||||
size_t totalMatchSize = 0;
|
||||
size_t litSize = 0;
|
||||
size_t n;
|
||||
assert(seqs);
|
||||
for (n=0; n<nbSeqs; n++) {
|
||||
totalMatchSize += seqs[n].matchLength;
|
||||
litSize += seqs[n].litLength;
|
||||
if (seqs[n].matchLength == 0) {
|
||||
assert(seqs[n].offset == 0);
|
||||
size_t i = 0;
|
||||
int found_terminator = 0;
|
||||
size_t vl_max = __riscv_vsetvlmax_e32m1();
|
||||
typedef uint32_t __attribute__((may_alias)) aliased_u32;
|
||||
vuint32m1_t v_lit_sum = __riscv_vmv_v_x_u32m1(0, vl_max);
|
||||
vuint32m1_t v_match_sum = __riscv_vmv_v_x_u32m1(0, vl_max);
|
||||
|
||||
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;
|
||||
} 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;
|
||||
bs.nbSequences = ERROR(externalSequences_invalid);
|
||||
return bs;
|
||||
}
|
||||
{ BlockSummary bs;
|
||||
bs.nbSequences = n+1;
|
||||
bs.nbSequences = i;
|
||||
bs.blockSize = litSize + totalMatchSize;
|
||||
bs.litSize = litSize;
|
||||
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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -707,7 +707,7 @@ ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE con
|
|||
{
|
||||
assert(iend > 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;
|
||||
ip = ilimit_w;
|
||||
}
|
||||
|
|
@ -800,7 +800,7 @@ ZSTD_storeSeq(SeqStore_t* seqStorePtr,
|
|||
ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16);
|
||||
ZSTD_copy16(seqStorePtr->lit, literals);
|
||||
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 {
|
||||
ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);
|
||||
|
|
@ -1523,7 +1523,7 @@ typedef struct {
|
|||
/* for benchmark */
|
||||
size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
|
||||
const ZSTD_Sequence* const inSeqs, size_t nbSequences,
|
||||
int const repcodeResolution);
|
||||
int repcodeResolution);
|
||||
|
||||
typedef struct {
|
||||
size_t nbSequences;
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,44 @@ ZSTD_row_getNEONMask(const U32 rowEntries, const BYTE* const src, const BYTE tag
|
|||
}
|
||||
}
|
||||
#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
|
||||
* 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);
|
||||
|
||||
#else /* SW or NEON-LE */
|
||||
#elif defined(ZSTD_ARCH_RISCV_RVV) && (__riscv_xlen == 64)
|
||||
|
||||
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 */
|
||||
if (MEM_isLittleEndian()) {
|
||||
return ZSTD_row_getNEONMask(rowEntries, src, tag, headGrouped);
|
||||
}
|
||||
# endif /* ZSTD_ARCH_ARM_NEON */
|
||||
|
||||
|
||||
#endif
|
||||
/* SWAR */
|
||||
{ const int chunkSize = sizeof(size_t);
|
||||
const size_t shiftAmount = ((chunkSize * 8) - chunkSize);
|
||||
|
|
|
|||
|
|
@ -152,8 +152,12 @@ void ZSTD_ldm_adjustParameters(ldmParams_t* params,
|
|||
}
|
||||
}
|
||||
if (params->hashLog == 0) {
|
||||
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) {
|
||||
params->minMatchLength = LDM_MIN_MATCH_LENGTH;
|
||||
if (cParams->strategy >= ZSTD_btultra)
|
||||
|
|
|
|||
|
|
@ -1382,16 +1382,8 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|||
assert(storeEnd < ZSTD_OPT_SIZE);
|
||||
DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
|
||||
storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off);
|
||||
if (lastStretch.litlen > 0) {
|
||||
/* last "sequence" is unfinished: just a bunch of literals */
|
||||
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) {
|
||||
ZSTD_optimal_t nextStretch = opt[stretchPos];
|
||||
opt[storeStart].litlen = nextStretch.litlen;
|
||||
|
|
|
|||
|
|
@ -1008,6 +1008,7 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
|
|||
{
|
||||
unsigned jobID;
|
||||
DEBUGLOG(3, "ZSTDMT_releaseAllJobResources");
|
||||
if (mtctx->jobs) {
|
||||
for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
|
||||
/* Copy the mutex/cond out */
|
||||
ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;
|
||||
|
|
@ -1021,6 +1022,7 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
|
|||
mtctx->jobs[jobID].job_mutex = mutex;
|
||||
mtctx->jobs[jobID].job_cond = cond;
|
||||
}
|
||||
}
|
||||
mtctx->inBuff.buffer = g_nullBuffer;
|
||||
mtctx->inBuff.filled = 0;
|
||||
mtctx->allJobsCompleted = 1;
|
||||
|
|
@ -1268,8 +1270,7 @@ size_t ZSTDMT_initCStream_internal(
|
|||
|
||||
if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
|
||||
ZSTDMT_waitForAllJobsCompleted(mtctx);
|
||||
ZSTDMT_releaseAllJobResources(mtctx);
|
||||
mtctx->allJobsCompleted = 1;
|
||||
ZSTDMT_releaseAllJobResources(mtctx); /* Will set allJobsCompleted to 1 */
|
||||
}
|
||||
|
||||
mtctx->params = params;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
/* **************************************************************
|
||||
* Dependencies
|
||||
****************************************************************/
|
||||
#include <stddef.h> /* size_t */
|
||||
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
|
||||
#include "../common/compiler.h"
|
||||
#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;
|
||||
|
||||
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.
|
||||
* This condition is false on x32.
|
||||
|
|
@ -578,7 +579,7 @@ HUF_decompress1X1_usingDTable_internal_body(
|
|||
const HUF_DTable* DTable)
|
||||
{
|
||||
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 HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
|
||||
BIT_DStream_t bitD;
|
||||
|
|
@ -786,17 +787,17 @@ void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||
|
||||
#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \
|
||||
do { \
|
||||
int const index = (int)(bits[(_stream)] >> 53); \
|
||||
int const entry = (int)dtable[index]; \
|
||||
bits[(_stream)] <<= (entry & 0x3F); \
|
||||
op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \
|
||||
U64 const index = bits[(_stream)] >> 53; \
|
||||
U16 const entry = dtable[index]; \
|
||||
bits[(_stream)] <<= entry & 0x3F; \
|
||||
op[(_stream)][(_symbol)] = (BYTE)(entry >> 8); \
|
||||
} while (0)
|
||||
|
||||
#define HUF_4X1_RELOAD_STREAM(_stream) \
|
||||
#define HUF_5X1_RELOAD_STREAM(_stream) \
|
||||
do { \
|
||||
int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||
int const nbBits = ctz & 7; \
|
||||
int const nbBytes = ctz >> 3; \
|
||||
U64 const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||
U64 const nbBits = ctz & 7; \
|
||||
U64 const nbBytes = ctz >> 3; \
|
||||
op[(_stream)] += 5; \
|
||||
ip[(_stream)] -= nbBytes; \
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
#undef HUF_4X1_DECODE_SYMBOL
|
||||
#undef HUF_4X1_RELOAD_STREAM
|
||||
#undef HUF_5X1_RELOAD_STREAM
|
||||
}
|
||||
|
||||
_out:
|
||||
|
|
@ -845,7 +846,7 @@ HUF_decompress4X1_usingDTable_internal_fast(
|
|||
{
|
||||
void const* dt = DTable + 1;
|
||||
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;
|
||||
{ size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
|
||||
FORWARD_IF_ERROR(ret, "Failed to init fast loop args");
|
||||
|
|
@ -1362,7 +1363,7 @@ HUF_decompress1X2_usingDTable_internal_body(
|
|||
|
||||
/* decode */
|
||||
{ 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 HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
|
||||
DTableDesc const dtd = HUF_getDTableDesc(DTable);
|
||||
|
|
@ -1605,54 +1606,62 @@ void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs*
|
|||
#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \
|
||||
do { \
|
||||
if ((_decode3) || (_stream) != 3) { \
|
||||
int const index = (int)(bits[(_stream)] >> 53); \
|
||||
HUF_DEltX2 const entry = dtable[index]; \
|
||||
MEM_write16(op[(_stream)], entry.sequence); \
|
||||
bits[(_stream)] <<= (entry.nbBits) & 0x3F; \
|
||||
op[(_stream)] += (entry.length); \
|
||||
U64 const index = bits[(_stream)] >> 53; \
|
||||
size_t const entry = MEM_readLE32(&dtable[index]); \
|
||||
MEM_write16(op[(_stream)], (U16)entry); \
|
||||
bits[(_stream)] <<= (entry >> 16) & 0x3F; \
|
||||
op[(_stream)] += entry >> 24; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define HUF_4X2_RELOAD_STREAM(_stream) \
|
||||
#define HUF_5X2_RELOAD_STREAM(_stream, _decode3) \
|
||||
do { \
|
||||
HUF_4X2_DECODE_SYMBOL(3, 1); \
|
||||
if (_decode3) HUF_4X2_DECODE_SYMBOL(3, 1); \
|
||||
{ \
|
||||
int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||
int const nbBits = ctz & 7; \
|
||||
int const nbBytes = ctz >> 3; \
|
||||
U64 const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \
|
||||
U64 const nbBits = ctz & 7; \
|
||||
U64 const nbBytes = ctz >> 3; \
|
||||
ip[(_stream)] -= nbBytes; \
|
||||
bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \
|
||||
bits[(_stream)] <<= nbBits; \
|
||||
} \
|
||||
} 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
|
||||
* unroll the inner loops, which destroys performance.
|
||||
*/
|
||||
do {
|
||||
/* Decode 5 symbols from each of the first 3 streams.
|
||||
* The final stream will be decoded during the reload phase
|
||||
* to reduce register pressure.
|
||||
/* Decode 5 symbols from each of the first 3 or 4 streams.
|
||||
* In the 3-way case the final stream will be decoded during
|
||||
* 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, 0);
|
||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0);
|
||||
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, HUF_4X2_4WAY);
|
||||
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, HUF_4X2_4WAY);
|
||||
HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, HUF_4X2_4WAY);
|
||||
|
||||
/* Decode one symbol from the final stream */
|
||||
HUF_4X2_DECODE_SYMBOL(3, 1);
|
||||
/* In the 3-way case decode one symbol from the final stream. */
|
||||
HUF_4X2_DECODE_SYMBOL(3, HUF_4X2_3WAY);
|
||||
|
||||
/* Decode 4 symbols from the final stream & reload bitstreams.
|
||||
* The final stream is reloaded last, meaning that all 5 symbols
|
||||
* are decoded from the final stream before it is reloaded.
|
||||
/* In the 3-way case decode 4 symbols from the final stream &
|
||||
* reload bitstreams. The final stream is reloaded last, meaning
|
||||
* 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);
|
||||
}
|
||||
|
||||
#undef HUF_4X2_DECODE_SYMBOL
|
||||
#undef HUF_4X2_RELOAD_STREAM
|
||||
#undef HUF_5X2_RELOAD_STREAM
|
||||
|
||||
_out:
|
||||
|
||||
|
|
@ -1671,7 +1680,7 @@ HUF_decompress4X2_usingDTable_internal_fast(
|
|||
HUF_DecompressFastLoopFn loopFn) {
|
||||
void const* dt = DTable + 1;
|
||||
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;
|
||||
{
|
||||
size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,16 @@
|
|||
|
||||
#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
|
||||
|
||||
/* 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:
|
||||
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. */
|
||||
push %rax
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset rax, -16
|
||||
push %rbx
|
||||
.cfi_def_cfa_offset 24
|
||||
.cfi_offset rbx, -24
|
||||
push %rcx
|
||||
.cfi_def_cfa_offset 32
|
||||
.cfi_offset rcx, -32
|
||||
push %rdx
|
||||
.cfi_def_cfa_offset 40
|
||||
.cfi_offset rdx, -40
|
||||
push %rbp
|
||||
.cfi_def_cfa_offset 48
|
||||
.cfi_offset rbp, -48
|
||||
push %rsi
|
||||
.cfi_def_cfa_offset 56
|
||||
.cfi_offset rsi, -56
|
||||
push %rdi
|
||||
.cfi_def_cfa_offset 64
|
||||
.cfi_offset rdi, -64
|
||||
push %r8
|
||||
.cfi_def_cfa_offset 72
|
||||
.cfi_offset r8, -72
|
||||
push %r9
|
||||
.cfi_def_cfa_offset 80
|
||||
.cfi_offset r9, -80
|
||||
push %r10
|
||||
.cfi_def_cfa_offset 88
|
||||
.cfi_offset r10, -88
|
||||
push %r11
|
||||
.cfi_def_cfa_offset 96
|
||||
.cfi_offset r11, -96
|
||||
push %r12
|
||||
.cfi_def_cfa_offset 104
|
||||
.cfi_offset r12, -104
|
||||
push %r13
|
||||
.cfi_def_cfa_offset 112
|
||||
.cfi_offset r13, -112
|
||||
push %r14
|
||||
.cfi_def_cfa_offset 120
|
||||
.cfi_offset r14, -120
|
||||
push %r15
|
||||
.cfi_def_cfa_offset 128
|
||||
.cfi_offset r15, -128
|
||||
|
||||
/* Read HUF_DecompressAsmArgs* args from %rax */
|
||||
#if defined(_WIN32)
|
||||
|
|
@ -154,13 +197,18 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||
movq 88(%rax), %bits3
|
||||
movq 96(%rax), %dtable
|
||||
push %rax /* argument */
|
||||
.cfi_def_cfa_offset 136
|
||||
push 104(%rax) /* ilowest */
|
||||
.cfi_def_cfa_offset 144
|
||||
push 112(%rax) /* oend */
|
||||
.cfi_def_cfa_offset 152
|
||||
push %olimit /* olimit space */
|
||||
.cfi_def_cfa_offset 160
|
||||
|
||||
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
|
||||
* %r15, %rax may be clobbered
|
||||
* rbx, rdx must be saved
|
||||
|
|
@ -207,19 +255,19 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||
/* If (op3 + 20 > olimit) */
|
||||
movq %op3, %rax /* rax = op3 */
|
||||
cmpq %rax, %olimit /* op3 == olimit */
|
||||
je .L_4X1_exit
|
||||
je LOCAL_LABEL(4X1_exit)
|
||||
|
||||
/* If (ip1 < ip0) go to exit */
|
||||
cmpq %ip0, %ip1
|
||||
jb .L_4X1_exit
|
||||
jb LOCAL_LABEL(4X1_exit)
|
||||
|
||||
/* If (ip2 < ip1) go to exit */
|
||||
cmpq %ip1, %ip2
|
||||
jb .L_4X1_exit
|
||||
jb LOCAL_LABEL(4X1_exit)
|
||||
|
||||
/* If (ip3 < ip2) go to exit */
|
||||
cmpq %ip2, %ip3
|
||||
jb .L_4X1_exit
|
||||
jb LOCAL_LABEL(4X1_exit)
|
||||
|
||||
/* Reads top 11 bits from bits[n]
|
||||
* Loads dt[bits[n]] into var[n]
|
||||
|
|
@ -280,7 +328,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||
|
||||
.p2align 6
|
||||
|
||||
.L_4X1_loop_body:
|
||||
LOCAL_LABEL(4X1_loop_body):
|
||||
/* Decode 5 symbols in each of the 4 streams (20 total)
|
||||
* 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 */
|
||||
cmp %op3, 24(%rsp)
|
||||
ja .L_4X1_loop_body
|
||||
ja LOCAL_LABEL(4X1_loop_body)
|
||||
|
||||
/* Reload ip[1,2,3] from stack */
|
||||
movq 0(%rsp), %ip1
|
||||
|
|
@ -326,20 +374,25 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||
movq 16(%rsp), %ip3
|
||||
|
||||
/* Re-compute olimit */
|
||||
jmp .L_4X1_compute_olimit
|
||||
jmp LOCAL_LABEL(4X1_compute_olimit)
|
||||
|
||||
#undef GET_NEXT_DELT
|
||||
#undef DECODE_FROM_DELT
|
||||
#undef DECODE
|
||||
#undef RELOAD_BITS
|
||||
.L_4X1_exit:
|
||||
LOCAL_LABEL(4X1_exit):
|
||||
addq $24, %rsp
|
||||
.cfi_def_cfa_offset 160
|
||||
|
||||
/* Restore stack (oend & olimit) */
|
||||
pop %rax /* olimit */
|
||||
.cfi_def_cfa_offset 152
|
||||
pop %rax /* oend */
|
||||
.cfi_def_cfa_offset 144
|
||||
pop %rax /* ilowest */
|
||||
.cfi_def_cfa_offset 136
|
||||
pop %rax /* arg */
|
||||
.cfi_def_cfa_offset 128
|
||||
|
||||
/* Save ip / op / bits */
|
||||
movq %ip0, 0(%rax)
|
||||
|
|
@ -357,41 +410,105 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
|
|||
|
||||
/* Restore registers */
|
||||
pop %r15
|
||||
.cfi_restore r15
|
||||
.cfi_def_cfa_offset 120
|
||||
pop %r14
|
||||
.cfi_restore r14
|
||||
.cfi_def_cfa_offset 112
|
||||
pop %r13
|
||||
.cfi_restore r13
|
||||
.cfi_def_cfa_offset 104
|
||||
pop %r12
|
||||
.cfi_restore r12
|
||||
.cfi_def_cfa_offset 96
|
||||
pop %r11
|
||||
.cfi_restore r11
|
||||
.cfi_def_cfa_offset 88
|
||||
pop %r10
|
||||
.cfi_restore r10
|
||||
.cfi_def_cfa_offset 80
|
||||
pop %r9
|
||||
.cfi_restore r9
|
||||
.cfi_def_cfa_offset 72
|
||||
pop %r8
|
||||
.cfi_restore r8
|
||||
.cfi_def_cfa_offset 64
|
||||
pop %rdi
|
||||
.cfi_restore rdi
|
||||
.cfi_def_cfa_offset 56
|
||||
pop %rsi
|
||||
.cfi_restore rsi
|
||||
.cfi_def_cfa_offset 48
|
||||
pop %rbp
|
||||
.cfi_restore rbp
|
||||
.cfi_def_cfa_offset 40
|
||||
pop %rdx
|
||||
.cfi_restore rdx
|
||||
.cfi_def_cfa_offset 32
|
||||
pop %rcx
|
||||
.cfi_restore rcx
|
||||
.cfi_def_cfa_offset 24
|
||||
pop %rbx
|
||||
.cfi_restore rbx
|
||||
.cfi_def_cfa_offset 16
|
||||
pop %rax
|
||||
.cfi_restore rax
|
||||
.cfi_def_cfa_offset 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
_HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
||||
HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
||||
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. */
|
||||
push %rax
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset rax, -16
|
||||
push %rbx
|
||||
.cfi_def_cfa_offset 24
|
||||
.cfi_offset rbx, -24
|
||||
push %rcx
|
||||
.cfi_def_cfa_offset 32
|
||||
.cfi_offset rcx, -32
|
||||
push %rdx
|
||||
.cfi_def_cfa_offset 40
|
||||
.cfi_offset rdx, -40
|
||||
push %rbp
|
||||
.cfi_def_cfa_offset 48
|
||||
.cfi_offset rbp, -48
|
||||
push %rsi
|
||||
.cfi_def_cfa_offset 56
|
||||
.cfi_offset rsi, -56
|
||||
push %rdi
|
||||
.cfi_def_cfa_offset 64
|
||||
.cfi_offset rdi, -64
|
||||
push %r8
|
||||
.cfi_def_cfa_offset 72
|
||||
.cfi_offset r8, -72
|
||||
push %r9
|
||||
.cfi_def_cfa_offset 80
|
||||
.cfi_offset r9, -80
|
||||
push %r10
|
||||
.cfi_def_cfa_offset 88
|
||||
.cfi_offset r10, -88
|
||||
push %r11
|
||||
.cfi_def_cfa_offset 96
|
||||
.cfi_offset r11, -96
|
||||
push %r12
|
||||
.cfi_def_cfa_offset 104
|
||||
.cfi_offset r12, -104
|
||||
push %r13
|
||||
.cfi_def_cfa_offset 112
|
||||
.cfi_offset r13, -112
|
||||
push %r14
|
||||
.cfi_def_cfa_offset 120
|
||||
.cfi_offset r14, -120
|
||||
push %r15
|
||||
.cfi_def_cfa_offset 128
|
||||
.cfi_offset r15, -128
|
||||
|
||||
/* Read HUF_DecompressAsmArgs* args from %rax */
|
||||
#if defined(_WIN32)
|
||||
|
|
@ -413,25 +530,33 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||
movq 88(%rax), %bits3
|
||||
movq 96(%rax), %dtable
|
||||
push %rax /* argument */
|
||||
.cfi_def_cfa_offset 136
|
||||
push %rax /* olimit */
|
||||
.cfi_def_cfa_offset 144
|
||||
push 104(%rax) /* ilowest */
|
||||
.cfi_def_cfa_offset 152
|
||||
|
||||
movq 112(%rax), %rax
|
||||
push %rax /* oend3 */
|
||||
.cfi_def_cfa_offset 160
|
||||
|
||||
movq %op3, %rax
|
||||
push %rax /* oend2 */
|
||||
.cfi_def_cfa_offset 168
|
||||
|
||||
movq %op2, %rax
|
||||
push %rax /* oend1 */
|
||||
.cfi_def_cfa_offset 176
|
||||
|
||||
movq %op1, %rax
|
||||
push %rax /* oend0 */
|
||||
.cfi_def_cfa_offset 184
|
||||
|
||||
/* Scratch space */
|
||||
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
|
||||
* %r15, %rax may be clobbered
|
||||
* rdx must be saved
|
||||
|
|
@ -495,19 +620,19 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||
/* If (op3 + 10 > olimit) */
|
||||
movq %op3, %rax /* rax = op3 */
|
||||
cmpq %rax, %olimit /* op3 == olimit */
|
||||
je .L_4X2_exit
|
||||
je LOCAL_LABEL(4X2_exit)
|
||||
|
||||
/* If (ip1 < ip0) go to exit */
|
||||
cmpq %ip0, %ip1
|
||||
jb .L_4X2_exit
|
||||
jb LOCAL_LABEL(4X2_exit)
|
||||
|
||||
/* If (ip2 < ip1) go to exit */
|
||||
cmpq %ip1, %ip2
|
||||
jb .L_4X2_exit
|
||||
jb LOCAL_LABEL(4X2_exit)
|
||||
|
||||
/* If (ip3 < ip2) go to exit */
|
||||
cmpq %ip2, %ip3
|
||||
jb .L_4X2_exit
|
||||
jb LOCAL_LABEL(4X2_exit)
|
||||
|
||||
#define DECODE(n, idx) \
|
||||
movq %bits##n, %rax; \
|
||||
|
|
@ -534,7 +659,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||
|
||||
.p2align 6
|
||||
|
||||
.L_4X2_loop_body:
|
||||
LOCAL_LABEL(4X2_loop_body):
|
||||
/* We clobber r8, so store it on the stack */
|
||||
movq %r8, 0(%rsp)
|
||||
|
||||
|
|
@ -551,21 +676,29 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||
FOR_EACH_STREAM(RELOAD_BITS)
|
||||
|
||||
cmp %op3, 48(%rsp)
|
||||
ja .L_4X2_loop_body
|
||||
jmp .L_4X2_compute_olimit
|
||||
ja LOCAL_LABEL(4X2_loop_body)
|
||||
jmp LOCAL_LABEL(4X2_compute_olimit)
|
||||
|
||||
#undef DECODE
|
||||
#undef RELOAD_BITS
|
||||
.L_4X2_exit:
|
||||
LOCAL_LABEL(4X2_exit):
|
||||
addq $8, %rsp
|
||||
.cfi_def_cfa_offset 184
|
||||
/* Restore stack (oend & olimit) */
|
||||
pop %rax /* oend0 */
|
||||
.cfi_def_cfa_offset 176
|
||||
pop %rax /* oend1 */
|
||||
.cfi_def_cfa_offset 168
|
||||
pop %rax /* oend2 */
|
||||
.cfi_def_cfa_offset 160
|
||||
pop %rax /* oend3 */
|
||||
.cfi_def_cfa_offset 152
|
||||
pop %rax /* ilowest */
|
||||
.cfi_def_cfa_offset 144
|
||||
pop %rax /* olimit */
|
||||
.cfi_def_cfa_offset 136
|
||||
pop %rax /* arg */
|
||||
.cfi_def_cfa_offset 128
|
||||
|
||||
/* Save ip / op / bits */
|
||||
movq %ip0, 0(%rax)
|
||||
|
|
@ -583,20 +716,51 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
|
|||
|
||||
/* Restore registers */
|
||||
pop %r15
|
||||
.cfi_restore r15
|
||||
.cfi_def_cfa_offset 120
|
||||
pop %r14
|
||||
.cfi_restore r14
|
||||
.cfi_def_cfa_offset 112
|
||||
pop %r13
|
||||
.cfi_restore r13
|
||||
.cfi_def_cfa_offset 104
|
||||
pop %r12
|
||||
.cfi_restore r12
|
||||
.cfi_def_cfa_offset 96
|
||||
pop %r11
|
||||
.cfi_restore r11
|
||||
.cfi_def_cfa_offset 88
|
||||
pop %r10
|
||||
.cfi_restore r10
|
||||
.cfi_def_cfa_offset 80
|
||||
pop %r9
|
||||
.cfi_restore r9
|
||||
.cfi_def_cfa_offset 72
|
||||
pop %r8
|
||||
.cfi_restore r8
|
||||
.cfi_def_cfa_offset 64
|
||||
pop %rdi
|
||||
.cfi_restore rdi
|
||||
.cfi_def_cfa_offset 56
|
||||
pop %rsi
|
||||
.cfi_restore rsi
|
||||
.cfi_def_cfa_offset 48
|
||||
pop %rbp
|
||||
.cfi_restore rbp
|
||||
.cfi_def_cfa_offset 40
|
||||
pop %rdx
|
||||
.cfi_restore rdx
|
||||
.cfi_def_cfa_offset 32
|
||||
pop %rcx
|
||||
.cfi_restore rcx
|
||||
.cfi_def_cfa_offset 24
|
||||
pop %rbx
|
||||
.cfi_restore rbx
|
||||
.cfi_def_cfa_offset 16
|
||||
pop %rax
|
||||
.cfi_restore rax
|
||||
.cfi_def_cfa_offset 8
|
||||
ret
|
||||
.cfi_endproc
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,14 +16,13 @@
|
|||
*********************************************************/
|
||||
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
|
||||
#include "../common/compiler.h" /* prefetch */
|
||||
#include "../common/cpu.h" /* bmi2 */
|
||||
#include "../common/mem.h" /* low level memory routines */
|
||||
#include <stddef.h>
|
||||
#define FSE_STATIC_LINKING_ONLY
|
||||
#include "../common/fse.h"
|
||||
#include "../common/huf.h"
|
||||
#include "../common/zstd_internal.h"
|
||||
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
||||
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
||||
#include "zstd_decompress_block.h"
|
||||
#include "../common/bits.h" /* ZSTD_highbit32 */
|
||||
|
||||
|
|
@ -734,9 +733,10 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||
ip++;
|
||||
|
||||
/* Build DTables */
|
||||
assert(ip <= iend);
|
||||
{ size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
|
||||
LLtype, MaxLL, LLFSELog,
|
||||
ip, iend-ip,
|
||||
ip, (size_t)(iend-ip),
|
||||
LL_base, LL_bits,
|
||||
LL_defaultDTable, dctx->fseEntropy,
|
||||
dctx->ddictIsCold, nbSeq,
|
||||
|
|
@ -746,9 +746,10 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||
ip += llhSize;
|
||||
}
|
||||
|
||||
assert(ip <= iend);
|
||||
{ size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
|
||||
OFtype, MaxOff, OffFSELog,
|
||||
ip, iend-ip,
|
||||
ip, (size_t)(iend-ip),
|
||||
OF_base, OF_bits,
|
||||
OF_defaultDTable, dctx->fseEntropy,
|
||||
dctx->ddictIsCold, nbSeq,
|
||||
|
|
@ -758,9 +759,10 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|||
ip += ofhSize;
|
||||
}
|
||||
|
||||
assert(ip <= iend);
|
||||
{ size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
|
||||
MLtype, MaxML, MLFSELog,
|
||||
ip, iend-ip,
|
||||
ip, (size_t)(iend-ip),
|
||||
ML_base, ML_bits,
|
||||
ML_defaultDTable, dctx->fseEntropy,
|
||||
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
|
||||
* 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);
|
||||
if (offset < 8) {
|
||||
/* 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.
|
||||
* 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;
|
||||
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) {
|
||||
/* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */
|
||||
assert(length >= 8);
|
||||
ZSTD_overlapCopy8(&op, &ip, diff);
|
||||
assert(diff > 0);
|
||||
ZSTD_overlapCopy8(&op, &ip, (size_t)diff);
|
||||
length -= 8;
|
||||
assert(op - ip >= 8);
|
||||
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) {
|
||||
/* Wildcopy until we get close to the end. */
|
||||
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;
|
||||
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():
|
||||
* 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 */
|
||||
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;
|
||||
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) {
|
||||
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;
|
||||
op += oend - WILDCOPY_OVERLENGTH - op;
|
||||
}
|
||||
|
|
@ -936,7 +943,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
|
|||
return sequenceLength;
|
||||
}
|
||||
/* span extDict & currentPrefixSegment */
|
||||
{ size_t const length1 = dictEnd - match;
|
||||
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||
ZSTD_memmove(oLitEnd, match, length1);
|
||||
op = oLitEnd + length1;
|
||||
sequence.matchLength -= length1;
|
||||
|
|
@ -985,7 +992,7 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
|
|||
return sequenceLength;
|
||||
}
|
||||
/* span extDict & currentPrefixSegment */
|
||||
{ size_t const length1 = dictEnd - match;
|
||||
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||
ZSTD_memmove(oLitEnd, match, length1);
|
||||
op = oLitEnd + length1;
|
||||
sequence.matchLength -= length1;
|
||||
|
|
@ -1058,7 +1065,7 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||
return sequenceLength;
|
||||
}
|
||||
/* span extDict & currentPrefixSegment */
|
||||
{ size_t const length1 = dictEnd - match;
|
||||
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||
ZSTD_memmove(oLitEnd, match, length1);
|
||||
op = oLitEnd + length1;
|
||||
sequence.matchLength -= length1;
|
||||
|
|
@ -1079,7 +1086,7 @@ size_t ZSTD_execSequence(BYTE* op,
|
|||
* longer than literals (in general). In silesia, ~10% of matches are longer
|
||||
* 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;
|
||||
}
|
||||
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 (sequence.matchLength > 8) {
|
||||
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;
|
||||
}
|
||||
|
|
@ -1151,7 +1158,7 @@ size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
|
|||
return sequenceLength;
|
||||
}
|
||||
/* span extDict & currentPrefixSegment */
|
||||
{ size_t const length1 = dictEnd - match;
|
||||
{ size_t const length1 = (size_t)(dictEnd - match);
|
||||
ZSTD_memmove(oLitEnd, match, length1);
|
||||
op = oLitEnd + 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
|
||||
* 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;
|
||||
}
|
||||
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 (sequence.matchLength > 8) {
|
||||
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;
|
||||
}
|
||||
|
|
@ -1229,6 +1236,10 @@ FORCE_INLINE_TEMPLATE seq_t
|
|||
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
|
||||
{
|
||||
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.
|
||||
* 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
|
||||
* ZSTD_memcpy hack.
|
||||
*/
|
||||
#if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__))
|
||||
# if defined(__GNUC__) && !defined(__clang__)
|
||||
ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS;
|
||||
ZSTD_seqSymbol* const llDInfo = &llDInfoS;
|
||||
ZSTD_seqSymbol* const mlDInfo = &mlDInfoS;
|
||||
|
|
@ -1250,6 +1261,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||
const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
|
||||
const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
|
||||
# endif
|
||||
(void)longOffsets;
|
||||
seq.matchLength = mlDInfo->baseValue;
|
||||
seq.litLength = llDInfo->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(mlBits <= MaxMLBits);
|
||||
assert(ofBits <= MaxOff);
|
||||
/*
|
||||
* As gcc has better branch and block analyzers, sometimes it is only
|
||||
* valuable to mark likeliness for clang, it gives around 3-4% of
|
||||
* performance.
|
||||
/* As GCC has better branch and block analyzers, sometimes it is only
|
||||
* valuable to mark likeliness for Clang.
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
|
|
@ -1333,7 +1433,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, c
|
|||
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
||||
|
||||
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->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 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);
|
||||
}
|
||||
}
|
||||
#endif /* defined(__aarch64__) */
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
|
@ -1405,10 +1506,8 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|||
const void* seqStart, size_t seqSize, int nbSeq,
|
||||
const ZSTD_longOffset_e isLongOffset)
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
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;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
||||
|
|
@ -1423,7 +1522,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|||
dctx->fseEntropy = 1;
|
||||
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||
RETURN_ERROR_IF(
|
||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
|
||||
ERR_isError(BIT_initDStream(&seqState.DStream, seqStart, seqSize)),
|
||||
corruption_detected, "");
|
||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
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 (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);
|
||||
if (leftoverLit) {
|
||||
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 ZSTD_longOffset_e isLongOffset)
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
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;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
const BYTE* const litEnd = litPtr + dctx->litSize;
|
||||
|
|
@ -1635,7 +1735,7 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
|
|||
dctx->fseEntropy = 1;
|
||||
{ U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||
RETURN_ERROR_IF(
|
||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)),
|
||||
ERR_isError(BIT_initDStream(&seqState.DStream, seqStart, seqSize)),
|
||||
corruption_detected, "");
|
||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
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;
|
||||
/* 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 */
|
||||
const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset);
|
||||
PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
|
||||
const BYTE* const match = (const BYTE*)ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, (ptrdiff_t)prefetchPos), (ptrdiff_t)sequence.offset);
|
||||
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;
|
||||
}
|
||||
|
|
@ -1736,10 +1836,10 @@ ZSTD_decompressSequencesLong_body(
|
|||
const void* seqStart, size_t seqSize, int nbSeq,
|
||||
const ZSTD_longOffset_e isLongOffset)
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
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;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
||||
|
|
@ -1761,9 +1861,8 @@ ZSTD_decompressSequencesLong_body(
|
|||
dctx->fseEntropy = 1;
|
||||
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
|
||||
assert(dst != NULL);
|
||||
assert(iend >= ip);
|
||||
RETURN_ERROR_IF(
|
||||
ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
|
||||
ERR_isError(BIT_initDStream(&seqState.DStream, seqStart, seqSize)),
|
||||
corruption_detected, "");
|
||||
ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
|
||||
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) {
|
||||
/* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
|
||||
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
||||
if (leftoverLit)
|
||||
{
|
||||
const size_t leftoverLit = (size_t)(dctx->litBufferEnd - litPtr);
|
||||
assert(dctx->litBufferEnd >= litPtr);
|
||||
if (leftoverLit) {
|
||||
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
||||
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
||||
sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit;
|
||||
|
|
@ -1828,7 +1927,8 @@ ZSTD_decompressSequencesLong_body(
|
|||
for ( ; seqNb<nbSeq ; seqNb++) {
|
||||
seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
|
||||
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) {
|
||||
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
||||
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
||||
|
|
@ -1867,7 +1967,8 @@ ZSTD_decompressSequencesLong_body(
|
|||
|
||||
/* last literal segment */
|
||||
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, "");
|
||||
if (op != NULL) {
|
||||
ZSTD_memmove(op, litPtr, lastLLSize);
|
||||
|
|
@ -1876,7 +1977,8 @@ ZSTD_decompressSequencesLong_body(
|
|||
litPtr = dctx->litExtraBuffer;
|
||||
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, "");
|
||||
if (op != NULL) {
|
||||
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
|
||||
* 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 {
|
||||
|
|
@ -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.
|
||||
*/
|
||||
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.
|
||||
* Offsets are long if they are larger than ZSTD_maxShortOffset().
|
||||
* We don't expect that to be the case in 64-bit mode.
|
||||
|
|
|
|||
|
|
@ -21,14 +21,18 @@
|
|||
/*-*************************************
|
||||
* Dependencies
|
||||
***************************************/
|
||||
/* qsort_r is an extension. */
|
||||
#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \
|
||||
defined(__CYGWIN__) || defined(__MSYS__)
|
||||
#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */
|
||||
/* qsort_r is an extension.
|
||||
*
|
||||
* Android NDK does not ship qsort_r().
|
||||
*/
|
||||
#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__CYGWIN__) || defined(__MSYS__)
|
||||
# ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define __STDC_WANT_LIB_EXT1__ 1 /* request C11 Annex K, which includes qsort_s() */
|
||||
|
||||
#include <stdio.h> /* fprintf */
|
||||
#include <stdlib.h> /* malloc, free, qsort_r */
|
||||
|
||||
|
|
@ -39,6 +43,7 @@
|
|||
# define ZDICT_STATIC_LINKING_ONLY
|
||||
#endif
|
||||
|
||||
#include "../common/debug.h" /* DEBUG_STATIC_ASSERT */
|
||||
#include "../common/mem.h" /* read */
|
||||
#include "../common/pool.h" /* POOL_ctx */
|
||||
#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_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
|
||||
*
|
||||
* Captures the `displayLevel` variable in the local scope.
|
||||
***************************************/
|
||||
#ifndef LOCALDISPLAYLEVEL
|
||||
static int g_displayLevel = 0;
|
||||
#endif
|
||||
#undef DISPLAY
|
||||
#define DISPLAY(...) \
|
||||
{ \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
#undef LOCALDISPLAYLEVEL
|
||||
#define LOCALDISPLAYLEVEL(displayLevel, l, ...) \
|
||||
#undef DISPLAYLEVEL
|
||||
#define DISPLAYLEVEL(l, ...) \
|
||||
if (displayLevel >= l) { \
|
||||
DISPLAY(__VA_ARGS__); \
|
||||
} /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
||||
#undef DISPLAYLEVEL
|
||||
#define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__)
|
||||
|
||||
#ifndef LOCALDISPLAYUPDATE
|
||||
static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
|
||||
static clock_t g_time = 0;
|
||||
#endif
|
||||
#undef LOCALDISPLAYUPDATE
|
||||
#define LOCALDISPLAYUPDATE(displayLevel, l, ...) \
|
||||
#undef DISPLAYUPDATE
|
||||
#define DISPLAYUPDATE(lastUpdateTime, l, ...) \
|
||||
if (displayLevel >= l) { \
|
||||
if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \
|
||||
g_time = clock(); \
|
||||
const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100; \
|
||||
if ((clock() - lastUpdateTime > refreshRate) || (displayLevel >= 4)) { \
|
||||
lastUpdateTime = clock(); \
|
||||
DISPLAY(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#undef DISPLAYUPDATE
|
||||
#define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__)
|
||||
|
||||
/*-*************************************
|
||||
* Hash table
|
||||
|
|
@ -239,10 +262,11 @@ typedef struct {
|
|||
U32 *freqs;
|
||||
U32 *dmerAt;
|
||||
unsigned d;
|
||||
int displayLevel;
|
||||
} COVER_ctx_t;
|
||||
|
||||
#if !defined(_GNU_SOURCE) && !defined(__APPLE__) && !defined(_MSC_VER)
|
||||
/* C90 only offers qsort() that needs a global context. */
|
||||
#if ZDICT_QSORT == ZDICT_QSORT_C90
|
||||
/* Use global context for non-reentrant sort functions */
|
||||
static COVER_ctx_t *g_coverCtx = NULL;
|
||||
#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
|
||||
*/
|
||||
#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) {
|
||||
#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) {
|
||||
#else /* C90 fallback.*/
|
||||
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.
|
||||
*/
|
||||
#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) {
|
||||
#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) {
|
||||
#else /* C90 fallback.*/
|
||||
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
|
||||
* to clean it up.
|
||||
*/
|
||||
static void stableSort(COVER_ctx_t *ctx) {
|
||||
#if defined(__APPLE__)
|
||||
static void stableSort(COVER_ctx_t *ctx)
|
||||
{
|
||||
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),
|
||||
ctx,
|
||||
(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),
|
||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
||||
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),
|
||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
|
||||
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.*/
|
||||
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),
|
||||
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
|
||||
#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,
|
||||
const size_t *samplesSizes, unsigned nbSamples,
|
||||
unsigned d, double splitPoint)
|
||||
unsigned d, double splitPoint, int displayLevel)
|
||||
{
|
||||
const BYTE *const samples = (const BYTE *)samplesBuffer;
|
||||
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 size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
|
||||
const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
|
||||
ctx->displayLevel = displayLevel;
|
||||
/* Checks */
|
||||
if (totalSamplesSize < MAX(d, sizeof(U64)) ||
|
||||
totalSamplesSize >= (size_t)COVER_MAX_SAMPLES_SIZE) {
|
||||
|
|
@ -694,7 +721,7 @@ void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLeve
|
|||
if (ratio >= 10) {
|
||||
return;
|
||||
}
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1,
|
||||
DISPLAYLEVEL(1,
|
||||
"WARNING: The maximum dictionary size %u is too large "
|
||||
"compared to the source size %u! "
|
||||
"size(source)/size(dictionary) = %f, but it should be >= "
|
||||
|
|
@ -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));
|
||||
size_t zeroScoreRun = 0;
|
||||
size_t epoch;
|
||||
clock_t lastUpdateTime = 0;
|
||||
const int displayLevel = ctx->displayLevel;
|
||||
DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
|
||||
(U32)epochs.num, (U32)epochs.size);
|
||||
/* 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;
|
||||
memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
|
||||
DISPLAYUPDATE(
|
||||
lastUpdateTime,
|
||||
2, "\r%u%% ",
|
||||
(unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
|
||||
}
|
||||
|
|
@ -784,9 +814,8 @@ ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
|
|||
BYTE* const dict = (BYTE*)dictBuffer;
|
||||
COVER_ctx_t ctx;
|
||||
COVER_map_t activeDmers;
|
||||
const int displayLevel = (int)parameters.zParams.notificationLevel;
|
||||
parameters.splitPoint = 1.0;
|
||||
/* Initialize global data */
|
||||
g_displayLevel = (int)parameters.zParams.notificationLevel;
|
||||
/* Checks */
|
||||
if (!COVER_checkParameters(parameters, dictBufferCapacity)) {
|
||||
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
|
||||
|
|
@ -804,12 +833,12 @@ ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
|
|||
/* Initialize context and activeDmers */
|
||||
{
|
||||
size_t const initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
|
||||
parameters.d, parameters.splitPoint);
|
||||
parameters.d, parameters.splitPoint, displayLevel);
|
||||
if (ZSTD_isError(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)) {
|
||||
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
||||
COVER_ctx_destroy(&ctx);
|
||||
|
|
@ -1132,6 +1161,7 @@ static void COVER_tryParameters(void *opaque)
|
|||
BYTE* const dict = (BYTE*)malloc(dictBufferCapacity);
|
||||
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
||||
U32* const freqs = (U32*)malloc(ctx->suffixSize * sizeof(U32));
|
||||
const int displayLevel = ctx->displayLevel;
|
||||
if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
|
||||
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
||||
goto _cleanup;
|
||||
|
|
@ -1183,21 +1213,22 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||
(1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize);
|
||||
const unsigned shrinkDict = 0;
|
||||
/* Local variables */
|
||||
const int displayLevel = parameters->zParams.notificationLevel;
|
||||
int displayLevel = (int)parameters->zParams.notificationLevel;
|
||||
unsigned iteration = 1;
|
||||
unsigned d;
|
||||
unsigned k;
|
||||
COVER_best_t best;
|
||||
POOL_ctx *pool = NULL;
|
||||
int warned = 0;
|
||||
clock_t lastUpdateTime = 0;
|
||||
|
||||
/* Checks */
|
||||
if (splitPoint <= 0 || splitPoint > 1) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n");
|
||||
DISPLAYLEVEL(1, "Incorrect parameters\n");
|
||||
return ERROR(parameter_outOfBound);
|
||||
}
|
||||
if (kMinK < kMaxD || kMaxK < kMinK) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n");
|
||||
DISPLAYLEVEL(1, "Incorrect parameters\n");
|
||||
return ERROR(parameter_outOfBound);
|
||||
}
|
||||
if (nbSamples == 0) {
|
||||
|
|
@ -1217,19 +1248,19 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||
}
|
||||
/* Initialization */
|
||||
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 */
|
||||
LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
|
||||
DISPLAYLEVEL(2, "Trying %u different sets of parameters\n",
|
||||
kIterations);
|
||||
for (d = kMinD; d <= kMaxD; d += 2) {
|
||||
/* Initialize the context for this value of d */
|
||||
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)) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n");
|
||||
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
||||
COVER_best_destroy(&best);
|
||||
POOL_free(pool);
|
||||
return initVal;
|
||||
|
|
@ -1244,9 +1275,9 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||
/* Prepare the arguments */
|
||||
COVER_tryParameters_data_t *data = (COVER_tryParameters_data_t *)malloc(
|
||||
sizeof(COVER_tryParameters_data_t));
|
||||
LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k);
|
||||
DISPLAYLEVEL(3, "k=%u\n", k);
|
||||
if (!data) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n");
|
||||
DISPLAYLEVEL(1, "Failed to allocate parameters\n");
|
||||
COVER_best_destroy(&best);
|
||||
COVER_ctx_destroy(&ctx);
|
||||
POOL_free(pool);
|
||||
|
|
@ -1261,7 +1292,7 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||
data->parameters.splitPoint = splitPoint;
|
||||
data->parameters.steps = kSteps;
|
||||
data->parameters.shrinkDict = shrinkDict;
|
||||
data->parameters.zParams.notificationLevel = g_displayLevel;
|
||||
data->parameters.zParams.notificationLevel = (unsigned)ctx.displayLevel;
|
||||
/* Check the parameters */
|
||||
if (!COVER_checkParameters(data->parameters, dictBufferCapacity)) {
|
||||
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
|
||||
|
|
@ -1276,14 +1307,14 @@ ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
|||
COVER_tryParameters(data);
|
||||
}
|
||||
/* Print status */
|
||||
LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ",
|
||||
DISPLAYUPDATE(lastUpdateTime, 2, "\r%u%% ",
|
||||
(unsigned)((iteration * 100) / kIterations));
|
||||
++iteration;
|
||||
}
|
||||
COVER_best_wait(&best);
|
||||
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 */
|
||||
{
|
||||
const size_t dictSize = best.dictSize;
|
||||
|
|
|
|||
|
|
@ -25,23 +25,22 @@
|
|||
*/
|
||||
|
||||
/*- Compiler specifics -*/
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable : 4244)
|
||||
# pragma warning(disable : 4127) /* C4127 : Condition expression is constant */
|
||||
#endif
|
||||
|
||||
|
||||
/*- Dependencies -*/
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "divsufsort.h"
|
||||
|
||||
#define PTRDIFF_TO_INT(x) (assert((x) <= INT_MAX && (x) >= INT_MIN), (int)(x))
|
||||
|
||||
/*- Constants -*/
|
||||
#if defined(INLINE)
|
||||
# undef INLINE
|
||||
|
|
@ -199,8 +198,8 @@ ss_isqrt(int x) {
|
|||
int y, e;
|
||||
|
||||
if(x >= (SS_BLOCKSIZE * SS_BLOCKSIZE)) { return SS_BLOCKSIZE; }
|
||||
e = (x & 0xffff0000) ?
|
||||
((x & 0xff000000) ?
|
||||
e = ((unsigned)x & 0xffff0000) ?
|
||||
(((unsigned)x & 0xff000000) ?
|
||||
24 + lg_table[(x >> 24) & 0xff] :
|
||||
16 + lg_table[(x >> 16) & 0xff]) :
|
||||
((x & 0x0000ff00) ?
|
||||
|
|
@ -354,7 +353,7 @@ ss_pivot(const unsigned char *Td, const int *PA, int *first, int *last) {
|
|||
int *middle;
|
||||
int t;
|
||||
|
||||
t = last - first;
|
||||
t = PTRDIFF_TO_INT(last - first);
|
||||
middle = first + t / 2;
|
||||
|
||||
if(t <= 512) {
|
||||
|
|
@ -409,7 +408,7 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||
int limit;
|
||||
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 1 < SS_INSERTIONSORT_THRESHOLD
|
||||
|
|
@ -420,7 +419,7 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||
}
|
||||
|
||||
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) {
|
||||
for(a = first + 1, v = Td[PA[*first]]; a < last; ++a) {
|
||||
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(1 < (a - first)) {
|
||||
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 {
|
||||
first = a, limit = -1;
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
} else {
|
||||
last = a, depth += 1, limit = ss_ilg(a - first);
|
||||
last = a, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(a - first));
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
|
@ -481,9 +480,9 @@ ss_mintrosort(const unsigned char *T, const int *PA,
|
|||
if(a <= d) {
|
||||
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); }
|
||||
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); }
|
||||
|
||||
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((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);
|
||||
last = a;
|
||||
} else if((a - first) <= (c - b)) {
|
||||
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;
|
||||
} else {
|
||||
STACK_PUSH(c, last, 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 {
|
||||
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);
|
||||
first = c;
|
||||
} else if((last - c) <= (c - b)) {
|
||||
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;
|
||||
} else {
|
||||
STACK_PUSH(first, a, 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 {
|
||||
limit += 1;
|
||||
if(Td[PA[*first] - 1] < v) {
|
||||
first = ss_partition(PA, first, last, depth);
|
||||
limit = ss_ilg(last - first);
|
||||
limit = ss_ilg(PTRDIFF_TO_INT(last - first));
|
||||
}
|
||||
depth += 1;
|
||||
}
|
||||
|
|
@ -551,7 +550,8 @@ void
|
|||
ss_rotate(int *first, int *middle, int *last) {
|
||||
int *a, *b, t;
|
||||
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);) {
|
||||
if(l == r) { ss_blockswap(first, middle, l); break; }
|
||||
if(l < r) {
|
||||
|
|
@ -601,7 +601,7 @@ ss_inplacemerge(const unsigned char *T, const int *PA,
|
|||
for(;;) {
|
||||
if(*(last - 1) < 0) { x = 1; 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;
|
||||
len = half, half >>= 1) {
|
||||
b = a + half;
|
||||
|
|
@ -640,7 +640,7 @@ ss_mergeforward(const unsigned char *T, const int *PA,
|
|||
int r;
|
||||
|
||||
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;;) {
|
||||
r = ss_compare(T, PA + *b, PA + *c, depth);
|
||||
|
|
@ -692,7 +692,7 @@ ss_mergebackward(const unsigned char *T, const int *PA,
|
|||
int x;
|
||||
|
||||
bufend = buf + (last - middle) - 1;
|
||||
ss_blockswap(buf, middle, last - middle);
|
||||
ss_blockswap(buf, middle, PTRDIFF_TO_INT(last - middle));
|
||||
|
||||
x = 0;
|
||||
if(*bufend < 0) { p1 = PA + ~*bufend; x |= 1; }
|
||||
|
|
@ -781,7 +781,7 @@ ss_swapmerge(const unsigned char *T, const int *PA,
|
|||
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;
|
||||
len = half, half >>= 1) {
|
||||
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);
|
||||
#else
|
||||
if((bufsize < SS_BLOCKSIZE) &&
|
||||
(bufsize < (last - first)) &&
|
||||
(bufsize < (limit = ss_isqrt(last - first)))) {
|
||||
(bufsize < PTRDIFF_TO_INT(last - first)) &&
|
||||
(bufsize < (limit = ss_isqrt(PTRDIFF_TO_INT(last - first))))) {
|
||||
if(SS_BLOCKSIZE < limit) { limit = SS_BLOCKSIZE; }
|
||||
buf = middle = last - limit, bufsize = limit;
|
||||
} else {
|
||||
|
|
@ -863,7 +863,7 @@ sssort(const unsigned char *T, const int *PA,
|
|||
#elif 1 < SS_BLOCKSIZE
|
||||
ss_insertionsort(T, PA, a, a + SS_BLOCKSIZE, depth);
|
||||
#endif
|
||||
curbufsize = last - (a + SS_BLOCKSIZE);
|
||||
curbufsize = PTRDIFF_TO_INT(last - (a + SS_BLOCKSIZE));
|
||||
curbuf = a + SS_BLOCKSIZE;
|
||||
if(curbufsize <= bufsize) { curbufsize = bufsize, curbuf = buf; }
|
||||
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 t;
|
||||
|
||||
t = last - first;
|
||||
t = PTRDIFF_TO_INT(last - first);
|
||||
middle = first + t / 2;
|
||||
|
||||
if(t <= 512) {
|
||||
|
|
@ -1098,9 +1098,9 @@ tr_partition(const int *ISAd,
|
|||
|
||||
if(a <= d) {
|
||||
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); }
|
||||
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); }
|
||||
first += (b - a), last -= (d - c);
|
||||
}
|
||||
|
|
@ -1117,17 +1117,17 @@ tr_copy(int *ISA, const int *SA,
|
|||
int *c, *d, *e;
|
||||
int s, v;
|
||||
|
||||
v = b - SA - 1;
|
||||
v = PTRDIFF_TO_INT(b - SA - 1);
|
||||
for(c = first, d = a - 1; c <= d; ++c) {
|
||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||
*++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) {
|
||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||
*--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 rank, lastrank, newrank = -1;
|
||||
|
||||
v = b - SA - 1;
|
||||
v = PTRDIFF_TO_INT(b - SA - 1);
|
||||
lastrank = -1;
|
||||
for(c = first, d = a - 1; c <= d; ++c) {
|
||||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||
*++d = s;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1155,7 +1155,7 @@ tr_partialcopy(int *ISA, const int *SA,
|
|||
lastrank = -1;
|
||||
for(e = d; first <= e; --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; }
|
||||
}
|
||||
|
||||
|
|
@ -1164,7 +1164,7 @@ tr_partialcopy(int *ISA, const int *SA,
|
|||
if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
|
||||
*--d = s;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1180,23 +1180,23 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||
int *a, *b, *c;
|
||||
int t;
|
||||
int v, x = 0;
|
||||
int incr = ISAd - ISA;
|
||||
int incr = PTRDIFF_TO_INT(ISAd - ISA);
|
||||
int limit, next;
|
||||
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 == -1) {
|
||||
/* 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 */
|
||||
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) {
|
||||
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 */
|
||||
|
|
@ -1207,19 +1207,19 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||
}
|
||||
if((a - first) <= (last - b)) {
|
||||
if(1 < (a - first)) {
|
||||
STACK_PUSH5(ISAd, b, last, tr_ilg(last - b), trlink);
|
||||
last = a, limit = tr_ilg(a - first);
|
||||
STACK_PUSH5(ISAd, b, last, tr_ilg(PTRDIFF_TO_INT(last - b)), trlink);
|
||||
last = a, limit = tr_ilg(PTRDIFF_TO_INT(a - first));
|
||||
} else if(1 < (last - b)) {
|
||||
first = b, limit = tr_ilg(last - b);
|
||||
first = b, limit = tr_ilg(PTRDIFF_TO_INT(last - b));
|
||||
} else {
|
||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||
}
|
||||
} else {
|
||||
if(1 < (last - b)) {
|
||||
STACK_PUSH5(ISAd, first, a, tr_ilg(a - first), trlink);
|
||||
first = b, limit = tr_ilg(last - b);
|
||||
STACK_PUSH5(ISAd, first, a, tr_ilg(PTRDIFF_TO_INT(a - first)), trlink);
|
||||
first = b, limit = tr_ilg(PTRDIFF_TO_INT(last - b));
|
||||
} else if(1 < (a - first)) {
|
||||
last = a, limit = tr_ilg(a - first);
|
||||
last = a, limit = tr_ilg(PTRDIFF_TO_INT(a - first));
|
||||
} else {
|
||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||
}
|
||||
|
|
@ -1228,26 +1228,26 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||
/* tandem repeat copy */
|
||||
a = stack[--ssize].b, b = stack[ssize].c;
|
||||
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 {
|
||||
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);
|
||||
} else {
|
||||
/* sorted partition */
|
||||
if(0 <= *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;
|
||||
}
|
||||
if(first < last) {
|
||||
a = first; do { *a = ~*a; } while(*++a < 0);
|
||||
next = (ISA[*a] != ISAd[*a]) ? tr_ilg(a - first + 1) : -1;
|
||||
if(++a < last) { for(b = first, v = a - SA - 1; b < a; ++b) { ISA[*b] = v; } }
|
||||
next = (ISA[*a] != ISAd[*a]) ? tr_ilg(PTRDIFF_TO_INT(a - first + 1)) : -1;
|
||||
if(++a < last) { for(b = first, v = PTRDIFF_TO_INT(a - SA - 1); b < a; ++b) { ISA[*b] = v; } }
|
||||
|
||||
/* push */
|
||||
if(trbudget_check(budget, a - first)) {
|
||||
if(trbudget_check(budget, PTRDIFF_TO_INT(a - first))) {
|
||||
if((a - first) <= (last - a)) {
|
||||
STACK_PUSH5(ISAd, a, last, -3, trlink);
|
||||
ISAd += incr, last = a, limit = next;
|
||||
|
|
@ -1281,7 +1281,7 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||
}
|
||||
|
||||
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(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 */
|
||||
tr_partition(ISAd, first, first + 1, last, &a, &b, v);
|
||||
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 */
|
||||
for(c = first, v = 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; } }
|
||||
for(c = first, v = PTRDIFF_TO_INT(a - SA - 1); c < a; ++c) { ISA[*c] = v; }
|
||||
if(b < last) { for(c = a, v = PTRDIFF_TO_INT(b - SA - 1); c < b; ++c) { ISA[*c] = v; } }
|
||||
|
||||
/* 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((last - b) <= (b - a)) {
|
||||
if(1 < (a - first)) {
|
||||
|
|
@ -1381,8 +1381,8 @@ tr_introsort(int *ISA, const int *ISAd,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if(trbudget_check(budget, last - first)) {
|
||||
limit = tr_ilg(last - first), ISAd += incr;
|
||||
if(trbudget_check(budget, PTRDIFF_TO_INT(last - first))) {
|
||||
limit = tr_ilg(PTRDIFF_TO_INT(last - first)), ISAd += incr;
|
||||
} else {
|
||||
if(0 <= trlink) { stack[trlink].d = -1; }
|
||||
STACK_POP5(ISAd, first, last, limit, trlink);
|
||||
|
|
@ -1420,7 +1420,7 @@ trsort(int *ISA, int *SA, int n, int depth) {
|
|||
budget.count = 0;
|
||||
tr_introsort(ISA, ISAd, SA, first, last, &budget);
|
||||
if(budget.count != 0) { unsorted += budget.count; }
|
||||
else { skip = first - last; }
|
||||
else { skip = PTRDIFF_TO_INT(first - last); }
|
||||
} else if((last - first) == 1) {
|
||||
skip = -1;
|
||||
}
|
||||
|
|
@ -1634,7 +1634,7 @@ construct_SA(const unsigned char *T, int *SA,
|
|||
c0 = T[--s];
|
||||
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
||||
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);
|
||||
}
|
||||
assert(k < j); assert(k != NULL);
|
||||
|
|
@ -1658,7 +1658,7 @@ construct_SA(const unsigned char *T, int *SA,
|
|||
c0 = T[--s];
|
||||
if((s == 0) || (T[s - 1] < c0)) { s = ~s; }
|
||||
if(c0 != c2) {
|
||||
BUCKET_A(c2) = k - SA;
|
||||
BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
|
||||
k = SA + BUCKET_A(c2 = c0);
|
||||
}
|
||||
assert(i < k);
|
||||
|
|
@ -1698,7 +1698,7 @@ construct_BWT(const unsigned char *T, int *SA,
|
|||
*j = ~((int)c0);
|
||||
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
||||
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);
|
||||
}
|
||||
assert(k < j); assert(k != NULL);
|
||||
|
|
@ -1726,7 +1726,7 @@ construct_BWT(const unsigned char *T, int *SA,
|
|||
*i = c0;
|
||||
if((0 < s) && (T[s - 1] < c0)) { s = ~((int)T[s - 1]); }
|
||||
if(c0 != c2) {
|
||||
BUCKET_A(c2) = k - SA;
|
||||
BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
|
||||
k = SA + BUCKET_A(c2 = c0);
|
||||
}
|
||||
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
|
||||
|
|
@ -1776,13 +1776,13 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||
assert(((s + 1) < n) && (T[s] <= T[s + 1]));
|
||||
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];
|
||||
*j = ~((int)c0);
|
||||
if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
|
||||
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);
|
||||
}
|
||||
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. */
|
||||
k = SA + BUCKET_A(c2 = T[n - 1]);
|
||||
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]);
|
||||
}
|
||||
else {
|
||||
|
|
@ -1814,17 +1814,17 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||
if(0 < (s = *i)) {
|
||||
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];
|
||||
*i = c0;
|
||||
if(c0 != c2) {
|
||||
BUCKET_A(c2) = k - SA;
|
||||
BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
|
||||
k = SA + BUCKET_A(c2 = c0);
|
||||
}
|
||||
assert(i < k);
|
||||
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]);
|
||||
} else
|
||||
*k++ = s;
|
||||
|
|
@ -1835,7 +1835,7 @@ construct_BWT_indexes(const unsigned char *T, int *SA,
|
|||
}
|
||||
}
|
||||
|
||||
return orig - SA;
|
||||
return PTRDIFF_TO_INT(orig - SA);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -49,38 +49,30 @@
|
|||
|
||||
/*-*************************************
|
||||
* Console display
|
||||
*
|
||||
* Captures the `displayLevel` variable in the local scope.
|
||||
***************************************/
|
||||
#ifndef LOCALDISPLAYLEVEL
|
||||
static int g_displayLevel = 0;
|
||||
#endif
|
||||
#undef DISPLAY
|
||||
#define DISPLAY(...) \
|
||||
{ \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
#undef LOCALDISPLAYLEVEL
|
||||
#define LOCALDISPLAYLEVEL(displayLevel, l, ...) \
|
||||
#undef DISPLAYLEVEL
|
||||
#define DISPLAYLEVEL(l, ...) \
|
||||
if (displayLevel >= l) { \
|
||||
DISPLAY(__VA_ARGS__); \
|
||||
} /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
|
||||
#undef DISPLAYLEVEL
|
||||
#define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__)
|
||||
|
||||
#ifndef LOCALDISPLAYUPDATE
|
||||
static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
|
||||
static clock_t g_time = 0;
|
||||
#endif
|
||||
#undef LOCALDISPLAYUPDATE
|
||||
#define LOCALDISPLAYUPDATE(displayLevel, l, ...) \
|
||||
#undef DISPLAYUPDATE
|
||||
#define DISPLAYUPDATE(lastUpdateTime, l, ...) \
|
||||
if (displayLevel >= l) { \
|
||||
if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \
|
||||
g_time = clock(); \
|
||||
const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100; \
|
||||
if ((clock() - lastUpdateTime > refreshRate) || (displayLevel >= 4)) { \
|
||||
lastUpdateTime = clock(); \
|
||||
DISPLAY(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
#undef DISPLAYUPDATE
|
||||
#define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__)
|
||||
|
||||
|
||||
/*-*************************************
|
||||
|
|
@ -136,6 +128,7 @@ typedef struct {
|
|||
unsigned d;
|
||||
unsigned f;
|
||||
FASTCOVER_accel_t accelParams;
|
||||
int displayLevel;
|
||||
} FASTCOVER_ctx_t;
|
||||
|
||||
|
||||
|
|
@ -314,7 +307,8 @@ FASTCOVER_ctx_init(FASTCOVER_ctx_t* ctx,
|
|||
const void* samplesBuffer,
|
||||
const size_t* samplesSizes, unsigned nbSamples,
|
||||
unsigned d, double splitPoint, unsigned f,
|
||||
FASTCOVER_accel_t accelParams)
|
||||
FASTCOVER_accel_t accelParams,
|
||||
int displayLevel)
|
||||
{
|
||||
const BYTE* const samples = (const BYTE*)samplesBuffer;
|
||||
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 size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
|
||||
const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
|
||||
ctx->displayLevel = displayLevel;
|
||||
|
||||
/* Checks */
|
||||
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(
|
||||
(U32)dictBufferCapacity, (U32)ctx->nbDmers, parameters.k, 1);
|
||||
const size_t maxZeroScoreRun = 10;
|
||||
const int displayLevel = ctx->displayLevel;
|
||||
size_t zeroScoreRun = 0;
|
||||
clock_t lastUpdateTime = 0;
|
||||
size_t epoch;
|
||||
DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
|
||||
(U32)epochs.num, (U32)epochs.size);
|
||||
|
|
@ -447,6 +444,7 @@ FASTCOVER_buildDictionary(const FASTCOVER_ctx_t* ctx,
|
|||
tail -= segmentSize;
|
||||
memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
|
||||
DISPLAYUPDATE(
|
||||
lastUpdateTime,
|
||||
2, "\r%u%% ",
|
||||
(unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
|
||||
}
|
||||
|
|
@ -484,6 +482,7 @@ static void FASTCOVER_tryParameters(void* opaque)
|
|||
BYTE *const dict = (BYTE*)malloc(dictBufferCapacity);
|
||||
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
||||
U32* freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32));
|
||||
const int displayLevel = ctx->displayLevel;
|
||||
if (!segmentFreqs || !dict || !freqs) {
|
||||
DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n");
|
||||
goto _cleanup;
|
||||
|
|
@ -555,8 +554,7 @@ ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity,
|
|||
FASTCOVER_ctx_t ctx;
|
||||
ZDICT_cover_params_t coverParams;
|
||||
FASTCOVER_accel_t accelParams;
|
||||
/* Initialize global data */
|
||||
g_displayLevel = (int)parameters.zParams.notificationLevel;
|
||||
const int displayLevel = (int)parameters.zParams.notificationLevel;
|
||||
/* Assign splitPoint and f if not provided */
|
||||
parameters.splitPoint = 1.0;
|
||||
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,
|
||||
coverParams.d, parameters.splitPoint, parameters.f,
|
||||
accelParams);
|
||||
accelParams, displayLevel);
|
||||
if (ZSTD_isError(initVal)) {
|
||||
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
||||
return initVal;
|
||||
}
|
||||
}
|
||||
COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, g_displayLevel);
|
||||
COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, displayLevel);
|
||||
/* Build the dictionary */
|
||||
DISPLAYLEVEL(2, "Building dictionary\n");
|
||||
{
|
||||
|
|
@ -646,25 +644,26 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||
COVER_best_t best;
|
||||
POOL_ctx *pool = NULL;
|
||||
int warned = 0;
|
||||
clock_t lastUpdateTime = 0;
|
||||
/* Checks */
|
||||
if (splitPoint <= 0 || splitPoint > 1) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect splitPoint\n");
|
||||
DISPLAYLEVEL(1, "Incorrect splitPoint\n");
|
||||
return ERROR(parameter_outOfBound);
|
||||
}
|
||||
if (accel == 0 || accel > FASTCOVER_MAX_ACCEL) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect accel\n");
|
||||
DISPLAYLEVEL(1, "Incorrect accel\n");
|
||||
return ERROR(parameter_outOfBound);
|
||||
}
|
||||
if (kMinK < kMaxD || kMaxK < kMinK) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect k\n");
|
||||
DISPLAYLEVEL(1, "Incorrect k\n");
|
||||
return ERROR(parameter_outOfBound);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
return ERROR(dstSize_tooSmall);
|
||||
}
|
||||
|
|
@ -679,19 +678,18 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||
memset(&coverParams, 0 , sizeof(coverParams));
|
||||
FASTCOVER_convertToCoverParams(*parameters, &coverParams);
|
||||
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 */
|
||||
LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
|
||||
kIterations);
|
||||
DISPLAYLEVEL(2, "Trying %u different sets of parameters\n", kIterations);
|
||||
for (d = kMinD; d <= kMaxD; d += 2) {
|
||||
/* Initialize the context for this value of d */
|
||||
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)) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n");
|
||||
DISPLAYLEVEL(1, "Failed to initialize context\n");
|
||||
COVER_best_destroy(&best);
|
||||
POOL_free(pool);
|
||||
return initVal;
|
||||
|
|
@ -706,9 +704,9 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||
/* Prepare the arguments */
|
||||
FASTCOVER_tryParameters_data_t *data = (FASTCOVER_tryParameters_data_t *)malloc(
|
||||
sizeof(FASTCOVER_tryParameters_data_t));
|
||||
LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k);
|
||||
DISPLAYLEVEL(3, "k=%u\n", k);
|
||||
if (!data) {
|
||||
LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n");
|
||||
DISPLAYLEVEL(1, "Failed to allocate parameters\n");
|
||||
COVER_best_destroy(&best);
|
||||
FASTCOVER_ctx_destroy(&ctx);
|
||||
POOL_free(pool);
|
||||
|
|
@ -723,7 +721,7 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||
data->parameters.splitPoint = splitPoint;
|
||||
data->parameters.steps = kSteps;
|
||||
data->parameters.shrinkDict = shrinkDict;
|
||||
data->parameters.zParams.notificationLevel = (unsigned)g_displayLevel;
|
||||
data->parameters.zParams.notificationLevel = (unsigned)ctx.displayLevel;
|
||||
/* Check the parameters */
|
||||
if (!FASTCOVER_checkParameters(data->parameters, dictBufferCapacity,
|
||||
data->ctx->f, accel)) {
|
||||
|
|
@ -739,14 +737,15 @@ ZDICT_optimizeTrainFromBuffer_fastCover(
|
|||
FASTCOVER_tryParameters(data);
|
||||
}
|
||||
/* Print status */
|
||||
LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ",
|
||||
DISPLAYUPDATE(lastUpdateTime,
|
||||
2, "\r%u%% ",
|
||||
(unsigned)((iteration * 100) / kIterations));
|
||||
++iteration;
|
||||
}
|
||||
COVER_best_wait(&best);
|
||||
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 */
|
||||
{
|
||||
const size_t dictSize = best.dictSize;
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ static void ZDICT_initDictItem(dictItem* d)
|
|||
#define MINMATCHLENGTH 7 /* heuristic determined experimentally */
|
||||
static dictItem ZDICT_analyzePos(
|
||||
BYTE* doneMarks,
|
||||
const int* suffix, U32 start,
|
||||
const unsigned* suffix, U32 start,
|
||||
const void* buffer, U32 minRatio, U32 notificationLevel)
|
||||
{
|
||||
U32 lengthList[LLIMIT] = {0};
|
||||
|
|
@ -293,8 +293,10 @@ static dictItem ZDICT_analyzePos(
|
|||
for (i=(int)(maxLength-2); i>=0; i--)
|
||||
cumulLength[i] = cumulLength[i+1] + lengthList[i];
|
||||
|
||||
for (i=LLIMIT-1; i>=MINMATCHLENGTH; i--) if (cumulLength[i]>=minRatio) break;
|
||||
maxLength = i;
|
||||
{ unsigned u;
|
||||
for (u=LLIMIT-1; u>=MINMATCHLENGTH; u--) if (cumulLength[u]>=minRatio) break;
|
||||
maxLength = u;
|
||||
}
|
||||
|
||||
/* reduce maxLength in case of final into repetitive data */
|
||||
{ U32 l = (U32)maxLength;
|
||||
|
|
@ -306,8 +308,10 @@ static dictItem ZDICT_analyzePos(
|
|||
|
||||
/* calculate savings */
|
||||
savings[5] = 0;
|
||||
for (i=MINMATCHLENGTH; i<=(int)maxLength; i++)
|
||||
savings[i] = savings[i-1] + (lengthList[i] * (i-3));
|
||||
{ unsigned u;
|
||||
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",
|
||||
(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 */
|
||||
/* 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 */
|
||||
if (addedLength > 0) { /* otherwise, elt fully included into existing */
|
||||
table[u].length += addedLength;
|
||||
table[u].savings += elt.savings * addedLength / elt.length; /* rough approx */
|
||||
table[u].length += (unsigned)addedLength;
|
||||
table[u].savings += elt.savings * (unsigned)addedLength / elt.length; /* rough approx */
|
||||
}
|
||||
/* sort : improve rank */
|
||||
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 (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].savings += (U32)(elt.savings * addedLength / elt.length);
|
||||
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,
|
||||
unsigned minRatio, U32 notificationLevel)
|
||||
{
|
||||
int* const suffix0 = (int*)malloc((bufferSize+2)*sizeof(*suffix0));
|
||||
int* const suffix = suffix0+1;
|
||||
unsigned* const suffix0 = (unsigned*)malloc((bufferSize+2)*sizeof(*suffix0));
|
||||
unsigned* const suffix = suffix0+1;
|
||||
U32* reverseSuffix = (U32*)malloc((bufferSize)*sizeof(*reverseSuffix));
|
||||
BYTE* doneMarks = (BYTE*)malloc((bufferSize+16)*sizeof(*doneMarks)); /* +16 for overflow security */
|
||||
U32* filePos = (U32*)malloc(nbFiles * sizeof(*filePos));
|
||||
|
|
@ -503,11 +507,11 @@ static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
|
|||
|
||||
/* sort */
|
||||
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; }
|
||||
}
|
||||
suffix[bufferSize] = (int)bufferSize; /* leads into noise */
|
||||
suffix0[0] = (int)bufferSize; /* leads into noise */
|
||||
suffix[bufferSize] = (unsigned)bufferSize; /* leads into noise */
|
||||
suffix0[0] = (unsigned)bufferSize; /* leads into noise */
|
||||
/* build reverse suffix sort */
|
||||
{ size_t pos;
|
||||
for (pos=0; pos < bufferSize; pos++)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,55 @@
|
|||
@ECHO OFF
|
||||
MKDIR bin\dll bin\static bin\example bin\include
|
||||
COPY tests\fullbench.c bin\example\
|
||||
COPY programs\datagen.c bin\example\
|
||||
COPY programs\datagen.h bin\example\
|
||||
COPY programs\util.h bin\example\
|
||||
COPY programs\platform.h bin\example\
|
||||
COPY lib\common\mem.h bin\example\
|
||||
COPY lib\common\zstd_internal.h bin\example\
|
||||
COPY lib\common\error_private.h bin\example\
|
||||
COPY lib\common\xxhash.h bin\example\
|
||||
COPY lib\libzstd.a bin\static\libzstd_static.lib
|
||||
COPY lib\dll\libzstd.* bin\dll\
|
||||
COPY lib\dll\example\Makefile bin\example\
|
||||
COPY lib\dll\example\fullbench-dll.* bin\example\
|
||||
COPY lib\dll\example\README.md bin\
|
||||
COPY lib\zstd.h bin\include\
|
||||
COPY lib\common\zstd_errors.h bin\include\
|
||||
COPY lib\dictBuilder\zdict.h bin\include\
|
||||
COPY programs\zstd.exe bin\zstd.exe
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
rem Detect build type based on available files
|
||||
set BUILD_TYPE=make
|
||||
if exist "build\cmake\build\lib\Release\zstd_static.lib" set BUILD_TYPE=cmake
|
||||
|
||||
echo Detected build type: %BUILD_TYPE%
|
||||
|
||||
rem Create required directories
|
||||
mkdir bin\dll bin\static bin\example bin\include
|
||||
|
||||
rem Copy common files using a subroutine. Exits immediately on failure.
|
||||
call :copyFile "tests\fullbench.c" "bin\example\"
|
||||
call :copyFile "programs\datagen.c" "bin\example\"
|
||||
call :copyFile "programs\datagen.h" "bin\example\"
|
||||
call :copyFile "programs\util.h" "bin\example\"
|
||||
call :copyFile "programs\platform.h" "bin\example\"
|
||||
call :copyFile "lib\common\mem.h" "bin\example\"
|
||||
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
|
||||
17
lib/install_oses.mk
Normal file
17
lib/install_oses.mk
Normal file
|
|
@ -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)
|
||||
{
|
||||
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* op = ostart;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
size_t errorCode, dumpsLength;
|
||||
size_t errorCode = 0;
|
||||
size_t dumpsLength = 0;
|
||||
const BYTE* litPtr = litStart;
|
||||
const BYTE* const litEnd = litStart + litSize;
|
||||
int nbSeq;
|
||||
const BYTE* dumps;
|
||||
int nbSeq = 0;
|
||||
const BYTE* dumps = NULL;
|
||||
U32* DTableLL = dctx->LLTable;
|
||||
U32* DTableML = dctx->MLTable;
|
||||
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;
|
||||
U32 magicNumber;
|
||||
size_t errorCode=0;
|
||||
blockProperties_t blockProperties;
|
||||
blockProperties_t blockProperties = { 0 };
|
||||
|
||||
/* Frame Header */
|
||||
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)
|
||||
{
|
||||
return a<0 ? -a : a;
|
||||
return a<0 ? (short)-a : a;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return a<0 ? -a : a;
|
||||
return a<0 ? (short)-a : a;
|
||||
}
|
||||
|
||||
static size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
|
||||
|
|
|
|||
|
|
@ -1224,7 +1224,7 @@ const char* FSEv05_getErrorName(size_t code) { return ERR_getErrorName(code); }
|
|||
/*-**************************************************************
|
||||
* 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,
|
||||
|
|
@ -3972,8 +3972,15 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
|
|||
zbc->outStart += flushedSize;
|
||||
if (flushedSize == toFlushSize) {
|
||||
zbc->stage = ZBUFFv05ds_read;
|
||||
if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize)
|
||||
zbc->outStart = zbc->outEnd = 0;
|
||||
if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize) {
|
||||
/* 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;
|
||||
}
|
||||
/* cannot flush everything */
|
||||
|
|
|
|||
|
|
@ -1202,7 +1202,7 @@ static unsigned HUFv06_isError(size_t code) { return ERR_isError(code); }
|
|||
/*-**************************************************************
|
||||
* 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,
|
||||
const void* headerBuffer, size_t hbSize)
|
||||
|
|
|
|||
|
|
@ -28,12 +28,8 @@ LIB_BINDIR ?= $(LIB_SRCDIR)
|
|||
# configures a bunch of other variables to space-optimized defaults.
|
||||
ZSTD_LIB_MINIFY ?= 0
|
||||
|
||||
# Legacy support
|
||||
ifneq ($(ZSTD_LIB_MINIFY), 0)
|
||||
# Legacy support disabled by default
|
||||
ZSTD_LEGACY_SUPPORT ?= 0
|
||||
else
|
||||
ZSTD_LEGACY_SUPPORT ?= 5
|
||||
endif
|
||||
ZSTD_LEGACY_MULTITHREADED_API ?= 0
|
||||
|
||||
# Build size optimizations
|
||||
|
|
@ -206,7 +202,10 @@ endif
|
|||
endif
|
||||
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
|
||||
ifeq ($(UNAME), Darwin)
|
||||
|
|
|
|||
|
|
@ -14,3 +14,4 @@ Version: @VERSION@
|
|||
Libs: -L${libdir} -lzstd @LIBS_MT@
|
||||
Libs.private: @LIBS_PRIVATE@
|
||||
Cflags: -I${includedir} @LIBS_MT@
|
||||
License: BSD-3-Clause OR GPL-2.0-only
|
||||
|
|
|
|||
|
|
@ -1,27 +1,6 @@
|
|||
module libzstd [extern_c] {
|
||||
header "zstd.h"
|
||||
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] {
|
||||
header "zdict.h"
|
||||
|
|
|
|||
73
lib/zstd.h
73
lib/zstd.h
|
|
@ -110,8 +110,8 @@ extern "C" {
|
|||
|
||||
/*------ Version ------*/
|
||||
#define ZSTD_VERSION_MAJOR 1
|
||||
#define ZSTD_VERSION_MINOR 5
|
||||
#define ZSTD_VERSION_RELEASE 7
|
||||
#define ZSTD_VERSION_MINOR 6
|
||||
#define ZSTD_VERSION_RELEASE 0
|
||||
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
|
||||
|
||||
/*! ZSTD_versionNumber() :
|
||||
|
|
@ -176,30 +176,30 @@ ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
|
|||
|
||||
/*====== Decompression helper functions ======*/
|
||||
|
||||
/*! ZSTD_getFrameContentSize() : requires v1.3.0+
|
||||
* `src` should point to the start of a ZSTD encoded frame.
|
||||
* `srcSize` must be at least as large as the frame header.
|
||||
* hint : any size >= `ZSTD_frameHeaderSize_max` is large enough.
|
||||
* @return : - decompressed size of `src` frame content, if known
|
||||
* - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
|
||||
* - 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".
|
||||
* 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).
|
||||
* 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.
|
||||
* Optionally, application can rely on some implicit limit,
|
||||
* as ZSTD_decompress() only needs an upper bound of decompressed size.
|
||||
* (For example, data could be necessarily cut into blocks <= 16 KB).
|
||||
* note 3 : decompressed size is always present when compression is completed using single-pass functions,
|
||||
* such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict().
|
||||
* note 4 : decompressed size can be very large (64-bits value),
|
||||
* potentially larger than what local system can handle as a single memory segment.
|
||||
* In which case, it's necessary to use streaming mode to decompress data.
|
||||
* note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified.
|
||||
* Always ensure return value fits within application's authorized limits.
|
||||
* Each application can set its own limits.
|
||||
* note 6 : This function replaces ZSTD_getDecompressedSize() */
|
||||
/*! @brief Returns the decompressed content size stored in a ZSTD frame header.
|
||||
*
|
||||
* @since v1.3.0
|
||||
*
|
||||
* @param src Pointer to the beginning of a ZSTD encoded frame.
|
||||
* @param srcSize Size of the buffer pointed to by @p src. It must be at least as large as the frame header.
|
||||
* Any value greater than or equal to `ZSTD_frameHeaderSize_max` is sufficient.
|
||||
* @return The decompressed size in bytes when the value is available in the frame header.
|
||||
* @retval ZSTD_CONTENTSIZE_UNKNOWN The frame does not encode a decompressed size (typical for streaming).
|
||||
* @retval ZSTD_CONTENTSIZE_ERROR An error occurred (e.g. invalid magic number, @p srcSize too small).
|
||||
*
|
||||
* @note The return value is not compatible with `ZSTD_isError()`.
|
||||
* @note A return value of 0 denotes a valid but empty frame. Skippable frames also report 0.
|
||||
* @note The decompressed size field is optional. When it is absent (the function returns @c ZSTD_CONTENTSIZE_UNKNOWN),
|
||||
* the caller must rely on streaming decompression or an application-specific upper bound. `ZSTD_decompress()`
|
||||
* only requires an upper bound, so applications may enforce their own block limits (for example 16 KB).
|
||||
* @note The decompressed size is guaranteed to be present when compression was performed with single-pass APIs such as
|
||||
* `ZSTD_compress()`, `ZSTD_compressCCtx()`, `ZSTD_compress_usingDict()`, or `ZSTD_compress_usingCDict()`.
|
||||
* @note The decompressed size is a 64-bit value and may exceed the addressable space of the system. Use streaming
|
||||
* decompression when the value is too large to materialize in contiguous memory.
|
||||
* @warning When processing untrusted input, validate the returned size against the application's limits; attackers may
|
||||
* forge an arbitrarily large value.
|
||||
* @note This function replaces `ZSTD_getDecompressedSize()`.
|
||||
*/
|
||||
#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
|
||||
#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
|
||||
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_freeFunction) (void* opaque, void* address);
|
||||
typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
|
||||
static
|
||||
#ifdef __GNUC__
|
||||
__attribute__((__unused__))
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) && __clang_major__ >= 5
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
static
|
||||
#ifdef __GNUC__
|
||||
__attribute__((__unused__))
|
||||
#endif
|
||||
ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
|
||||
#if defined(__clang__) && __clang_major__ >= 5
|
||||
#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) */
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ endif
|
|||
|
||||
zstd : $(BUILD_DIR)/zstd
|
||||
if [ $(BIN_ISDIFFERENT) -eq 1 ]; then \
|
||||
cp -f $<$(EXT) $@$(EXT); \
|
||||
$(CP) $<$(EXT) $@$(EXT); \
|
||||
echo zstd build completed; \
|
||||
else \
|
||||
echo zstd already built; \
|
||||
|
|
@ -271,7 +271,7 @@ zstd-dictBuilder: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) $(ZDICT_SRC) zst
|
|||
|
||||
CLEAN += zstdmt
|
||||
zstdmt: zstd
|
||||
ln -sf zstd zstdmt
|
||||
$(LN) -sf zstd zstdmt
|
||||
|
||||
.PHONY: generate_res
|
||||
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
|
||||
#-----------------------------------------------------------------------------
|
||||
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)
|
||||
EGREP_OPTIONS ?=
|
||||
|
|
@ -414,15 +414,15 @@ install:
|
|||
[ -e $(DESTDIR)$(MAN1DIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(MAN1DIR)/
|
||||
@echo Installing binaries
|
||||
$(INSTALL_PROGRAM) zstd$(EXT) $(DESTDIR)$(BINDIR)/zstd$(EXT)
|
||||
ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdcat$(EXT)
|
||||
ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd$(EXT)
|
||||
ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdmt$(EXT)
|
||||
$(LN) -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdcat$(EXT)
|
||||
$(LN) -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd$(EXT)
|
||||
$(LN) -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/zstdmt$(EXT)
|
||||
$(INSTALL_SCRIPT) zstdless $(DESTDIR)$(BINDIR)/zstdless
|
||||
$(INSTALL_SCRIPT) zstdgrep $(DESTDIR)$(BINDIR)/zstdgrep
|
||||
@echo Installing man pages
|
||||
$(INSTALL_MAN) zstd.1 $(DESTDIR)$(MAN1DIR)/zstd.1
|
||||
ln -sf zstd.1 $(DESTDIR)$(MAN1DIR)/zstdcat.1
|
||||
ln -sf zstd.1 $(DESTDIR)$(MAN1DIR)/unzstd.1
|
||||
$(LN) -sf zstd.1 $(DESTDIR)$(MAN1DIR)/zstdcat.1
|
||||
$(LN) -sf zstd.1 $(DESTDIR)$(MAN1DIR)/unzstd.1
|
||||
$(INSTALL_MAN) zstdgrep.1 $(DESTDIR)$(MAN1DIR)/zstdgrep.1
|
||||
$(INSTALL_MAN) zstdless.1 $(DESTDIR)$(MAN1DIR)/zstdless.1
|
||||
@echo zstd installation completed
|
||||
|
|
|
|||
|
|
@ -79,6 +79,13 @@ There are however other Makefile targets that create different variations of CLI
|
|||
This can be useful to produce smaller binaries.
|
||||
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
|
||||
generates a runtime exception. By default, this feature may be
|
||||
degraded/disabled on some platforms unless additional compiler directives are
|
||||
|
|
@ -153,7 +160,7 @@ Usage: zstd [OPTIONS...] [INPUT... | -] [-o OUTPUT]
|
|||
Options:
|
||||
-o OUTPUT Write output to a single file, OUTPUT.
|
||||
-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;
|
||||
lower numbers provide faster compression, higher numbers yield
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ BMK_advancedParams_t BMK_initAdvancedParams(void)
|
|||
BMK_advancedParams_t const res = {
|
||||
BMK_both, /* mode */
|
||||
BMK_TIMETEST_DEFAULT_S, /* nbSeconds */
|
||||
0, /* blockSize */
|
||||
0, /* chunkSizeMax */
|
||||
0, /* targetCBlockSize */
|
||||
0, /* nbWorkers */
|
||||
0, /* realTime */
|
||||
|
|
@ -227,16 +227,6 @@ BMK_advancedParams_t BMK_initAdvancedParams(void)
|
|||
/* ********************************************************
|
||||
* 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 MAX
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
|
@ -435,16 +425,16 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||
const char* displayName,
|
||||
const BMK_advancedParams_t* adv)
|
||||
{
|
||||
size_t const blockSize =
|
||||
((adv->blockSize >= 32 && (adv->mode != BMK_decodeOnly))
|
||||
? adv->blockSize
|
||||
size_t const chunkSizeMax =
|
||||
((adv->chunkSizeMax >= 32 && (adv->mode != BMK_decodeOnly))
|
||||
? adv->chunkSizeMax
|
||||
: srcSize)
|
||||
+ (!srcSize); /* avoid div by 0 */
|
||||
BMK_benchResult_t benchResult;
|
||||
size_t const loadedCompressedSize = srcSize;
|
||||
size_t cSize = 0;
|
||||
double ratio = 0.;
|
||||
U32 nbBlocks;
|
||||
U32 nbChunks = 0;
|
||||
|
||||
assert(cctx != 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;
|
||||
char* cPtr = (char*)compressedBuffer;
|
||||
char* resPtr = (char*)(*resultBufferPtr);
|
||||
U32 fileNb;
|
||||
for (nbBlocks = 0, fileNb = 0; fileNb < nbFiles; fileNb++) {
|
||||
U32 fileNb, chunkID;
|
||||
for (chunkID = 0, fileNb = 0; fileNb < nbFiles; fileNb++) {
|
||||
size_t remaining = fileSizes[fileNb];
|
||||
U32 const nbBlocksforThisFile = (adv->mode == BMK_decodeOnly)
|
||||
U32 const nbChunksforThisFile = (adv->mode == BMK_decodeOnly)
|
||||
? 1
|
||||
: (U32)((remaining + (blockSize - 1)) / blockSize);
|
||||
U32 const blockEnd = nbBlocks + nbBlocksforThisFile;
|
||||
for (; nbBlocks < blockEnd; nbBlocks++) {
|
||||
size_t const thisBlockSize = MIN(remaining, blockSize);
|
||||
srcPtrs[nbBlocks] = srcPtr;
|
||||
srcSizes[nbBlocks] = thisBlockSize;
|
||||
cPtrs[nbBlocks] = cPtr;
|
||||
cCapacities[nbBlocks] = (adv->mode == BMK_decodeOnly)
|
||||
? thisBlockSize
|
||||
: ZSTD_compressBound(thisBlockSize);
|
||||
resPtrs[nbBlocks] = resPtr;
|
||||
resSizes[nbBlocks] = (adv->mode == BMK_decodeOnly)
|
||||
: (U32)((remaining + (chunkSizeMax - 1)) / chunkSizeMax);
|
||||
U32 const chunkIdEnd = chunkID + nbChunksforThisFile;
|
||||
for (; chunkID < chunkIdEnd; chunkID++) {
|
||||
size_t const chunkSize = MIN(remaining, chunkSizeMax);
|
||||
srcPtrs[chunkID] = srcPtr;
|
||||
srcSizes[chunkID] = chunkSize;
|
||||
cPtrs[chunkID] = cPtr;
|
||||
cCapacities[chunkID] = (adv->mode == BMK_decodeOnly)
|
||||
? chunkSize
|
||||
: ZSTD_compressBound(chunkSize);
|
||||
resPtrs[chunkID] = resPtr;
|
||||
resSizes[chunkID] = (adv->mode == BMK_decodeOnly)
|
||||
? (size_t)ZSTD_findDecompressedSize(
|
||||
srcPtr, thisBlockSize)
|
||||
: thisBlockSize;
|
||||
srcPtr += thisBlockSize;
|
||||
cPtr += cCapacities[nbBlocks];
|
||||
resPtr += thisBlockSize;
|
||||
remaining -= thisBlockSize;
|
||||
srcPtr, chunkSize)
|
||||
: chunkSize;
|
||||
srcPtr += chunkSize;
|
||||
cPtr += cCapacities[chunkID];
|
||||
resPtr += chunkSize;
|
||||
remaining -= chunkSize;
|
||||
if (adv->mode == BMK_decodeOnly) {
|
||||
cSizes[nbBlocks] = thisBlockSize;
|
||||
benchResult.cSize = thisBlockSize;
|
||||
cSizes[chunkID] = chunkSize;
|
||||
benchResult.cSize = chunkSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
nbChunks = chunkID;
|
||||
}
|
||||
|
||||
/* warming up `compressedBuffer` */
|
||||
|
|
@ -569,7 +560,7 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||
cbp.initFn = local_initCCtx; /* BMK_initCCtx */
|
||||
cbp.initPayload = &cctxprep;
|
||||
cbp.errorFn = ZSTD_isError;
|
||||
cbp.blockCount = nbBlocks;
|
||||
cbp.blockCount = nbChunks;
|
||||
cbp.srcBuffers = srcPtrs;
|
||||
cbp.srcSizes = srcSizes;
|
||||
cbp.dstBuffers = cPtrs;
|
||||
|
|
@ -588,7 +579,7 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||
dbp.initFn = local_initDCtx;
|
||||
dbp.initPayload = &dctxprep;
|
||||
dbp.errorFn = ZSTD_isError;
|
||||
dbp.blockCount = nbBlocks;
|
||||
dbp.blockCount = nbChunks;
|
||||
dbp.srcBuffers = (const void* const*)cPtrs;
|
||||
dbp.srcSizes = cSizes;
|
||||
dbp.dstBuffers = resPtrs;
|
||||
|
|
@ -690,8 +681,7 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||
} /* while (!(compressionCompleted && decompressionCompleted)) */
|
||||
|
||||
/* CRC Checking */
|
||||
{
|
||||
const BYTE* resultBuffer = (const BYTE*)(*resultBufferPtr);
|
||||
{ const BYTE* resultBuffer = (const BYTE*)(*resultBufferPtr);
|
||||
U64 const crcCheck = XXH64(resultBuffer, srcSize, 0);
|
||||
if ((adv->mode == BMK_both) && (crcOrig != crcCheck)) {
|
||||
size_t u;
|
||||
|
|
@ -704,14 +694,14 @@ static BMK_benchOutcome_t BMK_benchMemAdvancedNoAlloc(
|
|||
unsigned segNb, bNb, pos;
|
||||
size_t bacc = 0;
|
||||
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)
|
||||
break;
|
||||
bacc += srcSizes[segNb];
|
||||
}
|
||||
pos = (U32)(u - bacc);
|
||||
bNb = pos / (128 KB);
|
||||
DISPLAY("(sample %u, block %u, pos %u) \n",
|
||||
DISPLAY("(sample %u, chunk %u, pos %u) \n",
|
||||
segNb,
|
||||
bNb,
|
||||
pos);
|
||||
|
|
@ -795,25 +785,24 @@ BMK_benchOutcome_t BMK_benchMemAdvanced(
|
|||
int const dstParamsError =
|
||||
!dstBuffer ^ !dstCapacity; /* must be both NULL or none */
|
||||
|
||||
size_t const blockSize =
|
||||
((adv->blockSize >= 32 && (adv->mode != BMK_decodeOnly))
|
||||
? adv->blockSize
|
||||
size_t const chunkSize =
|
||||
((adv->chunkSizeMax >= 32 && (adv->mode != BMK_decodeOnly))
|
||||
? adv->chunkSizeMax
|
||||
: srcSize)
|
||||
+ (!srcSize) /* avoid div by 0 */;
|
||||
U32 const maxNbBlocks =
|
||||
(U32)((srcSize + (blockSize - 1)) / blockSize) + nbFiles;
|
||||
U32 const nbChunksMax =
|
||||
(U32)((srcSize + (chunkSize - 1)) / chunkSize) + nbFiles;
|
||||
|
||||
/* these are the blockTable parameters, just split up */
|
||||
const void** const srcPtrs =
|
||||
(const void**)malloc(maxNbBlocks * sizeof(void*));
|
||||
size_t* const srcSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
||||
(const void**)malloc(nbChunksMax * sizeof(void*));
|
||||
size_t* const srcSizes = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||
|
||||
void** const cPtrs = (void**)malloc(maxNbBlocks * sizeof(void*));
|
||||
size_t* const cSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
||||
size_t* const cCapacities = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
||||
void** const cPtrs = (void**)malloc(nbChunksMax * sizeof(void*));
|
||||
size_t* const cSizes = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||
size_t* const cCapacities = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||
|
||||
void** const resPtrs = (void**)malloc(maxNbBlocks * sizeof(void*));
|
||||
size_t* const resSizes = (size_t*)malloc(maxNbBlocks * sizeof(size_t));
|
||||
void** const resPtrs = (void**)malloc(nbChunksMax * sizeof(void*));
|
||||
size_t* const resSizes = (size_t*)malloc(nbChunksMax * sizeof(size_t));
|
||||
|
||||
BMK_timedFnState_t* timeStateCompress = BMK_createTimedFnState(
|
||||
adv->nbSeconds * 1000, BMK_RUNTEST_DEFAULT_MS);
|
||||
|
|
@ -825,7 +814,7 @@ BMK_benchOutcome_t BMK_benchMemAdvanced(
|
|||
|
||||
const size_t maxCompressedSize = dstCapacity
|
||||
? dstCapacity
|
||||
: ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024);
|
||||
: ZSTD_compressBound(srcSize) + (nbChunksMax * 1024);
|
||||
|
||||
void* const internalDstBuffer =
|
||||
dstBuffer ? NULL : malloc(maxCompressedSize);
|
||||
|
|
@ -964,12 +953,12 @@ static int BMK_benchCLevels(
|
|||
}
|
||||
|
||||
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_GIT_COMMIT_STRING,
|
||||
(unsigned)benchedSize,
|
||||
adv->nbSeconds,
|
||||
(unsigned)(adv->blockSize >> 10));
|
||||
(unsigned)(adv->chunkSizeMax >> 10));
|
||||
|
||||
for (level = startCLevel; level <= endCLevel; level++) {
|
||||
BMK_benchOutcome_t res = BMK_benchMemAdvanced(
|
||||
|
|
@ -1000,7 +989,7 @@ int BMK_syntheticTest(
|
|||
{
|
||||
char nameBuff[20] = { 0 };
|
||||
const char* name = nameBuff;
|
||||
size_t const benchedSize = adv->blockSize ? adv->blockSize : 10000000;
|
||||
size_t const benchedSize = adv->chunkSizeMax ? adv->chunkSizeMax : 10000000;
|
||||
|
||||
/* Memory allocation */
|
||||
void* const srcBuffer = malloc(benchedSize);
|
||||
|
|
|
|||
|
|
@ -92,9 +92,9 @@ typedef enum {
|
|||
} BMK_mode_t;
|
||||
|
||||
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 */
|
||||
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 */
|
||||
int nbWorkers; /* multithreading */
|
||||
unsigned realTime; /* real time priority */
|
||||
|
|
|
|||
|
|
@ -280,8 +280,15 @@ static fileStats DiB_fileStats(const char** fileNamesTable, int nbFiles, size_t
|
|||
for (n=0; n<nbFiles; n++) {
|
||||
S64 const fileSize = DiB_getFileSize(fileNamesTable[n]);
|
||||
/* TODO: is there a minimum sample size? What if the file is 1-byte? */
|
||||
if (fileSize == 0) {
|
||||
DISPLAYLEVEL(3, "Sample file '%s' has zero size, skipping...\n", fileNamesTable[n]);
|
||||
/* Skip empty or invalid files */
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -364,7 +371,7 @@ int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize,
|
|||
if (fs.nbSamples < 5) {
|
||||
DISPLAYLEVEL(2, "! Warning : nb of samples too low for proper processing !\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 */
|
||||
}
|
||||
if (fs.totalSizeToLoad < (S64)maxDictSize * 8) {
|
||||
|
|
|
|||
|
|
@ -125,6 +125,271 @@ char const* FIO_lzmaVersion(void)
|
|||
#define TEMPORARY_FILE_PERMISSIONS (0600)
|
||||
#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)
|
||||
**************************************/
|
||||
|
|
@ -288,7 +553,7 @@ FIO_prefs_t* FIO_createPreferences(void)
|
|||
ret->removeSrcFile = 0;
|
||||
ret->memLimit = 0;
|
||||
ret->nbWorkers = 1;
|
||||
ret->blockSize = 0;
|
||||
ret->jobSize = 0;
|
||||
ret->overlapLog = FIO_OVERLAP_LOG_NOTSET;
|
||||
ret->adaptiveMode = 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_setBlockSize(FIO_prefs_t* const prefs, int blockSize) {
|
||||
if (blockSize && prefs->nbWorkers==0)
|
||||
void FIO_setJobSize(FIO_prefs_t* const prefs, int jobSize) {
|
||||
if (jobSize && prefs->nbWorkers==0)
|
||||
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){
|
||||
|
|
@ -538,13 +803,15 @@ static int FIO_removeFile(const char* path)
|
|||
}
|
||||
|
||||
/** 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 */
|
||||
static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFileName, stat_t* statbuf)
|
||||
{
|
||||
int allowBlockDevices = prefs != NULL ? prefs->allowBlockDevices : 0;
|
||||
assert(srcFileName != NULL);
|
||||
assert(statbuf != NULL);
|
||||
|
||||
if (!strcmp(srcFileName, stdinmark)) {
|
||||
DISPLAYLEVEL(4,"Using stdin for input \n");
|
||||
SET_BINARY_MODE(stdin);
|
||||
|
|
@ -557,8 +824,10 @@ static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFile
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Accept regular files, FIFOs, and process substitution file descriptors */
|
||||
if (!UTIL_isRegularFileStat(statbuf)
|
||||
&& !UTIL_isFIFOStat(statbuf)
|
||||
&& !UTIL_isFileDescriptorPipe(srcFileName) /* Process substitution support */
|
||||
&& !(allowBlockDevices && UTIL_isBlockDevStat(statbuf))
|
||||
) {
|
||||
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 int mode)
|
||||
{
|
||||
int isDstRegFile;
|
||||
|
||||
if (prefs->testMode) return NULL; /* do not open file in test mode */
|
||||
|
||||
assert(dstFileName != NULL);
|
||||
|
|
@ -602,16 +869,7 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
isDstRegFile = UTIL_isRegularFile(dstFileName); /* invoke once */
|
||||
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) {
|
||||
if (UTIL_isRegularFile(dstFileName)) {
|
||||
/* Check if destination file already exists */
|
||||
#if !defined(_WIN32)
|
||||
/* 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)
|
||||
/* Windows requires opening the file as a "binary" file to avoid
|
||||
* 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");
|
||||
}
|
||||
#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 (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 {
|
||||
/* An increased buffer size can provide a significant performance
|
||||
* 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);
|
||||
if (*bufferPtr==NULL) EXM_THROW(34, "%s", strerror(errno));
|
||||
if (*bufferPtr == MAP_FAILED) {
|
||||
EXM_THROW(34, "%s", strerror(errno))
|
||||
}
|
||||
|
||||
close(fileHandle);
|
||||
return (size_t)fileSize;
|
||||
|
|
@ -1069,8 +1345,7 @@ typedef struct {
|
|||
const char* dictFileName;
|
||||
stat_t dictFileStat;
|
||||
ZSTD_CStream* cctx;
|
||||
WritePoolCtx_t *writeCtx;
|
||||
ReadPoolCtx_t *readCtx;
|
||||
FIO_SyncCompressIO io;
|
||||
} cRess_t;
|
||||
|
||||
/** ZSTD_cycleLog() :
|
||||
|
|
@ -1138,8 +1413,7 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
|||
dictBufferType = (useMMap && !forceNoUseMMap) ? FIO_mmapDict : FIO_mallocDict;
|
||||
FIO_initDict(&ress.dict, dictFileName, prefs, &ress.dictFileStat, dictBufferType); /* works with dictFileName==NULL */
|
||||
|
||||
ress.writeCtx = AIO_WritePool_create(prefs, ZSTD_CStreamOutSize());
|
||||
ress.readCtx = AIO_ReadPool_create(prefs, ZSTD_CStreamInSize());
|
||||
FIO_SyncCompressIO_init(&ress.io, prefs, ZSTD_CStreamInSize(), ZSTD_CStreamOutSize());
|
||||
|
||||
/* Advanced parameters, including dictionary */
|
||||
if (dictFileName && (ress.dict.dictBuffer==NULL))
|
||||
|
|
@ -1183,7 +1457,7 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
|||
#ifdef ZSTD_MULTITHREAD
|
||||
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_jobSize, prefs->blockSize) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_jobSize, prefs->jobSize) );
|
||||
if (prefs->overlapLog != FIO_OVERLAP_LOG_NOTSET) {
|
||||
DISPLAYLEVEL(3,"set overlapLog = %u \n", 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)
|
||||
{
|
||||
FIO_freeDict(&(ress->dict));
|
||||
AIO_WritePool_free(ress->writeCtx);
|
||||
AIO_ReadPool_free(ress->readCtx);
|
||||
FIO_SyncCompressIO_destroy(&ress->io);
|
||||
ZSTD_freeCStream(ress->cctx); /* never fails */
|
||||
}
|
||||
|
||||
|
||||
#ifdef ZSTD_GZCOMPRESS
|
||||
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,
|
||||
int compressionLevel, U64* readsize)
|
||||
{
|
||||
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||
z_stream strm;
|
||||
IOJob_t *writeJob = NULL;
|
||||
|
||||
if (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);
|
||||
} }
|
||||
|
||||
writeJob = AIO_WritePool_acquireJob(ress->writeCtx);
|
||||
strm.next_in = 0;
|
||||
strm.avail_in = 0;
|
||||
strm.next_out = (Bytef*)writeJob->buffer;
|
||||
strm.avail_out = (uInt)writeJob->bufferSize;
|
||||
strm.next_out = (Bytef*)syncIO->outBuffer;
|
||||
strm.avail_out = (uInt)syncIO->outCapacity;
|
||||
|
||||
while (1) {
|
||||
int ret;
|
||||
if (strm.avail_in == 0) {
|
||||
AIO_ReadPool_fillBuffer(ress->readCtx, ZSTD_CStreamInSize());
|
||||
if (ress->readCtx->srcBufferLoaded == 0) break;
|
||||
inFileSize += ress->readCtx->srcBufferLoaded;
|
||||
strm.next_in = (z_const unsigned char*)ress->readCtx->srcBuffer;
|
||||
strm.avail_in = (uInt)ress->readCtx->srcBufferLoaded;
|
||||
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, ZSTD_CStreamInSize());
|
||||
if (syncIO->srcBufferLoaded == 0) break;
|
||||
inFileSize += added;
|
||||
*readsize += added;
|
||||
strm.next_in = (z_const unsigned char*)syncIO->srcBuffer;
|
||||
strm.avail_in = (uInt)syncIO->srcBufferLoaded;
|
||||
}
|
||||
|
||||
{
|
||||
size_t const availBefore = strm.avail_in;
|
||||
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)
|
||||
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) {
|
||||
writeJob->usedBufferSize = cSize;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, cSize);
|
||||
outFileSize += cSize;
|
||||
strm.next_out = (Bytef*)writeJob->buffer;
|
||||
strm.avail_out = (uInt)writeJob->bufferSize;
|
||||
strm.next_out = (Bytef*)syncIO->outBuffer;
|
||||
strm.avail_out = (uInt)syncIO->outCapacity;
|
||||
} }
|
||||
if (srcFileSize == UTIL_FILESIZE_UNKNOWN) {
|
||||
DISPLAYUPDATE_PROGRESS(
|
||||
|
|
@ -1279,13 +1551,12 @@ FIO_compressGzFrame(const cRess_t* ress, /* buffers & handlers are used, but no
|
|||
|
||||
while (1) {
|
||||
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) {
|
||||
writeJob->usedBufferSize = cSize;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, cSize);
|
||||
outFileSize += cSize;
|
||||
strm.next_out = (Bytef*)writeJob->buffer;
|
||||
strm.avail_out = (uInt)writeJob->bufferSize;
|
||||
strm.next_out = (Bytef*)syncIO->outBuffer;
|
||||
strm.avail_out = (uInt)syncIO->outCapacity;
|
||||
} }
|
||||
if (ret == Z_STREAM_END) break;
|
||||
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);
|
||||
} }
|
||||
*readsize = inFileSize;
|
||||
AIO_WritePool_releaseIoJob(writeJob);
|
||||
AIO_WritePool_sparseWriteEnd(ress->writeCtx);
|
||||
FIO_SyncCompressIO_finish(syncIO);
|
||||
return outFileSize;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1310,11 +1580,11 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
|||
const char* srcFileName, U64 const srcFileSize,
|
||||
int compressionLevel, U64* readsize, int plain_lzma)
|
||||
{
|
||||
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
lzma_action action = LZMA_RUN;
|
||||
lzma_ret ret;
|
||||
IOJob_t *writeJob = NULL;
|
||||
|
||||
if (compressionLevel < 0) compressionLevel = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
writeJob =AIO_WritePool_acquireJob(ress->writeCtx);
|
||||
strm.next_out = (BYTE*)writeJob->buffer;
|
||||
strm.avail_out = writeJob->bufferSize;
|
||||
strm.next_out = (BYTE*)syncIO->outBuffer;
|
||||
strm.avail_out = syncIO->outCapacity;
|
||||
strm.next_in = 0;
|
||||
strm.avail_in = 0;
|
||||
|
||||
while (1) {
|
||||
if (strm.avail_in == 0) {
|
||||
size_t const inSize = AIO_ReadPool_fillBuffer(ress->readCtx, ZSTD_CStreamInSize());
|
||||
if (ress->readCtx->srcBufferLoaded == 0) action = LZMA_FINISH;
|
||||
inFileSize += inSize;
|
||||
strm.next_in = (BYTE const*)ress->readCtx->srcBuffer;
|
||||
strm.avail_in = ress->readCtx->srcBufferLoaded;
|
||||
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, ZSTD_CStreamInSize());
|
||||
if (syncIO->srcBufferLoaded == 0) action = LZMA_FINISH;
|
||||
inFileSize += added;
|
||||
*readsize += added;
|
||||
strm.next_in = (BYTE const*)syncIO->srcBuffer;
|
||||
strm.avail_in = syncIO->srcBufferLoaded;
|
||||
}
|
||||
|
||||
{
|
||||
size_t const availBefore = strm.avail_in;
|
||||
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)
|
||||
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) {
|
||||
writeJob->usedBufferSize = compBytes;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, compBytes);
|
||||
outFileSize += compBytes;
|
||||
strm.next_out = (BYTE*)writeJob->buffer;
|
||||
strm.avail_out = writeJob->bufferSize;
|
||||
strm.next_out = (BYTE*)syncIO->outBuffer;
|
||||
strm.avail_out = syncIO->outCapacity;
|
||||
} }
|
||||
if (srcFileSize == UTIL_FILESIZE_UNKNOWN)
|
||||
DISPLAYUPDATE_PROGRESS("\rRead : %u MB ==> %.2f%%",
|
||||
|
|
@ -1378,8 +1646,7 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
|||
lzma_end(&strm);
|
||||
*readsize = inFileSize;
|
||||
|
||||
AIO_WritePool_releaseIoJob(writeJob);
|
||||
AIO_WritePool_sparseWriteEnd(ress->writeCtx);
|
||||
FIO_SyncCompressIO_finish(syncIO);
|
||||
|
||||
return outFileSize;
|
||||
}
|
||||
|
|
@ -1400,21 +1667,20 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||
int compressionLevel, int checksumFlag,
|
||||
U64* readsize)
|
||||
{
|
||||
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||
const size_t blockSize = FIO_LZ4_GetBlockSize_FromBlockId(LZ4F_max64KB);
|
||||
unsigned long long inFileSize = 0, outFileSize = 0;
|
||||
|
||||
LZ4F_preferences_t prefs;
|
||||
LZ4F_compressionContext_t ctx;
|
||||
|
||||
IOJob_t* writeJob = AIO_WritePool_acquireJob(ress->writeCtx);
|
||||
|
||||
LZ4F_errorCode_t const errorCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
||||
if (LZ4F_isError(errorCode))
|
||||
EXM_THROW(31, "zstd: failed to create lz4 compression context");
|
||||
|
||||
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 */
|
||||
prefs.autoFlush = 0;
|
||||
|
|
@ -1425,25 +1691,26 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||
#if LZ4_VERSION_NUMBER >= 10600
|
||||
prefs.frameInfo.contentSize = (srcFileSize==UTIL_FILESIZE_UNKNOWN) ? 0 : srcFileSize;
|
||||
#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))
|
||||
EXM_THROW(33, "File header generation failed : %s",
|
||||
LZ4F_getErrorName(headerSize));
|
||||
writeJob->usedBufferSize = headerSize;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, 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 (ress->readCtx->srcBufferLoaded) {
|
||||
size_t inSize = MIN(blockSize, ress->readCtx->srcBufferLoaded);
|
||||
size_t const outSize = LZ4F_compressUpdate(ctx, writeJob->buffer, writeJob->bufferSize,
|
||||
ress->readCtx->srcBuffer, inSize, NULL);
|
||||
while (syncIO->srcBufferLoaded) {
|
||||
size_t const inSize = MIN(blockSize, syncIO->srcBufferLoaded);
|
||||
size_t const outSize = LZ4F_compressUpdate(ctx, syncIO->outBuffer, syncIO->outCapacity,
|
||||
syncIO->srcBuffer, inSize, NULL);
|
||||
if (LZ4F_isError(outSize))
|
||||
EXM_THROW(35, "zstd: %s: lz4 compression failed : %s",
|
||||
srcFileName, LZ4F_getErrorName(outSize));
|
||||
|
|
@ -1458,30 +1725,27 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||
(double)outFileSize/(double)inFileSize*100);
|
||||
}
|
||||
|
||||
/* Write Block */
|
||||
writeJob->usedBufferSize = outSize;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, outSize);
|
||||
|
||||
/* Read next block */
|
||||
AIO_ReadPool_consumeBytes(ress->readCtx, inSize);
|
||||
inFileSize += AIO_ReadPool_fillBuffer(ress->readCtx, blockSize);
|
||||
FIO_SyncCompressIO_consumeBytes(syncIO, inSize);
|
||||
{
|
||||
size_t const added = FIO_SyncCompressIO_fillBuffer(syncIO, blockSize);
|
||||
inFileSize += added;
|
||||
*readsize += added;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of Stream mark */
|
||||
headerSize = LZ4F_compressEnd(ctx, writeJob->buffer, writeJob->bufferSize, NULL);
|
||||
headerSize = LZ4F_compressEnd(ctx, syncIO->outBuffer, syncIO->outCapacity, NULL);
|
||||
if (LZ4F_isError(headerSize))
|
||||
EXM_THROW(38, "zstd: %s: lz4 end of file generation failed : %s",
|
||||
srcFileName, LZ4F_getErrorName(headerSize));
|
||||
|
||||
writeJob->usedBufferSize = headerSize;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, headerSize);
|
||||
outFileSize += headerSize;
|
||||
}
|
||||
|
||||
*readsize = inFileSize;
|
||||
LZ4F_freeCompressionContext(ctx);
|
||||
AIO_WritePool_releaseIoJob(writeJob);
|
||||
AIO_WritePool_sparseWriteEnd(ress->writeCtx);
|
||||
FIO_SyncCompressIO_finish(syncIO);
|
||||
|
||||
return outFileSize;
|
||||
}
|
||||
|
|
@ -1490,12 +1754,11 @@ FIO_compressLz4Frame(cRess_t* ress,
|
|||
static unsigned long long
|
||||
FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
||||
FIO_prefs_t* const prefs,
|
||||
const cRess_t* ressPtr,
|
||||
cRess_t* ress,
|
||||
const char* srcFileName, U64 fileSize,
|
||||
int compressionLevel, U64* readsize)
|
||||
{
|
||||
cRess_t const ress = *ressPtr;
|
||||
IOJob_t* writeJob = AIO_WritePool_acquireJob(ressPtr->writeCtx);
|
||||
FIO_SyncCompressIO* const syncIO = &ress->io;
|
||||
|
||||
U64 compressedfilesize = 0;
|
||||
ZSTD_EndDirective directive = ZSTD_e_continue;
|
||||
|
|
@ -1520,16 +1783,16 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||
/* init */
|
||||
if (fileSize != UTIL_FILESIZE_UNKNOWN) {
|
||||
pledgedSrcSize = fileSize;
|
||||
CHECK(ZSTD_CCtx_setPledgedSrcSize(ress.cctx, fileSize));
|
||||
CHECK(ZSTD_CCtx_setPledgedSrcSize(ress->cctx, fileSize));
|
||||
} else if (prefs->streamSrcSize > 0) {
|
||||
/* unknown source size; use the declared stream size */
|
||||
pledgedSrcSize = prefs->streamSrcSize;
|
||||
CHECK( ZSTD_CCtx_setPledgedSrcSize(ress.cctx, prefs->streamSrcSize) );
|
||||
CHECK( ZSTD_CCtx_setPledgedSrcSize(ress->cctx, prefs->streamSrcSize) );
|
||||
}
|
||||
|
||||
{ int windowLog;
|
||||
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 (prefs->ldmFlag) {
|
||||
/* 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 {
|
||||
size_t stillToFlush;
|
||||
/* Fill input Buffer */
|
||||
size_t const inSize = AIO_ReadPool_fillBuffer(ress.readCtx, ZSTD_CStreamInSize());
|
||||
ZSTD_inBuffer inBuff = setInBuffer( ress.readCtx->srcBuffer, ress.readCtx->srcBufferLoaded, 0 );
|
||||
size_t const inSize = FIO_SyncCompressIO_fillBuffer(syncIO, ZSTD_CStreamInSize());
|
||||
ZSTD_inBuffer inBuff = setInBuffer( syncIO->srcBuffer, syncIO->srcBufferLoaded, 0 );
|
||||
DISPLAYLEVEL(6, "fread %u bytes from source \n", (unsigned)inSize);
|
||||
*readsize += inSize;
|
||||
|
||||
if ((ress.readCtx->srcBufferLoaded == 0) || (*readsize == fileSize))
|
||||
if ((syncIO->srcBufferLoaded == 0) || (*readsize == fileSize))
|
||||
directive = ZSTD_e_end;
|
||||
|
||||
stillToFlush = 1;
|
||||
|
|
@ -1560,10 +1823,10 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||
|| (directive == ZSTD_e_end && stillToFlush != 0) ) {
|
||||
|
||||
size_t const oldIPos = inBuff.pos;
|
||||
ZSTD_outBuffer outBuff = setOutBuffer( writeJob->buffer, writeJob->bufferSize, 0 );
|
||||
size_t const toFlushNow = ZSTD_toFlushNow(ress.cctx);
|
||||
CHECK_V(stillToFlush, ZSTD_compressStream2(ress.cctx, &outBuff, &inBuff, directive));
|
||||
AIO_ReadPool_consumeBytes(ress.readCtx, inBuff.pos - oldIPos);
|
||||
ZSTD_outBuffer outBuff = setOutBuffer( syncIO->outBuffer, syncIO->outCapacity, 0 );
|
||||
size_t const toFlushNow = ZSTD_toFlushNow(ress->cctx);
|
||||
CHECK_V(stillToFlush, ZSTD_compressStream2(ress->cctx, &outBuff, &inBuff, directive));
|
||||
FIO_SyncCompressIO_consumeBytes(syncIO, inBuff.pos - oldIPos);
|
||||
|
||||
/* count stats */
|
||||
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",
|
||||
(unsigned)directive, (unsigned)inBuff.pos, (unsigned)inBuff.size, (unsigned)outBuff.pos);
|
||||
if (outBuff.pos) {
|
||||
writeJob->usedBufferSize = outBuff.pos;
|
||||
AIO_WritePool_enqueueAndReacquireWriteJob(&writeJob);
|
||||
FIO_SyncCompressIO_commitOut(syncIO, syncIO->outBuffer, outBuff.pos);
|
||||
compressedfilesize += outBuff.pos;
|
||||
}
|
||||
|
||||
/* adaptive mode : statistics measurement and speed correction */
|
||||
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();
|
||||
|
||||
|
|
@ -1654,14 +1916,14 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||
if (compressionLevel > ZSTD_maxCLevel()) compressionLevel = ZSTD_maxCLevel();
|
||||
if (compressionLevel > prefs->maxAdaptLevel) compressionLevel = prefs->maxAdaptLevel;
|
||||
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) {
|
||||
DISPLAYLEVEL(6, "faster speed , lighter compression \n")
|
||||
compressionLevel --;
|
||||
if (compressionLevel < prefs->minAdaptLevel) compressionLevel = prefs->minAdaptLevel;
|
||||
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;
|
||||
|
||||
|
|
@ -1671,7 +1933,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||
|
||||
/* display notification */
|
||||
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;
|
||||
UTIL_HumanReadableSize_t const buffered_hrs = UTIL_makeHumanReadableSize(zfp.ingested - 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);
|
||||
}
|
||||
|
||||
AIO_WritePool_releaseIoJob(writeJob);
|
||||
AIO_WritePool_sparseWriteEnd(ressPtr->writeCtx);
|
||||
FIO_SyncCompressIO_finish(syncIO);
|
||||
|
||||
return compressedfilesize;
|
||||
}
|
||||
|
|
@ -1732,7 +1993,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
|||
static int
|
||||
FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
||||
FIO_prefs_t* const prefs,
|
||||
cRess_t ress,
|
||||
cRess_t* ress,
|
||||
const char* dstFileName, const char* srcFileName,
|
||||
int compressionLevel)
|
||||
{
|
||||
|
|
@ -1747,12 +2008,12 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
|||
switch (prefs->compressionType) {
|
||||
default:
|
||||
case FIO_zstdCompression:
|
||||
compressedfilesize = FIO_compressZstdFrame(fCtx, prefs, &ress, srcFileName, fileSize, compressionLevel, &readsize);
|
||||
compressedfilesize = FIO_compressZstdFrame(fCtx, prefs, ress, srcFileName, fileSize, compressionLevel, &readsize);
|
||||
break;
|
||||
|
||||
case FIO_gzipCompression:
|
||||
#ifdef ZSTD_GZCOMPRESS
|
||||
compressedfilesize = FIO_compressGzFrame(&ress, srcFileName, fileSize, compressionLevel, &readsize);
|
||||
compressedfilesize = FIO_compressGzFrame(ress, srcFileName, fileSize, compressionLevel, &readsize);
|
||||
#else
|
||||
(void)compressionLevel;
|
||||
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_lzmaCompression:
|
||||
#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
|
||||
(void)compressionLevel;
|
||||
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:
|
||||
#ifdef ZSTD_LZ4COMPRESS
|
||||
compressedfilesize = FIO_compressLz4Frame(&ress, srcFileName, fileSize, compressionLevel, prefs->checksumFlag, &readsize);
|
||||
compressedfilesize = FIO_compressLz4Frame(ress, srcFileName, fileSize, compressionLevel, prefs->checksumFlag, &readsize);
|
||||
#else
|
||||
(void)compressionLevel;
|
||||
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,
|
||||
FIO_prefs_t* const prefs,
|
||||
cRess_t ress,
|
||||
cRess_t* ress,
|
||||
const char* dstFileName,
|
||||
const char* srcFileName,
|
||||
const stat_t* srcFileStat,
|
||||
|
|
@ -1840,8 +2101,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||
int transferStat = 0;
|
||||
int dstFd = -1;
|
||||
|
||||
assert(AIO_ReadPool_getFile(ress.readCtx) != NULL);
|
||||
if (AIO_WritePool_getFile(ress.writeCtx) == NULL) {
|
||||
if (ress->io.dstFile == NULL) {
|
||||
int dstFileInitialPermissions = DEFAULT_FILE_PERMISSIONS;
|
||||
if ( strcmp (srcFileName, stdinmark)
|
||||
&& strcmp (dstFileName, stdoutmark)
|
||||
|
|
@ -1852,15 +2112,13 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||
|
||||
closeDstFile = 1;
|
||||
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 */
|
||||
dstFd = fileno(dstFile);
|
||||
AIO_WritePool_setFile(ress.writeCtx, dstFile);
|
||||
FIO_SyncCompressIO_setDst(&ress->io, dstFile);
|
||||
}
|
||||
/* 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.
|
||||
*/
|
||||
/* Must only be added after FIO_openDstFile() succeeds. */
|
||||
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);
|
||||
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));
|
||||
result=1;
|
||||
}
|
||||
|
|
@ -1883,10 +2141,9 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
|
|||
UTIL_utime(dstFileName, srcFileStat);
|
||||
}
|
||||
|
||||
if ( (result != 0) /* operation failure */
|
||||
&& strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */
|
||||
) {
|
||||
FIO_removeFile(dstFileName); /* remove compression artefact; note don't do anything special if remove() fails */
|
||||
if ( (result != 0)
|
||||
&& strcmp(dstFileName, stdoutmark) ) {
|
||||
FIO_removeFile(dstFileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2020,7 +2277,7 @@ static const char *compressedFileExtensions[] = {
|
|||
static int
|
||||
FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
||||
FIO_prefs_t* const prefs,
|
||||
cRess_t ress,
|
||||
cRess_t* ress,
|
||||
const char* dstFileName,
|
||||
const char* srcFileName,
|
||||
int compressionLevel)
|
||||
|
|
@ -2042,7 +2299,7 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
|||
}
|
||||
|
||||
/* 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);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -2061,23 +2318,21 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
|
|||
srcFile = FIO_openSrcFile(prefs, srcFileName, &srcFileStat);
|
||||
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 */
|
||||
fileSize = UTIL_getFileSizeStat(&srcFileStat);
|
||||
if(fileSize != UTIL_FILESIZE_UNKNOWN && fileSize < ZSTD_BLOCKSIZE_MAX * 3) {
|
||||
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);
|
||||
}
|
||||
(void)fileSize;
|
||||
|
||||
AIO_ReadPool_setFile(ress.readCtx, srcFile);
|
||||
FIO_SyncCompressIO_setSrc(&ress->io, srcFile);
|
||||
result = FIO_compressFilename_dstFile(
|
||||
fCtx, prefs, ress,
|
||||
dstFileName, srcFileName,
|
||||
&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 */
|
||||
&& result == 0 /* success */
|
||||
|
|
@ -2118,7 +2373,7 @@ void FIO_displayCompressionParameters(const FIO_prefs_t* prefs)
|
|||
DISPLAY("%s", INDEX(sparseOptions, prefs->sparseFileSupport));
|
||||
DISPLAY("%s", prefs->dictIDFlag ? "" : " --no-dictID");
|
||||
DISPLAY("%s", INDEX(checkSumOptions, prefs->checksumFlag));
|
||||
DISPLAY(" --block-size=%d", prefs->blockSize);
|
||||
DISPLAY(" --jobsize=%d", prefs->jobSize);
|
||||
if (prefs->adaptiveMode)
|
||||
DISPLAY(" --adapt=min=%d,max=%d", prefs->minAdaptLevel, prefs->maxAdaptLevel);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
return result;
|
||||
|
|
@ -2241,13 +2498,13 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
|||
if (dstFile == NULL) { /* could not open outFileName */
|
||||
error = 1;
|
||||
} else {
|
||||
AIO_WritePool_setFile(ress.writeCtx, dstFile);
|
||||
FIO_SyncCompressIO_setDst(&ress.io, dstFile);
|
||||
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++;
|
||||
error |= status;
|
||||
}
|
||||
if (AIO_WritePool_closeFile(ress.writeCtx))
|
||||
if (FIO_SyncCompressIO_closeDst(&ress.io))
|
||||
EXM_THROW(29, "Write error (%s) : cannot properly close %s",
|
||||
strerror(errno), outFileName);
|
||||
}
|
||||
|
|
@ -2271,7 +2528,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
|||
} else {
|
||||
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++;
|
||||
error |= status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel);
|
||||
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_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag);
|
||||
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 dictIDFlag;
|
||||
int checksumFlag;
|
||||
int blockSize;
|
||||
int jobSize;
|
||||
int overlapLog;
|
||||
int adaptiveMode;
|
||||
int useRowMatchFinder;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|| defined __x86_64__ || defined _M_X64 /* x86 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(__riscv) && __riscv_xlen == 64) /* RISC-V 64-bit */ \
|
||||
|| defined _LP64 || defined __LP64__ /* NetBSD, OpenBSD */ || defined __64BIT__ /* AIX */ || defined _ADDR64 /* Cray */ \
|
||||
|| (defined __SIZEOF_POINTER__ && __SIZEOF_POINTER__ == 8) /* gcc */
|
||||
# if !defined(__64BIT__)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue