Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b53da1f6f4 | ||
|
|
693aa7bad2 | ||
|
|
1eba76a2d1 | ||
|
|
b9302410bf | ||
|
|
0118fe65ff | ||
|
|
608bacf6cb | ||
|
|
c0c38ba1db | ||
|
|
5a3e16f0c2 | ||
|
|
2c94f9fc61 | ||
|
|
695181c2e0 | ||
|
|
20821a46f4 | ||
|
|
1715601e55 | ||
|
|
07d7ebe448 | ||
|
|
67a426c322 | ||
|
|
4432dac93b | ||
|
|
de9de869a3 | ||
|
|
c1a244d534 | ||
|
|
c48889f097 | ||
|
|
ebc2dfa821 | ||
|
|
634bfd339f | ||
|
|
8b97931ae1 | ||
|
|
dff4a0e867 | ||
|
|
9fb4a42c7b | ||
|
|
515807182f | ||
|
|
edf2b1176d | ||
|
|
eace4abc25 | ||
|
|
756bd59322 | ||
|
|
77ae664ba6 | ||
|
|
ea288e0d8e | ||
|
|
cd1551d261 | ||
|
|
7222614a19 | ||
|
|
e4b914e663 | ||
|
|
49a9e070f5 | ||
|
|
d2dd35ae65 | ||
|
|
413b3198b0 | ||
|
|
b9dd821441 | ||
|
|
d1a6d080cf | ||
|
|
d2b7f2e27a | ||
|
|
eed64d75f4 | ||
|
|
316f3d2224 | ||
|
|
a51511e7a7 | ||
|
|
3c6f5d5eca | ||
|
|
21697b9c9e | ||
|
|
5d1fec8ce1 | ||
|
|
a3feed8dcd | ||
|
|
3d6c903056 | ||
|
|
3b1aba42cc | ||
|
|
0f18059a4e | ||
|
|
b5fd348a85 | ||
|
|
5df2a21f1e | ||
|
|
e50f88ca4c | ||
|
|
27498ff00f | ||
|
|
c4d54ab9bf | ||
|
|
2fa4c8c405 | ||
|
|
6e390ced1f | ||
|
|
0933775d79 | ||
|
|
16ec1cf355 | ||
|
|
713d4953f7 | ||
|
|
6c0bfc468c | ||
|
|
a1d7b9d654 | ||
|
|
24d59a655d | ||
|
|
0388054aab | ||
|
|
ac95a30455 | ||
|
|
4d6c78fb89 | ||
|
|
eb1a09df61 | ||
|
|
029f974ddc | ||
|
|
c7e42e147b | ||
|
|
a80b10f5e6 | ||
|
|
527a20c3cd | ||
|
|
3cbdbb888b | ||
|
|
ce6d1b9376 | ||
|
|
74d65eaa92 | ||
|
|
3835957b2d | ||
|
|
0f1a52b349 | ||
|
|
d7db928f72 | ||
|
|
aec1e8c715 | ||
|
|
45ee23f6a1 | ||
|
|
221e4659cd | ||
|
|
9b7f9d26d5 | ||
|
|
61db590ad8 | ||
|
|
aad85f19f0 | ||
|
|
04139c3ff2 | ||
|
|
61b63e9060 | ||
|
|
c03e1305ff | ||
|
|
390e050b1d | ||
|
|
59b2c596d7 | ||
|
|
99dde00fc9 | ||
|
|
d1c0ae9e6c | ||
|
|
3d91ab74a1 | ||
|
|
adb54293ab | ||
|
|
08fef036ec | ||
|
|
c79411a483 | ||
|
|
f2c0312889 | ||
|
|
f7cffb5d9d | ||
|
|
91e6480458 | ||
|
|
9b0772177c | ||
|
|
a2adc6df9f | ||
|
|
a774c57973 | ||
|
|
b2bff75a7a | ||
|
|
444c4650a0 | ||
|
|
bb6ca68713 | ||
|
|
7736549bea | ||
|
|
f39178b445 | ||
|
|
c62eb05964 | ||
|
|
3ac842d6cc | ||
|
|
f520f6dfbe | ||
|
|
8884cb887d | ||
|
|
74f85818a6 | ||
|
|
552efcac2d | ||
|
|
a294a19990 | ||
|
|
e59c9459a5 | ||
|
|
e2ad174d73 | ||
|
|
2636f53619 | ||
|
|
856f38e6c5 | ||
|
|
54a4998a80 | ||
|
|
e926e9c4c3 | ||
|
|
f9b1e711ba | ||
|
|
824dff4917 | ||
|
|
b5e990dc08 | ||
|
|
b9748757b0 | ||
|
|
134be2731a | ||
|
|
874a590e5c | ||
|
|
9f327c02fd | ||
|
|
f5b3f64d3f | ||
|
|
aee3dc877f | ||
|
|
d6e3de77dc | ||
|
|
e0d5eca8fa | ||
|
|
1e65711ca5 | ||
|
|
7e6729055a | ||
|
|
0bad3e5c0f | ||
|
|
7c2a17edf6 | ||
|
|
649a766220 | ||
|
|
b45d22c851 | ||
|
|
927859f5e8 | ||
|
|
8b6a4b5b7c | ||
|
|
7e6c53c7fe | ||
|
|
e7b782087a | ||
|
|
1d6d64afa3 | ||
|
|
0766540b59 | ||
|
|
821d9acd17 | ||
|
|
69085db61c | ||
|
|
33b73db33c | ||
|
|
c416015ab5 | ||
|
|
9ae0dd9336 | ||
|
|
92a2b5ccc9 | ||
|
|
3324e87cff | ||
|
|
2901b5e675 | ||
|
|
7a620b190e | ||
|
|
f9802d80a0 | ||
|
|
4f7584e7a3 | ||
|
|
17222654bf | ||
|
|
c2c9b8a7ec | ||
|
|
22b7bff2bc | ||
|
|
ea52fc3606 | ||
|
|
7c1a79f232 | ||
|
|
d1a6a9d285 | ||
|
|
5a6d3eef2b | ||
|
|
fd5b608f1c | ||
|
|
f933668d3f | ||
|
|
cefdc023f7 | ||
|
|
890d85bdb4 | ||
|
|
9866148e22 | ||
|
|
f011f639de | ||
|
|
0d793a675a | ||
|
|
a077a6a0a9 | ||
|
|
58476bcf7f | ||
|
|
9d31c704d5 | ||
|
|
a98a6e2091 | ||
|
|
e856052576 | ||
|
|
66e811d782 | ||
|
|
bc0a1e4d59 | ||
|
|
a0835b5bab | ||
|
|
ff2f888d56 | ||
|
|
3fd21d5438 | ||
|
|
7f8be046b9 | ||
|
|
cfff4c1cd5 | ||
|
|
603829d3d2 | ||
|
|
f1585fefa2 | ||
|
|
dd1a7e41ee | ||
|
|
d4f7d75f84 | ||
|
|
20afffefbc | ||
|
|
f1225b186e | ||
|
|
f2ac2b7bcf | ||
|
|
8429525de0 | ||
|
|
5c41490bfe | ||
|
|
339d8ba103 | ||
|
|
7e11bd012b | ||
|
|
585196353d | ||
|
|
8233f55df8 | ||
|
|
52aa7f47dd | ||
|
|
9a9d3f76c4 | ||
|
|
f9884036c2 | ||
|
|
9648bf027b | ||
|
|
eacf1b3bc3 | ||
|
|
f78917cdd3 | ||
|
|
7c495e8ea2 | ||
|
|
ceadfa2444 | ||
|
|
a7cb4af573 | ||
|
|
87dcf71115 | ||
|
|
7f09cdc8a8 | ||
|
|
54cc01c5be | ||
|
|
456ca2aa06 | ||
|
|
792fdf84f8 | ||
|
|
3536e9d5ff | ||
|
|
d4d1e45bcb | ||
|
|
d5eb7d1569 | ||
|
|
c11db9c8b5 | ||
|
|
4680d817c0 | ||
|
|
ae85676d44 | ||
|
|
ce34dc39a0 | ||
|
|
0b39531d75 | ||
|
|
9b8f337357 |
+5
-31
@@ -31,38 +31,11 @@ jobs:
|
||||
command: |
|
||||
make gnu90build; make clean
|
||||
make gnu99build; make clean
|
||||
make ppc64build; make clean
|
||||
make ppcbuild ; make clean
|
||||
make armbuild ; make clean
|
||||
make ppc64build V=1; make clean
|
||||
make ppcbuild V=1; make clean
|
||||
make armbuild V=1; make clean
|
||||
make -C tests test-legacy test-longmatch; make clean
|
||||
make -C lib libzstd-nomt; make clean
|
||||
# This step is only run on release tags.
|
||||
# It publishes the source tarball as artifacts and if the GITHUB_TOKEN
|
||||
# environment variable is set it will publish the source tarball to the
|
||||
# tagged release.
|
||||
publish-github-release:
|
||||
docker:
|
||||
- image: fbopensource/zstd-circleci-primary:0.0.1
|
||||
environment:
|
||||
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Publish
|
||||
command: |
|
||||
export VERSION=$(echo $CIRCLE_TAG | tail -c +2)
|
||||
export ZSTD_VERSION=zstd-$VERSION
|
||||
git archive $CIRCLE_TAG --prefix $ZSTD_VERSION/ --format tar \
|
||||
-o $ZSTD_VERSION.tar
|
||||
sha256sum $ZSTD_VERSION.tar > $ZSTD_VERSION.tar.sha256
|
||||
zstd -19 $ZSTD_VERSION.tar
|
||||
sha256sum $ZSTD_VERSION.tar.zst > $ZSTD_VERSION.tar.zst.sha256
|
||||
gzip -k -9 $ZSTD_VERSION.tar
|
||||
sha256sum $ZSTD_VERSION.tar.gz > $ZSTD_VERSION.tar.gz.sha256
|
||||
mkdir -p $CIRCLE_ARTIFACTS
|
||||
cp $ZSTD_VERSION.tar* $CIRCLE_ARTIFACTS
|
||||
- store_artifacts:
|
||||
path: /tmp/circleci-artifacts
|
||||
# This step should only be run in a cron job
|
||||
regression-test:
|
||||
docker:
|
||||
@@ -143,8 +116,9 @@ workflows:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release
|
||||
- dev
|
||||
- master
|
||||
jobs:
|
||||
# Run daily long regression tests
|
||||
- regression-test
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ task:
|
||||
name: FreeBSD (shortest)
|
||||
freebsd_instance:
|
||||
matrix:
|
||||
image_family: freebsd-12-1
|
||||
image_family: freebsd-12-2
|
||||
# The stable 11.3 image causes "Agent is not responding" so use a snapshot
|
||||
image_family: freebsd-11-3-snap
|
||||
install_script: pkg install -y gmake coreutils
|
||||
|
||||
@@ -2,14 +2,13 @@ name: generic-dev
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ dev, master, actionsTest ]
|
||||
branches: [ dev, release, actionsTest ]
|
||||
|
||||
jobs:
|
||||
|
||||
# Dev PR jobs that still have to be migrated from travis
|
||||
#
|
||||
# icc (need self-hosted)
|
||||
# versionTag
|
||||
# versionTag (only on release tags)
|
||||
# valgrindTest (keeps failing for some reason. need investigation)
|
||||
# staticAnalyze (need trusty so need self-hosted)
|
||||
# pcc-fuzz: (need trusty so need self-hosted)
|
||||
@@ -19,7 +18,7 @@ jobs:
|
||||
# I need admins permissions to the repo for that it looks like
|
||||
# So I'm tabling that for now
|
||||
#
|
||||
# The master branch exclusive jobs will be in a separate
|
||||
# The release branch exclusive jobs will be in a separate
|
||||
# workflow file (the osx tests and meson build that is)
|
||||
|
||||
benchmarking:
|
||||
@@ -36,22 +35,34 @@ jobs:
|
||||
- name: make test
|
||||
run: make test
|
||||
|
||||
gcc-6-7-libzstd:
|
||||
check-32bit: # designed to catch https://github.com/facebook/zstd/issues/2428
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: gcc-6 + gcc-7 + libzstdmt compilation
|
||||
- name: make check on 32-bit
|
||||
run: |
|
||||
make gcc6install gcc7install
|
||||
CC=gcc-6 CFLAGS=-Werror make -j all
|
||||
make clean
|
||||
sudo apt update
|
||||
APT_PACKAGES="gcc-multilib" make apt-install
|
||||
CFLAGS="-m32 -O1 -fstack-protector" make check V=1
|
||||
|
||||
gcc-7-libzstd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: gcc-7 + libzstdmt compilation
|
||||
run: |
|
||||
make gcc7install
|
||||
CC=gcc-7 CFLAGS=-Werror make -j all
|
||||
make clean
|
||||
LDFLAGS=-Wl,--no-undefined make -C lib libzstd-mt
|
||||
make -C tests zbufftest-dll
|
||||
|
||||
# candidate test (to check) : underlink test
|
||||
# LDFLAGS=-Wl,--no-undefined : will make the linker fail if dll is underlinked
|
||||
# zbufftest-dll : test that a user program can link to multi-threaded libzstd without specifying -pthread
|
||||
|
||||
gcc-8-asan-ubsan-testzstd:
|
||||
runs-on: ubuntu-16.04 # fails on 18.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: gcc-8 + ASan + UBSan + Test Zstd
|
||||
@@ -59,30 +70,32 @@ jobs:
|
||||
make gcc8install
|
||||
CC=gcc-8 CFLAGS="-Werror" make -j all
|
||||
make clean
|
||||
CC=gcc-8 make -j uasan-test-zstd </dev/null
|
||||
CC=gcc-8 make -j uasan-test-zstd </dev/null V=1
|
||||
|
||||
gcc-6-asan-ubsan-testzstd-32bit:
|
||||
gcc-asan-ubsan-testzstd-32bit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: gcc-6 + ASan + UBSan + Test Zstd, 32bit mode
|
||||
- name: ASan + UBSan + Test Zstd, 32bit mode
|
||||
run: |
|
||||
make gcc6install libc6install
|
||||
CC=gcc-6 CFLAGS="-Werror -m32" make -j all32
|
||||
make libc6install
|
||||
CFLAGS="-Werror -m32" make -j all32
|
||||
make clean
|
||||
CC=gcc-6 make -j uasan-test-zstd32
|
||||
make -j uasan-test-zstd32 V=1
|
||||
|
||||
clang-38-msan-testzstd:
|
||||
runs-on: ubuntu-16.04 # fails on 18.04
|
||||
clang-msan-testzstd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: clang-3.8 + MSan + Test Zstd
|
||||
- name: clang + MSan + Test Zstd
|
||||
run: |
|
||||
# make clang38install (doesn't work)
|
||||
sudo apt-add-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8 main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-3.8
|
||||
CC=clang-3.8 make clean msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0
|
||||
sudo apt-get install clang
|
||||
CC=clang make msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0 V=1
|
||||
|
||||
# Note : external libraries must be turned off when using MSAN tests,
|
||||
# because they are not msan-instrumented,
|
||||
# so any data coming from these libraries is always considered "uninitialized"
|
||||
|
||||
cmake-build-and-test-check:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -104,26 +117,14 @@ jobs:
|
||||
make gcc8install
|
||||
CC=gcc-8 FUZZER_FLAGS="--long-tests" make clean uasan-fuzztest
|
||||
|
||||
gcc-6-asan-ubsan-fuzz32:
|
||||
gcc-asan-ubsan-fuzz32:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: gcc-6 + ASan + UBSan + Fuzz Test 32bit
|
||||
- name: ASan + UBSan + Fuzz Test 32bit
|
||||
run: |
|
||||
make gcc6install libc6install
|
||||
CC=gcc-6 CFLAGS="-O2 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest
|
||||
|
||||
clang-38-msan-fuzz:
|
||||
runs-on: ubuntu-16.04 # fails on 18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: clang-3.8 + MSan + Fuzz Test
|
||||
run: |
|
||||
# make clang38install (doesn't work)
|
||||
sudo apt-add-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8 main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-3.8
|
||||
CC=clang-3.8 make clean msan-fuzztest
|
||||
make libc6install
|
||||
CFLAGS="-O2 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest
|
||||
|
||||
asan-ubsan-msan-regression:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -147,7 +148,7 @@ jobs:
|
||||
make clean
|
||||
make c99build
|
||||
make clean
|
||||
make travis-install
|
||||
make travis-install # just ensures `make install` works
|
||||
|
||||
mingw-cross-compilation:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -189,21 +190,25 @@ jobs:
|
||||
tar -xf shellcheck-v0.7.1.linux.x86_64.tar.xz
|
||||
shellcheck-v0.7.1/shellcheck --shell=sh --severity=warning --exclude=SC2010 tests/playTests.sh
|
||||
|
||||
icc:
|
||||
name: icc-check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: install icc
|
||||
run: |
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt-get -qqq update
|
||||
sudo apt-get install -y wget build-essential pkg-config cmake ca-certificates gnupg
|
||||
sudo wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||
sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||
sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y intel-basekit intel-hpckit
|
||||
- uses: actions/checkout@v2
|
||||
- name: make check
|
||||
run: |
|
||||
make CC=/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc check
|
||||
# For reference : icc tests
|
||||
# icc tests are currently failing on Github Actions, likely to issues during installation stage
|
||||
# To be fixed later
|
||||
#
|
||||
# icc:
|
||||
# name: icc-check
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: install icc
|
||||
# run: |
|
||||
# export DEBIAN_FRONTEND=noninteractive
|
||||
# sudo apt-get -qqq update
|
||||
# sudo apt-get install -y wget build-essential pkg-config cmake ca-certificates gnupg
|
||||
# sudo wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||
# sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
|
||||
# sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main"
|
||||
# sudo apt-get update
|
||||
# sudo apt-get install -y intel-basekit intel-hpckit
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: make check
|
||||
# run: |
|
||||
# make CC=/opt/intel/oneapi/compiler/latest/linux/bin/intel64/icc check
|
||||
|
||||
@@ -2,10 +2,10 @@ name: generic-release
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
# This will eventually only be for pushes to master
|
||||
# This will eventually only be for pushes to release
|
||||
# but for dogfooding purposes, I'm running it even
|
||||
# on dev pushes
|
||||
branches: [ dev, master, actionsTest ]
|
||||
branches: [ dev, release, actionsTest ]
|
||||
|
||||
jobs:
|
||||
# missing jobs
|
||||
@@ -34,23 +34,21 @@ jobs:
|
||||
make -C tests test-zbuff
|
||||
|
||||
tsan:
|
||||
runs-on: ubuntu-16.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: thread sanitizer
|
||||
run: |
|
||||
sudo apt-add-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.8 main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-3.8
|
||||
CC=clang-3.8 make tsan-test-zstream
|
||||
CC=clang-3.8 make tsan-fuzztest
|
||||
CC=clang make tsan-test-zstream
|
||||
CC=clang make tsan-fuzztest
|
||||
|
||||
zlib-wrapper:
|
||||
runs-on: ubuntu-16.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: zlib wrapper test
|
||||
run: |
|
||||
make gpp6install valgrindinstall
|
||||
make valgrindinstall
|
||||
make -C zlibWrapper test
|
||||
make -C zlibWrapper valgrindTest
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ name: linux-kernel
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ dev, master, actionsTest ]
|
||||
branches: [ dev, release, actionsTest ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
@@ -6,7 +6,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sanitizer: [address, undefined, memory]
|
||||
sanitizer: [address, undefined]
|
||||
steps:
|
||||
- name: Build Fuzzers (${{ matrix.sanitizer }})
|
||||
id: build
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
name: publish-release-artifacts
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
publish-release-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Archive
|
||||
env:
|
||||
RELEASE_SIGNING_KEY: ${{ secrets.RELEASE_SIGNING_KEY }}
|
||||
RELEASE_SIGNING_KEY_PASSPHRASE: ${{ secrets.RELEASE_SIGNING_KEY_PASSPHRASE }}
|
||||
run: |
|
||||
# compute file name
|
||||
export TAG="$(echo "$GITHUB_REF" | sed -n 's_^refs/tags/__p')"
|
||||
if [ -z "$TAG" ]; then
|
||||
echo "action must be run on a tag. GITHUB_REF is not a tag: $GITHUB_REF"
|
||||
exit 1
|
||||
fi
|
||||
# Attempt to extract "1.2.3" from "v1.2.3" to maintain artifact name backwards compat.
|
||||
# Otherwise, degrade to using full tag.
|
||||
export VERSION="$(echo "$TAG" | sed 's_^v\([0-9]\+\.[0-9]\+\.[0-9]\+\)$_\1_')"
|
||||
export ZSTD_VERSION="zstd-$VERSION"
|
||||
|
||||
# archive
|
||||
git archive $TAG \
|
||||
--prefix $ZSTD_VERSION/ \
|
||||
--format tar \
|
||||
-o $ZSTD_VERSION.tar
|
||||
|
||||
# Do the rest of the work in a sub-dir so we can glob everything we want to publish.
|
||||
mkdir artifacts/
|
||||
mv $ZSTD_VERSION.tar artifacts/
|
||||
cd artifacts/
|
||||
|
||||
# compress
|
||||
zstd -k -19 $ZSTD_VERSION.tar
|
||||
gzip -k -9 $ZSTD_VERSION.tar
|
||||
|
||||
# we only publish the compressed tarballs
|
||||
rm $ZSTD_VERSION.tar
|
||||
|
||||
# hash
|
||||
sha256sum $ZSTD_VERSION.tar.zst > $ZSTD_VERSION.tar.zst.sha256
|
||||
sha256sum $ZSTD_VERSION.tar.gz > $ZSTD_VERSION.tar.gz.sha256
|
||||
|
||||
# sign
|
||||
if [ -n "$RELEASE_SIGNING_KEY" ]; then
|
||||
export GPG_BATCH_OPTS="--batch --no-use-agent --pinentry-mode loopback --no-tty --yes"
|
||||
echo "$RELEASE_SIGNING_KEY" | gpg $GPG_BATCH_OPTS --import
|
||||
gpg $GPG_BATCH_OPTS --armor --sign --sign-with signing@zstd.net --detach-sig --passphrase "$RELEASE_SIGNING_KEY_PASSPHRASE" --output $ZSTD_VERSION.tar.zst.sig $ZSTD_VERSION.tar.zst
|
||||
gpg $GPG_BATCH_OPTS --armor --sign --sign-with signing@zstd.net --detach-sig --passphrase "$RELEASE_SIGNING_KEY_PASSPHRASE" --output $ZSTD_VERSION.tar.gz.sig $ZSTD_VERSION.tar.gz
|
||||
fi
|
||||
|
||||
- name: Publish
|
||||
uses: skx/github-action-publish-binaries@release-1.3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
args: artifacts/*
|
||||
+9
-114
@@ -8,6 +8,7 @@ git:
|
||||
branches:
|
||||
only:
|
||||
- dev
|
||||
- release
|
||||
- master
|
||||
- travisTest
|
||||
|
||||
@@ -31,49 +32,6 @@ matrix:
|
||||
script:
|
||||
- make check
|
||||
|
||||
- name: make benchmarking
|
||||
script:
|
||||
- make benchmarking
|
||||
|
||||
- name: make test (complete)
|
||||
script:
|
||||
# DEVNULLRIGHTS : will request sudo rights to test permissions on /dev/null
|
||||
- DEVNULLRIGHTS=test make test
|
||||
|
||||
- name: gcc-6 + gcc-7 + libzstdmt compilation # ~ 6mn
|
||||
script:
|
||||
- make gcc6install gcc7install
|
||||
- CC=gcc-6 CFLAGS=-Werror make -j all
|
||||
- make clean
|
||||
- CC=gcc-7 CFLAGS=-Werror make -j all
|
||||
- make clean
|
||||
- LDFLAGS=-Wl,--no-undefined make -C lib libzstd-mt
|
||||
- make -C tests zbufftest-dll
|
||||
# LDFLAGS=-Wl,--no-undefined : will make the linker fail if dll is underlinked
|
||||
# zbufftest-dll : test that a user program can link to multi-threaded libzstd without specifying -pthread
|
||||
|
||||
- name: gcc-8 + ASan + UBSan + Test Zstd # ~6.5mn
|
||||
script:
|
||||
- make gcc8install
|
||||
- CC=gcc-8 CFLAGS="-Werror" make -j all
|
||||
- make clean
|
||||
- CC=gcc-8 make -j uasan-test-zstd </dev/null # test when stdin is not a tty
|
||||
|
||||
- name: gcc-6 + ASan + UBSan + Test Zstd, 32bit mode # ~4mn
|
||||
script:
|
||||
- make gcc6install libc6install
|
||||
- CC=gcc-6 CFLAGS="-Werror -m32" make -j all32
|
||||
- make clean
|
||||
- CC=gcc-6 make -j uasan-test-zstd32 # note : can complain about pointer overflow
|
||||
|
||||
- name: clang-3.8 + MSan + Test Zstd # ~3.5mn
|
||||
script:
|
||||
- make clang38install
|
||||
# External libraries must be turned off when using MSAN tests,
|
||||
# because they are not msan-instrumented,
|
||||
# so any data coming from these libraries is always considered "uninitialized"
|
||||
- CC=clang-3.8 make clean msan-test-zstd HAVE_ZLIB=0 HAVE_LZ4=0 HAVE_LZMA=0
|
||||
|
||||
- name: Minimal Decompressor Macros # ~5mn
|
||||
script:
|
||||
- make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror"
|
||||
@@ -85,51 +43,11 @@ matrix:
|
||||
- make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS"
|
||||
- make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS"
|
||||
|
||||
- name: cmake build and test check # ~6mn
|
||||
script:
|
||||
- make cmakebuild
|
||||
|
||||
- name: static analyzer scanbuild # ~26mn
|
||||
dist: trusty # note : it's important to pin down a version of static analyzer, since different versions report different false positives
|
||||
script:
|
||||
- make staticAnalyze
|
||||
|
||||
- name: gcc-8 + ASan + UBSan + Fuzz Test # ~19mn
|
||||
script:
|
||||
- make gcc8install
|
||||
- CC=gcc-8 make clean uasan-fuzztest
|
||||
|
||||
- name: gcc-6 + ASan + UBSan + Fuzz Test 32bit # ~15.5mn
|
||||
script:
|
||||
- make gcc6install libc6install
|
||||
- CC=gcc-6 CFLAGS="-O2 -m32" make uasan-fuzztest # can complain about pointer overflow
|
||||
|
||||
- name: clang-3.8 + MSan + Fuzz Test # ~14.5mn
|
||||
script:
|
||||
- make clang38install
|
||||
- CC=clang-3.8 make clean msan-fuzztest
|
||||
|
||||
- name: ASan + UBSan + MSan + Regression Test # ~ 4.5mn
|
||||
script:
|
||||
- make -j uasanregressiontest
|
||||
- make clean
|
||||
- make -j msanregressiontest
|
||||
|
||||
- name: C++, gnu90 and c99 compatibility # ~3mn
|
||||
script:
|
||||
- make cxxtest
|
||||
- make clean
|
||||
- make gnu90build
|
||||
- make clean
|
||||
- make c99build
|
||||
- make clean
|
||||
- make travis-install # just ensures `make install` works
|
||||
|
||||
- name: mingw cross-compilation
|
||||
script :
|
||||
- sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix;
|
||||
- CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CFLAGS="-Werror -O1" make zstd
|
||||
|
||||
- name: Valgrind + Fuzz Test Stack Mode # ~ 7mn
|
||||
script:
|
||||
- make valgrindinstall
|
||||
@@ -162,33 +80,28 @@ matrix:
|
||||
- make -C tests checkTag
|
||||
- tests/checkTag "$TRAVIS_BRANCH"
|
||||
|
||||
# tests for master branch and cron job only
|
||||
# tests for release branch and cron job only
|
||||
- name: OS-X # ~13mn
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
os: osx
|
||||
script:
|
||||
- make test
|
||||
- make -C lib all
|
||||
|
||||
- name: zbuff test
|
||||
if: branch = master
|
||||
script:
|
||||
- make -C tests test-zbuff
|
||||
|
||||
- name: Versions Compatibility Test # 11.5mn
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
script:
|
||||
- make -C tests versionsTest
|
||||
|
||||
- name: thread sanitizer # ~29mn
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
script:
|
||||
- make clang38install
|
||||
- CC=clang-3.8 make tsan-test-zstream
|
||||
- CC=clang-3.8 make tsan-fuzztest
|
||||
|
||||
- name: PPC64LE + Fuzz test # ~13mn
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
arch: ppc64le
|
||||
script:
|
||||
- cat /proc/cpuinfo
|
||||
@@ -196,40 +109,22 @@ matrix:
|
||||
|
||||
- name: Qemu PPC64 + Fuzz test # ~13mn, presumed Big-Endian (?)
|
||||
dist: trusty # note : PPC64 cross-compilation for Qemu tests seems broken on Xenial
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
script:
|
||||
- make ppcinstall
|
||||
- make ppc64fuzz
|
||||
|
||||
# note : we already have aarch64 tests on hardware
|
||||
- name: Qemu aarch64 + Fuzz Test (on Xenial) # ~14mn
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
dist: xenial
|
||||
script:
|
||||
- make arminstall
|
||||
- make aarch64fuzz
|
||||
|
||||
- name: zlib wrapper test # ~7.5mn
|
||||
if: branch = master
|
||||
script:
|
||||
- make gpp6install valgrindinstall
|
||||
- make -C zlibWrapper test
|
||||
- make -C zlibWrapper valgrindTest
|
||||
|
||||
- name: LZ4, thread pool, and partial libs tests # ~4mn
|
||||
if: branch = master
|
||||
script:
|
||||
- make lz4install
|
||||
- make -C tests test-lz4
|
||||
- make check < /dev/null | tee # mess with lz4 console detection
|
||||
- make clean
|
||||
- make -C tests test-pool
|
||||
- make clean
|
||||
- bash tests/libzstd_partial_builds.sh
|
||||
|
||||
# meson dedicated test
|
||||
- name: Xenial (Meson + clang) # ~15mn
|
||||
if: branch = master
|
||||
if: branch = release
|
||||
dist: xenial
|
||||
language: cpp
|
||||
compiler: clang
|
||||
|
||||
@@ -1,4 +1,33 @@
|
||||
v1.4.7
|
||||
v1.4.9 (Mar 1, 2021)
|
||||
bug: Use `umask()` to Constrain Created File Permissions (#2495, @felixhandte)
|
||||
bug: Make Simple Single-Pass Functions Ignore Advanced Parameters (#2498, @terrelln)
|
||||
api: Add (De)Compression Tracing Functionality (#2482, @terrelln)
|
||||
api: Support References to Multiple DDicts (#2446, @senhuang42)
|
||||
api: Add Function to Generate Skippable Frame (#2439, @senhuang42)
|
||||
perf: New Algorithms for the Long Distance Matcher (#2483, @mpu)
|
||||
perf: Performance Improvements for Long Distance Matcher (#2464, @mpu)
|
||||
perf: Don't Shrink Window Log when Streaming with a Dictionary (#2451, @terrelln)
|
||||
cli: Fix `--output-dir-mirror`'s Rejection of `..`-Containing Paths (#2512, @felixhandte)
|
||||
cli: Allow Input From Console When `-f`/`--force` is Passed (#2466, @felixhandte)
|
||||
cli: Improve Help Message (#2500, @senhuang42)
|
||||
tests: Remove Flaky Tests (#2455, #2486, #2445, @Cyan4973)
|
||||
tests: Correctly Invoke md5 Utility on NetBSD (#2492, @niacat)
|
||||
tests: Avoid Using `stat -c` on NetBSD (#2513, @felixhandte)
|
||||
build: Zstd CLI Can Now be Linked to Dynamic `libzstd` (#2457, #2454 @Cyan4973)
|
||||
build: Hide and Avoid Using Static-Only Symbols (#2501, #2504, @skitt)
|
||||
build: CMake: Enable Only C for lib/ and programs/ Projects (#2498, @concatime)
|
||||
build: CMake: Use `configure_file()` to Create the `.pc` File (#2462, @lazka)
|
||||
build: Fix Fuzzer Compiler Detection & Update UBSAN Flags (#2503, @terrelln)
|
||||
build: Add Guards for `_LARGEFILE_SOURCE` and `_LARGEFILE64_SOURCE` (#2444, @indygreg)
|
||||
build: Improve `zlibwrapper` Makefile (#2437, @Cyan4973)
|
||||
contrib: Add `recover_directory` Program (#2473, @terrelln)
|
||||
doc: Change License Year to 2021 (#2452 & #2465, @terrelln & @senhuang42)
|
||||
doc: Fix Typos (#2459, @ThomasWaldmann)
|
||||
|
||||
v1.4.8 (Dec 18, 2020)
|
||||
hotfix: wrong alignment of an internal buffer
|
||||
|
||||
v1.4.7 (Dec 16, 2020)
|
||||
perf: stronger --long mode at high compression levels, by @senhuang42
|
||||
perf: stronger --patch-from at high compression levels, thanks to --long improvements
|
||||
perf: faster dictionary compression at medium compression levels, by @felixhandte
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ possible.
|
||||
## Our Development Process
|
||||
New versions are being developed in the "dev" branch,
|
||||
or in their own feature branch.
|
||||
When they are deemed ready for a release, they are merged into "master".
|
||||
When they are deemed ready for a release, they are merged into "release".
|
||||
|
||||
As a consequences, all contributions must stage first through "dev"
|
||||
or their own feature branch.
|
||||
@@ -383,7 +383,7 @@ CI tests run every time a pull request (PR) is created or updated. The exact tes
|
||||
that get run will depend on the destination branch you specify. Some tests take
|
||||
longer to run than others. Currently, our CI is set up to run a short
|
||||
series of tests when creating a PR to the dev branch and a longer series of tests
|
||||
when creating a PR to the master branch. You can look in the configuration files
|
||||
when creating a PR to the release branch. You can look in the configuration files
|
||||
of the respective CI platform for more information on what gets run when.
|
||||
|
||||
Most people will just want to create a PR with the destination set to their local dev
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) 2015-2021, Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -48,7 +48,7 @@ allmost: allzstd zlibwrapper
|
||||
|
||||
# skip zwrapper, can't build that on alternate architectures without the proper zlib installed
|
||||
.PHONY: allzstd
|
||||
allzstd: lib-all
|
||||
allzstd: lib
|
||||
$(Q)$(MAKE) -C $(PRGDIR) all
|
||||
$(Q)$(MAKE) -C $(TESTDIR) all
|
||||
|
||||
@@ -57,9 +57,8 @@ all32:
|
||||
$(MAKE) -C $(PRGDIR) zstd32
|
||||
$(MAKE) -C $(TESTDIR) all32
|
||||
|
||||
.PHONY: lib lib-release libzstd.a
|
||||
lib-all : lib
|
||||
lib lib-release lib-all :
|
||||
.PHONY: lib lib-release
|
||||
lib lib-release :
|
||||
$(Q)$(MAKE) -C $(ZSTDDIR) $@
|
||||
|
||||
.PHONY: zstd zstd-release
|
||||
@@ -225,10 +224,10 @@ aarch64build: clean
|
||||
CC=aarch64-linux-gnu-gcc CFLAGS="-Werror" $(MAKE) allzstd
|
||||
|
||||
ppcbuild: clean
|
||||
CC=powerpc-linux-gnu-gcc CFLAGS="-m32 -Wno-attributes -Werror" $(MAKE) allzstd
|
||||
CC=powerpc-linux-gnu-gcc CFLAGS="-m32 -Wno-attributes -Werror" $(MAKE) -j allzstd
|
||||
|
||||
ppc64build: clean
|
||||
CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) allzstd
|
||||
CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) -j allzstd
|
||||
|
||||
armfuzz: clean
|
||||
CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest
|
||||
@@ -287,12 +286,11 @@ uasanregressiontest:
|
||||
msanregressiontest:
|
||||
$(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=memory" CXXFLAGS="-O3 -fsanitize=memory"
|
||||
|
||||
# run UBsan with -fsanitize-recover=signed-integer-overflow
|
||||
# due to a bug in UBsan when doing pointer subtraction
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63303
|
||||
# run UBsan with -fsanitize-recover=pointer-overflow
|
||||
# this only works with recent compilers such as gcc 8+
|
||||
|
||||
usan: clean
|
||||
$(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=undefined -Werror"
|
||||
$(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=undefined -Werror"
|
||||
|
||||
asan: clean
|
||||
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=address -Werror"
|
||||
@@ -310,10 +308,10 @@ asan32: clean
|
||||
$(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
|
||||
|
||||
uasan: clean
|
||||
$(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=address,undefined -Werror"
|
||||
$(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=address,undefined -Werror"
|
||||
|
||||
uasan-%: clean
|
||||
LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=address,undefined -Werror" $(MAKE) -C $(TESTDIR) $*
|
||||
LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=address,undefined -Werror" $(MAKE) -C $(TESTDIR) $*
|
||||
|
||||
tsan-%: clean
|
||||
LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread -Werror" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS=--no-big-tests
|
||||
|
||||
@@ -193,7 +193,7 @@ Zstandard is dual-licensed under [BSD](LICENSE) and [GPLv2](COPYING).
|
||||
|
||||
## Contributing
|
||||
|
||||
The "dev" branch is the one where all contributions are merged before reaching "master".
|
||||
If you plan to propose a patch, please commit into the "dev" branch, or its own feature branch.
|
||||
Direct commit to "master" are not permitted.
|
||||
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).
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ They consist of the following tests:
|
||||
|
||||
Long Tests
|
||||
----------
|
||||
Long tests run on all commits to `master` branch,
|
||||
Long tests run on all commits to `release` branch,
|
||||
and once a day on the current version of `dev` branch,
|
||||
on TravisCI.
|
||||
They consist of the following tests:
|
||||
|
||||
+9
-9
@@ -1,20 +1,20 @@
|
||||
# Following tests are run _only_ on master branch
|
||||
# To reproduce these tests, it's possible to push into a branch `appveyorTest`
|
||||
# or a branch `visual*`, they will intentionnally trigger `master` tests
|
||||
# Following tests are run _only_ on `release` branch
|
||||
# and on selected feature branch named `appveyorTest` or `visual*`
|
||||
|
||||
-
|
||||
version: 1.0.{build}
|
||||
branches:
|
||||
only:
|
||||
- release
|
||||
- master
|
||||
- appveyorTest
|
||||
- /appveyor*/
|
||||
- /visual*/
|
||||
environment:
|
||||
matrix:
|
||||
- COMPILER: "gcc"
|
||||
HOST: "mingw"
|
||||
PLATFORM: "x64"
|
||||
SCRIPT: "make allzstd MOREFLAGS=-static && make -C tests fullbench-lib"
|
||||
SCRIPT: "make allzstd MOREFLAGS=-static"
|
||||
ARTIFACT: "true"
|
||||
BUILD: "true"
|
||||
- COMPILER: "gcc"
|
||||
@@ -26,7 +26,7 @@
|
||||
- COMPILER: "clang"
|
||||
HOST: "mingw"
|
||||
PLATFORM: "x64"
|
||||
SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make allzstd"
|
||||
SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1"
|
||||
BUILD: "true"
|
||||
|
||||
- COMPILER: "gcc"
|
||||
@@ -92,9 +92,9 @@
|
||||
cd programs\ && 7z a -tzip -mx9 zstd-win-binary-%PLATFORM%.zip zstd.exe &&
|
||||
appveyor PushArtifact zstd-win-binary-%PLATFORM%.zip &&
|
||||
cp zstd.exe ..\bin\zstd.exe &&
|
||||
git clone --depth 1 --branch master https://github.com/facebook/zstd &&
|
||||
git clone --depth 1 --branch release https://github.com/facebook/zstd &&
|
||||
cd zstd &&
|
||||
git archive --format=tar master -o zstd-src.tar &&
|
||||
git archive --format=tar release -o zstd-src.tar &&
|
||||
..\zstd -19 zstd-src.tar &&
|
||||
appveyor PushArtifact zstd-src.tar.zst &&
|
||||
certUtil -hashfile zstd-src.tar.zst SHA256 > zstd-src.tar.zst.sha256.sig &&
|
||||
@@ -204,7 +204,7 @@
|
||||
- COMPILER: "clang"
|
||||
HOST: "mingw"
|
||||
PLATFORM: "x64"
|
||||
SCRIPT: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd"
|
||||
SCRIPT: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1"
|
||||
|
||||
- COMPILER: "visual"
|
||||
HOST: "visual"
|
||||
|
||||
@@ -480,6 +480,10 @@
|
||||
RelativePath="..\..\..\programs\zstdcli.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\programs\zstdcli_trace.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\lib\compress\zstdmt_compress.c"
|
||||
>
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
<ClCompile Include="..\..\..\programs\dibio.c" />
|
||||
<ClCompile Include="..\..\..\programs\fileio.c" />
|
||||
<ClCompile Include="..\..\..\programs\zstdcli.c" />
|
||||
<ClCompile Include="..\..\..\programs\zstdcli_trace.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\lib\common\pool.h" />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# in the COPYING file in the root directory of this source tree).
|
||||
# ################################################################
|
||||
|
||||
project(libzstd)
|
||||
project(libzstd C)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
||||
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
|
||||
@@ -137,7 +137,7 @@ endif ()
|
||||
if (UNIX OR MINGW)
|
||||
# pkg-config
|
||||
set(PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
set(EXEC_PREFIX "\\$$\{prefix}")
|
||||
set(EXEC_PREFIX "\${prefix}")
|
||||
set(LIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}")
|
||||
set(INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
||||
set(VERSION "${zstd_VERSION}")
|
||||
@@ -149,24 +149,13 @@ if (UNIX OR MINGW)
|
||||
string(SUBSTRING "${INCLUDEDIR}" ${PREFIX_LENGTH} -1 INCLUDEDIR_SUFFIX)
|
||||
|
||||
if ("${INCLUDEDIR_PREFIX}" STREQUAL "${PREFIX}")
|
||||
set(INCLUDEDIR_PREFIX "\\$$\{prefix}")
|
||||
set(INCLUDEDIR "\${prefix}${INCLUDEDIR_SUFFIX}")
|
||||
endif()
|
||||
if ("${LIBDIR_PREFIX}" STREQUAL "${PREFIX}")
|
||||
set(LIBDIR_PREFIX "\\$$\{exec_prefix}")
|
||||
set(LIBDIR "\${exec_prefix}${LIBDIR_SUFFIX}")
|
||||
endif()
|
||||
|
||||
add_custom_target(libzstd.pc ALL
|
||||
${CMAKE_COMMAND}
|
||||
-DIN=${LIBRARY_DIR}/libzstd.pc.in
|
||||
-DOUT="libzstd.pc"
|
||||
-DPREFIX="${PREFIX}"
|
||||
-DEXEC_PREFIX="${EXEC_PREFIX}"
|
||||
-DINCLUDEDIR="${INCLUDEDIR_PREFIX}${INCLUDEDIR_SUFFIX}"
|
||||
-DLIBDIR="${LIBDIR_PREFIX}${LIBDIR_SUFFIX}"
|
||||
-DVERSION="${VERSION}"
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig.cmake
|
||||
COMMENT "Creating pkg-config file")
|
||||
|
||||
configure_file("${LIBRARY_DIR}/libzstd.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
configure_file("${IN}" "${OUT}" @ONLY)
|
||||
@@ -7,7 +7,7 @@
|
||||
# in the COPYING file in the root directory of this source tree).
|
||||
# ################################################################
|
||||
|
||||
project(programs)
|
||||
project(programs C)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
|
||||
|
||||
@@ -32,7 +32,7 @@ if (MSVC)
|
||||
set(PlatformDependResources ${MSVC_RESOURCE_DIR}/zstd.rc)
|
||||
endif ()
|
||||
|
||||
add_executable(zstd ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/dibio.c ${PlatformDependResources})
|
||||
add_executable(zstd ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/dibio.c ${PROGRAMS_DIR}/zstdcli_trace.c ${PlatformDependResources})
|
||||
target_link_libraries(zstd ${PROGRAMS_ZSTD_LINK_TARGET})
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
target_link_libraries(zstd rt)
|
||||
@@ -75,7 +75,7 @@ if (UNIX)
|
||||
|
||||
add_executable(zstd-frugal ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/fileio.c)
|
||||
target_link_libraries(zstd-frugal ${PROGRAMS_ZSTD_LINK_TARGET})
|
||||
set_property(TARGET zstd-frugal APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_NOBENCH;ZSTD_NODICT")
|
||||
set_property(TARGET zstd-frugal APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_NOBENCH;ZSTD_NODICT;ZSTD_NOTRACE")
|
||||
endif ()
|
||||
|
||||
# Add multi-threading support definitions
|
||||
|
||||
@@ -22,6 +22,7 @@ libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'),
|
||||
join_paths(zstd_rootdir, 'lib/common/threading.c'),
|
||||
join_paths(zstd_rootdir, 'lib/common/pool.c'),
|
||||
join_paths(zstd_rootdir, 'lib/common/zstd_common.c'),
|
||||
join_paths(zstd_rootdir, 'lib/common/zstd_trace.c'),
|
||||
join_paths(zstd_rootdir, 'lib/common/error_private.c'),
|
||||
join_paths(zstd_rootdir, 'lib/common/xxhash.c'),
|
||||
join_paths(zstd_rootdir, 'lib/compress/hist.c'),
|
||||
|
||||
@@ -17,7 +17,8 @@ zstd_programs_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'),
|
||||
join_paths(zstd_rootdir, 'programs/benchfn.c'),
|
||||
join_paths(zstd_rootdir, 'programs/benchzstd.c'),
|
||||
join_paths(zstd_rootdir, 'programs/datagen.c'),
|
||||
join_paths(zstd_rootdir, 'programs/dibio.c')]
|
||||
join_paths(zstd_rootdir, 'programs/dibio.c'),
|
||||
join_paths(zstd_rootdir, 'programs/zstdcli_trace.c')]
|
||||
|
||||
zstd_c_args = libzstd_debug_cflags
|
||||
if use_multi_thread
|
||||
@@ -73,7 +74,7 @@ zstd_frugal_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'),
|
||||
executable('zstd-frugal',
|
||||
zstd_frugal_sources,
|
||||
dependencies: libzstd_dep,
|
||||
c_args: [ '-DZSTD_NOBENCH', '-DZSTD_NODICT' ],
|
||||
c_args: [ '-DZSTD_NOBENCH', '-DZSTD_NODICT', '-DZSTD_NOTRACE' ],
|
||||
install: true)
|
||||
|
||||
install_data(join_paths(zstd_rootdir, 'programs/zstdgrep'),
|
||||
|
||||
@@ -32,4 +32,4 @@ check_flipped_bits: check_flipped_bits.c $(ZSTDLIBDIR)/libzstd.a
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f check_flipped_bits
|
||||
rm -f check_flipped_bits
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
# ################################################################
|
||||
# Copyright (c) 2020-2020, Facebook, Inc.
|
||||
# Copyright (c) 2021-2021, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -27,6 +27,8 @@ SKIPPED_FILES = [
|
||||
"common/pool.h",
|
||||
"common/threading.c",
|
||||
"common/threading.h",
|
||||
"common/zstd_trace.c",
|
||||
"common/zstd_trace.h",
|
||||
"compress/zstdmt_compress.h",
|
||||
"compress/zstdmt_compress.c",
|
||||
]
|
||||
@@ -430,7 +432,7 @@ class Freestanding(object):
|
||||
external_xxhash: bool, xxh64_state: Optional[str],
|
||||
xxh64_prefix: Optional[str], rewritten_includes: [(str, str)],
|
||||
defs: [(str, Optional[str])], replaces: [(str, str)],
|
||||
undefs: [str], excludes: [str]
|
||||
undefs: [str], excludes: [str], seds: [str],
|
||||
):
|
||||
self._zstd_deps = zstd_deps
|
||||
self._mem = mem
|
||||
@@ -444,6 +446,7 @@ class Freestanding(object):
|
||||
self._replaces = replaces
|
||||
self._undefs = undefs
|
||||
self._excludes = excludes
|
||||
self._seds = seds
|
||||
|
||||
def _dst_lib_file_paths(self):
|
||||
"""
|
||||
@@ -471,7 +474,7 @@ class Freestanding(object):
|
||||
dst_path = os.path.join(self._dst_lib, lib_path)
|
||||
self._log(f"\tCopying: {src_path} -> {dst_path}")
|
||||
shutil.copyfile(src_path, dst_path)
|
||||
|
||||
|
||||
def _copy_source_lib(self):
|
||||
self._log("Copying source library into output library")
|
||||
|
||||
@@ -481,14 +484,14 @@ class Freestanding(object):
|
||||
for subdir in INCLUDED_SUBDIRS:
|
||||
src_dir = os.path.join(self._src_lib, subdir)
|
||||
dst_dir = os.path.join(self._dst_lib, subdir)
|
||||
|
||||
|
||||
assert os.path.exists(src_dir)
|
||||
os.makedirs(dst_dir, exist_ok=True)
|
||||
|
||||
for filename in os.listdir(src_dir):
|
||||
lib_path = os.path.join(subdir, filename)
|
||||
self._copy_file(lib_path)
|
||||
|
||||
|
||||
def _copy_zstd_deps(self):
|
||||
dst_zstd_deps = os.path.join(self._dst_lib, "common", "zstd_deps.h")
|
||||
self._log(f"Copying zstd_deps: {self._zstd_deps} -> {dst_zstd_deps}")
|
||||
@@ -508,7 +511,7 @@ class Freestanding(object):
|
||||
assert not (undef and value is not None)
|
||||
for filepath in self._dst_lib_file_paths():
|
||||
file = FileLines(filepath)
|
||||
|
||||
|
||||
def _hardwire_defines(self):
|
||||
self._log("Hardwiring macros")
|
||||
partial_preprocessor = PartialPreprocessor(self._defs, self._replaces, self._undefs)
|
||||
@@ -536,7 +539,7 @@ class Freestanding(object):
|
||||
skipped.append(line)
|
||||
if end_re.search(line) is not None:
|
||||
assert begin_re.search(line) is None
|
||||
self._log(f"\t\tRemoving excluded section: {exclude}")
|
||||
self._log(f"\t\tRemoving excluded section: {exclude}")
|
||||
for s in skipped:
|
||||
self._log(f"\t\t\t- {s}")
|
||||
emit = True
|
||||
@@ -559,12 +562,12 @@ class Freestanding(object):
|
||||
e = match.end('include')
|
||||
file.lines[i] = line[:s] + rewritten + line[e:]
|
||||
file.write()
|
||||
|
||||
|
||||
def _rewrite_includes(self):
|
||||
self._log("Rewriting includes")
|
||||
for original, rewritten in self._rewritten_includes:
|
||||
self._rewrite_include(original, rewritten)
|
||||
|
||||
|
||||
def _replace_xxh64_prefix(self):
|
||||
if self._xxh64_prefix is None:
|
||||
return
|
||||
@@ -576,7 +579,7 @@ class Freestanding(object):
|
||||
)
|
||||
if self._xxh64_prefix is not None:
|
||||
replacements.append(
|
||||
(re.compile(r"([^\w]|^)(?P<orig>XXH64)_"), self._xxh64_prefix)
|
||||
(re.compile(r"([^\w]|^)(?P<orig>XXH64)[\(_]"), self._xxh64_prefix)
|
||||
)
|
||||
for filepath in self._dst_lib_file_paths():
|
||||
file = FileLines(filepath)
|
||||
@@ -596,6 +599,48 @@ class Freestanding(object):
|
||||
file.lines[i] = line
|
||||
file.write()
|
||||
|
||||
def _parse_sed(self, sed):
|
||||
assert sed[0] == 's'
|
||||
delim = sed[1]
|
||||
match = re.fullmatch(f's{delim}(.+){delim}(.*){delim}(.*)', sed)
|
||||
assert match is not None
|
||||
regex = re.compile(match.group(1))
|
||||
format_str = match.group(2)
|
||||
is_global = match.group(3) == 'g'
|
||||
return regex, format_str, is_global
|
||||
|
||||
def _process_sed(self, sed):
|
||||
self._log(f"Processing sed: {sed}")
|
||||
regex, format_str, is_global = self._parse_sed(sed)
|
||||
|
||||
for filepath in self._dst_lib_file_paths():
|
||||
file = FileLines(filepath)
|
||||
for i, line in enumerate(file.lines):
|
||||
modified = False
|
||||
while True:
|
||||
match = regex.search(line)
|
||||
if match is None:
|
||||
break
|
||||
replacement = format_str.format(match.groups(''), match.groupdict(''))
|
||||
b = match.start()
|
||||
e = match.end()
|
||||
line = line[:b] + replacement + line[e:]
|
||||
modified = True
|
||||
if not is_global:
|
||||
break
|
||||
if modified:
|
||||
self._log(f"\t- {file.lines[i][:-1]}")
|
||||
self._log(f"\t+ {line[:-1]}")
|
||||
file.lines[i] = line
|
||||
file.write()
|
||||
|
||||
def _process_seds(self):
|
||||
self._log("Processing seds")
|
||||
for sed in self._seds:
|
||||
self._process_sed(sed)
|
||||
|
||||
|
||||
|
||||
def go(self):
|
||||
self._copy_source_lib()
|
||||
self._copy_zstd_deps()
|
||||
@@ -604,6 +649,7 @@ class Freestanding(object):
|
||||
self._remove_excludes()
|
||||
self._rewrite_includes()
|
||||
self._replace_xxh64_prefix()
|
||||
self._process_seds()
|
||||
|
||||
|
||||
def parse_optional_pair(defines: [str]) -> [(str, Optional[str])]:
|
||||
@@ -641,6 +687,7 @@ def main(name, args):
|
||||
parser.add_argument("--xxh64-state", default=None, help="Alternate XXH64 state type (excluding _) e.g. --xxh64-state='struct xxh64_state'")
|
||||
parser.add_argument("--xxh64-prefix", default=None, help="Alternate XXH64 function prefix (excluding _) e.g. --xxh64-prefix=xxh64")
|
||||
parser.add_argument("--rewrite-include", default=[], dest="rewritten_includes", action="append", help="Rewrite an include REGEX=NEW (e.g. '<stddef\\.h>=<linux/types.h>')")
|
||||
parser.add_argument("--sed", default=[], dest="seds", action="append", help="Apply a sed replacement. Format: `s/REGEX/FORMAT/[g]`. REGEX is a Python regex. FORMAT is a Python format string formatted by the regex dict.")
|
||||
parser.add_argument("-D", "--define", default=[], dest="defs", action="append", help="Pre-define this macro (can be passed multiple times)")
|
||||
parser.add_argument("-U", "--undefine", default=[], dest="undefs", action="append", help="Pre-undefine this macro (can be passed mutliple times)")
|
||||
parser.add_argument("-R", "--replace", default=[], dest="replaces", action="append", help="Pre-define this macro and replace the first ifndef block with its definition")
|
||||
@@ -656,6 +703,11 @@ def main(name, args):
|
||||
if name in args.undefs:
|
||||
raise RuntimeError(f"{name} is both defined and undefined!")
|
||||
|
||||
# Always set tracing to 0
|
||||
if "ZSTD_NO_TRACE" not in (arg[0] for arg in args.defs):
|
||||
args.defs.append(("ZSTD_NO_TRACE", None))
|
||||
args.defs.append(("ZSTD_TRACE", "0"))
|
||||
|
||||
args.replaces = parse_pair(args.replaces)
|
||||
for name, _ in args.replaces:
|
||||
if name in args.undefs or name in args.defs:
|
||||
@@ -688,7 +740,8 @@ def main(name, args):
|
||||
args.defs,
|
||||
args.replaces,
|
||||
args.undefs,
|
||||
args.excludes
|
||||
args.excludes,
|
||||
args.seds,
|
||||
).go()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2015-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -22,6 +22,10 @@ libzstd:
|
||||
--xxh64-prefix 'xxh64' \
|
||||
--rewrite-include '<limits\.h>=<linux/limits.h>' \
|
||||
--rewrite-include '<stddef\.h>=<linux/types.h>' \
|
||||
--rewrite-include '"\.\./zstd.h"=<linux/zstd.h>' \
|
||||
--rewrite-include '"(\.\./common/)?zstd_errors.h"=<linux/zstd_errors.h>' \
|
||||
--sed 's,/\*\*\*,/* *,g' \
|
||||
--sed 's,/\*\*,/*,g' \
|
||||
-DZSTD_NO_INTRINSICS \
|
||||
-DZSTD_NO_UNUSED_FUNCTIONS \
|
||||
-DZSTD_LEGACY_SUPPORT=0 \
|
||||
@@ -35,7 +39,6 @@ libzstd:
|
||||
-DZSTD_ADDRESS_SANITIZER=0 \
|
||||
-DZSTD_MEMORY_SANITIZER=0 \
|
||||
-DZSTD_COMPRESS_HEAPMODE=1 \
|
||||
-UZSTD_NO_INLINE \
|
||||
-UNO_PREFETCH \
|
||||
-U__cplusplus \
|
||||
-UZSTD_DLL_EXPORT \
|
||||
@@ -45,7 +48,14 @@ libzstd:
|
||||
-U_MSC_VER \
|
||||
-U_WIN32 \
|
||||
-RZSTDLIB_VISIBILITY= \
|
||||
-RZSTDERRORLIB_VISIBILITY=
|
||||
-RZSTDERRORLIB_VISIBILITY= \
|
||||
-RZSTD_FALLTHROUGH=fallthrough \
|
||||
-DZSTD_HAVE_WEAK_SYMBOLS=0 \
|
||||
-DZSTD_TRACE=0 \
|
||||
-DZSTD_NO_TRACE \
|
||||
-DZSTD_LINUX_KERNEL
|
||||
mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h
|
||||
mv linux/lib/zstd/common/zstd_errors.h linux/include/linux/
|
||||
cp linux_zstd.h linux/include/linux/zstd.h
|
||||
cp zstd_compress_module.c linux/lib/zstd
|
||||
cp zstd_decompress_module.c linux/lib/zstd
|
||||
@@ -60,15 +70,18 @@ import: libzstd
|
||||
rm -f $(LINUX)/include/linux/zstd_errors.h
|
||||
rm -rf $(LINUX)/lib/zstd
|
||||
cp linux/include/linux/zstd.h $(LINUX)/include/linux
|
||||
cp linux/include/linux/zstd_lib.h $(LINUX)/include/linux
|
||||
cp linux/include/linux/zstd_errors.h $(LINUX)/include/linux
|
||||
cp -r linux/lib/zstd $(LINUX)/lib
|
||||
|
||||
import-upstream:
|
||||
rm -rf $(LINUX)/lib/zstd
|
||||
mkdir $(LINUX)/lib/zstd
|
||||
cp ../../lib/zstd.h $(LINUX)/lib/zstd
|
||||
cp ../../lib/zstd.h $(LINUX)/include/linux/zstd_lib.h
|
||||
cp -r ../../lib/common $(LINUX)/lib/zstd
|
||||
cp -r ../../lib/compress $(LINUX)/lib/zstd
|
||||
cp -r ../../lib/decompress $(LINUX)/lib/zstd
|
||||
mv $(LINUX)/lib/zstd/common/zstd_errors.h $(LINUX)/include/linux
|
||||
rm $(LINUX)/lib/zstd/common/threading.*
|
||||
rm $(LINUX)/lib/zstd/common/pool.*
|
||||
rm $(LINUX)/lib/zstd/common/xxhash.*
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file includes every .c file needed for decompression.
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
# ################################################################
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
# in the COPYING file in the root directory of this source tree).
|
||||
# You may select, at your option, one of the above-listed licenses.
|
||||
# ################################################################
|
||||
obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
|
||||
obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
|
||||
|
||||
ccflags-y += -O3
|
||||
|
||||
zstd_compress-y := \
|
||||
zstd_compress_module.o \
|
||||
common/debug.o \
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of https://github.com/facebook/zstd.
|
||||
* An additional grant of patent rights can be found in the PATENTS file in the
|
||||
* same directory.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation. This program is dual-licensed; you may select
|
||||
* either version 2 of the GNU General Public License ("GPL") or BSD license
|
||||
* ("BSD").
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of https://github.com/facebook/zstd) and
|
||||
* the GPLv2 (found in the COPYING file in the root directory of
|
||||
* https://github.com/facebook/zstd). You may select, at your option, one of the
|
||||
* above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef LINUX_ZSTD_H
|
||||
@@ -27,6 +22,8 @@
|
||||
|
||||
/* ====== Dependency ====== */
|
||||
#include <linux/types.h>
|
||||
#include <linux/zstd_errors.h>
|
||||
#include <linux/zstd_lib.h>
|
||||
|
||||
/* ====== Helper Functions ====== */
|
||||
/**
|
||||
@@ -45,13 +42,18 @@ size_t zstd_compress_bound(size_t src_size);
|
||||
*/
|
||||
unsigned int zstd_is_error(size_t code);
|
||||
|
||||
/**
|
||||
* enum zstd_error_code - zstd error codes
|
||||
*/
|
||||
typedef ZSTD_ErrorCode zstd_error_code;
|
||||
|
||||
/**
|
||||
* zstd_get_error_code() - translates an error function result to an error code
|
||||
* @code: The function result for which zstd_is_error(code) is true.
|
||||
*
|
||||
* Return: A unique error code for this error.
|
||||
*/
|
||||
int zstd_get_error_code(size_t code);
|
||||
zstd_error_code zstd_get_error_code(size_t code);
|
||||
|
||||
/**
|
||||
* zstd_get_error_name() - translates an error function result to a string
|
||||
@@ -61,76 +63,67 @@ int zstd_get_error_code(size_t code);
|
||||
*/
|
||||
const char *zstd_get_error_name(size_t code);
|
||||
|
||||
/**
|
||||
* zstd_min_clevel() - minimum allowed compression level
|
||||
*
|
||||
* Return: The minimum allowed compression level.
|
||||
*/
|
||||
int zstd_min_clevel(void);
|
||||
|
||||
/**
|
||||
* zstd_max_clevel() - maximum allowed compression level
|
||||
*
|
||||
* Return: The maximum allowed compression level.
|
||||
*/
|
||||
int zstd_max_clevel(void);
|
||||
|
||||
/* ====== Parameter Selection ====== */
|
||||
|
||||
/**
|
||||
* enum zstd_strategy - zstd compression search strategy
|
||||
*
|
||||
* From faster to stronger.
|
||||
* From faster to stronger. See zstd_lib.h.
|
||||
*/
|
||||
enum zstd_strategy {
|
||||
zstd_fast = 1,
|
||||
zstd_dfast = 2,
|
||||
zstd_greedy = 3,
|
||||
zstd_lazy = 4,
|
||||
zstd_lazy2 = 5,
|
||||
zstd_btlazy2 = 6,
|
||||
zstd_btopt = 7,
|
||||
zstd_btultra = 8,
|
||||
zstd_btultra2 = 9
|
||||
};
|
||||
typedef ZSTD_strategy zstd_strategy;
|
||||
|
||||
/**
|
||||
* struct zstd_compression_parameters - zstd compression parameters
|
||||
* @window_log: Log of the largest match distance. Larger means more
|
||||
* compression, and more memory needed during decompression.
|
||||
* @chain_log: Fully searched segment. Larger means more compression,
|
||||
* slower, and more memory (useless for fast).
|
||||
* @hash_log: Dispatch table. Larger means more compression,
|
||||
* slower, and more memory.
|
||||
* @search_log: Number of searches. Larger means more compression and slower.
|
||||
* @search_length: Match length searched. Larger means faster decompression,
|
||||
* sometimes less compression.
|
||||
* @target_length: Acceptable match size for optimal parser (only). Larger means
|
||||
* more compression, and slower.
|
||||
* @strategy: The zstd compression strategy.
|
||||
* @windowLog: Log of the largest match distance. Larger means more
|
||||
* compression, and more memory needed during decompression.
|
||||
* @chainLog: Fully searched segment. Larger means more compression,
|
||||
* slower, and more memory (useless for fast).
|
||||
* @hashLog: Dispatch table. Larger means more compression,
|
||||
* slower, and more memory.
|
||||
* @searchLog: Number of searches. Larger means more compression and slower.
|
||||
* @searchLength: Match length searched. Larger means faster decompression,
|
||||
* sometimes less compression.
|
||||
* @targetLength: Acceptable match size for optimal parser (only). Larger means
|
||||
* more compression, and slower.
|
||||
* @strategy: The zstd compression strategy.
|
||||
*
|
||||
* See zstd_lib.h.
|
||||
*/
|
||||
struct zstd_compression_parameters {
|
||||
unsigned int window_log;
|
||||
unsigned int chain_log;
|
||||
unsigned int hash_log;
|
||||
unsigned int search_log;
|
||||
unsigned int search_length;
|
||||
unsigned int target_length;
|
||||
enum zstd_strategy strategy;
|
||||
};
|
||||
typedef ZSTD_compressionParameters zstd_compression_parameters;
|
||||
|
||||
/**
|
||||
* struct zstd_frame_parameters - zstd frame parameters
|
||||
* @content_size_flag: Controls whether content size will be present in the
|
||||
* frame header (when known).
|
||||
* @checksum_flag: Controls whether a 32-bit checksum is generated at the
|
||||
* end of the frame for error detection.
|
||||
* @no_dict_id_flag: Controls whether dictID will be saved into the frame
|
||||
* header when using dictionary compression.
|
||||
* @contentSizeFlag: Controls whether content size will be present in the
|
||||
* frame header (when known).
|
||||
* @checksumFlag: Controls whether a 32-bit checksum is generated at the
|
||||
* end of the frame for error detection.
|
||||
* @noDictIDFlag: Controls whether dictID will be saved into the frame
|
||||
* header when using dictionary compression.
|
||||
*
|
||||
* The default value is all fields set to 0.
|
||||
* The default value is all fields set to 0. See zstd_lib.h.
|
||||
*/
|
||||
struct zstd_frame_parameters {
|
||||
unsigned int content_size_flag;
|
||||
unsigned int checksum_flag;
|
||||
unsigned int no_dict_id_flag;
|
||||
};
|
||||
typedef ZSTD_frameParameters zstd_frame_parameters;
|
||||
|
||||
/**
|
||||
* struct zstd_parameters - zstd parameters
|
||||
* @cparams: The compression parameters.
|
||||
* @fparams: The frame parameters.
|
||||
* @cParams: The compression parameters.
|
||||
* @fParams: The frame parameters.
|
||||
*/
|
||||
struct zstd_parameters {
|
||||
struct zstd_compression_parameters cparams;
|
||||
struct zstd_frame_parameters fparams;
|
||||
};
|
||||
typedef ZSTD_parameters zstd_parameters;
|
||||
|
||||
/**
|
||||
* zstd_get_params() - returns zstd_parameters for selected level
|
||||
@@ -140,12 +133,12 @@ struct zstd_parameters {
|
||||
*
|
||||
* Return: The selected zstd_parameters.
|
||||
*/
|
||||
struct zstd_parameters zstd_get_params(int level,
|
||||
zstd_parameters zstd_get_params(int level,
|
||||
unsigned long long estimated_src_size);
|
||||
|
||||
/* ====== Single-pass Compression ====== */
|
||||
|
||||
typedef struct ZSTD_CCtx_s zstd_cctx;
|
||||
typedef ZSTD_CCtx zstd_cctx;
|
||||
|
||||
/**
|
||||
* zstd_cctx_workspace_bound() - max memory needed to initialize a zstd_cctx
|
||||
@@ -158,8 +151,7 @@ typedef struct ZSTD_CCtx_s zstd_cctx;
|
||||
* Return: A lower bound on the size of the workspace that is passed to
|
||||
* zstd_init_cctx().
|
||||
*/
|
||||
size_t zstd_cctx_workspace_bound(
|
||||
const struct zstd_compression_parameters *parameters);
|
||||
size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *parameters);
|
||||
|
||||
/**
|
||||
* zstd_init_cctx() - initialize a zstd compression context
|
||||
@@ -186,11 +178,11 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size);
|
||||
* zstd_is_error().
|
||||
*/
|
||||
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
|
||||
const void *src, size_t src_size, const struct zstd_parameters *parameters);
|
||||
const void *src, size_t src_size, const zstd_parameters *parameters);
|
||||
|
||||
/* ====== Single-pass Decompression ====== */
|
||||
|
||||
typedef struct ZSTD_DCtx_s zstd_dctx;
|
||||
typedef ZSTD_DCtx zstd_dctx;
|
||||
|
||||
/**
|
||||
* zstd_dctx_workspace_bound() - max memory needed to initialize a zstd_dctx
|
||||
@@ -236,12 +228,10 @@ size_t zstd_decompress_dctx(zstd_dctx *dctx, void *dst, size_t dst_capacity,
|
||||
* @size: Size of the input buffer.
|
||||
* @pos: Position where reading stopped. Will be updated.
|
||||
* Necessarily 0 <= pos <= size.
|
||||
*
|
||||
* See zstd_lib.h.
|
||||
*/
|
||||
struct zstd_in_buffer {
|
||||
const void *src;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
};
|
||||
typedef ZSTD_inBuffer zstd_in_buffer;
|
||||
|
||||
/**
|
||||
* struct zstd_out_buffer - output buffer for streaming
|
||||
@@ -249,16 +239,14 @@ struct zstd_in_buffer {
|
||||
* @size: Size of the output buffer.
|
||||
* @pos: Position where writing stopped. Will be updated.
|
||||
* Necessarily 0 <= pos <= size.
|
||||
*
|
||||
* See zstd_lib.h.
|
||||
*/
|
||||
struct zstd_out_buffer {
|
||||
void *dst;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
};
|
||||
typedef ZSTD_outBuffer zstd_out_buffer;
|
||||
|
||||
/* ====== Streaming Compression ====== */
|
||||
|
||||
typedef struct ZSTD_CCtx_s zstd_cstream;
|
||||
typedef ZSTD_CStream zstd_cstream;
|
||||
|
||||
/**
|
||||
* zstd_cstream_workspace_bound() - memory needed to initialize a zstd_cstream
|
||||
@@ -267,8 +255,7 @@ typedef struct ZSTD_CCtx_s zstd_cstream;
|
||||
* Return: A lower bound on the size of the workspace that is passed to
|
||||
* zstd_init_cstream().
|
||||
*/
|
||||
size_t zstd_cstream_workspace_bound(
|
||||
const struct zstd_compression_parameters *cparams);
|
||||
size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams);
|
||||
|
||||
/**
|
||||
* zstd_init_cstream() - initialize a zstd streaming compression context
|
||||
@@ -285,7 +272,7 @@ size_t zstd_cstream_workspace_bound(
|
||||
*
|
||||
* Return: The zstd streaming compression context or NULL on error.
|
||||
*/
|
||||
zstd_cstream *zstd_init_cstream(const struct zstd_parameters *parameters,
|
||||
zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters,
|
||||
unsigned long long pledged_src_size, void *workspace, size_t workspace_size);
|
||||
|
||||
/**
|
||||
@@ -320,8 +307,8 @@ size_t zstd_reset_cstream(zstd_cstream *cstream,
|
||||
* function call or an error, which can be checked using
|
||||
* zstd_is_error().
|
||||
*/
|
||||
size_t zstd_compress_stream(zstd_cstream *cstream,
|
||||
struct zstd_out_buffer *output, struct zstd_in_buffer *input);
|
||||
size_t zstd_compress_stream(zstd_cstream *cstream, zstd_out_buffer *output,
|
||||
zstd_in_buffer *input);
|
||||
|
||||
/**
|
||||
* zstd_flush_stream() - flush internal buffers into output
|
||||
@@ -336,7 +323,7 @@ size_t zstd_compress_stream(zstd_cstream *cstream,
|
||||
* Return: The number of bytes still present within internal buffers or an
|
||||
* error, which can be checked using zstd_is_error().
|
||||
*/
|
||||
size_t zstd_flush_stream(zstd_cstream *cstream, struct zstd_out_buffer *output);
|
||||
size_t zstd_flush_stream(zstd_cstream *cstream, zstd_out_buffer *output);
|
||||
|
||||
/**
|
||||
* zstd_end_stream() - flush internal buffers into output and end the frame
|
||||
@@ -350,11 +337,11 @@ size_t zstd_flush_stream(zstd_cstream *cstream, struct zstd_out_buffer *output);
|
||||
* Return: The number of bytes still present within internal buffers or an
|
||||
* error, which can be checked using zstd_is_error().
|
||||
*/
|
||||
size_t zstd_end_stream(zstd_cstream *cstream, struct zstd_out_buffer *output);
|
||||
size_t zstd_end_stream(zstd_cstream *cstream, zstd_out_buffer *output);
|
||||
|
||||
/* ====== Streaming Decompression ====== */
|
||||
|
||||
typedef struct ZSTD_DCtx_s zstd_dstream;
|
||||
typedef ZSTD_DStream zstd_dstream;
|
||||
|
||||
/**
|
||||
* zstd_dstream_workspace_bound() - memory needed to initialize a zstd_dstream
|
||||
@@ -411,8 +398,8 @@ size_t zstd_reset_dstream(zstd_dstream *dstream);
|
||||
* using zstd_is_error(). The size hint will never load more than the
|
||||
* frame.
|
||||
*/
|
||||
size_t zstd_decompress_stream(zstd_dstream *dstream,
|
||||
struct zstd_out_buffer *output, struct zstd_in_buffer *input);
|
||||
size_t zstd_decompress_stream(zstd_dstream *dstream, zstd_out_buffer *output,
|
||||
zstd_in_buffer *input);
|
||||
|
||||
/* ====== Frame Inspection Functions ====== */
|
||||
|
||||
@@ -431,20 +418,21 @@ size_t zstd_find_frame_compressed_size(const void *src, size_t src_size);
|
||||
|
||||
/**
|
||||
* struct zstd_frame_params - zstd frame parameters stored in the frame header
|
||||
* @frame_content_size: The frame content size, or 0 if not present.
|
||||
* @window_size: The window size, or 0 if the frame is a skippable frame.
|
||||
* @dict_id: The dictionary id, or 0 if not present.
|
||||
* @checksum_flag: Whether a checksum was used.
|
||||
* @frameContentSize: The frame content size, or ZSTD_CONTENTSIZE_UNKNOWN if not
|
||||
* present.
|
||||
* @windowSize: The window size, or 0 if the frame is a skippable frame.
|
||||
* @blockSizeMax: The maximum block size.
|
||||
* @frameType: The frame type (zstd or skippable)
|
||||
* @headerSize: The size of the frame header.
|
||||
* @dictID: The dictionary id, or 0 if not present.
|
||||
* @checksumFlag: Whether a checksum was used.
|
||||
*
|
||||
* See zstd_lib.h.
|
||||
*/
|
||||
struct zstd_frame_params {
|
||||
unsigned long long frame_content_size;
|
||||
unsigned int window_size;
|
||||
unsigned int dict_id;
|
||||
unsigned int checksum_flag;
|
||||
};
|
||||
typedef ZSTD_frameHeader zstd_frame_header;
|
||||
|
||||
/**
|
||||
* zstd_get_frame_params() - extracts parameters from a zstd or skippable frame
|
||||
* zstd_get_frame_header() - extracts parameters from a zstd or skippable frame
|
||||
* @params: On success the frame parameters are written here.
|
||||
* @src: The source buffer. It must point to a zstd or skippable frame.
|
||||
* @src_size: The size of the source buffer.
|
||||
@@ -453,7 +441,7 @@ struct zstd_frame_params {
|
||||
* must be provided to make forward progress. Otherwise it returns
|
||||
* an error, which can be checked using zstd_is_error().
|
||||
*/
|
||||
size_t zstd_get_frame_params(struct zstd_frame_params *params, const void *src,
|
||||
size_t zstd_get_frame_header(zstd_frame_header *params, const void *src,
|
||||
size_t src_size);
|
||||
|
||||
#endif /* LINUX_ZSTD_H */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# ################################################################
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
# in the COPYING file in the root directory of this source tree).
|
||||
# You may select, at your option, one of the above-listed licenses.
|
||||
# ################################################################
|
||||
|
||||
LINUX := ../linux
|
||||
LINUX_ZSTDLIB := $(LINUX)/lib/zstd
|
||||
@@ -7,9 +16,9 @@ CPPFLAGS += -I$(LINUX)/include -I$(LINUX_ZSTDLIB) -Iinclude -DNDEBUG
|
||||
CPPFLAGS += -DZSTD_ASAN_DONT_POISON_WORKSPACE
|
||||
|
||||
LINUX_ZSTD_MODULE := $(wildcard $(LINUX_ZSTDLIB)/*.c)
|
||||
LINUX_ZSTD_COMMON := $(wildcard $(LINUX_ZSTDLIB)/common/*.c)
|
||||
LINUX_ZSTD_COMPRESS := $(wildcard $(LINUX_ZSTDLIB)/compress/*.c)
|
||||
LINUX_ZSTD_DECOMPRESS := $(wildcard $(LINUX_ZSTDLIB)/decompress/*.c)
|
||||
LINUX_ZSTD_COMMON := $(wildcard $(LINUX_ZSTDLIB)/common/*.c)
|
||||
LINUX_ZSTD_COMPRESS := $(wildcard $(LINUX_ZSTDLIB)/compress/*.c)
|
||||
LINUX_ZSTD_DECOMPRESS := $(wildcard $(LINUX_ZSTDLIB)/decompress/*.c)
|
||||
LINUX_ZSTD_FILES := $(LINUX_ZSTD_MODULE) $(LINUX_ZSTD_COMMON) $(LINUX_ZSTD_COMPRESS) $(LINUX_ZSTD_DECOMPRESS)
|
||||
LINUX_ZSTD_OBJECTS := $(LINUX_ZSTD_FILES:.c=.o)
|
||||
|
||||
@@ -29,6 +38,7 @@ run-test: test static_test
|
||||
|
||||
.PHONY:
|
||||
clean:
|
||||
$(RM) -f $(LINUX_ZSTDLIB)/*.o
|
||||
$(RM) -f $(LINUX_ZSTDLIB)/**/*.o
|
||||
$(RM) -f *.o *.a
|
||||
$(RM) -f test
|
||||
|
||||
@@ -4,13 +4,23 @@
|
||||
#include <assert.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define _LITTLE_ENDIAN 1
|
||||
#ifndef __LITTLE_ENDIAN
|
||||
# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN__)
|
||||
# define __LITTLE_ENDIAN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
# define _IS_LITTLE_ENDIAN 1
|
||||
#else
|
||||
# define _IS_LITTLE_ENDIAN 0
|
||||
#endif
|
||||
|
||||
static unsigned _isLittleEndian(void)
|
||||
{
|
||||
const union { uint32_t u; uint8_t c[4]; } one = { 1 };
|
||||
assert(_LITTLE_ENDIAN == one.c[0]);
|
||||
return _LITTLE_ENDIAN;
|
||||
assert(_IS_LITTLE_ENDIAN == one.c[0]);
|
||||
return _IS_LITTLE_ENDIAN;
|
||||
}
|
||||
|
||||
static uint16_t _swap16(uint16_t in)
|
||||
@@ -165,7 +175,7 @@ extern void __bad_unaligned_access_size(void);
|
||||
(void)0; \
|
||||
})
|
||||
|
||||
#if _LITTLE_ENDIAN
|
||||
#if _IS_LITTLE_ENDIAN
|
||||
# define get_unaligned __get_unaligned_le
|
||||
# define put_unaligned __put_unaligned_le
|
||||
#else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -14,4 +14,12 @@
|
||||
#define inline __inline __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef noinline
|
||||
#define noinline __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
#ifndef fallthrough
|
||||
#define fallthrough __attribute__((__fallthrough__))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -12,4 +12,8 @@
|
||||
|
||||
#define WARN_ON(x)
|
||||
|
||||
#define PTR_ALIGN(p, a) (typeof(p))ALIGN((unsigned long long)(p), (a))
|
||||
#define ALIGN(x, a) ALIGN_MASK((x), (a) - 1)
|
||||
#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -36,7 +36,6 @@ test_not_present "ZSTD_NO_INTRINSICS"
|
||||
test_not_present "ZSTD_NO_UNUSED_FUNCTIONS"
|
||||
test_not_present "ZSTD_LEGACY_SUPPORT"
|
||||
test_not_present "STATIC_BMI2"
|
||||
test_not_present "ZSTD_NO_INLINE"
|
||||
test_not_present "ZSTD_DLL_EXPORT"
|
||||
test_not_present "ZSTD_DLL_IMPORT"
|
||||
test_not_present "__ICCARM__"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 7-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -57,10 +57,10 @@ static void test_btrfs(test_data_t const *data) {
|
||||
fprintf(stderr, "testing btrfs use cases... ");
|
||||
size_t const size = MIN(data->dataSize, 128 * 1024);
|
||||
for (int level = -1; level < 16; ++level) {
|
||||
struct zstd_parameters params = zstd_get_params(level, size);
|
||||
CONTROL(params.cparams.window_log <= 17);
|
||||
zstd_parameters params = zstd_get_params(level, size);
|
||||
CONTROL(params.cParams.windowLog <= 17);
|
||||
size_t const workspaceSize =
|
||||
MAX(zstd_cstream_workspace_bound(¶ms.cparams),
|
||||
MAX(zstd_cstream_workspace_bound(¶ms.cParams),
|
||||
zstd_dstream_workspace_bound(size));
|
||||
void *workspace = malloc(workspaceSize);
|
||||
CONTROL(workspace != NULL);
|
||||
@@ -72,8 +72,8 @@ static void test_btrfs(test_data_t const *data) {
|
||||
{
|
||||
zstd_cstream *cctx = zstd_init_cstream(¶ms, size, workspace, workspaceSize);
|
||||
CONTROL(cctx != NULL);
|
||||
struct zstd_out_buffer out = {NULL, 0, 0};
|
||||
struct zstd_in_buffer in = {NULL, 0, 0};
|
||||
zstd_out_buffer out = {NULL, 0, 0};
|
||||
zstd_in_buffer in = {NULL, 0, 0};
|
||||
for (;;) {
|
||||
if (in.pos == in.size) {
|
||||
in.src = ip;
|
||||
@@ -107,10 +107,10 @@ static void test_btrfs(test_data_t const *data) {
|
||||
op = data->data2;
|
||||
oend = op + size;
|
||||
{
|
||||
zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cparams.window_log, workspace, workspaceSize);
|
||||
zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cParams.windowLog, workspace, workspaceSize);
|
||||
CONTROL(dctx != NULL);
|
||||
struct zstd_out_buffer out = {NULL, 0, 0};
|
||||
struct zstd_in_buffer in = {NULL, 0, 0};
|
||||
zstd_out_buffer out = {NULL, 0, 0};
|
||||
zstd_in_buffer in = {NULL, 0, 0};
|
||||
for (;;) {
|
||||
if (in.pos == in.size) {
|
||||
in.src = ip;
|
||||
@@ -144,8 +144,8 @@ static void test_decompress_unzstd(test_data_t const *data) {
|
||||
fprintf(stderr, "Testing decompress unzstd... ");
|
||||
size_t cSize;
|
||||
{
|
||||
struct zstd_parameters params = zstd_get_params(19, 0);
|
||||
size_t const wkspSize = zstd_cctx_workspace_bound(¶ms.cparams);
|
||||
zstd_parameters params = zstd_get_params(19, 0);
|
||||
size_t const wkspSize = zstd_cctx_workspace_bound(¶ms.cParams);
|
||||
void* wksp = malloc(wkspSize);
|
||||
CONTROL(wksp != NULL);
|
||||
zstd_cctx* cctx = zstd_init_cctx(wksp, wkspSize);
|
||||
@@ -169,6 +169,13 @@ static void test_decompress_unzstd(test_data_t const *data) {
|
||||
fprintf(stderr, "Ok\n");
|
||||
}
|
||||
|
||||
static void test_f2fs() {
|
||||
fprintf(stderr, "testing f2fs uses... ");
|
||||
CONTROL(zstd_min_clevel() < 0);
|
||||
CONTROL(zstd_max_clevel() == 22);
|
||||
fprintf(stderr, "Ok\n");
|
||||
}
|
||||
|
||||
static char *g_stack = NULL;
|
||||
|
||||
static void __attribute__((noinline)) use(void *x) {
|
||||
@@ -195,6 +202,7 @@ static void __attribute__((noinline)) check_stack() {
|
||||
|
||||
static void test_stack_usage(test_data_t const *data) {
|
||||
set_stack();
|
||||
test_f2fs();
|
||||
test_btrfs(data);
|
||||
test_decompress_unzstd(data);
|
||||
check_stack();
|
||||
@@ -202,6 +210,7 @@ static void test_stack_usage(test_data_t const *data) {
|
||||
|
||||
int main(void) {
|
||||
test_data_t data = create_test_data();
|
||||
test_f2fs();
|
||||
test_btrfs(&data);
|
||||
test_decompress_unzstd(&data);
|
||||
test_stack_usage(&data);
|
||||
|
||||
@@ -1,102 +1,87 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/zstd.h>
|
||||
|
||||
#include "zstd.h"
|
||||
#include "common/zstd_deps.h"
|
||||
#include "common/zstd_internal.h"
|
||||
|
||||
static void zstd_check_structs(void) {
|
||||
/* Check that the structs have the same size. */
|
||||
ZSTD_STATIC_ASSERT(sizeof(ZSTD_parameters) ==
|
||||
sizeof(struct zstd_parameters));
|
||||
ZSTD_STATIC_ASSERT(sizeof(ZSTD_compressionParameters) ==
|
||||
sizeof(struct zstd_compression_parameters));
|
||||
ZSTD_STATIC_ASSERT(sizeof(ZSTD_frameParameters) ==
|
||||
sizeof(struct zstd_frame_parameters));
|
||||
/* Zstd guarantees that the layout of the structs never change. Verify it. */
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_parameters, cParams) ==
|
||||
offsetof(struct zstd_parameters, cparams));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_parameters, fParams) ==
|
||||
offsetof(struct zstd_parameters, fparams));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, windowLog) ==
|
||||
offsetof(struct zstd_compression_parameters, window_log));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, chainLog) ==
|
||||
offsetof(struct zstd_compression_parameters, chain_log));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, hashLog) ==
|
||||
offsetof(struct zstd_compression_parameters, hash_log));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, searchLog) ==
|
||||
offsetof(struct zstd_compression_parameters, search_log));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, minMatch) ==
|
||||
offsetof(struct zstd_compression_parameters, search_length));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, targetLength) ==
|
||||
offsetof(struct zstd_compression_parameters, target_length));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_compressionParameters, strategy) ==
|
||||
offsetof(struct zstd_compression_parameters, strategy));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_frameParameters, contentSizeFlag) ==
|
||||
offsetof(struct zstd_frame_parameters, content_size_flag));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_frameParameters, checksumFlag) ==
|
||||
offsetof(struct zstd_frame_parameters, checksum_flag));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_frameParameters, noDictIDFlag) ==
|
||||
offsetof(struct zstd_frame_parameters, no_dict_id_flag));
|
||||
/* Check that the strategies are the same. This can change. */
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_fast == (int)zstd_fast);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_dfast == (int)zstd_dfast);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_greedy == (int)zstd_greedy);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_lazy == (int)zstd_lazy);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_lazy2 == (int)zstd_lazy2);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_btlazy2 == (int)zstd_btlazy2);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_btopt == (int)zstd_btopt);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_btultra == (int)zstd_btultra);
|
||||
ZSTD_STATIC_ASSERT((int)ZSTD_btultra2 == (int)zstd_btultra2);
|
||||
/* Check input buffer */
|
||||
ZSTD_STATIC_ASSERT(sizeof(ZSTD_inBuffer) == sizeof(struct zstd_in_buffer));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_inBuffer, src) ==
|
||||
offsetof(struct zstd_in_buffer, src));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_inBuffer, size) ==
|
||||
offsetof(struct zstd_in_buffer, size));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_inBuffer, pos) ==
|
||||
offsetof(struct zstd_in_buffer, pos));
|
||||
/* Check output buffer */
|
||||
ZSTD_STATIC_ASSERT(sizeof(ZSTD_outBuffer) ==
|
||||
sizeof(struct zstd_out_buffer));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_outBuffer, dst) ==
|
||||
offsetof(struct zstd_out_buffer, dst));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_outBuffer, size) ==
|
||||
offsetof(struct zstd_out_buffer, size));
|
||||
ZSTD_STATIC_ASSERT(offsetof(ZSTD_outBuffer, pos) ==
|
||||
offsetof(struct zstd_out_buffer, pos));
|
||||
#define ZSTD_FORWARD_IF_ERR(ret) \
|
||||
do { \
|
||||
size_t const __ret = (ret); \
|
||||
if (ZSTD_isError(__ret)) \
|
||||
return __ret; \
|
||||
} while (0)
|
||||
|
||||
static size_t zstd_cctx_init(zstd_cctx *cctx, const zstd_parameters *parameters,
|
||||
unsigned long long pledged_src_size)
|
||||
{
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_reset(
|
||||
cctx, ZSTD_reset_session_and_parameters));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setPledgedSrcSize(
|
||||
cctx, pledged_src_size));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_windowLog, parameters->cParams.windowLog));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_hashLog, parameters->cParams.hashLog));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_chainLog, parameters->cParams.chainLog));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_searchLog, parameters->cParams.searchLog));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_minMatch, parameters->cParams.minMatch));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_targetLength, parameters->cParams.targetLength));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_strategy, parameters->cParams.strategy));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_contentSizeFlag, parameters->fParams.contentSizeFlag));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_checksumFlag, parameters->fParams.checksumFlag));
|
||||
ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter(
|
||||
cctx, ZSTD_c_dictIDFlag, !parameters->fParams.noDictIDFlag));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zstd_min_clevel(void)
|
||||
{
|
||||
return ZSTD_minCLevel();
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_min_clevel);
|
||||
|
||||
int zstd_max_clevel(void)
|
||||
{
|
||||
return ZSTD_maxCLevel();
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_max_clevel);
|
||||
|
||||
size_t zstd_compress_bound(size_t src_size)
|
||||
{
|
||||
return ZSTD_compressBound(src_size);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_compress_bound);
|
||||
|
||||
struct zstd_parameters zstd_get_params(int level,
|
||||
zstd_parameters zstd_get_params(int level,
|
||||
unsigned long long estimated_src_size)
|
||||
{
|
||||
const ZSTD_parameters params = ZSTD_getParams(level, estimated_src_size, 0);
|
||||
struct zstd_parameters out;
|
||||
|
||||
/* no-op */
|
||||
zstd_check_structs();
|
||||
ZSTD_memcpy(&out, ¶ms, sizeof(out));
|
||||
return out;
|
||||
return ZSTD_getParams(level, estimated_src_size, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_get_params);
|
||||
|
||||
size_t zstd_cctx_workspace_bound(
|
||||
const struct zstd_compression_parameters *cparams)
|
||||
size_t zstd_cctx_workspace_bound(const zstd_compression_parameters *cparams)
|
||||
{
|
||||
ZSTD_compressionParameters p;
|
||||
|
||||
ZSTD_memcpy(&p, cparams, sizeof(p));
|
||||
return ZSTD_estimateCCtxSize_usingCParams(p);
|
||||
return ZSTD_estimateCCtxSize_usingCParams(*cparams);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_cctx_workspace_bound);
|
||||
|
||||
@@ -109,31 +94,23 @@ zstd_cctx *zstd_init_cctx(void *workspace, size_t workspace_size)
|
||||
EXPORT_SYMBOL(zstd_init_cctx);
|
||||
|
||||
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
|
||||
const void *src, size_t src_size, const struct zstd_parameters *parameters)
|
||||
const void *src, size_t src_size, const zstd_parameters *parameters)
|
||||
{
|
||||
ZSTD_parameters p;
|
||||
|
||||
ZSTD_memcpy(&p, parameters, sizeof(p));
|
||||
return ZSTD_compress_advanced(cctx, dst, dst_capacity, src, src_size, NULL, 0, p);
|
||||
ZSTD_FORWARD_IF_ERR(zstd_cctx_init(cctx, parameters, src_size));
|
||||
return ZSTD_compress2(cctx, dst, dst_capacity, src, src_size);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_compress_cctx);
|
||||
|
||||
size_t zstd_cstream_workspace_bound(
|
||||
const struct zstd_compression_parameters *cparams)
|
||||
size_t zstd_cstream_workspace_bound(const zstd_compression_parameters *cparams)
|
||||
{
|
||||
ZSTD_compressionParameters p;
|
||||
|
||||
ZSTD_memcpy(&p, cparams, sizeof(p));
|
||||
return ZSTD_estimateCStreamSize_usingCParams(p);
|
||||
return ZSTD_estimateCStreamSize_usingCParams(*cparams);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_cstream_workspace_bound);
|
||||
|
||||
zstd_cstream *zstd_init_cstream(const struct zstd_parameters *parameters,
|
||||
zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters,
|
||||
unsigned long long pledged_src_size, void *workspace, size_t workspace_size)
|
||||
{
|
||||
ZSTD_parameters p;
|
||||
zstd_cstream *cstream;
|
||||
size_t ret;
|
||||
|
||||
if (workspace == NULL)
|
||||
return NULL;
|
||||
@@ -146,9 +123,7 @@ zstd_cstream *zstd_init_cstream(const struct zstd_parameters *parameters,
|
||||
if (pledged_src_size == 0)
|
||||
pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN;
|
||||
|
||||
ZSTD_memcpy(&p, parameters, sizeof(p));
|
||||
ret = ZSTD_initCStream_advanced(cstream, NULL, 0, p, pledged_src_size);
|
||||
if (ZSTD_isError(ret))
|
||||
if (ZSTD_isError(zstd_cctx_init(cstream, parameters, pledged_src_size)))
|
||||
return NULL;
|
||||
|
||||
return cstream;
|
||||
@@ -162,43 +137,22 @@ size_t zstd_reset_cstream(zstd_cstream *cstream,
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_reset_cstream);
|
||||
|
||||
size_t zstd_compress_stream(zstd_cstream *cstream,
|
||||
struct zstd_out_buffer *output, struct zstd_in_buffer *input)
|
||||
size_t zstd_compress_stream(zstd_cstream *cstream, zstd_out_buffer *output,
|
||||
zstd_in_buffer *input)
|
||||
{
|
||||
ZSTD_outBuffer o;
|
||||
ZSTD_inBuffer i;
|
||||
size_t ret;
|
||||
|
||||
ZSTD_memcpy(&o, output, sizeof(o));
|
||||
ZSTD_memcpy(&i, input, sizeof(i));
|
||||
ret = ZSTD_compressStream(cstream, &o, &i);
|
||||
ZSTD_memcpy(output, &o, sizeof(o));
|
||||
ZSTD_memcpy(input, &i, sizeof(i));
|
||||
return ret;
|
||||
return ZSTD_compressStream(cstream, output, input);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_compress_stream);
|
||||
|
||||
size_t zstd_flush_stream(zstd_cstream *cstream, struct zstd_out_buffer *output)
|
||||
size_t zstd_flush_stream(zstd_cstream *cstream, zstd_out_buffer *output)
|
||||
{
|
||||
ZSTD_outBuffer o;
|
||||
size_t ret;
|
||||
|
||||
ZSTD_memcpy(&o, output, sizeof(o));
|
||||
ret = ZSTD_flushStream(cstream, &o);
|
||||
ZSTD_memcpy(output, &o, sizeof(o));
|
||||
return ret;
|
||||
return ZSTD_flushStream(cstream, output);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_flush_stream);
|
||||
|
||||
size_t zstd_end_stream(zstd_cstream *cstream, struct zstd_out_buffer *output)
|
||||
size_t zstd_end_stream(zstd_cstream *cstream, zstd_out_buffer *output)
|
||||
{
|
||||
ZSTD_outBuffer o;
|
||||
size_t ret;
|
||||
|
||||
ZSTD_memcpy(&o, output, sizeof(o));
|
||||
ret = ZSTD_endStream(cstream, &o);
|
||||
ZSTD_memcpy(output, &o, sizeof(o));
|
||||
return ret;
|
||||
return ZSTD_endStream(cstream, output);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_end_stream);
|
||||
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/zstd.h>
|
||||
|
||||
#include "zstd.h"
|
||||
#include "common/zstd_deps.h"
|
||||
#include "common/zstd_errors.h"
|
||||
|
||||
/* Common symbols. zstd_compress must depend on zstd_decompress. */
|
||||
|
||||
@@ -17,7 +24,7 @@ unsigned int zstd_is_error(size_t code)
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_is_error);
|
||||
|
||||
int zstd_get_error_code(size_t code)
|
||||
zstd_error_code zstd_get_error_code(size_t code)
|
||||
{
|
||||
return ZSTD_getErrorCode(code);
|
||||
}
|
||||
@@ -74,19 +81,10 @@ size_t zstd_reset_dstream(zstd_dstream *dstream)
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_reset_dstream);
|
||||
|
||||
size_t zstd_decompress_stream(zstd_dstream *dstream,
|
||||
struct zstd_out_buffer *output, struct zstd_in_buffer *input)
|
||||
size_t zstd_decompress_stream(zstd_dstream *dstream, zstd_out_buffer *output,
|
||||
zstd_in_buffer *input)
|
||||
{
|
||||
ZSTD_outBuffer o;
|
||||
ZSTD_inBuffer i;
|
||||
size_t ret;
|
||||
|
||||
ZSTD_memcpy(&o, output, sizeof(o));
|
||||
ZSTD_memcpy(&i, input, sizeof(i));
|
||||
ret = ZSTD_decompressStream(dstream, &o, &i);
|
||||
ZSTD_memcpy(output, &o, sizeof(o));
|
||||
ZSTD_memcpy(input, &i, sizeof(i));
|
||||
return ret;
|
||||
return ZSTD_decompressStream(dstream, output, input);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_decompress_stream);
|
||||
|
||||
@@ -96,27 +94,12 @@ size_t zstd_find_frame_compressed_size(const void *src, size_t src_size)
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_find_frame_compressed_size);
|
||||
|
||||
size_t zstd_get_frame_params(struct zstd_frame_params *params, const void *src,
|
||||
size_t zstd_get_frame_header(zstd_frame_header *header, const void *src,
|
||||
size_t src_size)
|
||||
{
|
||||
ZSTD_frameHeader h;
|
||||
const size_t ret = ZSTD_getFrameHeader(&h, src, src_size);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (h.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
|
||||
params->frame_content_size = h.frameContentSize;
|
||||
else
|
||||
params->frame_content_size = 0;
|
||||
|
||||
params->window_size = h.windowSize;
|
||||
params->dict_id = h.dictID;
|
||||
params->checksum_flag = h.checksumFlag;
|
||||
|
||||
return ret;
|
||||
return ZSTD_getFrameHeader(header, src, src_size);
|
||||
}
|
||||
EXPORT_SYMBOL(zstd_get_frame_params);
|
||||
EXPORT_SYMBOL(zstd_get_frame_header);
|
||||
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
MODULE_DESCRIPTION("Zstd Decompressor");
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -71,7 +72,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) {
|
||||
#endif /* ZSTD_DEPS_MATH64 */
|
||||
#endif /* ZSTD_DEPS_NEED_MATH64 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* This is only requested when DEBUGLEVEL >= 1, meaning
|
||||
* it is disabled in production.
|
||||
* Need:
|
||||
@@ -88,7 +89,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) {
|
||||
#endif /* ZSTD_DEPS_ASSERT */
|
||||
#endif /* ZSTD_DEPS_NEED_ASSERT */
|
||||
|
||||
/*
|
||||
/*
|
||||
* This is only requested when DEBUGLEVEL >= 2, meaning
|
||||
* it is disabled in production.
|
||||
* Need:
|
||||
@@ -105,7 +106,7 @@ static uint64_t ZSTD_div64(uint64_t dividend, uint32_t divisor) {
|
||||
#endif /* ZSTD_DEPS_IO */
|
||||
#endif /* ZSTD_DEPS_NEED_IO */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Only requested when MSAN is enabled.
|
||||
* Need:
|
||||
* intptr_t
|
||||
|
||||
@@ -274,7 +274,7 @@ static void compress(
|
||||
return;
|
||||
}
|
||||
{
|
||||
auto err = ZSTD_resetCStream(ctx.get(), 0);
|
||||
auto err = ZSTD_CCtx_reset(ctx.get(), ZSTD_reset_session_only);
|
||||
if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) {
|
||||
return;
|
||||
}
|
||||
@@ -432,7 +432,7 @@ static void decompress(
|
||||
return;
|
||||
}
|
||||
{
|
||||
auto err = ZSTD_resetDStream(ctx.get());
|
||||
auto err = ZSTD_DCtx_reset(ctx.get(), ZSTD_reset_session_only);
|
||||
if (!errorHolder.check(!ZSTD_isError(err), ZSTD_getErrorName(err))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2019-present, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
# LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
# in the COPYING file in the root directory of this source tree).
|
||||
# ################################################################
|
||||
|
||||
.PHONY: all
|
||||
all: recover_directory
|
||||
|
||||
ZSTDLIBDIR ?= ../../lib
|
||||
PROGRAMDIR ?= ../../programs
|
||||
|
||||
CFLAGS ?= -O3
|
||||
CFLAGS += -I$(ZSTDLIBDIR) -I$(PROGRAMDIR)
|
||||
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
|
||||
-Wstrict-aliasing=1 -Wswitch-enum \
|
||||
-Wstrict-prototypes -Wundef \
|
||||
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
|
||||
-Wredundant-decls -Wmissing-prototypes
|
||||
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
|
||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
.PHONY: $(ZSTDLIBDIR)/libzstd.a
|
||||
$(ZSTDLIBDIR)/libzstd.a:
|
||||
$(MAKE) -C $(ZSTDLIBDIR) libzstd.a
|
||||
|
||||
recover_directory: recover_directory.c $(ZSTDLIBDIR)/libzstd.a $(PROGRAMDIR)/util.c
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f recover_directory
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ZSTD_STATIC_LINKING_ONLY
|
||||
#include "util.h"
|
||||
#include "zstd.h"
|
||||
|
||||
#define CHECK(cond, ...) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
fprintf(stderr, "%s:%d CHECK(%s) failed: ", __FILE__, __LINE__, #cond); \
|
||||
fprintf(stderr, "" __VA_ARGS__); \
|
||||
fprintf(stderr, "\n"); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void usage(char const *program) {
|
||||
fprintf(stderr, "USAGE: %s FILE.zst PREFIX\n", program);
|
||||
fprintf(stderr, "FILE.zst: A zstd compressed file with multiple frames\n");
|
||||
fprintf(stderr, "PREFIX: The output prefix. Uncompressed files will be "
|
||||
"created named ${PREFIX}0 ${PREFIX}1...\n\n");
|
||||
fprintf(stderr, "This program takes concatenated zstd frames and "
|
||||
"decompresses them into individual files.\n");
|
||||
fprintf(stderr, "E.g. files created with a command like: zstd -r directory "
|
||||
"-o file.zst\n");
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
size_t size;
|
||||
size_t frames;
|
||||
size_t maxFrameSize;
|
||||
} ZstdFrames;
|
||||
|
||||
static ZstdFrames readFile(char const *fileName) {
|
||||
U64 const fileSize = UTIL_getFileSize(fileName);
|
||||
CHECK(fileSize != UTIL_FILESIZE_UNKNOWN, "Unknown file size!");
|
||||
|
||||
char *const data = (char *)malloc(fileSize);
|
||||
CHECK(data != NULL, "Allocation failed");
|
||||
|
||||
FILE *file = fopen(fileName, "rb");
|
||||
CHECK(file != NULL, "fopen failed");
|
||||
|
||||
size_t const readSize = fread(data, 1, fileSize, file);
|
||||
CHECK(readSize == fileSize, "fread failed");
|
||||
|
||||
fclose(file);
|
||||
ZstdFrames frames;
|
||||
frames.data = (char *)data;
|
||||
frames.size = fileSize;
|
||||
frames.frames = 0;
|
||||
|
||||
size_t index;
|
||||
size_t maxFrameSize = 0;
|
||||
for (index = 0; index < fileSize;) {
|
||||
size_t const frameSize =
|
||||
ZSTD_findFrameCompressedSize(data + index, fileSize - index);
|
||||
CHECK(!ZSTD_isError(frameSize), "Bad zstd frame: %s",
|
||||
ZSTD_getErrorName(frameSize));
|
||||
if (frameSize > maxFrameSize)
|
||||
maxFrameSize = frameSize;
|
||||
frames.frames += 1;
|
||||
index += frameSize;
|
||||
}
|
||||
CHECK(index == fileSize, "Zstd file corrupt!");
|
||||
frames.maxFrameSize = maxFrameSize;
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
static int computePadding(size_t numFrames) {
|
||||
return snprintf(NULL, 0, "%u", (unsigned)numFrames);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 3) {
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
char const *const zstdFile = argv[1];
|
||||
char const *const prefix = argv[2];
|
||||
|
||||
ZstdFrames frames = readFile(zstdFile);
|
||||
|
||||
if (frames.frames <= 1) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"%s only has %u zstd frame. Simply use `zstd -d` to decompress it.\n",
|
||||
zstdFile, (unsigned)frames.frames);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int const padding = computePadding(frames.frames - 1);
|
||||
|
||||
size_t const outFileNameSize = strlen(prefix) + padding + 1;
|
||||
char* outFileName = malloc(outFileNameSize);
|
||||
CHECK(outFileName != NULL, "Allocation failure");
|
||||
|
||||
size_t const bufferSize = 128 * 1024;
|
||||
void *buffer = malloc(bufferSize);
|
||||
CHECK(buffer != NULL, "Allocation failure");
|
||||
|
||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
||||
CHECK(dctx != NULL, "Allocation failure");
|
||||
|
||||
fprintf(stderr, "Recovering %u files...\n", (unsigned)frames.frames);
|
||||
|
||||
size_t index;
|
||||
size_t frame = 0;
|
||||
for (index = 0; index < frames.size; ++frame) {
|
||||
size_t const frameSize =
|
||||
ZSTD_findFrameCompressedSize(frames.data + index, frames.size - index);
|
||||
|
||||
int const ret = snprintf(outFileName, outFileNameSize, "%s%0*u", prefix, padding, (unsigned)frame);
|
||||
CHECK(ret >= 0 && (size_t)ret <= outFileNameSize, "snprintf failed!");
|
||||
|
||||
FILE* outFile = fopen(outFileName, "wb");
|
||||
CHECK(outFile != NULL, "fopen failed");
|
||||
|
||||
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only);
|
||||
ZSTD_inBuffer in = {frames.data + index, frameSize, 0};
|
||||
while (in.pos < in.size) {
|
||||
ZSTD_outBuffer out = {buffer, bufferSize, 0};
|
||||
CHECK(!ZSTD_isError(ZSTD_decompressStream(dctx, &out, &in)), "decompression failed");
|
||||
size_t const writeSize = fwrite(out.dst, 1, out.pos, outFile);
|
||||
CHECK(writeSize == out.pos, "fwrite failed");
|
||||
}
|
||||
fclose(outFile);
|
||||
fprintf(stderr, "Recovered %s\n", outFileName);
|
||||
index += frameSize;
|
||||
}
|
||||
fprintf(stderr, "Complete\n");
|
||||
|
||||
free(outFileName);
|
||||
ZSTD_freeDCtx(dctx);
|
||||
free(buffer);
|
||||
free(frames.data);
|
||||
return 0;
|
||||
}
|
||||
@@ -16,13 +16,13 @@ ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME)
|
||||
CPPFLAGS += -I../ -I$(ZSTDLIB_PATH) -I$(ZSTDLIB_PATH)/common
|
||||
|
||||
CFLAGS ?= -O3
|
||||
CFLAGS += -g
|
||||
CFLAGS += -g -Wall -Wextra -Wcast-qual -Wcast-align -Wconversion \
|
||||
-Wformat=2 -Wstrict-aliasing=1
|
||||
|
||||
SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c $(ZSTDLIB)
|
||||
|
||||
.PHONY: default clean test
|
||||
|
||||
default: seekable_tests
|
||||
default: test
|
||||
|
||||
test: seekable_tests
|
||||
./seekable_tests
|
||||
@@ -30,9 +30,9 @@ test: seekable_tests
|
||||
$(ZSTDLIB):
|
||||
$(MAKE) -C $(ZSTDLIB_PATH) $(ZSTDLIB_NAME)
|
||||
|
||||
seekable_tests : seekable_tests.c $(SEEKABLE_OBJS)
|
||||
seekable_tests : $(SEEKABLE_OBJS)
|
||||
|
||||
clean:
|
||||
@rm -f core *.o tmp* result* *.zst \
|
||||
@$(RM) core *.o tmp* result* *.zst \
|
||||
seekable_tests
|
||||
@echo Cleaning completed
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // malloc
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "zstd_seekable.h"
|
||||
|
||||
@@ -8,7 +10,83 @@
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
unsigned testNb = 1;
|
||||
(void)argc; (void)argv;
|
||||
printf("Beginning zstd seekable format tests...\n");
|
||||
|
||||
printf("Test %u - simple round trip: ", testNb++);
|
||||
{ size_t const inSize = 4000;
|
||||
void* const inBuffer = malloc(inSize);
|
||||
assert(inBuffer != NULL);
|
||||
|
||||
size_t const seekCapacity = 5000;
|
||||
void* const seekBuffer = malloc(seekCapacity);
|
||||
assert(seekBuffer != NULL);
|
||||
size_t seekSize;
|
||||
|
||||
size_t const outCapacity = inSize;
|
||||
void* const outBuffer = malloc(outCapacity);
|
||||
assert(outBuffer != NULL);
|
||||
|
||||
ZSTD_seekable_CStream* const zscs = ZSTD_seekable_createCStream();
|
||||
assert(zscs != NULL);
|
||||
|
||||
{ size_t const initStatus = ZSTD_seekable_initCStream(zscs, 9, 0 /* checksumFlag */, (unsigned)inSize /* maxFrameSize */);
|
||||
assert(!ZSTD_isError(initStatus));
|
||||
}
|
||||
|
||||
{ ZSTD_outBuffer outb = { .dst=seekBuffer, .pos=0, .size=seekCapacity };
|
||||
ZSTD_inBuffer inb = { .src=inBuffer, .pos=0, .size=inSize };
|
||||
|
||||
size_t const cStatus = ZSTD_seekable_compressStream(zscs, &outb, &inb);
|
||||
assert(!ZSTD_isError(cStatus));
|
||||
assert(inb.pos == inb.size);
|
||||
|
||||
size_t const endStatus = ZSTD_seekable_endStream(zscs, &outb);
|
||||
assert(!ZSTD_isError(endStatus));
|
||||
seekSize = outb.pos;
|
||||
}
|
||||
|
||||
ZSTD_seekable* const stream = ZSTD_seekable_create();
|
||||
assert(stream != NULL);
|
||||
{ size_t const initStatus = ZSTD_seekable_initBuff(stream, seekBuffer, seekSize);
|
||||
assert(!ZSTD_isError(initStatus)); }
|
||||
|
||||
{ size_t const decStatus = ZSTD_seekable_decompress(stream, outBuffer, outCapacity, 0);
|
||||
assert(decStatus == inSize); }
|
||||
|
||||
/* unit test ZSTD_seekTable functions */
|
||||
ZSTD_seekTable* const zst = ZSTD_seekTable_create_fromSeekable(stream);
|
||||
assert(zst != NULL);
|
||||
|
||||
unsigned const nbFrames = ZSTD_seekTable_getNumFrames(zst);
|
||||
assert(nbFrames > 0);
|
||||
|
||||
unsigned long long const frame0Offset = ZSTD_seekTable_getFrameCompressedOffset(zst, 0);
|
||||
assert(frame0Offset == 0);
|
||||
|
||||
unsigned long long const content0Offset = ZSTD_seekTable_getFrameDecompressedOffset(zst, 0);
|
||||
assert(content0Offset == 0);
|
||||
|
||||
size_t const cSize = ZSTD_seekTable_getFrameCompressedSize(zst, 0);
|
||||
assert(!ZSTD_isError(cSize));
|
||||
assert(cSize <= seekCapacity);
|
||||
|
||||
size_t const origSize = ZSTD_seekTable_getFrameDecompressedSize(zst, 0);
|
||||
assert(origSize == inSize);
|
||||
|
||||
unsigned const fo1idx = ZSTD_seekTable_offsetToFrameIndex(zst, 1);
|
||||
assert(fo1idx == 0);
|
||||
|
||||
free(inBuffer);
|
||||
free(seekBuffer);
|
||||
free(outBuffer);
|
||||
ZSTD_seekable_freeCStream(zscs);
|
||||
ZSTD_seekTable_free(zst);
|
||||
ZSTD_seekable_free(stream);
|
||||
}
|
||||
printf("Success!\n");
|
||||
|
||||
|
||||
printf("Test %u - check that seekable decompress does not hang: ", testNb++);
|
||||
{ /* Github issue #2335 */
|
||||
const size_t compressed_size = 17;
|
||||
@@ -25,7 +103,7 @@ int main(int argc, const char** argv)
|
||||
'\x00',
|
||||
'\x00',
|
||||
'\x00',
|
||||
';',
|
||||
(uint8_t)('\x03'),
|
||||
(uint8_t)('\xb1'),
|
||||
(uint8_t)('\xea'),
|
||||
(uint8_t)('\x92'),
|
||||
@@ -34,6 +112,61 @@ int main(int argc, const char** argv)
|
||||
const size_t uncompressed_size = 32;
|
||||
uint8_t uncompressed_data[32];
|
||||
|
||||
ZSTD_seekable* const stream = ZSTD_seekable_create();
|
||||
assert(stream != NULL);
|
||||
{ size_t const status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size);
|
||||
if (ZSTD_isError(status)) {
|
||||
ZSTD_seekable_free(stream);
|
||||
goto _test_error;
|
||||
} }
|
||||
|
||||
/* Should return an error, but not hang */
|
||||
{ const size_t offset = 2;
|
||||
size_t const status = ZSTD_seekable_decompress(stream, uncompressed_data, uncompressed_size, offset);
|
||||
if (!ZSTD_isError(status)) {
|
||||
ZSTD_seekable_free(stream);
|
||||
goto _test_error;
|
||||
} }
|
||||
|
||||
ZSTD_seekable_free(stream);
|
||||
}
|
||||
printf("Success!\n");
|
||||
|
||||
printf("Test %u - check #2 that seekable decompress does not hang: ", testNb++);
|
||||
{ /* Github issue #FIXME */
|
||||
const size_t compressed_size = 27;
|
||||
const uint8_t compressed_data[27] = {
|
||||
(uint8_t)'\x28',
|
||||
(uint8_t)'\xb5',
|
||||
(uint8_t)'\x2f',
|
||||
(uint8_t)'\xfd',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x32',
|
||||
(uint8_t)'\x91',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x5e',
|
||||
(uint8_t)'\x2a',
|
||||
(uint8_t)'\x4d',
|
||||
(uint8_t)'\x18',
|
||||
(uint8_t)'\x09',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\x00',
|
||||
(uint8_t)'\xb1',
|
||||
(uint8_t)'\xea',
|
||||
(uint8_t)'\x92',
|
||||
(uint8_t)'\x8f',
|
||||
};
|
||||
const size_t uncompressed_size = 400;
|
||||
uint8_t uncompressed_data[400];
|
||||
|
||||
ZSTD_seekable* stream = ZSTD_seekable_create();
|
||||
size_t status = ZSTD_seekable_initBuff(stream, compressed_data, compressed_size);
|
||||
if (ZSTD_isError(status)) {
|
||||
|
||||
@@ -29,6 +29,7 @@ extern "C" {
|
||||
|
||||
typedef struct ZSTD_seekable_CStream_s ZSTD_seekable_CStream;
|
||||
typedef struct ZSTD_seekable_s ZSTD_seekable;
|
||||
typedef struct ZSTD_seekTable_s ZSTD_seekTable;
|
||||
|
||||
/*-****************************************************************************
|
||||
* Seekable compression - HowTo
|
||||
@@ -107,6 +108,7 @@ ZSTDLIB_API size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl);
|
||||
ZSTDLIB_API size_t ZSTD_seekable_logFrame(ZSTD_frameLog* fl, unsigned compressedSize, unsigned decompressedSize, unsigned checksum);
|
||||
ZSTDLIB_API size_t ZSTD_seekable_writeSeekTable(ZSTD_frameLog* fl, ZSTD_outBuffer* output);
|
||||
|
||||
|
||||
/*-****************************************************************************
|
||||
* Seekable decompression - HowTo
|
||||
* A ZSTD_seekable object is required to tracking the seekTable.
|
||||
@@ -161,13 +163,42 @@ ZSTDLIB_API size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t
|
||||
ZSTDLIB_API size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned frameIndex);
|
||||
|
||||
#define ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE (0ULL-2)
|
||||
/*===== Seek Table access functions =====*/
|
||||
ZSTDLIB_API unsigned ZSTD_seekable_getNumFrames(ZSTD_seekable* const zs);
|
||||
ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameCompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex);
|
||||
ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameDecompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex);
|
||||
ZSTDLIB_API size_t ZSTD_seekable_getFrameCompressedSize(ZSTD_seekable* const zs, unsigned frameIndex);
|
||||
ZSTDLIB_API size_t ZSTD_seekable_getFrameDecompressedSize(ZSTD_seekable* const zs, unsigned frameIndex);
|
||||
ZSTDLIB_API unsigned ZSTD_seekable_offsetToFrameIndex(ZSTD_seekable* const zs, unsigned long long offset);
|
||||
/*===== Seekable seek table access functions =====*/
|
||||
ZSTDLIB_API unsigned ZSTD_seekable_getNumFrames(const ZSTD_seekable* zs);
|
||||
ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameCompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex);
|
||||
ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameDecompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex);
|
||||
ZSTDLIB_API size_t ZSTD_seekable_getFrameCompressedSize(const ZSTD_seekable* zs, unsigned frameIndex);
|
||||
ZSTDLIB_API size_t ZSTD_seekable_getFrameDecompressedSize(const ZSTD_seekable* zs, unsigned frameIndex);
|
||||
ZSTDLIB_API unsigned ZSTD_seekable_offsetToFrameIndex(const ZSTD_seekable* zs, unsigned long long offset);
|
||||
|
||||
|
||||
/*-****************************************************************************
|
||||
* Direct exploitation of the seekTable
|
||||
*
|
||||
* Memory constrained use cases that manage multiple archives
|
||||
* benefit from retaining multiple archive seek tables
|
||||
* without retaining a ZSTD_seekable instance for each.
|
||||
*
|
||||
* Below API allow the above-mentioned use cases
|
||||
* to initialize a ZSTD_seekable, extract its (smaller) ZSTD_seekTable,
|
||||
* then throw the ZSTD_seekable away to save memory.
|
||||
*
|
||||
* Standard ZSTD operations can then be used
|
||||
* to decompress frames based on seek table offsets.
|
||||
******************************************************************************/
|
||||
|
||||
/*===== Independent seek table management =====*/
|
||||
ZSTDLIB_API ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs);
|
||||
ZSTDLIB_API size_t ZSTD_seekTable_free(ZSTD_seekTable* st);
|
||||
|
||||
/*===== Direct seek table access functions =====*/
|
||||
ZSTDLIB_API unsigned ZSTD_seekTable_getNumFrames(const ZSTD_seekTable* st);
|
||||
ZSTDLIB_API unsigned long long ZSTD_seekTable_getFrameCompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex);
|
||||
ZSTDLIB_API unsigned long long ZSTD_seekTable_getFrameDecompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex);
|
||||
ZSTDLIB_API size_t ZSTD_seekTable_getFrameCompressedSize(const ZSTD_seekTable* st, unsigned frameIndex);
|
||||
ZSTDLIB_API size_t ZSTD_seekTable_getFrameDecompressedSize(const ZSTD_seekTable* st, unsigned frameIndex);
|
||||
ZSTDLIB_API unsigned ZSTD_seekTable_offsetToFrameIndex(const ZSTD_seekTable* st, unsigned long long offset);
|
||||
|
||||
|
||||
/*===== Seekable advanced I/O API =====*/
|
||||
typedef int(ZSTD_seekable_read)(void* opaque, void* buffer, size_t n);
|
||||
|
||||
@@ -53,7 +53,7 @@ __`Frame_Size`__
|
||||
The total size of the skippable frame, not including the `Skippable_Magic_Number` or `Frame_Size`.
|
||||
This is for compatibility with [Zstandard skippable frames].
|
||||
|
||||
[Zstandard skippable frames]: https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#skippable-frames
|
||||
[Zstandard skippable frames]: https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#skippable-frames
|
||||
|
||||
#### `Seek_Table_Footer`
|
||||
The seek table footer format is as follows:
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "zstd.h"
|
||||
#include "zstd_errors.h"
|
||||
#include "mem.h"
|
||||
|
||||
#include "zstd_seekable.h"
|
||||
|
||||
#define CHECK_Z(f) { size_t const ret = (f); if (ret != 0) return ret; }
|
||||
@@ -63,19 +64,18 @@ struct ZSTD_seekable_CStream_s {
|
||||
int writingSeekTable;
|
||||
};
|
||||
|
||||
size_t ZSTD_seekable_frameLog_allocVec(ZSTD_frameLog* fl)
|
||||
static size_t ZSTD_seekable_frameLog_allocVec(ZSTD_frameLog* fl)
|
||||
{
|
||||
/* allocate some initial space */
|
||||
size_t const FRAMELOG_STARTING_CAPACITY = 16;
|
||||
fl->entries = (framelogEntry_t*)malloc(
|
||||
sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY);
|
||||
if (fl->entries == NULL) return ERROR(memory_allocation);
|
||||
fl->capacity = FRAMELOG_STARTING_CAPACITY;
|
||||
|
||||
fl->capacity = (U32)FRAMELOG_STARTING_CAPACITY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ZSTD_seekable_frameLog_freeVec(ZSTD_frameLog* fl)
|
||||
static size_t ZSTD_seekable_frameLog_freeVec(ZSTD_frameLog* fl)
|
||||
{
|
||||
if (fl != NULL) free(fl->entries);
|
||||
return 0;
|
||||
@@ -83,7 +83,7 @@ size_t ZSTD_seekable_frameLog_freeVec(ZSTD_frameLog* fl)
|
||||
|
||||
ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag)
|
||||
{
|
||||
ZSTD_frameLog* fl = malloc(sizeof(ZSTD_frameLog));
|
||||
ZSTD_frameLog* const fl = malloc(sizeof(ZSTD_frameLog));
|
||||
if (fl == NULL) return NULL;
|
||||
|
||||
if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(fl))) {
|
||||
@@ -106,10 +106,9 @@ size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZSTD_seekable_CStream* ZSTD_seekable_createCStream()
|
||||
ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void)
|
||||
{
|
||||
ZSTD_seekable_CStream* zcs = malloc(sizeof(ZSTD_seekable_CStream));
|
||||
|
||||
ZSTD_seekable_CStream* const zcs = malloc(sizeof(ZSTD_seekable_CStream));
|
||||
if (zcs == NULL) return NULL;
|
||||
|
||||
memset(zcs, 0, sizeof(*zcs));
|
||||
@@ -134,7 +133,6 @@ size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs)
|
||||
ZSTD_freeCStream(zcs->cstream);
|
||||
ZSTD_seekable_frameLog_freeVec(&zcs->framelog);
|
||||
free(zcs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -152,9 +150,8 @@ size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs,
|
||||
return ERROR(frameParameter_unsupported);
|
||||
}
|
||||
|
||||
zcs->maxFrameSize = maxFrameSize
|
||||
? maxFrameSize
|
||||
: ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE;
|
||||
zcs->maxFrameSize = maxFrameSize ?
|
||||
maxFrameSize : ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE;
|
||||
|
||||
zcs->framelog.checksumFlag = checksumFlag;
|
||||
if (zcs->framelog.checksumFlag) {
|
||||
@@ -204,7 +201,7 @@ size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output
|
||||
/* end the frame */
|
||||
size_t ret = ZSTD_endStream(zcs->cstream, output);
|
||||
|
||||
zcs->frameCSize += output->pos - prevOutPos;
|
||||
zcs->frameCSize += (U32)(output->pos - prevOutPos);
|
||||
|
||||
/* need to flush before doing the rest */
|
||||
if (ret) return ret;
|
||||
@@ -223,9 +220,8 @@ size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output
|
||||
zcs->frameCSize = 0;
|
||||
zcs->frameDSize = 0;
|
||||
|
||||
ZSTD_resetCStream(zcs->cstream, 0);
|
||||
if (zcs->framelog.checksumFlag)
|
||||
XXH64_reset(&zcs->xxhState, 0);
|
||||
ZSTD_CCtx_reset(zcs->cstream, ZSTD_reset_session_only);
|
||||
if (zcs->framelog.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -248,8 +244,8 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer*
|
||||
XXH64_update(&zcs->xxhState, inBase, inTmp.pos);
|
||||
}
|
||||
|
||||
zcs->frameCSize += output->pos - prevOutPos;
|
||||
zcs->frameDSize += inTmp.pos;
|
||||
zcs->frameCSize += (U32)(output->pos - prevOutPos);
|
||||
zcs->frameDSize += (U32)inTmp.pos;
|
||||
|
||||
input->pos += inTmp.pos;
|
||||
|
||||
@@ -290,7 +286,7 @@ static inline size_t ZSTD_stwrite32(ZSTD_frameLog* fl,
|
||||
memcpy((BYTE*)output->dst + output->pos,
|
||||
tmp + (fl->seekTablePos - offset), lenWrite);
|
||||
output->pos += lenWrite;
|
||||
fl->seekTablePos += lenWrite;
|
||||
fl->seekTablePos += (U32)lenWrite;
|
||||
|
||||
if (lenWrite < 4) return ZSTD_seekable_seekTableSize(fl) - fl->seekTablePos;
|
||||
}
|
||||
@@ -339,8 +335,7 @@ size_t ZSTD_seekable_writeSeekTable(ZSTD_frameLog* fl, ZSTD_outBuffer* output)
|
||||
|
||||
if (output->size - output->pos < 1) return seekTableLen - fl->seekTablePos;
|
||||
if (fl->seekTablePos < seekTableLen - 4) {
|
||||
BYTE sfd = 0;
|
||||
sfd |= (fl->checksumFlag) << 7;
|
||||
BYTE const sfd = (BYTE)((fl->checksumFlag) << 7);
|
||||
|
||||
((BYTE*)output->dst)[output->pos] = sfd;
|
||||
output->pos++;
|
||||
|
||||
@@ -107,7 +107,8 @@ typedef struct {
|
||||
|
||||
static int ZSTD_seekable_read_buff(void* opaque, void* buffer, size_t n)
|
||||
{
|
||||
buffWrapper_t* buff = (buffWrapper_t*) opaque;
|
||||
buffWrapper_t* const buff = (buffWrapper_t*)opaque;
|
||||
assert(buff != NULL);
|
||||
if (buff->pos + n > buff->size) return -1;
|
||||
memcpy(buffer, (const BYTE*)buff->ptr + buff->pos, n);
|
||||
buff->pos += n;
|
||||
@@ -118,15 +119,17 @@ static int ZSTD_seekable_seek_buff(void* opaque, long long offset, int origin)
|
||||
{
|
||||
buffWrapper_t* const buff = (buffWrapper_t*) opaque;
|
||||
unsigned long long newOffset;
|
||||
assert(buff != NULL);
|
||||
switch (origin) {
|
||||
case SEEK_SET:
|
||||
newOffset = offset;
|
||||
assert(offset >= 0);
|
||||
newOffset = (unsigned long long)offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
newOffset = (unsigned long long)buff->pos + offset;
|
||||
newOffset = (unsigned long long)((long long)buff->pos + offset);
|
||||
break;
|
||||
case SEEK_END:
|
||||
newOffset = (unsigned long long)buff->size + offset;
|
||||
newOffset = (unsigned long long)((long long)buff->size + offset);
|
||||
break;
|
||||
default:
|
||||
assert(0); /* not possible */
|
||||
@@ -144,18 +147,18 @@ typedef struct {
|
||||
U32 checksum;
|
||||
} seekEntry_t;
|
||||
|
||||
typedef struct {
|
||||
struct ZSTD_seekTable_s {
|
||||
seekEntry_t* entries;
|
||||
size_t tableLen;
|
||||
|
||||
int checksumFlag;
|
||||
} seekTable_t;
|
||||
};
|
||||
|
||||
#define SEEKABLE_BUFF_SIZE ZSTD_BLOCKSIZE_MAX
|
||||
|
||||
struct ZSTD_seekable_s {
|
||||
ZSTD_DStream* dstream;
|
||||
seekTable_t seekTable;
|
||||
ZSTD_seekTable seekTable;
|
||||
ZSTD_seekable_customFile src;
|
||||
|
||||
U64 decompressedOffset;
|
||||
@@ -173,8 +176,7 @@ struct ZSTD_seekable_s {
|
||||
|
||||
ZSTD_seekable* ZSTD_seekable_create(void)
|
||||
{
|
||||
ZSTD_seekable* zs = malloc(sizeof(ZSTD_seekable));
|
||||
|
||||
ZSTD_seekable* const zs = malloc(sizeof(ZSTD_seekable));
|
||||
if (zs == NULL) return NULL;
|
||||
|
||||
/* also initializes stage to zsds_init */
|
||||
@@ -195,7 +197,35 @@ size_t ZSTD_seekable_free(ZSTD_seekable* zs)
|
||||
ZSTD_freeDStream(zs->dstream);
|
||||
free(zs->seekTable.entries);
|
||||
free(zs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs)
|
||||
{
|
||||
ZSTD_seekTable* const st = malloc(sizeof(ZSTD_seekTable));
|
||||
if (st==NULL) return NULL;
|
||||
|
||||
st->checksumFlag = zs->seekTable.checksumFlag;
|
||||
st->tableLen = zs->seekTable.tableLen;
|
||||
|
||||
/* Allocate an extra entry at the end to match logic of initial allocation */
|
||||
size_t const entriesSize = sizeof(seekEntry_t) * (zs->seekTable.tableLen + 1);
|
||||
seekEntry_t* const entries = (seekEntry_t*)malloc(entriesSize);
|
||||
if (entries==NULL) {
|
||||
free(st);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(entries, zs->seekTable.entries, entriesSize);
|
||||
st->entries = entries;
|
||||
return st;
|
||||
}
|
||||
|
||||
size_t ZSTD_seekTable_free(ZSTD_seekTable* st)
|
||||
{
|
||||
if (st == NULL) return 0; /* support free on null */
|
||||
free(st->entries);
|
||||
free(st);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -203,19 +233,24 @@ size_t ZSTD_seekable_free(ZSTD_seekable* zs)
|
||||
* Performs a binary search to find the last frame with a decompressed offset
|
||||
* <= pos
|
||||
* @return : the frame's index */
|
||||
unsigned ZSTD_seekable_offsetToFrameIndex(ZSTD_seekable* const zs, unsigned long long pos)
|
||||
unsigned ZSTD_seekable_offsetToFrameIndex(const ZSTD_seekable* zs, unsigned long long pos)
|
||||
{
|
||||
return ZSTD_seekTable_offsetToFrameIndex(&zs->seekTable, pos);
|
||||
}
|
||||
|
||||
unsigned ZSTD_seekTable_offsetToFrameIndex(const ZSTD_seekTable* st, unsigned long long pos)
|
||||
{
|
||||
U32 lo = 0;
|
||||
U32 hi = (U32)zs->seekTable.tableLen;
|
||||
assert(zs->seekTable.tableLen <= UINT_MAX);
|
||||
U32 hi = (U32)st->tableLen;
|
||||
assert(st->tableLen <= UINT_MAX);
|
||||
|
||||
if (pos >= zs->seekTable.entries[zs->seekTable.tableLen].dOffset) {
|
||||
return (U32)zs->seekTable.tableLen;
|
||||
if (pos >= st->entries[st->tableLen].dOffset) {
|
||||
return (unsigned)st->tableLen;
|
||||
}
|
||||
|
||||
while (lo + 1 < hi) {
|
||||
U32 const mid = lo + ((hi - lo) >> 1);
|
||||
if (zs->seekTable.entries[mid].dOffset <= pos) {
|
||||
if (st->entries[mid].dOffset <= pos) {
|
||||
lo = mid;
|
||||
} else {
|
||||
hi = mid;
|
||||
@@ -224,36 +259,61 @@ unsigned ZSTD_seekable_offsetToFrameIndex(ZSTD_seekable* const zs, unsigned long
|
||||
return lo;
|
||||
}
|
||||
|
||||
unsigned ZSTD_seekable_getNumFrames(ZSTD_seekable* const zs)
|
||||
unsigned ZSTD_seekable_getNumFrames(const ZSTD_seekable* zs)
|
||||
{
|
||||
assert(zs->seekTable.tableLen <= UINT_MAX);
|
||||
return (unsigned)zs->seekTable.tableLen;
|
||||
return ZSTD_seekTable_getNumFrames(&zs->seekTable);
|
||||
}
|
||||
|
||||
unsigned long long ZSTD_seekable_getFrameCompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex)
|
||||
unsigned ZSTD_seekTable_getNumFrames(const ZSTD_seekTable* st)
|
||||
{
|
||||
if (frameIndex >= zs->seekTable.tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE;
|
||||
return zs->seekTable.entries[frameIndex].cOffset;
|
||||
assert(st->tableLen <= UINT_MAX);
|
||||
return (unsigned)st->tableLen;
|
||||
}
|
||||
|
||||
unsigned long long ZSTD_seekable_getFrameDecompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex)
|
||||
unsigned long long ZSTD_seekable_getFrameCompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex)
|
||||
{
|
||||
if (frameIndex >= zs->seekTable.tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE;
|
||||
return zs->seekTable.entries[frameIndex].dOffset;
|
||||
return ZSTD_seekTable_getFrameCompressedOffset(&zs->seekTable, frameIndex);
|
||||
}
|
||||
|
||||
size_t ZSTD_seekable_getFrameCompressedSize(ZSTD_seekable* const zs, unsigned frameIndex)
|
||||
unsigned long long ZSTD_seekTable_getFrameCompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex)
|
||||
{
|
||||
if (frameIndex >= zs->seekTable.tableLen) return ERROR(frameIndex_tooLarge);
|
||||
return zs->seekTable.entries[frameIndex + 1].cOffset -
|
||||
zs->seekTable.entries[frameIndex].cOffset;
|
||||
if (frameIndex >= st->tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE;
|
||||
return st->entries[frameIndex].cOffset;
|
||||
}
|
||||
|
||||
size_t ZSTD_seekable_getFrameDecompressedSize(ZSTD_seekable* const zs, unsigned frameIndex)
|
||||
unsigned long long ZSTD_seekable_getFrameDecompressedOffset(const ZSTD_seekable* zs, unsigned frameIndex)
|
||||
{
|
||||
if (frameIndex > zs->seekTable.tableLen) return ERROR(frameIndex_tooLarge);
|
||||
return zs->seekTable.entries[frameIndex + 1].dOffset -
|
||||
zs->seekTable.entries[frameIndex].dOffset;
|
||||
return ZSTD_seekTable_getFrameDecompressedOffset(&zs->seekTable, frameIndex);
|
||||
}
|
||||
|
||||
unsigned long long ZSTD_seekTable_getFrameDecompressedOffset(const ZSTD_seekTable* st, unsigned frameIndex)
|
||||
{
|
||||
if (frameIndex >= st->tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE;
|
||||
return st->entries[frameIndex].dOffset;
|
||||
}
|
||||
|
||||
size_t ZSTD_seekable_getFrameCompressedSize(const ZSTD_seekable* zs, unsigned frameIndex)
|
||||
{
|
||||
return ZSTD_seekTable_getFrameCompressedSize(&zs->seekTable, frameIndex);
|
||||
}
|
||||
|
||||
size_t ZSTD_seekTable_getFrameCompressedSize(const ZSTD_seekTable* st, unsigned frameIndex)
|
||||
{
|
||||
if (frameIndex >= st->tableLen) return ERROR(frameIndex_tooLarge);
|
||||
return st->entries[frameIndex + 1].cOffset -
|
||||
st->entries[frameIndex].cOffset;
|
||||
}
|
||||
|
||||
size_t ZSTD_seekable_getFrameDecompressedSize(const ZSTD_seekable* zs, unsigned frameIndex)
|
||||
{
|
||||
return ZSTD_seekTable_getFrameDecompressedSize(&zs->seekTable, frameIndex);
|
||||
}
|
||||
|
||||
size_t ZSTD_seekTable_getFrameDecompressedSize(const ZSTD_seekTable* st, unsigned frameIndex)
|
||||
{
|
||||
if (frameIndex > st->tableLen) return ERROR(frameIndex_tooLarge);
|
||||
return st->entries[frameIndex + 1].dOffset -
|
||||
st->entries[frameIndex].dOffset;
|
||||
}
|
||||
|
||||
static size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable* zs)
|
||||
@@ -272,10 +332,9 @@ static size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable* zs)
|
||||
checksumFlag = sfd >> 7;
|
||||
|
||||
/* check reserved bits */
|
||||
if ((checksumFlag >> 2) & 0x1f) {
|
||||
if ((sfd >> 2) & 0x1f) {
|
||||
return ERROR(corruption_detected);
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
||||
{ U32 const numFrames = MEM_readLE32(zs->inBuff);
|
||||
U32 const sizePerEntry = 8 + (checksumFlag?4:0);
|
||||
@@ -283,12 +342,9 @@ static size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable* zs)
|
||||
U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_SKIPPABLEHEADERSIZE;
|
||||
|
||||
U32 remaining = frameSize - ZSTD_seekTableFooterSize; /* don't need to re-read footer */
|
||||
{
|
||||
U32 const toRead = MIN(remaining, SEEKABLE_BUFF_SIZE);
|
||||
|
||||
{ U32 const toRead = MIN(remaining, SEEKABLE_BUFF_SIZE);
|
||||
CHECK_IO(src.seek(src.opaque, -(S64)frameSize, SEEK_END));
|
||||
CHECK_IO(src.read(src.opaque, zs->inBuff, toRead));
|
||||
|
||||
remaining -= toRead;
|
||||
}
|
||||
|
||||
@@ -301,19 +357,15 @@ static size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable* zs)
|
||||
|
||||
{ /* Allocate an extra entry at the end so that we can do size
|
||||
* computations on the last element without special case */
|
||||
seekEntry_t* entries = (seekEntry_t*)malloc(sizeof(seekEntry_t) * (numFrames + 1));
|
||||
seekEntry_t* const entries = (seekEntry_t*)malloc(sizeof(seekEntry_t) * (numFrames + 1));
|
||||
|
||||
U32 idx = 0;
|
||||
U32 pos = 8;
|
||||
|
||||
|
||||
U64 cOffset = 0;
|
||||
U64 dOffset = 0;
|
||||
|
||||
if (!entries) {
|
||||
free(entries);
|
||||
return ERROR(memory_allocation);
|
||||
}
|
||||
if (entries == NULL) return ERROR(memory_allocation);
|
||||
|
||||
/* compute cumulative positions */
|
||||
for (; idx < numFrames; idx++) {
|
||||
@@ -383,24 +435,30 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
|
||||
{
|
||||
U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset);
|
||||
U32 noOutputProgressCount = 0;
|
||||
size_t srcBytesRead = 0;
|
||||
do {
|
||||
/* check if we can continue from a previous decompress job */
|
||||
if (targetFrame != zs->curFrame || offset != zs->decompressedOffset) {
|
||||
zs->decompressedOffset = zs->seekTable.entries[targetFrame].dOffset;
|
||||
zs->curFrame = targetFrame;
|
||||
|
||||
assert(zs->seekTable.entries[targetFrame].cOffset < LLONG_MAX);
|
||||
CHECK_IO(zs->src.seek(zs->src.opaque,
|
||||
zs->seekTable.entries[targetFrame].cOffset,
|
||||
(long long)zs->seekTable.entries[targetFrame].cOffset,
|
||||
SEEK_SET));
|
||||
zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0};
|
||||
XXH64_reset(&zs->xxhState, 0);
|
||||
ZSTD_resetDStream(zs->dstream);
|
||||
ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only);
|
||||
if (srcBytesRead > zs->buffWrapper.size) {
|
||||
return ERROR(seekableIO);
|
||||
}
|
||||
}
|
||||
|
||||
while (zs->decompressedOffset < offset + len) {
|
||||
size_t toRead;
|
||||
ZSTD_outBuffer outTmp;
|
||||
size_t prevOutPos;
|
||||
size_t prevInPos;
|
||||
size_t forwardProgress;
|
||||
if (zs->decompressedOffset < offset) {
|
||||
/* dummy decompressions until we get to the target offset */
|
||||
@@ -410,6 +468,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
|
||||
}
|
||||
|
||||
prevOutPos = outTmp.pos;
|
||||
prevInPos = zs->in.pos;
|
||||
toRead = ZSTD_decompressStream(zs->dstream, &outTmp, &zs->in);
|
||||
if (ZSTD_isError(toRead)) {
|
||||
return toRead;
|
||||
@@ -428,6 +487,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
|
||||
noOutputProgressCount = 0;
|
||||
}
|
||||
zs->decompressedOffset += forwardProgress;
|
||||
srcBytesRead += zs->in.pos - prevInPos;
|
||||
|
||||
if (toRead == 0) {
|
||||
/* frame complete */
|
||||
@@ -453,7 +513,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
|
||||
zs->in.size = toRead;
|
||||
zs->in.pos = 0;
|
||||
}
|
||||
}
|
||||
} /* while (zs->decompressedOffset < offset + len) */
|
||||
} while (zs->decompressedOffset != offset + len);
|
||||
|
||||
return len;
|
||||
@@ -465,8 +525,7 @@ size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSiz
|
||||
return ERROR(frameIndex_tooLarge);
|
||||
}
|
||||
|
||||
{
|
||||
size_t const decompressedSize =
|
||||
{ size_t const decompressedSize =
|
||||
zs->seekTable.entries[frameIndex + 1].dOffset -
|
||||
zs->seekTable.entries[frameIndex].dOffset;
|
||||
if (dstSize < decompressedSize) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* \endcode
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -42,6 +42,7 @@
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#define ZSTD_MULTITHREAD
|
||||
#endif
|
||||
#define ZSTD_TRACE 0
|
||||
|
||||
/* Include zstd_deps.h first with all the options we need enabled. */
|
||||
#define ZSTD_DEPS_NEED_MALLOC
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* \endcode
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -38,6 +38,7 @@
|
||||
#define XXH_INLINE_ALL
|
||||
#define ZSTD_LEGACY_SUPPORT 0
|
||||
#define ZSTD_STRIP_ERROR_STRINGS
|
||||
#define ZSTD_TRACE 0
|
||||
|
||||
/* Include zstd_deps.h first with all the options we need enabled. */
|
||||
#define ZSTD_DEPS_NEED_MALLOC
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -3,7 +3,7 @@ Zstandard Compression Format
|
||||
|
||||
### Notices
|
||||
|
||||
Copyright (c) 2016-2020 Yann Collet, Facebook, Inc.
|
||||
Copyright (c) 2016-2021 Yann Collet, Facebook, Inc.
|
||||
|
||||
Permission is granted to copy and distribute this document
|
||||
for any purpose and without charge,
|
||||
|
||||
+38
-7
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>zstd 1.4.7 Manual</title>
|
||||
<title>zstd 1.4.9 Manual</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>zstd 1.4.7 Manual</h1>
|
||||
<h1>zstd 1.4.9 Manual</h1>
|
||||
<hr>
|
||||
<a name="Contents"></a><h2>Contents</h2>
|
||||
<ol>
|
||||
@@ -473,12 +473,14 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
||||
* ZSTD_d_format
|
||||
* ZSTD_d_stableOutBuffer
|
||||
* ZSTD_d_forceIgnoreChecksum
|
||||
* ZSTD_d_refMultipleDDicts
|
||||
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
|
||||
* note : never ever use experimentalParam? names directly
|
||||
*/
|
||||
ZSTD_d_experimentalParam1=1000,
|
||||
ZSTD_d_experimentalParam2=1001,
|
||||
ZSTD_d_experimentalParam3=1002
|
||||
ZSTD_d_experimentalParam3=1002,
|
||||
ZSTD_d_experimentalParam4=1003
|
||||
|
||||
} ZSTD_dParameter;
|
||||
</b></pre><BR>
|
||||
@@ -816,7 +818,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds);
|
||||
</b><p> Reference a prepared dictionary, to be used for all next compressed frames.
|
||||
Note that compression parameters are enforced from within CDict,
|
||||
and supersede any compression parameter previously set within CCtx.
|
||||
The parameters ignored are labled as "superseded-by-cdict" in the ZSTD_cParameter enum docs.
|
||||
The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs.
|
||||
The ignored parameters will be used again if the CCtx is returned to no-dictionary mode.
|
||||
The dictionary will remain valid for future compressed frames using same CCtx.
|
||||
@result : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
@@ -867,6 +869,13 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds);
|
||||
<pre><b>size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
|
||||
</b><p> Reference a prepared dictionary, to be used to decompress next frames.
|
||||
The dictionary remains active for decompression of future frames using same DCtx.
|
||||
|
||||
If called with ZSTD_d_refMultipleDDicts enabled, repeated calls of this function
|
||||
will store the DDict references in a table, and the DDict used for decompression
|
||||
will be determined at decompression time, as per the dict ID in the frame.
|
||||
The memory for the table is allocated on the first call to refDDict, and can be
|
||||
freed with ZSTD_freeDCtx().
|
||||
|
||||
@result : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
Note 1 : Currently, only one dictionary can be managed.
|
||||
Referencing a new dictionary effectively "discards" any previous one.
|
||||
@@ -995,6 +1004,12 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
||||
ZSTD_d_ignoreChecksum = 1
|
||||
} ZSTD_forceIgnoreChecksum_e;
|
||||
</b></pre><BR>
|
||||
<pre><b>typedef enum {
|
||||
</b>/* Note: this enum controls ZSTD_d_refMultipleDDicts */<b>
|
||||
ZSTD_rmd_refSingleDDict = 0,
|
||||
ZSTD_rmd_refMultipleDDicts = 1
|
||||
} ZSTD_refMultipleDDicts_e;
|
||||
</b></pre><BR>
|
||||
<pre><b>typedef enum {
|
||||
</b>/* Note: this enum and the behavior it controls are effectively internal<b>
|
||||
* implementation details of the compressor. They are expected to continue
|
||||
@@ -1073,7 +1088,7 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
||||
`srcSize` must be the _exact_ size of this series
|
||||
(i.e. there should be a frame boundary at `src + srcSize`)
|
||||
@return : - upper-bound for the decompressed size of all data in all successive frames
|
||||
- if an error occured: ZSTD_CONTENTSIZE_ERROR
|
||||
- if an error occurred: ZSTD_CONTENTSIZE_ERROR
|
||||
|
||||
note 1 : an error can occur if `src` contains an invalid or incorrectly formatted frame.
|
||||
note 2 : the upper-bound is exact when the decompressed size field is available in every ZSTD encoded frame of `src`.
|
||||
@@ -1155,6 +1170,22 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
|
||||
|
||||
</p></pre><BR>
|
||||
|
||||
<pre><b>size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
|
||||
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 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.
|
||||
|
||||
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).
|
||||
|
||||
@return : number of bytes written or a ZSTD error.
|
||||
|
||||
</p></pre><BR>
|
||||
|
||||
<a name="Chapter16"></a><h2>Memory management</h2><pre></pre>
|
||||
|
||||
<pre><b>size_t ZSTD_estimateCCtxSize(int compressionLevel);
|
||||
@@ -1328,7 +1359,7 @@ ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; </b>/**< this con
|
||||
how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?)
|
||||
</p></pre><BR>
|
||||
|
||||
<pre><b>size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
|
||||
<pre><b>size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
|
||||
</b><p> Get the requested compression parameter value, selected by enum ZSTD_cParameter,
|
||||
and store it into int* value.
|
||||
@return : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
@@ -1382,7 +1413,7 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
|
||||
|
||||
</p></pre><BR>
|
||||
|
||||
<pre><b>size_t ZSTD_CCtxParams_getParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
|
||||
<pre><b>size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
|
||||
</b><p> Similar to ZSTD_CCtx_getParameter.
|
||||
Get the requested value of one compression parameter, selected by enum ZSTD_cParameter.
|
||||
@result : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020 Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Martin Liska, SUSE, Facebook, Inc.
|
||||
* Copyright (c) Martin Liska, SUSE, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+11
-9
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -179,6 +179,8 @@ ifeq ($(UNAME), Darwin)
|
||||
HASH ?= md5
|
||||
else ifeq ($(UNAME), FreeBSD)
|
||||
HASH ?= gmd5sum
|
||||
else ifeq ($(UNAME), NetBSD)
|
||||
HASH ?= md5 -n
|
||||
else ifeq ($(UNAME), OpenBSD)
|
||||
HASH ?= md5
|
||||
endif
|
||||
@@ -208,20 +210,17 @@ else
|
||||
endif
|
||||
|
||||
SET_CACHE_DIRECTORY = \
|
||||
$(MAKE) --no-print-directory $@ \
|
||||
+$(MAKE) --no-print-directory $@ \
|
||||
BUILD_DIR=obj/$(HASH_DIR) \
|
||||
CPPFLAGS="$(CPPFLAGS)" \
|
||||
CFLAGS="$(CFLAGS)" \
|
||||
LDFLAGS="$(LDFLAGS)"
|
||||
|
||||
|
||||
.PHONY: lib-all all clean install uninstall
|
||||
|
||||
# alias
|
||||
lib-all: all
|
||||
|
||||
.PHONY: all
|
||||
all: lib
|
||||
|
||||
|
||||
.PHONY: libzstd.a # must be run every time
|
||||
|
||||
ifndef BUILD_DIR
|
||||
@@ -258,8 +257,8 @@ else # not Windows
|
||||
|
||||
LIBZSTD = libzstd.$(SHARED_EXT_VER)
|
||||
.PHONY: $(LIBZSTD) # must be run every time
|
||||
$(LIBZSTD): CFLAGS += -fPIC
|
||||
$(LIBZSTD): LDFLAGS += -shared -fvisibility=hidden
|
||||
$(LIBZSTD): CFLAGS += -fPIC -fvisibility=hidden
|
||||
$(LIBZSTD): LDFLAGS += -shared
|
||||
|
||||
ifndef BUILD_DIR
|
||||
# determine BUILD_DIR from compilation flags
|
||||
@@ -339,6 +338,7 @@ libzstd-nomt: $(ZSTD_NOMT_FILES)
|
||||
@echo files : $(ZSTD_NOMT_FILES)
|
||||
$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) -r *.dSYM # macOS-specific
|
||||
$(RM) core *.o *.a *.gcda *.$(SHARED_EXT) *.$(SHARED_EXT).* libzstd.pc
|
||||
@@ -407,6 +407,7 @@ libzstd.pc: libzstd.pc.in
|
||||
-e 's|@VERSION@|$(VERSION)|' \
|
||||
$< >$@
|
||||
|
||||
.PHONY: install
|
||||
install: install-pc install-static install-shared install-includes
|
||||
@echo zstd static and shared library installed
|
||||
|
||||
@@ -437,6 +438,7 @@ install-includes:
|
||||
$(INSTALL_DATA) common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)
|
||||
$(INSTALL_DATA) dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
$(RM) $(DESTDIR)$(LIBDIR)/libzstd.a
|
||||
$(RM) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* bitstream
|
||||
* Part of FSE library
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
@@ -293,22 +293,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
|
||||
switch(srcSize)
|
||||
{
|
||||
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
+35
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -90,6 +90,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* target attribute */
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
@@ -206,6 +207,39 @@
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
|
||||
/* C-language Attributes are added in C23. */
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
|
||||
# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
|
||||
#else
|
||||
# define ZSTD_HAS_C_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
|
||||
/* Only use C++ attributes in C++. Some compilers report support for C++
|
||||
* attributes when compiling with C.
|
||||
*/
|
||||
#if defined(__cplusplus) && defined(__has_cpp_attribute)
|
||||
# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||
#else
|
||||
# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
|
||||
/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
|
||||
* - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
|
||||
* - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
|
||||
* - Else: __attribute__((__fallthrough__))
|
||||
*/
|
||||
#ifndef ZSTD_FALLTHROUGH
|
||||
# if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
|
||||
# define ZSTD_FALLTHROUGH [[fallthrough]]
|
||||
# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
|
||||
# define ZSTD_FALLTHROUGH [[fallthrough]]
|
||||
# elif __has_attribute(__fallthrough__)
|
||||
# define ZSTD_FALLTHROUGH __attribute__((__fallthrough__))
|
||||
# else
|
||||
# define ZSTD_FALLTHROUGH
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* detects whether we are being compiled under msan */
|
||||
#ifndef ZSTD_MEMORY_SANITIZER
|
||||
# if __has_feature(memory_sanitizer)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* debug
|
||||
* Part of FSE library
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* debug
|
||||
* Part of FSE library
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ******************************************************************
|
||||
* Common functions of New Generation Entropy library
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+5
-4
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* FSE : Finite State Entropy codec
|
||||
* Public Prototypes declaration
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
@@ -335,9 +335,10 @@ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
|
||||
|
||||
/* FSE_buildCTable_wksp() :
|
||||
* Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
|
||||
* `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog)`.
|
||||
* `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`.
|
||||
*/
|
||||
#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * (maxSymbolValue + 2) + (1ull << tableLog))
|
||||
#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (maxSymbolValue + 2 + (1ull << (tableLog - 2)))
|
||||
#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog))
|
||||
size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
|
||||
|
||||
#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8)
|
||||
@@ -351,7 +352,7 @@ size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
|
||||
size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
|
||||
/**< build a fake FSE_DTable, designed to always generate the same symbolValue */
|
||||
|
||||
#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue))
|
||||
#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1)
|
||||
#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned))
|
||||
size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize);
|
||||
/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)` */
|
||||
|
||||
+25
-15
@@ -1,6 +1,6 @@
|
||||
/* ******************************************************************
|
||||
* FSE : Finite State Entropy decoder
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
@@ -310,6 +310,12 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size
|
||||
return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
short ncount[FSE_MAX_SYMBOL_VALUE + 1];
|
||||
FSE_DTable dtable[1]; /* Dynamically sized */
|
||||
} FSE_DecompressWksp;
|
||||
|
||||
|
||||
FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* cSrc, size_t cSrcSize,
|
||||
@@ -318,33 +324,37 @@ FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
|
||||
{
|
||||
const BYTE* const istart = (const BYTE*)cSrc;
|
||||
const BYTE* ip = istart;
|
||||
short counting[FSE_MAX_SYMBOL_VALUE+1];
|
||||
unsigned tableLog;
|
||||
unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
|
||||
FSE_DTable* const dtable = (FSE_DTable*)workSpace;
|
||||
FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
|
||||
|
||||
DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
|
||||
if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
|
||||
|
||||
/* normal FSE decoding mode */
|
||||
size_t const NCountLength = FSE_readNCount_bmi2(counting, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
|
||||
if (FSE_isError(NCountLength)) return NCountLength;
|
||||
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
|
||||
assert(NCountLength <= cSrcSize);
|
||||
ip += NCountLength;
|
||||
cSrcSize -= NCountLength;
|
||||
{
|
||||
size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
|
||||
if (FSE_isError(NCountLength)) return NCountLength;
|
||||
if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
|
||||
assert(NCountLength <= cSrcSize);
|
||||
ip += NCountLength;
|
||||
cSrcSize -= NCountLength;
|
||||
}
|
||||
|
||||
if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge);
|
||||
workSpace = dtable + FSE_DTABLE_SIZE_U32(tableLog);
|
||||
wkspSize -= FSE_DTABLE_SIZE(tableLog);
|
||||
workSpace = wksp->dtable + FSE_DTABLE_SIZE_U32(tableLog);
|
||||
wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
|
||||
|
||||
CHECK_F( FSE_buildDTable_internal(dtable, counting, maxSymbolValue, tableLog, workSpace, wkspSize) );
|
||||
CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
|
||||
|
||||
{
|
||||
const void* ptr = dtable;
|
||||
const void* ptr = wksp->dtable;
|
||||
const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
|
||||
const U32 fastMode = DTableH->fastMode;
|
||||
|
||||
/* select fast mode (static) */
|
||||
if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1);
|
||||
return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0);
|
||||
if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1);
|
||||
return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* huff0 huffman codec,
|
||||
* part of Finite State Entropy library
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
@@ -192,6 +192,7 @@ size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
|
||||
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
|
||||
size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */
|
||||
size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
|
||||
size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize);
|
||||
size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
|
||||
size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
|
||||
int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
|
||||
@@ -278,7 +279,7 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
|
||||
* a required workspace size greater than that specified in the following
|
||||
* macro.
|
||||
*/
|
||||
#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10)
|
||||
#define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9))
|
||||
#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))
|
||||
|
||||
#ifndef HUF_FORCE_DECOMPRESS_X2
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -308,7 +308,7 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
|
||||
|
||||
MEM_STATIC U32 MEM_readLE24(const void* memPtr)
|
||||
{
|
||||
return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
|
||||
return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16);
|
||||
}
|
||||
|
||||
MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* xxHash - Fast Hash algorithm
|
||||
* Copyright (c) 2012-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - xxHash homepage: http://www.xxhash.com
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* xxHash - Extremely Fast Hash algorithm
|
||||
* Header File
|
||||
* Copyright (c) 2012-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - xxHash source repository : https://github.com/Cyan4973/xxHash
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -36,6 +36,11 @@
|
||||
# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
||||
#endif
|
||||
#include "xxhash.h" /* XXH_reset, update, digest */
|
||||
#ifndef ZSTD_NO_TRACE
|
||||
# include "zstd_trace.h"
|
||||
#else
|
||||
# define ZSTD_TRACE 0
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
@@ -365,7 +370,7 @@ typedef struct {
|
||||
|
||||
/* longLengthPos and longLengthID to allow us to represent either a single litLength or matchLength
|
||||
* in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
|
||||
* the existing value of the litLength or matchLength by 0x10000.
|
||||
* the existing value of the litLength or matchLength by 0x10000.
|
||||
*/
|
||||
U32 longLengthID; /* 0 == no longLength; 1 == Represent the long literal; 2 == Represent the long match; */
|
||||
U32 longLengthPos; /* Index of the sequence to apply long length modification to */
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include "zstd_trace.h"
|
||||
#include "../zstd.h"
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
#if ZSTD_TRACE && ZSTD_HAVE_WEAK_SYMBOLS
|
||||
|
||||
ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin(ZSTD_CCtx const* cctx)
|
||||
{
|
||||
(void)cctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZSTD_WEAK_ATTR void ZSTD_trace_compress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)trace;
|
||||
}
|
||||
|
||||
ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin(ZSTD_DCtx const* dctx)
|
||||
{
|
||||
(void)dctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)trace;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef ZSTD_TRACE_H
|
||||
#define ZSTD_TRACE_H
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* weak symbol support */
|
||||
#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && defined(__GNUC__) && \
|
||||
!defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \
|
||||
!defined(__CYGWIN__)
|
||||
# define ZSTD_HAVE_WEAK_SYMBOLS 1
|
||||
#else
|
||||
# define ZSTD_HAVE_WEAK_SYMBOLS 0
|
||||
#endif
|
||||
#if ZSTD_HAVE_WEAK_SYMBOLS
|
||||
# define ZSTD_WEAK_ATTR __attribute__((__weak__))
|
||||
#else
|
||||
# define ZSTD_WEAK_ATTR
|
||||
#endif
|
||||
|
||||
/* Only enable tracing when weak symbols are available. */
|
||||
#ifndef ZSTD_TRACE
|
||||
# define ZSTD_TRACE ZSTD_HAVE_WEAK_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if ZSTD_TRACE
|
||||
|
||||
struct ZSTD_CCtx_s;
|
||||
struct ZSTD_DCtx_s;
|
||||
struct ZSTD_CCtx_params_s;
|
||||
|
||||
typedef struct {
|
||||
/**
|
||||
* ZSTD_VERSION_NUMBER
|
||||
*
|
||||
* This is guaranteed to be the first member of ZSTD_trace.
|
||||
* Otherwise, this struct is not stable between versions. If
|
||||
* the version number does not match your expectation, you
|
||||
* should not interpret the rest of the struct.
|
||||
*/
|
||||
unsigned version;
|
||||
/**
|
||||
* Non-zero if streaming (de)compression is used.
|
||||
*/
|
||||
unsigned streaming;
|
||||
/**
|
||||
* The dictionary ID.
|
||||
*/
|
||||
unsigned dictionaryID;
|
||||
/**
|
||||
* Is the dictionary cold?
|
||||
* Only set on decompression.
|
||||
*/
|
||||
unsigned dictionaryIsCold;
|
||||
/**
|
||||
* The dictionary size or zero if no dictionary.
|
||||
*/
|
||||
size_t dictionarySize;
|
||||
/**
|
||||
* The uncompressed size of the data.
|
||||
*/
|
||||
size_t uncompressedSize;
|
||||
/**
|
||||
* The compressed size of the data.
|
||||
*/
|
||||
size_t compressedSize;
|
||||
/**
|
||||
* The fully resolved CCtx parameters (NULL on decompression).
|
||||
*/
|
||||
struct ZSTD_CCtx_params_s const* params;
|
||||
/**
|
||||
* The ZSTD_CCtx pointer (NULL on decompression).
|
||||
*/
|
||||
struct ZSTD_CCtx_s const* cctx;
|
||||
/**
|
||||
* The ZSTD_DCtx pointer (NULL on compression).
|
||||
*/
|
||||
struct ZSTD_DCtx_s const* dctx;
|
||||
} ZSTD_Trace;
|
||||
|
||||
/**
|
||||
* A tracing context. It must be 0 when tracing is disabled.
|
||||
* Otherwise, any non-zero value returned by a tracing begin()
|
||||
* function is presented to any subsequent calls to end().
|
||||
*
|
||||
* Any non-zero value is treated as tracing is enabled and not
|
||||
* interpreted by the library.
|
||||
*
|
||||
* Two possible uses are:
|
||||
* * A timestamp for when the begin() function was called.
|
||||
* * A unique key identifying the (de)compression, like the
|
||||
* address of the [dc]ctx pointer if you need to track
|
||||
* more information than just a timestamp.
|
||||
*/
|
||||
typedef unsigned long long ZSTD_TraceCtx;
|
||||
|
||||
/**
|
||||
* Trace the beginning of a compression call.
|
||||
* @param cctx The dctx pointer for the compression.
|
||||
* It can be used as a key to map begin() to end().
|
||||
* @returns Non-zero if tracing is enabled. The return value is
|
||||
* passed to ZSTD_trace_compress_end().
|
||||
*/
|
||||
ZSTD_TraceCtx ZSTD_trace_compress_begin(struct ZSTD_CCtx_s const* cctx);
|
||||
|
||||
/**
|
||||
* Trace the end of a compression call.
|
||||
* @param ctx The return value of ZSTD_trace_compress_begin().
|
||||
* @param trace The zstd tracing info.
|
||||
*/
|
||||
void ZSTD_trace_compress_end(
|
||||
ZSTD_TraceCtx ctx,
|
||||
ZSTD_Trace const* trace);
|
||||
|
||||
/**
|
||||
* Trace the beginning of a decompression call.
|
||||
* @param dctx The dctx pointer for the decompression.
|
||||
* It can be used as a key to map begin() to end().
|
||||
* @returns Non-zero if tracing is enabled. The return value is
|
||||
* passed to ZSTD_trace_compress_end().
|
||||
*/
|
||||
ZSTD_TraceCtx ZSTD_trace_decompress_begin(struct ZSTD_DCtx_s const* dctx);
|
||||
|
||||
/**
|
||||
* Trace the end of a decompression call.
|
||||
* @param ctx The return value of ZSTD_trace_decompress_begin().
|
||||
* @param trace The zstd tracing info.
|
||||
*/
|
||||
void ZSTD_trace_decompress_end(
|
||||
ZSTD_TraceCtx ctx,
|
||||
ZSTD_Trace const* trace);
|
||||
|
||||
#endif /* ZSTD_TRACE */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZSTD_TRACE_H */
|
||||
@@ -1,6 +1,6 @@
|
||||
/* ******************************************************************
|
||||
* FSE : Finite State Entropy encoder
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* hist : Histogram functions
|
||||
* part of Finite State Entropy project
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* hist : Histogram functions
|
||||
* part of Finite State Entropy project
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
|
||||
+70
-43
@@ -1,6 +1,6 @@
|
||||
/* ******************************************************************
|
||||
* Huffman encoder, part of New Generation Entropy library
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
@@ -59,7 +59,15 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
|
||||
* Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
|
||||
*/
|
||||
#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
|
||||
static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
|
||||
|
||||
typedef struct {
|
||||
FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
|
||||
U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)];
|
||||
unsigned count[HUF_TABLELOG_MAX+1];
|
||||
S16 norm[HUF_TABLELOG_MAX+1];
|
||||
} HUF_CompressWeightsWksp;
|
||||
|
||||
static size_t HUF_compressWeights(void* dst, size_t dstSize, const void* weightTable, size_t wtSize, void* workspace, size_t workspaceSize)
|
||||
{
|
||||
BYTE* const ostart = (BYTE*) dst;
|
||||
BYTE* op = ostart;
|
||||
@@ -67,33 +75,30 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
|
||||
|
||||
unsigned maxSymbolValue = HUF_TABLELOG_MAX;
|
||||
U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
|
||||
HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)workspace;
|
||||
|
||||
FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
|
||||
BYTE scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)];
|
||||
|
||||
unsigned count[HUF_TABLELOG_MAX+1];
|
||||
S16 norm[HUF_TABLELOG_MAX+1];
|
||||
if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC);
|
||||
|
||||
/* init conditions */
|
||||
if (wtSize <= 1) return 0; /* Not compressible */
|
||||
|
||||
/* Scan input and build symbol stats */
|
||||
{ unsigned const maxCount = HIST_count_simple(count, &maxSymbolValue, weightTable, wtSize); /* never fails */
|
||||
{ unsigned const maxCount = HIST_count_simple(wksp->count, &maxSymbolValue, weightTable, wtSize); /* never fails */
|
||||
if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */
|
||||
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
||||
}
|
||||
|
||||
tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
|
||||
CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) );
|
||||
CHECK_F( FSE_normalizeCount(wksp->norm, tableLog, wksp->count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) );
|
||||
|
||||
/* Write table description header */
|
||||
{ CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), norm, maxSymbolValue, tableLog) );
|
||||
{ CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), wksp->norm, maxSymbolValue, tableLog) );
|
||||
op += hSize;
|
||||
}
|
||||
|
||||
/* Compress */
|
||||
CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
|
||||
{ CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, CTable) );
|
||||
CHECK_F( FSE_buildCTable_wksp(wksp->CTable, wksp->norm, maxSymbolValue, tableLog, wksp->scratchBuffer, sizeof(wksp->scratchBuffer)) );
|
||||
{ CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, wksp->CTable) );
|
||||
if (cSize == 0) return 0; /* not enough space for compressed data */
|
||||
op += cSize;
|
||||
}
|
||||
@@ -102,29 +107,33 @@ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weight
|
||||
}
|
||||
|
||||
|
||||
/*! HUF_writeCTable() :
|
||||
`CTable` : Huffman tree to save, using huf representation.
|
||||
@return : size of saved CTable */
|
||||
size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
||||
const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog)
|
||||
{
|
||||
typedef struct {
|
||||
HUF_CompressWeightsWksp wksp;
|
||||
BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
|
||||
BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
|
||||
} HUF_WriteCTableWksp;
|
||||
|
||||
size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
|
||||
const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog,
|
||||
void* workspace, size_t workspaceSize)
|
||||
{
|
||||
BYTE* op = (BYTE*)dst;
|
||||
U32 n;
|
||||
HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)workspace;
|
||||
|
||||
/* check conditions */
|
||||
/* check conditions */
|
||||
if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC);
|
||||
if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
|
||||
|
||||
/* convert to weight */
|
||||
bitsToWeight[0] = 0;
|
||||
wksp->bitsToWeight[0] = 0;
|
||||
for (n=1; n<huffLog+1; n++)
|
||||
bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
|
||||
wksp->bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
|
||||
for (n=0; n<maxSymbolValue; n++)
|
||||
huffWeight[n] = bitsToWeight[CTable[n].nbBits];
|
||||
wksp->huffWeight[n] = wksp->bitsToWeight[CTable[n].nbBits];
|
||||
|
||||
/* attempt weights compression by FSE */
|
||||
{ CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
|
||||
{ CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) );
|
||||
if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */
|
||||
op[0] = (BYTE)hSize;
|
||||
return hSize+1;
|
||||
@@ -134,12 +143,22 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
||||
if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
|
||||
if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
|
||||
op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
|
||||
huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
|
||||
wksp->huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
|
||||
for (n=0; n<maxSymbolValue; n+=2)
|
||||
op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
|
||||
op[(n/2)+1] = (BYTE)((wksp->huffWeight[n] << 4) + wksp->huffWeight[n+1]);
|
||||
return ((maxSymbolValue+1)/2) + 1;
|
||||
}
|
||||
|
||||
/*! HUF_writeCTable() :
|
||||
`CTable` : Huffman tree to save, using huf representation.
|
||||
@return : size of saved CTable */
|
||||
size_t HUF_writeCTable (void* dst, size_t maxDstSize,
|
||||
const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog)
|
||||
{
|
||||
HUF_WriteCTableWksp wksp;
|
||||
return HUF_writeCTable_wksp(dst, maxDstSize, CTable, maxSymbolValue, huffLog, &wksp, sizeof(wksp));
|
||||
}
|
||||
|
||||
|
||||
size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights)
|
||||
{
|
||||
@@ -577,16 +596,19 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
|
||||
n = srcSize & ~3; /* join to mod 4 */
|
||||
switch (srcSize & 3)
|
||||
{
|
||||
case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
|
||||
HUF_FLUSHBITS_2(&bitC);
|
||||
/* fall-through */
|
||||
case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
|
||||
HUF_FLUSHBITS_1(&bitC);
|
||||
/* fall-through */
|
||||
case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
|
||||
HUF_FLUSHBITS(&bitC);
|
||||
/* fall-through */
|
||||
case 0 : /* fall-through */
|
||||
case 3:
|
||||
HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
|
||||
HUF_FLUSHBITS_2(&bitC);
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 2:
|
||||
HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
|
||||
HUF_FLUSHBITS_1(&bitC);
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 1:
|
||||
HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
|
||||
HUF_FLUSHBITS(&bitC);
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 0: ZSTD_FALLTHROUGH;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@@ -732,29 +754,33 @@ static size_t HUF_compressCTable_internal(
|
||||
typedef struct {
|
||||
unsigned count[HUF_SYMBOLVALUE_MAX + 1];
|
||||
HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1];
|
||||
HUF_buildCTable_wksp_tables buildCTable_wksp;
|
||||
union {
|
||||
HUF_buildCTable_wksp_tables buildCTable_wksp;
|
||||
HUF_WriteCTableWksp writeCTable_wksp;
|
||||
} wksps;
|
||||
} HUF_compress_tables_t;
|
||||
|
||||
/* HUF_compress_internal() :
|
||||
* `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
|
||||
* `workSpace_align4` must be aligned on 4-bytes boundaries,
|
||||
* and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */
|
||||
static size_t
|
||||
HUF_compress_internal (void* dst, size_t dstSize,
|
||||
const void* src, size_t srcSize,
|
||||
unsigned maxSymbolValue, unsigned huffLog,
|
||||
HUF_nbStreams_e nbStreams,
|
||||
void* workSpace, size_t wkspSize,
|
||||
void* workSpace_align4, size_t wkspSize,
|
||||
HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
|
||||
const int bmi2)
|
||||
{
|
||||
HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;
|
||||
HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = ostart + dstSize;
|
||||
BYTE* op = ostart;
|
||||
|
||||
HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE);
|
||||
assert(((size_t)workSpace_align4 & 3) == 0); /* must be aligned on 4-bytes boundaries */
|
||||
|
||||
/* checks & inits */
|
||||
if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
|
||||
if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
|
||||
if (!srcSize) return 0; /* Uncompressed */
|
||||
if (!dstSize) return 0; /* cannot fit anything within dst budget */
|
||||
@@ -772,7 +798,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
||||
}
|
||||
|
||||
/* Scan input and build symbol stats */
|
||||
{ CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) );
|
||||
{ CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) );
|
||||
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
|
||||
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
|
||||
}
|
||||
@@ -794,7 +820,7 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
||||
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
||||
{ size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
|
||||
maxSymbolValue, huffLog,
|
||||
&table->buildCTable_wksp, sizeof(table->buildCTable_wksp));
|
||||
&table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp));
|
||||
CHECK_F(maxBits);
|
||||
huffLog = (U32)maxBits;
|
||||
/* Zero unused symbols in CTable, so we can check it for validity */
|
||||
@@ -803,7 +829,8 @@ HUF_compress_internal (void* dst, size_t dstSize,
|
||||
}
|
||||
|
||||
/* Write table description header */
|
||||
{ CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, table->CTable, maxSymbolValue, huffLog) );
|
||||
{ CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, table->CTable, maxSymbolValue, huffLog,
|
||||
&table->wksps.writeCTable_wksp, sizeof(table->wksps.writeCTable_wksp)) );
|
||||
/* Check if using previous huffman table is beneficial */
|
||||
if (repeat && *repeat != HUF_repeat_none) {
|
||||
size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue);
|
||||
|
||||
+185
-84
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -269,29 +269,46 @@ size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ZSTD_NO_CLEVEL 0
|
||||
|
||||
/**
|
||||
* Initializes the cctxParams from params and compressionLevel.
|
||||
* @param compressionLevel If params are derived from a compression level then that compression level, otherwise ZSTD_NO_CLEVEL.
|
||||
*/
|
||||
static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_parameters const* params, int compressionLevel)
|
||||
{
|
||||
assert(!ZSTD_checkCParams(params->cParams));
|
||||
ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
|
||||
cctxParams->cParams = params->cParams;
|
||||
cctxParams->fParams = params->fParams;
|
||||
/* Should not matter, as all cParams are presumed properly defined.
|
||||
* But, set it for tracing anyway.
|
||||
*/
|
||||
cctxParams->compressionLevel = compressionLevel;
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
|
||||
{
|
||||
RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
|
||||
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
|
||||
ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
|
||||
assert(!ZSTD_checkCParams(params.cParams));
|
||||
cctxParams->cParams = params.cParams;
|
||||
cctxParams->fParams = params.fParams;
|
||||
cctxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
||||
ZSTD_CCtxParams_init_internal(cctxParams, ¶ms, ZSTD_NO_CLEVEL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ZSTD_assignParamsToCCtxParams() :
|
||||
* params is presumed valid at this stage */
|
||||
static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
|
||||
const ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params)
|
||||
/**
|
||||
* Sets cctxParams' cParams and fParams from params, but otherwise leaves them alone.
|
||||
* @param param Validated zstd parameters.
|
||||
*/
|
||||
static void ZSTD_CCtxParams_setZstdParams(
|
||||
ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params)
|
||||
{
|
||||
ZSTD_CCtx_params ret = *cctxParams;
|
||||
assert(!ZSTD_checkCParams(params->cParams));
|
||||
ret.cParams = params->cParams;
|
||||
ret.fParams = params->fParams;
|
||||
ret.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
||||
return ret;
|
||||
cctxParams->cParams = params->cParams;
|
||||
cctxParams->fParams = params->fParams;
|
||||
/* Should not matter, as all cParams are presumed properly defined.
|
||||
* But, set it for tracing anyway.
|
||||
*/
|
||||
cctxParams->compressionLevel = ZSTD_NO_CLEVEL;
|
||||
}
|
||||
|
||||
ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
||||
@@ -755,8 +772,8 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
||||
return CCtxParams->ldmParams.bucketSizeLog;
|
||||
|
||||
case ZSTD_c_ldmHashRateLog :
|
||||
RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN,
|
||||
parameter_outOfBound, "Param out of bounds!");
|
||||
if (value!=0) /* 0 ==> default */
|
||||
BOUNDCHECK(ZSTD_c_ldmHashRateLog, value);
|
||||
CCtxParams->ldmParams.hashRateLog = value;
|
||||
return CCtxParams->ldmParams.hashRateLog;
|
||||
|
||||
@@ -796,13 +813,13 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
||||
}
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value)
|
||||
size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value)
|
||||
{
|
||||
return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value);
|
||||
}
|
||||
|
||||
size_t ZSTD_CCtxParams_getParameter(
|
||||
ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, int* value)
|
||||
ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
@@ -1188,15 +1205,26 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
|
||||
const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
|
||||
assert(ZSTD_checkCParams(cPar)==0);
|
||||
|
||||
if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
|
||||
srcSize = minSrcSize;
|
||||
|
||||
switch (mode) {
|
||||
case ZSTD_cpm_noAttachDict:
|
||||
case ZSTD_cpm_unknown:
|
||||
case ZSTD_cpm_noAttachDict:
|
||||
/* If we don't know the source size, don't make any
|
||||
* assumptions about it. We will already have selected
|
||||
* smaller parameters if a dictionary is in use.
|
||||
*/
|
||||
break;
|
||||
case ZSTD_cpm_createCDict:
|
||||
/* Assume a small source size when creating a dictionary
|
||||
* with an unkown source size.
|
||||
*/
|
||||
if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
|
||||
srcSize = minSrcSize;
|
||||
break;
|
||||
case ZSTD_cpm_attachDict:
|
||||
/* Dictionary has its own dedicated parameters which have
|
||||
* already been selected. We are selecting parameters
|
||||
* for only the source.
|
||||
*/
|
||||
dictSize = 0;
|
||||
break;
|
||||
default:
|
||||
@@ -1213,7 +1241,8 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
|
||||
ZSTD_highbit32(tSize-1) + 1;
|
||||
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
|
||||
}
|
||||
{ U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize);
|
||||
if (srcSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
||||
U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize);
|
||||
U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
|
||||
if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1;
|
||||
if (cycleLog > dictAndWindowLog)
|
||||
@@ -1360,8 +1389,15 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
|
||||
|
||||
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
|
||||
{
|
||||
ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
||||
return ZSTD_estimateCCtxSize_usingCParams(cParams);
|
||||
int tier = 0;
|
||||
size_t largestSize = 0;
|
||||
static const unsigned long long srcSizeTiers[4] = {16 KB, 128 KB, 256 KB, ZSTD_CONTENTSIZE_UNKNOWN};
|
||||
for (; tier < 4; ++tier) {
|
||||
/* Choose the set of cParams for a given level across all srcSizes that give the largest cctxSize */
|
||||
ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeTiers[tier], 0, ZSTD_cpm_noAttachDict);
|
||||
largestSize = MAX(ZSTD_estimateCCtxSize_usingCParams(cParams), largestSize);
|
||||
}
|
||||
return largestSize;
|
||||
}
|
||||
|
||||
size_t ZSTD_estimateCCtxSize(int compressionLevel)
|
||||
@@ -1369,6 +1405,7 @@ size_t ZSTD_estimateCCtxSize(int compressionLevel)
|
||||
int level;
|
||||
size_t memBudget = 0;
|
||||
for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {
|
||||
/* Ensure monotonically increasing memory usage as compression level increases */
|
||||
size_t const newMB = ZSTD_estimateCCtxSize_internal(level);
|
||||
if (newMB > memBudget) memBudget = newMB;
|
||||
}
|
||||
@@ -1615,7 +1652,6 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams);
|
||||
assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
|
||||
assert(params.ldmParams.hashRateLog < 32);
|
||||
zc->ldmState.hashPower = ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);
|
||||
}
|
||||
|
||||
{ size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
|
||||
@@ -1692,6 +1728,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
XXH64_reset(&zc->xxhState, 0);
|
||||
zc->stage = ZSTDcs_init;
|
||||
zc->dictID = 0;
|
||||
zc->dictContentSize = 0;
|
||||
|
||||
ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
|
||||
|
||||
@@ -1711,11 +1748,11 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
||||
/* ldm bucketOffsets table */
|
||||
if (params.ldmParams.enableLdm) {
|
||||
/* TODO: avoid memset? */
|
||||
size_t const ldmBucketSize =
|
||||
size_t const numBuckets =
|
||||
((size_t)1) << (params.ldmParams.hashLog -
|
||||
params.ldmParams.bucketSizeLog);
|
||||
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize);
|
||||
ZSTD_memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);
|
||||
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets);
|
||||
ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets);
|
||||
}
|
||||
|
||||
/* sequences storage */
|
||||
@@ -1852,6 +1889,7 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
|
||||
} }
|
||||
|
||||
cctx->dictID = cdict->dictID;
|
||||
cctx->dictContentSize = cdict->dictContentSize;
|
||||
|
||||
/* copy block state */
|
||||
ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
|
||||
@@ -1915,6 +1953,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
||||
}
|
||||
|
||||
cctx->dictID = cdict->dictID;
|
||||
cctx->dictContentSize = cdict->dictContentSize;
|
||||
|
||||
/* copy block state */
|
||||
ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
|
||||
@@ -2005,6 +2044,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
||||
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
||||
}
|
||||
dstCCtx->dictID = srcCCtx->dictID;
|
||||
dstCCtx->dictContentSize = srcCCtx->dictContentSize;
|
||||
|
||||
/* copy block state */
|
||||
ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));
|
||||
@@ -2937,7 +2977,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
if (!singleSegment) op[pos++] = windowLogByte;
|
||||
switch(dictIDSizeCode)
|
||||
{
|
||||
default: assert(0); /* impossible */
|
||||
default:
|
||||
assert(0); /* impossible */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 0 : break;
|
||||
case 1 : op[pos] = (BYTE)(dictID); pos++; break;
|
||||
case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
|
||||
@@ -2945,7 +2987,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
}
|
||||
switch(fcsCode)
|
||||
{
|
||||
default: assert(0); /* impossible */
|
||||
default:
|
||||
assert(0); /* impossible */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
|
||||
case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
|
||||
case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
|
||||
@@ -2954,6 +2998,26 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* ZSTD_writeSkippableFrame_advanced() :
|
||||
* Writes out a skippable frame with the specified magic number variant (16 are supported),
|
||||
* from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15, and the desired source data.
|
||||
*
|
||||
* Returns the total number of bytes written, or a ZSTD error code.
|
||||
*/
|
||||
size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize, unsigned magicVariant) {
|
||||
BYTE* op = (BYTE*)dst;
|
||||
RETURN_ERROR_IF(dstCapacity < srcSize + ZSTD_SKIPPABLEHEADERSIZE /* Skippable frame overhead */,
|
||||
dstSize_tooSmall, "Not enough room for skippable frame");
|
||||
RETURN_ERROR_IF(srcSize > (unsigned)0xFFFFFFFF, srcSize_wrong, "Src size too large for skippable frame");
|
||||
RETURN_ERROR_IF(magicVariant > 15, parameter_outOfBound, "Skippable frame magic number variant not supported");
|
||||
|
||||
MEM_writeLE32(op, (U32)(ZSTD_MAGIC_SKIPPABLE_START + magicVariant));
|
||||
MEM_writeLE32(op+4, (U32)srcSize);
|
||||
ZSTD_memcpy(op+8, src, srcSize);
|
||||
return srcSize + ZSTD_SKIPPABLEHEADERSIZE;
|
||||
}
|
||||
|
||||
/* ZSTD_writeLastEmptyBlock() :
|
||||
* output an empty Block with end-of-frame mark to complete a frame
|
||||
* @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
|
||||
@@ -3258,7 +3322,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
||||
|
||||
/* Dictionary format :
|
||||
* See :
|
||||
* https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
|
||||
* https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format
|
||||
*/
|
||||
/*! ZSTD_loadZstdDictionary() :
|
||||
* @return : dictID, or an error code
|
||||
@@ -3348,6 +3412,9 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
||||
const ZSTD_CCtx_params* params, U64 pledgedSrcSize,
|
||||
ZSTD_buffered_policy_e zbuff)
|
||||
{
|
||||
#if ZSTD_TRACE
|
||||
cctx->traceCtx = ZSTD_trace_compress_begin(cctx);
|
||||
#endif
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog);
|
||||
/* params are supposed to be fully validated at this point */
|
||||
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
|
||||
@@ -3377,6 +3444,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
||||
FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
|
||||
assert(dictID <= UINT_MAX);
|
||||
cctx->dictID = (U32)dictID;
|
||||
cctx->dictContentSize = cdict ? cdict->dictContentSize : dictSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -3405,8 +3473,8 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
||||
const void* dict, size_t dictSize,
|
||||
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
||||
{
|
||||
ZSTD_CCtx_params const cctxParams =
|
||||
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms);
|
||||
ZSTD_CCtx_params cctxParams;
|
||||
ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, ZSTD_NO_CLEVEL);
|
||||
return ZSTD_compressBegin_advanced_internal(cctx,
|
||||
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
||||
NULL /*cdict*/,
|
||||
@@ -3415,9 +3483,11 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
||||
|
||||
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
|
||||
{
|
||||
ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict);
|
||||
ZSTD_CCtx_params const cctxParams =
|
||||
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms);
|
||||
ZSTD_CCtx_params cctxParams;
|
||||
{
|
||||
ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict);
|
||||
ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel);
|
||||
}
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
|
||||
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
|
||||
&cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
||||
@@ -3471,6 +3541,30 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
||||
return op-ostart;
|
||||
}
|
||||
|
||||
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
|
||||
{
|
||||
#if ZSTD_TRACE
|
||||
if (cctx->traceCtx) {
|
||||
int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0;
|
||||
ZSTD_Trace trace;
|
||||
ZSTD_memset(&trace, 0, sizeof(trace));
|
||||
trace.version = ZSTD_VERSION_NUMBER;
|
||||
trace.streaming = streaming;
|
||||
trace.dictionaryID = cctx->dictID;
|
||||
trace.dictionarySize = cctx->dictContentSize;
|
||||
trace.uncompressedSize = cctx->consumedSrcSize;
|
||||
trace.compressedSize = cctx->producedCSize + extraCSize;
|
||||
trace.params = &cctx->appliedParams;
|
||||
trace.cctx = cctx;
|
||||
ZSTD_trace_compress_end(cctx->traceCtx, &trace);
|
||||
}
|
||||
cctx->traceCtx = 0;
|
||||
#else
|
||||
(void)cctx;
|
||||
(void)extraCSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize)
|
||||
@@ -3493,38 +3587,25 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
|
||||
(unsigned)cctx->pledgedSrcSizePlusOne-1,
|
||||
(unsigned)cctx->consumedSrcSize);
|
||||
}
|
||||
ZSTD_CCtx_trace(cctx, endResult);
|
||||
return cSize + endResult;
|
||||
}
|
||||
|
||||
static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const void* dict,size_t dictSize,
|
||||
const ZSTD_parameters* params)
|
||||
{
|
||||
ZSTD_CCtx_params const cctxParams =
|
||||
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
||||
DEBUGLOG(4, "ZSTD_compress_internal");
|
||||
return ZSTD_compress_advanced_internal(cctx,
|
||||
dst, dstCapacity,
|
||||
src, srcSize,
|
||||
dict, dictSize,
|
||||
&cctxParams);
|
||||
}
|
||||
|
||||
size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const void* dict,size_t dictSize,
|
||||
ZSTD_parameters params)
|
||||
{
|
||||
ZSTD_CCtx_params cctxParams;
|
||||
DEBUGLOG(4, "ZSTD_compress_advanced");
|
||||
FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), "");
|
||||
return ZSTD_compress_internal(cctx,
|
||||
dst, dstCapacity,
|
||||
src, srcSize,
|
||||
dict, dictSize,
|
||||
¶ms);
|
||||
ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, ZSTD_NO_CLEVEL);
|
||||
return ZSTD_compress_advanced_internal(cctx,
|
||||
dst, dstCapacity,
|
||||
src, srcSize,
|
||||
dict, dictSize,
|
||||
&cctxParams);
|
||||
}
|
||||
|
||||
/* Internal */
|
||||
@@ -3548,10 +3629,13 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
|
||||
const void* dict, size_t dictSize,
|
||||
int compressionLevel)
|
||||
{
|
||||
ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict);
|
||||
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, ¶ms);
|
||||
ZSTD_CCtx_params cctxParams;
|
||||
{
|
||||
ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict);
|
||||
assert(params.fParams.contentSizeFlag == 1);
|
||||
ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT: compressionLevel);
|
||||
}
|
||||
DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
|
||||
assert(params.fParams.contentSizeFlag == 1);
|
||||
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);
|
||||
}
|
||||
|
||||
@@ -3698,7 +3782,7 @@ static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
|
||||
assert(cdict != NULL);
|
||||
ZSTD_cwksp_move(&cdict->workspace, &ws);
|
||||
cdict->customMem = customMem;
|
||||
cdict->compressionLevel = 0; /* signals advanced API usage */
|
||||
cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */
|
||||
|
||||
return cdict;
|
||||
}
|
||||
@@ -3881,34 +3965,37 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
|
||||
ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
|
||||
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
|
||||
{
|
||||
ZSTD_CCtx_params cctxParams;
|
||||
DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
|
||||
RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!");
|
||||
{ ZSTD_CCtx_params params = cctx->requestedParams;
|
||||
/* Initialize the cctxParams from the cdict */
|
||||
{
|
||||
ZSTD_parameters params;
|
||||
params.fParams = fParams;
|
||||
params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
|
||||
|| pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
|
||||
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
||||
|| cdict->compressionLevel == 0 )
|
||||
&& (params.attachDictPref != ZSTD_dictForceLoad) ?
|
||||
|| cdict->compressionLevel == 0 ) ?
|
||||
ZSTD_getCParamsFromCDict(cdict)
|
||||
: ZSTD_getCParams(cdict->compressionLevel,
|
||||
pledgedSrcSize,
|
||||
cdict->dictContentSize);
|
||||
/* Increase window log to fit the entire dictionary and source if the
|
||||
* source size is known. Limit the increase to 19, which is the
|
||||
* window log for compression level 1 with the largest source size.
|
||||
*/
|
||||
if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
||||
U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19);
|
||||
U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;
|
||||
params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog);
|
||||
}
|
||||
params.fParams = fParams;
|
||||
return ZSTD_compressBegin_internal(cctx,
|
||||
NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
||||
cdict,
|
||||
¶ms, pledgedSrcSize,
|
||||
ZSTDb_not_buffered);
|
||||
ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, cdict->compressionLevel);
|
||||
}
|
||||
/* Increase window log to fit the entire dictionary and source if the
|
||||
* source size is known. Limit the increase to 19, which is the
|
||||
* window log for compression level 1 with the largest source size.
|
||||
*/
|
||||
if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
||||
U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19);
|
||||
U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;
|
||||
cctxParams.cParams.windowLog = MAX(cctxParams.cParams.windowLog, limitedSrcLog);
|
||||
}
|
||||
return ZSTD_compressBegin_internal(cctx,
|
||||
NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
||||
cdict,
|
||||
&cctxParams, pledgedSrcSize,
|
||||
ZSTDb_not_buffered);
|
||||
}
|
||||
|
||||
/* ZSTD_compressBegin_usingCDict() :
|
||||
@@ -4071,7 +4158,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) , "");
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
|
||||
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
|
||||
zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, ¶ms);
|
||||
ZSTD_CCtxParams_setZstdParams(&zcs->requestedParams, ¶ms);
|
||||
FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
|
||||
return 0;
|
||||
}
|
||||
@@ -4249,7 +4336,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
||||
zcs->outBuffFlushedSize = 0;
|
||||
zcs->streamStage = zcss_flush; /* pass-through to flush stage */
|
||||
}
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case zcss_flush:
|
||||
DEBUGLOG(5, "flush stage");
|
||||
assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
|
||||
@@ -4376,6 +4463,9 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
|
||||
params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
|
||||
}
|
||||
if (params.nbWorkers > 0) {
|
||||
#if ZSTD_TRACE
|
||||
cctx->traceCtx = ZSTD_trace_compress_begin(cctx);
|
||||
#endif
|
||||
/* mt context creation */
|
||||
if (cctx->mtctx == NULL) {
|
||||
DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
|
||||
@@ -4389,6 +4479,10 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
|
||||
cctx->mtctx,
|
||||
prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
|
||||
cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
|
||||
cctx->dictID = cctx->cdict ? cctx->cdict->dictID : 0;
|
||||
cctx->dictContentSize = cctx->cdict ? cctx->cdict->dictContentSize : prefixDict.dictSize;
|
||||
cctx->consumedSrcSize = 0;
|
||||
cctx->producedCSize = 0;
|
||||
cctx->streamStage = zcss_load;
|
||||
cctx->appliedParams = params;
|
||||
} else
|
||||
@@ -4450,8 +4544,12 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
|
||||
size_t const ipos = input->pos;
|
||||
size_t const opos = output->pos;
|
||||
flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
|
||||
cctx->consumedSrcSize += (U64)(input->pos - ipos);
|
||||
cctx->producedCSize += (U64)(output->pos - opos);
|
||||
if ( ZSTD_isError(flushMin)
|
||||
|| (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
|
||||
if (flushMin == 0)
|
||||
ZSTD_CCtx_trace(cctx, 0);
|
||||
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);
|
||||
}
|
||||
FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed");
|
||||
@@ -5099,7 +5197,10 @@ static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const
|
||||
static int ZSTD_dedicatedDictSearch_isSupported(
|
||||
ZSTD_compressionParameters const* cParams)
|
||||
{
|
||||
return (cParams->strategy >= ZSTD_greedy) && (cParams->strategy <= ZSTD_lazy2);
|
||||
return (cParams->strategy >= ZSTD_greedy)
|
||||
&& (cParams->strategy <= ZSTD_lazy2)
|
||||
&& (cParams->hashLog >= cParams->chainLog)
|
||||
&& (cParams->chainLog <= 24);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -183,13 +183,22 @@ typedef struct {
|
||||
U32 checksum;
|
||||
} ldmEntry_t;
|
||||
|
||||
typedef struct {
|
||||
BYTE const* split;
|
||||
U32 hash;
|
||||
U32 checksum;
|
||||
ldmEntry_t* bucket;
|
||||
} ldmMatchCandidate_t;
|
||||
|
||||
#define LDM_BATCH_SIZE 64
|
||||
|
||||
typedef struct {
|
||||
ZSTD_window_t window; /* State for the window round buffer management */
|
||||
ldmEntry_t* hashTable;
|
||||
U32 loadedDictEnd;
|
||||
BYTE* bucketOffsets; /* Next position in bucket to insert entry */
|
||||
U64 hashPower; /* Used to compute the rolling hash.
|
||||
* Depends on ldmParams.minMatchLength */
|
||||
size_t splitIndices[LDM_BATCH_SIZE];
|
||||
ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE];
|
||||
} ldmState_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -270,6 +279,7 @@ struct ZSTD_CCtx_s {
|
||||
ZSTD_CCtx_params requestedParams;
|
||||
ZSTD_CCtx_params appliedParams;
|
||||
U32 dictID;
|
||||
size_t dictContentSize;
|
||||
|
||||
ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */
|
||||
size_t blockSize;
|
||||
@@ -321,6 +331,11 @@ struct ZSTD_CCtx_s {
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
ZSTDMT_CCtx* mtctx;
|
||||
#endif
|
||||
|
||||
/* Tracing */
|
||||
#if ZSTD_TRACE
|
||||
ZSTD_TraceCtx traceCtx;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
|
||||
@@ -471,7 +486,7 @@ MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParam
|
||||
return 1;
|
||||
default:
|
||||
assert(0 /* impossible: pre-validated */);
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case ZSTD_lcm_auto:
|
||||
return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
|
||||
}
|
||||
@@ -1200,4 +1215,9 @@ size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSe
|
||||
* condition for correct operation : hashLog > 1 */
|
||||
U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
|
||||
|
||||
/** ZSTD_CCtx_trace() :
|
||||
* Trace the end of a compression call.
|
||||
*/
|
||||
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize);
|
||||
|
||||
#endif /* ZSTD_COMPRESS_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||
{
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
|
||||
|
||||
RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, "");
|
||||
@@ -42,7 +42,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
|
||||
|
||||
size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
||||
{
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
|
||||
|
||||
(void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -232,6 +232,11 @@ ZSTD_selectEncodingType(
|
||||
return set_compressed;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
S16 norm[MaxSeq + 1];
|
||||
U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)];
|
||||
} ZSTD_BuildCTableWksp;
|
||||
|
||||
size_t
|
||||
ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
||||
FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
|
||||
@@ -258,7 +263,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
||||
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
|
||||
return 0;
|
||||
case set_compressed: {
|
||||
S16 norm[MaxSeq + 1];
|
||||
ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace;
|
||||
size_t nbSeq_1 = nbSeq;
|
||||
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
|
||||
if (count[codeTable[nbSeq-1]] > 1) {
|
||||
@@ -266,11 +271,12 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
||||
nbSeq_1--;
|
||||
}
|
||||
assert(nbSeq_1 > 1);
|
||||
assert(entropyWorkspaceSize >= FSE_BUILD_CTABLE_WORKSPACE_SIZE(MaxSeq, MaxFSELog));
|
||||
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
|
||||
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
|
||||
assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp));
|
||||
(void)entropyWorkspaceSize;
|
||||
FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
|
||||
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, wksp->norm, max, tableLog); /* overflow protected */
|
||||
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
|
||||
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
|
||||
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "");
|
||||
return NCountSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -128,9 +128,10 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
|
||||
{ /* Build and write the CTable */
|
||||
size_t const newCSize = HUF_estimateCompressedSize(
|
||||
(HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
|
||||
size_t const hSize = HUF_writeCTable(
|
||||
size_t const hSize = HUF_writeCTable_wksp(
|
||||
hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
|
||||
(HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog);
|
||||
(HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog,
|
||||
nodeWksp, nodeWkspSize);
|
||||
/* Check against repeating the previous CTable */
|
||||
if (repeat != HUF_repeat_none) {
|
||||
size_t const oldCSize = HUF_estimateCompressedSize(
|
||||
@@ -304,7 +305,7 @@ ZSTD_buildSuperBlockEntropy(seqStore_t* seqStorePtr,
|
||||
* before we know the table size + compressed size, so we have a bound on the
|
||||
* table size. If we guessed incorrectly, we fall back to uncompressed literals.
|
||||
*
|
||||
* We write the header when writeEntropy=1 and set entropyWrriten=1 when we succeeded
|
||||
* We write the header when writeEntropy=1 and set entropyWritten=1 when we succeeded
|
||||
* in writing the header, otherwise it is set to 0.
|
||||
*
|
||||
* hufMetadata->hType has literals block type info.
|
||||
@@ -410,6 +411,8 @@ static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef*
|
||||
const seqDef* sp = sstart;
|
||||
size_t matchLengthSum = 0;
|
||||
size_t litLengthSum = 0;
|
||||
/* Only used by assert(), suppress unused variable warnings in production. */
|
||||
(void)litLengthSum;
|
||||
while (send-sp > 0) {
|
||||
ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
|
||||
litLengthSum += seqLen.litLength;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -503,7 +503,7 @@ MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
|
||||
|
||||
/**
|
||||
* Moves the management of a workspace from one cwksp to another. The src cwksp
|
||||
* is left in an invalid state (src must be re-init()'ed before its used again).
|
||||
* is left in an invalid state (src must be re-init()'ed before it's used again).
|
||||
*/
|
||||
MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) {
|
||||
*dst = *src;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -244,8 +244,6 @@ _search_next_long:
|
||||
while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
||||
}
|
||||
|
||||
/* fall-through */
|
||||
|
||||
_match_found:
|
||||
offset_2 = offset_1;
|
||||
offset_1 = offset;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -242,7 +242,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
|
||||
assert(endIndex - prefixStartIndex <= maxDistance);
|
||||
(void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */
|
||||
|
||||
/* ensure there will be no no underflow
|
||||
/* ensure there will be no underflow
|
||||
* when translating a dict index into a local index */
|
||||
assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -93,7 +93,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
|
||||
assert(curr >= btLow);
|
||||
assert(ip < iend); /* condition for ZSTD_count */
|
||||
|
||||
while (nbCompares-- && (matchIndex > windowLow)) {
|
||||
for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
|
||||
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||
assert(matchIndex < curr);
|
||||
@@ -185,7 +185,7 @@ ZSTD_DUBT_findBetterDictMatch (
|
||||
(void)dictMode;
|
||||
assert(dictMode == ZSTD_dictMatchState);
|
||||
|
||||
while (nbCompares-- && (dictMatchIndex > dictLowLimit)) {
|
||||
for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) {
|
||||
U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask);
|
||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||
const BYTE* match = dictBase + dictMatchIndex;
|
||||
@@ -309,7 +309,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
||||
matchIndex = hashTable[h];
|
||||
hashTable[h] = curr; /* Update Hash Table */
|
||||
|
||||
while (nbCompares-- && (matchIndex > windowLow)) {
|
||||
for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
|
||||
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||
const BYTE* match;
|
||||
@@ -357,6 +357,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
||||
|
||||
*smallerPtr = *largerPtr = 0;
|
||||
|
||||
assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
|
||||
if (dictMode == ZSTD_dictMatchState && nbCompares) {
|
||||
bestLength = ZSTD_DUBT_findBetterDictMatch(
|
||||
ms, ip, iend,
|
||||
@@ -660,6 +661,7 @@ size_t ZSTD_HcFindBestMatch_generic (
|
||||
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
|
||||
}
|
||||
|
||||
assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
|
||||
if (dictMode == ZSTD_dedicatedDictSearch) {
|
||||
const U32 ddsLowestIndex = dms->window.dictLimit;
|
||||
const BYTE* const ddsBase = dms->window.base;
|
||||
@@ -1264,7 +1266,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
||||
matchLength = ml2, start = ip, offset=offsetFound;
|
||||
}
|
||||
|
||||
if (matchLength < 4) {
|
||||
if (matchLength < 4) {
|
||||
ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+225
-199
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -11,13 +11,99 @@
|
||||
#include "zstd_ldm.h"
|
||||
|
||||
#include "../common/debug.h"
|
||||
#include "../common/xxhash.h"
|
||||
#include "zstd_fast.h" /* ZSTD_fillHashTable() */
|
||||
#include "zstd_double_fast.h" /* ZSTD_fillDoubleHashTable() */
|
||||
#include "zstd_ldm_geartab.h"
|
||||
|
||||
#define LDM_BUCKET_SIZE_LOG 3
|
||||
#define LDM_MIN_MATCH_LENGTH 64
|
||||
#define LDM_HASH_RLOG 7
|
||||
#define LDM_HASH_CHAR_OFFSET 10
|
||||
|
||||
typedef struct {
|
||||
U64 rolling;
|
||||
U64 stopMask;
|
||||
} ldmRollingHashState_t;
|
||||
|
||||
/** ZSTD_ldm_gear_init():
|
||||
*
|
||||
* Initializes the rolling hash state such that it will honor the
|
||||
* settings in params. */
|
||||
static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const* params)
|
||||
{
|
||||
unsigned maxBitsInMask = MIN(params->minMatchLength, 64);
|
||||
unsigned hashRateLog = params->hashRateLog;
|
||||
|
||||
state->rolling = ~(U32)0;
|
||||
|
||||
/* The choice of the splitting criterion is subject to two conditions:
|
||||
* 1. it has to trigger on average every 2^(hashRateLog) bytes;
|
||||
* 2. ideally, it has to depend on a window of minMatchLength bytes.
|
||||
*
|
||||
* In the gear hash algorithm, bit n depends on the last n bytes;
|
||||
* so in order to obtain a good quality splitting criterion it is
|
||||
* preferable to use bits with high weight.
|
||||
*
|
||||
* To match condition 1 we use a mask with hashRateLog bits set
|
||||
* and, because of the previous remark, we make sure these bits
|
||||
* have the highest possible weight while still respecting
|
||||
* condition 2.
|
||||
*/
|
||||
if (hashRateLog > 0 && hashRateLog <= maxBitsInMask) {
|
||||
state->stopMask = (((U64)1 << hashRateLog) - 1) << (maxBitsInMask - hashRateLog);
|
||||
} else {
|
||||
/* In this degenerate case we simply honor the hash rate. */
|
||||
state->stopMask = ((U64)1 << hashRateLog) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_gear_feed():
|
||||
*
|
||||
* Registers in the splits array all the split points found in the first
|
||||
* size bytes following the data pointer. This function terminates when
|
||||
* either all the data has been processed or LDM_BATCH_SIZE splits are
|
||||
* present in the splits array.
|
||||
*
|
||||
* Precondition: The splits array must not be full.
|
||||
* Returns: The number of bytes processed. */
|
||||
static size_t ZSTD_ldm_gear_feed(ldmRollingHashState_t* state,
|
||||
BYTE const* data, size_t size,
|
||||
size_t* splits, unsigned* numSplits)
|
||||
{
|
||||
size_t n;
|
||||
U64 hash, mask;
|
||||
|
||||
hash = state->rolling;
|
||||
mask = state->stopMask;
|
||||
n = 0;
|
||||
|
||||
#define GEAR_ITER_ONCE() do { \
|
||||
hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \
|
||||
n += 1; \
|
||||
if (UNLIKELY((hash & mask) == 0)) { \
|
||||
splits[*numSplits] = n; \
|
||||
*numSplits += 1; \
|
||||
if (*numSplits == LDM_BATCH_SIZE) \
|
||||
goto done; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
while (n + 3 < size) {
|
||||
GEAR_ITER_ONCE();
|
||||
GEAR_ITER_ONCE();
|
||||
GEAR_ITER_ONCE();
|
||||
GEAR_ITER_ONCE();
|
||||
}
|
||||
while (n < size) {
|
||||
GEAR_ITER_ONCE();
|
||||
}
|
||||
|
||||
#undef GEAR_ITER_ONCE
|
||||
|
||||
done:
|
||||
state->rolling = hash;
|
||||
return n;
|
||||
}
|
||||
|
||||
void ZSTD_ldm_adjustParameters(ldmParams_t* params,
|
||||
ZSTD_compressionParameters const* cParams)
|
||||
@@ -54,41 +140,6 @@ size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize)
|
||||
return params.enableLdm ? (maxChunkSize / params.minMatchLength) : 0;
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_getSmallHash() :
|
||||
* numBits should be <= 32
|
||||
* If numBits==0, returns 0.
|
||||
* @return : the most significant numBits of value. */
|
||||
static U32 ZSTD_ldm_getSmallHash(U64 value, U32 numBits)
|
||||
{
|
||||
assert(numBits <= 32);
|
||||
return numBits == 0 ? 0 : (U32)(value >> (64 - numBits));
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_getChecksum() :
|
||||
* numBitsToDiscard should be <= 32
|
||||
* @return : the next most significant 32 bits after numBitsToDiscard */
|
||||
static U32 ZSTD_ldm_getChecksum(U64 hash, U32 numBitsToDiscard)
|
||||
{
|
||||
assert(numBitsToDiscard <= 32);
|
||||
return (hash >> (64 - 32 - numBitsToDiscard)) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_getTag() ;
|
||||
* Given the hash, returns the most significant numTagBits bits
|
||||
* after (32 + hbits) bits.
|
||||
*
|
||||
* If there are not enough bits remaining, return the last
|
||||
* numTagBits bits. */
|
||||
static U32 ZSTD_ldm_getTag(U64 hash, U32 hbits, U32 numTagBits)
|
||||
{
|
||||
assert(numTagBits < 32 && hbits <= 32);
|
||||
if (32 - hbits < numTagBits) {
|
||||
return hash & (((U32)1 << numTagBits) - 1);
|
||||
} else {
|
||||
return (hash >> (32 - hbits - numTagBits)) & (((U32)1 << numTagBits) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_getBucket() :
|
||||
* Returns a pointer to the start of the bucket associated with hash. */
|
||||
static ldmEntry_t* ZSTD_ldm_getBucket(
|
||||
@@ -103,38 +154,12 @@ static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
|
||||
size_t const hash, const ldmEntry_t entry,
|
||||
ldmParams_t const ldmParams)
|
||||
{
|
||||
BYTE* const bucketOffsets = ldmState->bucketOffsets;
|
||||
*(ZSTD_ldm_getBucket(ldmState, hash, ldmParams) + bucketOffsets[hash]) = entry;
|
||||
bucketOffsets[hash]++;
|
||||
bucketOffsets[hash] &= ((U32)1 << ldmParams.bucketSizeLog) - 1;
|
||||
}
|
||||
BYTE* const pOffset = ldmState->bucketOffsets + hash;
|
||||
unsigned const offset = *pOffset;
|
||||
|
||||
*(ZSTD_ldm_getBucket(ldmState, hash, ldmParams) + offset) = entry;
|
||||
*pOffset = (BYTE)((offset + 1) & ((1u << ldmParams.bucketSizeLog) - 1));
|
||||
|
||||
/** ZSTD_ldm_makeEntryAndInsertByTag() :
|
||||
*
|
||||
* Gets the small hash, checksum, and tag from the rollingHash.
|
||||
*
|
||||
* If the tag matches (1 << ldmParams.hashRateLog)-1, then
|
||||
* creates an ldmEntry from the offset, and inserts it into the hash table.
|
||||
*
|
||||
* hBits is the length of the small hash, which is the most significant hBits
|
||||
* of rollingHash. The checksum is the next 32 most significant bits, followed
|
||||
* by ldmParams.hashRateLog bits that make up the tag. */
|
||||
static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
|
||||
U64 const rollingHash,
|
||||
U32 const hBits,
|
||||
U32 const offset,
|
||||
ldmParams_t const ldmParams)
|
||||
{
|
||||
U32 const tag = ZSTD_ldm_getTag(rollingHash, hBits, ldmParams.hashRateLog);
|
||||
U32 const tagMask = ((U32)1 << ldmParams.hashRateLog) - 1;
|
||||
if (tag == tagMask) {
|
||||
U32 const hash = ZSTD_ldm_getSmallHash(rollingHash, hBits);
|
||||
U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
|
||||
ldmEntry_t entry;
|
||||
entry.offset = offset;
|
||||
entry.checksum = checksum;
|
||||
ZSTD_ldm_insertEntry(ldmState, hash, entry, ldmParams);
|
||||
}
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_countBackwardsMatch() :
|
||||
@@ -212,43 +237,42 @@ static size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t* ms,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** ZSTD_ldm_fillLdmHashTable() :
|
||||
*
|
||||
* Fills hashTable from (lastHashed + 1) to iend (non-inclusive).
|
||||
* lastHash is the rolling hash that corresponds to lastHashed.
|
||||
*
|
||||
* Returns the rolling hash corresponding to position iend-1. */
|
||||
static U64 ZSTD_ldm_fillLdmHashTable(ldmState_t* state,
|
||||
U64 lastHash, const BYTE* lastHashed,
|
||||
const BYTE* iend, const BYTE* base,
|
||||
U32 hBits, ldmParams_t const ldmParams)
|
||||
{
|
||||
U64 rollingHash = lastHash;
|
||||
const BYTE* cur = lastHashed + 1;
|
||||
|
||||
while (cur < iend) {
|
||||
rollingHash = ZSTD_rollingHash_rotate(rollingHash, cur[-1],
|
||||
cur[ldmParams.minMatchLength-1],
|
||||
state->hashPower);
|
||||
ZSTD_ldm_makeEntryAndInsertByTag(state,
|
||||
rollingHash, hBits,
|
||||
(U32)(cur - base), ldmParams);
|
||||
++cur;
|
||||
}
|
||||
return rollingHash;
|
||||
}
|
||||
|
||||
void ZSTD_ldm_fillHashTable(
|
||||
ldmState_t* state, const BYTE* ip,
|
||||
ldmState_t* ldmState, const BYTE* ip,
|
||||
const BYTE* iend, ldmParams_t const* params)
|
||||
{
|
||||
U32 const minMatchLength = params->minMatchLength;
|
||||
U32 const hBits = params->hashLog - params->bucketSizeLog;
|
||||
BYTE const* const base = ldmState->window.base;
|
||||
BYTE const* const istart = ip;
|
||||
ldmRollingHashState_t hashState;
|
||||
size_t* const splits = ldmState->splitIndices;
|
||||
unsigned numSplits;
|
||||
|
||||
DEBUGLOG(5, "ZSTD_ldm_fillHashTable");
|
||||
if ((size_t)(iend - ip) >= params->minMatchLength) {
|
||||
U64 startingHash = ZSTD_rollingHash_compute(ip, params->minMatchLength);
|
||||
ZSTD_ldm_fillLdmHashTable(
|
||||
state, startingHash, ip, iend - params->minMatchLength, state->window.base,
|
||||
params->hashLog - params->bucketSizeLog,
|
||||
*params);
|
||||
|
||||
ZSTD_ldm_gear_init(&hashState, params);
|
||||
while (ip < iend) {
|
||||
size_t hashed;
|
||||
unsigned n;
|
||||
|
||||
numSplits = 0;
|
||||
hashed = ZSTD_ldm_gear_feed(&hashState, ip, iend - ip, splits, &numSplits);
|
||||
|
||||
for (n = 0; n < numSplits; n++) {
|
||||
if (ip + splits[n] >= istart + minMatchLength) {
|
||||
BYTE const* const split = ip + splits[n] - minMatchLength;
|
||||
U64 const xxhash = XXH64(split, minMatchLength, 0);
|
||||
U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1));
|
||||
ldmEntry_t entry;
|
||||
|
||||
entry.offset = (U32)(split - base);
|
||||
entry.checksum = (U32)(xxhash >> 32);
|
||||
ZSTD_ldm_insertEntry(ldmState, hash, entry, *params);
|
||||
}
|
||||
}
|
||||
|
||||
ip += hashed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,11 +298,8 @@ static size_t ZSTD_ldm_generateSequences_internal(
|
||||
/* LDM parameters */
|
||||
int const extDict = ZSTD_window_hasExtDict(ldmState->window);
|
||||
U32 const minMatchLength = params->minMatchLength;
|
||||
U64 const hashPower = ldmState->hashPower;
|
||||
U32 const entsPerBucket = 1U << params->bucketSizeLog;
|
||||
U32 const hBits = params->hashLog - params->bucketSizeLog;
|
||||
U32 const ldmBucketSize = 1U << params->bucketSizeLog;
|
||||
U32 const hashRateLog = params->hashRateLog;
|
||||
U32 const ldmTagMask = (1U << params->hashRateLog) - 1;
|
||||
/* Prefix and extDict parameters */
|
||||
U32 const dictLimit = ldmState->window.dictLimit;
|
||||
U32 const lowestIndex = extDict ? ldmState->window.lowLimit : dictLimit;
|
||||
@@ -290,45 +311,76 @@ static size_t ZSTD_ldm_generateSequences_internal(
|
||||
/* Input bounds */
|
||||
BYTE const* const istart = (BYTE const*)src;
|
||||
BYTE const* const iend = istart + srcSize;
|
||||
BYTE const* const ilimit = iend - MAX(minMatchLength, HASH_READ_SIZE);
|
||||
BYTE const* const ilimit = iend - HASH_READ_SIZE;
|
||||
/* Input positions */
|
||||
BYTE const* anchor = istart;
|
||||
BYTE const* ip = istart;
|
||||
/* Rolling hash */
|
||||
BYTE const* lastHashed = NULL;
|
||||
U64 rollingHash = 0;
|
||||
/* Rolling hash state */
|
||||
ldmRollingHashState_t hashState;
|
||||
/* Arrays for staged-processing */
|
||||
size_t* const splits = ldmState->splitIndices;
|
||||
ldmMatchCandidate_t* const candidates = ldmState->matchCandidates;
|
||||
unsigned numSplits;
|
||||
|
||||
while (ip <= ilimit) {
|
||||
size_t mLength;
|
||||
U32 const curr = (U32)(ip - base);
|
||||
size_t forwardMatchLength = 0, backwardMatchLength = 0;
|
||||
ldmEntry_t* bestEntry = NULL;
|
||||
if (ip != istart) {
|
||||
rollingHash = ZSTD_rollingHash_rotate(rollingHash, lastHashed[0],
|
||||
lastHashed[minMatchLength],
|
||||
hashPower);
|
||||
} else {
|
||||
rollingHash = ZSTD_rollingHash_compute(ip, minMatchLength);
|
||||
if (srcSize < minMatchLength)
|
||||
return iend - anchor;
|
||||
|
||||
/* Initialize the rolling hash state with the first minMatchLength bytes */
|
||||
ZSTD_ldm_gear_init(&hashState, params);
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
while (n < minMatchLength) {
|
||||
numSplits = 0;
|
||||
n += ZSTD_ldm_gear_feed(&hashState, ip + n, minMatchLength - n,
|
||||
splits, &numSplits);
|
||||
}
|
||||
lastHashed = ip;
|
||||
ip += minMatchLength;
|
||||
}
|
||||
|
||||
/* Do not insert and do not look for a match */
|
||||
if (ZSTD_ldm_getTag(rollingHash, hBits, hashRateLog) != ldmTagMask) {
|
||||
ip++;
|
||||
continue;
|
||||
while (ip < ilimit) {
|
||||
size_t hashed;
|
||||
unsigned n;
|
||||
|
||||
numSplits = 0;
|
||||
hashed = ZSTD_ldm_gear_feed(&hashState, ip, ilimit - ip,
|
||||
splits, &numSplits);
|
||||
|
||||
for (n = 0; n < numSplits; n++) {
|
||||
BYTE const* const split = ip + splits[n] - minMatchLength;
|
||||
U64 const xxhash = XXH64(split, minMatchLength, 0);
|
||||
U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1));
|
||||
|
||||
candidates[n].split = split;
|
||||
candidates[n].hash = hash;
|
||||
candidates[n].checksum = (U32)(xxhash >> 32);
|
||||
candidates[n].bucket = ZSTD_ldm_getBucket(ldmState, hash, *params);
|
||||
PREFETCH_L1(candidates[n].bucket);
|
||||
}
|
||||
|
||||
/* Get the best entry and compute the match lengths */
|
||||
{
|
||||
ldmEntry_t* const bucket =
|
||||
ZSTD_ldm_getBucket(ldmState,
|
||||
ZSTD_ldm_getSmallHash(rollingHash, hBits),
|
||||
*params);
|
||||
ldmEntry_t* cur;
|
||||
size_t bestMatchLength = 0;
|
||||
U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
|
||||
for (n = 0; n < numSplits; n++) {
|
||||
size_t forwardMatchLength = 0, backwardMatchLength = 0,
|
||||
bestMatchLength = 0, mLength;
|
||||
BYTE const* const split = candidates[n].split;
|
||||
U32 const checksum = candidates[n].checksum;
|
||||
U32 const hash = candidates[n].hash;
|
||||
ldmEntry_t* const bucket = candidates[n].bucket;
|
||||
ldmEntry_t const* cur;
|
||||
ldmEntry_t const* bestEntry = NULL;
|
||||
ldmEntry_t newEntry;
|
||||
|
||||
for (cur = bucket; cur < bucket + ldmBucketSize; ++cur) {
|
||||
newEntry.offset = (U32)(split - base);
|
||||
newEntry.checksum = checksum;
|
||||
|
||||
/* If a split point would generate a sequence overlapping with
|
||||
* the previous one, we merely register it in the hash table and
|
||||
* move on */
|
||||
if (split < anchor) {
|
||||
ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (cur = bucket; cur < bucket + entsPerBucket; cur++) {
|
||||
size_t curForwardMatchLength, curBackwardMatchLength,
|
||||
curTotalMatchLength;
|
||||
if (cur->checksum != checksum || cur->offset <= lowestIndex) {
|
||||
@@ -342,31 +394,23 @@ static size_t ZSTD_ldm_generateSequences_internal(
|
||||
cur->offset < dictLimit ? dictEnd : iend;
|
||||
BYTE const* const lowMatchPtr =
|
||||
cur->offset < dictLimit ? dictStart : lowPrefixPtr;
|
||||
|
||||
curForwardMatchLength = ZSTD_count_2segments(
|
||||
ip, pMatch, iend,
|
||||
matchEnd, lowPrefixPtr);
|
||||
curForwardMatchLength =
|
||||
ZSTD_count_2segments(split, pMatch, iend, matchEnd, lowPrefixPtr);
|
||||
if (curForwardMatchLength < minMatchLength) {
|
||||
continue;
|
||||
}
|
||||
curBackwardMatchLength =
|
||||
ZSTD_ldm_countBackwardsMatch_2segments(ip, anchor,
|
||||
pMatch, lowMatchPtr,
|
||||
dictStart, dictEnd);
|
||||
curTotalMatchLength = curForwardMatchLength +
|
||||
curBackwardMatchLength;
|
||||
curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments(
|
||||
split, anchor, pMatch, lowMatchPtr, dictStart, dictEnd);
|
||||
} else { /* !extDict */
|
||||
BYTE const* const pMatch = base + cur->offset;
|
||||
curForwardMatchLength = ZSTD_count(ip, pMatch, iend);
|
||||
curForwardMatchLength = ZSTD_count(split, pMatch, iend);
|
||||
if (curForwardMatchLength < minMatchLength) {
|
||||
continue;
|
||||
}
|
||||
curBackwardMatchLength =
|
||||
ZSTD_ldm_countBackwardsMatch(ip, anchor, pMatch,
|
||||
lowPrefixPtr);
|
||||
curTotalMatchLength = curForwardMatchLength +
|
||||
curBackwardMatchLength;
|
||||
ZSTD_ldm_countBackwardsMatch(split, anchor, pMatch, lowPrefixPtr);
|
||||
}
|
||||
curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength;
|
||||
|
||||
if (curTotalMatchLength > bestMatchLength) {
|
||||
bestMatchLength = curTotalMatchLength;
|
||||
@@ -375,57 +419,39 @@ static size_t ZSTD_ldm_generateSequences_internal(
|
||||
bestEntry = cur;
|
||||
}
|
||||
}
|
||||
|
||||
/* No match found -- insert an entry into the hash table
|
||||
* and process the next candidate match */
|
||||
if (bestEntry == NULL) {
|
||||
ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Match found */
|
||||
mLength = forwardMatchLength + backwardMatchLength;
|
||||
{
|
||||
U32 const offset = (U32)(split - base) - bestEntry->offset;
|
||||
rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
|
||||
|
||||
/* Out of sequence storage */
|
||||
if (rawSeqStore->size == rawSeqStore->capacity)
|
||||
return ERROR(dstSize_tooSmall);
|
||||
seq->litLength = (U32)(split - backwardMatchLength - anchor);
|
||||
seq->matchLength = (U32)mLength;
|
||||
seq->offset = offset;
|
||||
rawSeqStore->size++;
|
||||
}
|
||||
|
||||
/* Insert the current entry into the hash table --- it must be
|
||||
* done after the previous block to avoid clobbering bestEntry */
|
||||
ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
|
||||
|
||||
anchor = split + forwardMatchLength;
|
||||
}
|
||||
|
||||
/* No match found -- continue searching */
|
||||
if (bestEntry == NULL) {
|
||||
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash,
|
||||
hBits, curr,
|
||||
*params);
|
||||
ip++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Match found */
|
||||
mLength = forwardMatchLength + backwardMatchLength;
|
||||
ip -= backwardMatchLength;
|
||||
|
||||
{
|
||||
/* Store the sequence:
|
||||
* ip = curr - backwardMatchLength
|
||||
* The match is at (bestEntry->offset - backwardMatchLength)
|
||||
*/
|
||||
U32 const matchIndex = bestEntry->offset;
|
||||
U32 const offset = curr - matchIndex;
|
||||
rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
|
||||
|
||||
/* Out of sequence storage */
|
||||
if (rawSeqStore->size == rawSeqStore->capacity)
|
||||
return ERROR(dstSize_tooSmall);
|
||||
seq->litLength = (U32)(ip - anchor);
|
||||
seq->matchLength = (U32)mLength;
|
||||
seq->offset = offset;
|
||||
rawSeqStore->size++;
|
||||
}
|
||||
|
||||
/* Insert the current entry into the hash table */
|
||||
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
|
||||
(U32)(lastHashed - base),
|
||||
*params);
|
||||
|
||||
assert(ip + backwardMatchLength == lastHashed);
|
||||
|
||||
/* Fill the hash table from lastHashed+1 to ip+mLength*/
|
||||
/* Heuristic: don't need to fill the entire table at end of block */
|
||||
if (ip + mLength <= ilimit) {
|
||||
rollingHash = ZSTD_ldm_fillLdmHashTable(
|
||||
ldmState, rollingHash, lastHashed,
|
||||
ip + mLength, base, hBits, *params);
|
||||
lastHashed = ip + mLength - 1;
|
||||
}
|
||||
ip += mLength;
|
||||
anchor = ip;
|
||||
ip += hashed;
|
||||
}
|
||||
|
||||
return iend - anchor;
|
||||
}
|
||||
|
||||
@@ -620,7 +646,7 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
||||
|
||||
assert(rawSeqStore->pos <= rawSeqStore->size);
|
||||
assert(rawSeqStore->size <= rawSeqStore->capacity);
|
||||
/* Loop through each sequence and apply the block compressor to the lits */
|
||||
/* Loop through each sequence and apply the block compressor to the literals */
|
||||
while (rawSeqStore->pos < rawSeqStore->size && ip < iend) {
|
||||
/* maybeSplitSequence updates rawSeqStore->pos */
|
||||
rawSeq const sequence = maybeSplitSequence(rawSeqStore,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -73,7 +73,7 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
||||
*
|
||||
* Skip past `srcSize` bytes worth of sequences in `rawSeqStore`.
|
||||
* Avoids emitting matches less than `minMatch` bytes.
|
||||
* Must be called for data with is not passed to ZSTD_ldm_blockCompress().
|
||||
* Must be called for data that is not passed to ZSTD_ldm_blockCompress().
|
||||
*/
|
||||
void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize,
|
||||
U32 const minMatch);
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef ZSTD_LDM_GEARTAB_H
|
||||
#define ZSTD_LDM_GEARTAB_H
|
||||
|
||||
static U64 ZSTD_ldm_gearTab[256] = {
|
||||
0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc,
|
||||
0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05,
|
||||
0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e,
|
||||
0x9c8528f65badeaca, 0x86563706e2097529, 0x2902475fa375d889,
|
||||
0xafb32a9739a5ebe6, 0xce2714da3883e639, 0x21eaf821722e69e,
|
||||
0x37b628620b628, 0x49a8d455d88caf5, 0x8556d711e6958140,
|
||||
0x4f7ae74fc605c1f, 0x829f0c3468bd3a20, 0x4ffdc885c625179e,
|
||||
0x8473de048a3daf1b, 0x51008822b05646b2, 0x69d75d12b2d1cc5f,
|
||||
0x8c9d4a19159154bc, 0xc3cc10f4abbd4003, 0xd06ddc1cecb97391,
|
||||
0xbe48e6e7ed80302e, 0x3481db31cee03547, 0xacc3f67cdaa1d210,
|
||||
0x65cb771d8c7f96cc, 0x8eb27177055723dd, 0xc789950d44cd94be,
|
||||
0x934feadc3700b12b, 0x5e485f11edbdf182, 0x1e2e2a46fd64767a,
|
||||
0x2969ca71d82efa7c, 0x9d46e9935ebbba2e, 0xe056b67e05e6822b,
|
||||
0x94d73f55739d03a0, 0xcd7010bdb69b5a03, 0x455ef9fcd79b82f4,
|
||||
0x869cb54a8749c161, 0x38d1a4fa6185d225, 0xb475166f94bbe9bb,
|
||||
0xa4143548720959f1, 0x7aed4780ba6b26ba, 0xd0ce264439e02312,
|
||||
0x84366d746078d508, 0xa8ce973c72ed17be, 0x21c323a29a430b01,
|
||||
0x9962d617e3af80ee, 0xab0ce91d9c8cf75b, 0x530e8ee6d19a4dbc,
|
||||
0x2ef68c0cf53f5d72, 0xc03a681640a85506, 0x496e4e9f9c310967,
|
||||
0x78580472b59b14a0, 0x273824c23b388577, 0x66bf923ad45cb553,
|
||||
0x47ae1a5a2492ba86, 0x35e304569e229659, 0x4765182a46870b6f,
|
||||
0x6cbab625e9099412, 0xddac9a2e598522c1, 0x7172086e666624f2,
|
||||
0xdf5003ca503b7837, 0x88c0c1db78563d09, 0x58d51865acfc289d,
|
||||
0x177671aec65224f1, 0xfb79d8a241e967d7, 0x2be1e101cad9a49a,
|
||||
0x6625682f6e29186b, 0x399553457ac06e50, 0x35dffb4c23abb74,
|
||||
0x429db2591f54aade, 0xc52802a8037d1009, 0x6acb27381f0b25f3,
|
||||
0xf45e2551ee4f823b, 0x8b0ea2d99580c2f7, 0x3bed519cbcb4e1e1,
|
||||
0xff452823dbb010a, 0x9d42ed614f3dd267, 0x5b9313c06257c57b,
|
||||
0xa114b8008b5e1442, 0xc1fe311c11c13d4b, 0x66e8763ea34c5568,
|
||||
0x8b982af1c262f05d, 0xee8876faaa75fbb7, 0x8a62a4d0d172bb2a,
|
||||
0xc13d94a3b7449a97, 0x6dbbba9dc15d037c, 0xc786101f1d92e0f1,
|
||||
0xd78681a907a0b79b, 0xf61aaf2962c9abb9, 0x2cfd16fcd3cb7ad9,
|
||||
0x868c5b6744624d21, 0x25e650899c74ddd7, 0xba042af4a7c37463,
|
||||
0x4eb1a539465a3eca, 0xbe09dbf03b05d5ca, 0x774e5a362b5472ba,
|
||||
0x47a1221229d183cd, 0x504b0ca18ef5a2df, 0xdffbdfbde2456eb9,
|
||||
0x46cd2b2fbee34634, 0xf2aef8fe819d98c3, 0x357f5276d4599d61,
|
||||
0x24a5483879c453e3, 0x88026889192b4b9, 0x28da96671782dbec,
|
||||
0x4ef37c40588e9aaa, 0x8837b90651bc9fb3, 0xc164f741d3f0e5d6,
|
||||
0xbc135a0a704b70ba, 0x69cd868f7622ada, 0xbc37ba89e0b9c0ab,
|
||||
0x47c14a01323552f6, 0x4f00794bacee98bb, 0x7107de7d637a69d5,
|
||||
0x88af793bb6f2255e, 0xf3c6466b8799b598, 0xc288c616aa7f3b59,
|
||||
0x81ca63cf42fca3fd, 0x88d85ace36a2674b, 0xd056bd3792389e7,
|
||||
0xe55c396c4e9dd32d, 0xbefb504571e6c0a6, 0x96ab32115e91e8cc,
|
||||
0xbf8acb18de8f38d1, 0x66dae58801672606, 0x833b6017872317fb,
|
||||
0xb87c16f2d1c92864, 0xdb766a74e58b669c, 0x89659f85c61417be,
|
||||
0xc8daad856011ea0c, 0x76a4b565b6fe7eae, 0xa469d085f6237312,
|
||||
0xaaf0365683a3e96c, 0x4dbb746f8424f7b8, 0x638755af4e4acc1,
|
||||
0x3d7807f5bde64486, 0x17be6d8f5bbb7639, 0x903f0cd44dc35dc,
|
||||
0x67b672eafdf1196c, 0xa676ff93ed4c82f1, 0x521d1004c5053d9d,
|
||||
0x37ba9ad09ccc9202, 0x84e54d297aacfb51, 0xa0b4b776a143445,
|
||||
0x820d471e20b348e, 0x1874383cb83d46dc, 0x97edeec7a1efe11c,
|
||||
0xb330e50b1bdc42aa, 0x1dd91955ce70e032, 0xa514cdb88f2939d5,
|
||||
0x2791233fd90db9d3, 0x7b670a4cc50f7a9b, 0x77c07d2a05c6dfa5,
|
||||
0xe3778b6646d0a6fa, 0xb39c8eda47b56749, 0x933ed448addbef28,
|
||||
0xaf846af6ab7d0bf4, 0xe5af208eb666e49, 0x5e6622f73534cd6a,
|
||||
0x297daeca42ef5b6e, 0x862daef3d35539a6, 0xe68722498f8e1ea9,
|
||||
0x981c53093dc0d572, 0xfa09b0bfbf86fbf5, 0x30b1e96166219f15,
|
||||
0x70e7d466bdc4fb83, 0x5a66736e35f2a8e9, 0xcddb59d2b7c1baef,
|
||||
0xd6c7d247d26d8996, 0xea4e39eac8de1ba3, 0x539c8bb19fa3aff2,
|
||||
0x9f90e4c5fd508d8, 0xa34e5956fbaf3385, 0x2e2f8e151d3ef375,
|
||||
0x173691e9b83faec1, 0xb85a8d56bf016379, 0x8382381267408ae3,
|
||||
0xb90f901bbdc0096d, 0x7c6ad32933bcec65, 0x76bb5e2f2c8ad595,
|
||||
0x390f851a6cf46d28, 0xc3e6064da1c2da72, 0xc52a0c101cfa5389,
|
||||
0xd78eaf84a3fbc530, 0x3781b9e2288b997e, 0x73c2f6dea83d05c4,
|
||||
0x4228e364c5b5ed7, 0x9d7a3edf0da43911, 0x8edcfeda24686756,
|
||||
0x5e7667a7b7a9b3a1, 0x4c4f389fa143791d, 0xb08bc1023da7cddc,
|
||||
0x7ab4be3ae529b1cc, 0x754e6132dbe74ff9, 0x71635442a839df45,
|
||||
0x2f6fb1643fbe52de, 0x961e0a42cf7a8177, 0xf3b45d83d89ef2ea,
|
||||
0xee3de4cf4a6e3e9b, 0xcd6848542c3295e7, 0xe4cee1664c78662f,
|
||||
0x9947548b474c68c4, 0x25d73777a5ed8b0b, 0xc915b1d636b7fc,
|
||||
0x21c2ba75d9b0d2da, 0x5f6b5dcf608a64a1, 0xdcf333255ff9570c,
|
||||
0x633b922418ced4ee, 0xc136dde0b004b34a, 0x58cc83b05d4b2f5a,
|
||||
0x5eb424dda28e42d2, 0x62df47369739cd98, 0xb4e0b42485e4ce17,
|
||||
0x16e1f0c1f9a8d1e7, 0x8ec3916707560ebf, 0x62ba6e2df2cc9db3,
|
||||
0xcbf9f4ff77d83a16, 0x78d9d7d07d2bbcc4, 0xef554ce1e02c41f4,
|
||||
0x8d7581127eccf94d, 0xa9b53336cb3c8a05, 0x38c42c0bf45c4f91,
|
||||
0x640893cdf4488863, 0x80ec34bc575ea568, 0x39f324f5b48eaa40,
|
||||
0xe9d9ed1f8eff527f, 0x9224fc058cc5a214, 0xbaba00b04cfe7741,
|
||||
0x309a9f120fcf52af, 0xa558f3ec65626212, 0x424bec8b7adabe2f,
|
||||
0x41622513a6aea433, 0xb88da2d5324ca798, 0xd287733b245528a4,
|
||||
0x9a44697e6d68aec3, 0x7b1093be2f49bb28, 0x50bbec632e3d8aad,
|
||||
0x6cd90723e1ea8283, 0x897b9e7431b02bf3, 0x219efdcb338a7047,
|
||||
0x3b0311f0a27c0656, 0xdb17bf91c0db96e7, 0x8cd4fd6b4e85a5b2,
|
||||
0xfab071054ba6409d, 0x40d6fe831fa9dfd9, 0xaf358debad7d791e,
|
||||
0xeb8d0e25a65e3e58, 0xbbcbd3df14e08580, 0xcf751f27ecdab2b,
|
||||
0x2b4da14f2613d8f4
|
||||
};
|
||||
|
||||
#endif /* ZSTD_LDM_GEARTAB_H */
|
||||
+19
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -8,6 +8,20 @@
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable inlining for the optimal parser for the kernel build.
|
||||
* It is unlikely to be used in the kernel, and where it is used
|
||||
* latency shouldn't matter because it is very slow to begin with.
|
||||
* We prefer a ~180KB binary size win over faster optimal parsing.
|
||||
*
|
||||
* TODO(https://github.com/facebook/zstd/issues/2862):
|
||||
* Improve the code size of the optimal parser in general, so we
|
||||
* don't need this hack for the kernel build.
|
||||
*/
|
||||
#ifdef ZSTD_LINUX_KERNEL
|
||||
#define ZSTD_NO_INLINE 1
|
||||
#endif
|
||||
|
||||
#include "zstd_compress_internal.h"
|
||||
#include "hist.h"
|
||||
#include "zstd_opt.h"
|
||||
@@ -408,7 +422,7 @@ static U32 ZSTD_insertBt1(
|
||||
hashTable[h] = curr; /* Update Hash Table */
|
||||
|
||||
assert(windowLow > 0);
|
||||
while (nbCompares-- && (matchIndex >= windowLow)) {
|
||||
for (; nbCompares && (matchIndex >= windowLow); --nbCompares) {
|
||||
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||
assert(matchIndex < curr);
|
||||
@@ -639,7 +653,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
||||
|
||||
hashTable[h] = curr; /* Update Hash Table */
|
||||
|
||||
while (nbCompares-- && (matchIndex >= matchLow)) {
|
||||
for (; nbCompares && (matchIndex >= matchLow); --nbCompares) {
|
||||
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
||||
const BYTE* match;
|
||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||
@@ -692,12 +706,13 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
||||
|
||||
*smallerPtr = *largerPtr = 0;
|
||||
|
||||
assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
|
||||
if (dictMode == ZSTD_dictMatchState && nbCompares) {
|
||||
size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);
|
||||
U32 dictMatchIndex = dms->hashTable[dmsH];
|
||||
const U32* const dmsBt = dms->chainTable;
|
||||
commonLengthSmaller = commonLengthLarger = 0;
|
||||
while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) {
|
||||
for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) {
|
||||
const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);
|
||||
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||
const BYTE* match = dmsBase + dictMatchIndex;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -472,8 +472,6 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
|
||||
ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams);
|
||||
assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
|
||||
assert(params.ldmParams.hashRateLog < 32);
|
||||
serialState->ldmState.hashPower =
|
||||
ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);
|
||||
} else {
|
||||
ZSTD_memset(¶ms.ldmParams, 0, sizeof(params.ldmParams));
|
||||
}
|
||||
@@ -486,10 +484,10 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
|
||||
size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t);
|
||||
unsigned const bucketLog =
|
||||
params.ldmParams.hashLog - params.ldmParams.bucketSizeLog;
|
||||
size_t const bucketSize = (size_t)1 << bucketLog;
|
||||
unsigned const prevBucketLog =
|
||||
serialState->params.ldmParams.hashLog -
|
||||
serialState->params.ldmParams.bucketSizeLog;
|
||||
size_t const numBuckets = (size_t)1 << bucketLog;
|
||||
/* Size the seq pool tables */
|
||||
ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize));
|
||||
/* Reset the window */
|
||||
@@ -501,13 +499,13 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
|
||||
}
|
||||
if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) {
|
||||
ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
|
||||
serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(bucketSize, cMem);
|
||||
serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(numBuckets, cMem);
|
||||
}
|
||||
if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets)
|
||||
return 1;
|
||||
/* Zero the tables */
|
||||
ZSTD_memset(serialState->ldmState.hashTable, 0, hashSize);
|
||||
ZSTD_memset(serialState->ldmState.bucketOffsets, 0, bucketSize);
|
||||
ZSTD_memset(serialState->ldmState.bucketOffsets, 0, numBuckets);
|
||||
|
||||
/* Update window state and fill hash table with dict */
|
||||
serialState->ldmState.loadedDictEnd = 0;
|
||||
@@ -683,6 +681,8 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
||||
if (job->jobID != 0) jobParams.fParams.checksumFlag = 0;
|
||||
/* Don't run LDM for the chunks, since we handle it externally */
|
||||
jobParams.ldmParams.enableLdm = 0;
|
||||
/* Correct nbWorkers to 0. */
|
||||
jobParams.nbWorkers = 0;
|
||||
|
||||
|
||||
/* init */
|
||||
@@ -750,6 +750,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
||||
if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
|
||||
lastCBlockSize = cSize;
|
||||
} }
|
||||
ZSTD_CCtx_trace(cctx, 0);
|
||||
|
||||
_endJob:
|
||||
ZSTDMT_serialState_ensureFinished(job->serial, job->jobID, job->cSize);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ******************************************************************
|
||||
* huff0 huffman decoder,
|
||||
* part of Finite State Entropy library
|
||||
* Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
*
|
||||
* You can contact the author at :
|
||||
* - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
||||
@@ -528,13 +528,15 @@ typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
|
||||
static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed,
|
||||
const U32* rankValOrigin, const int minWeight,
|
||||
const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
|
||||
U32 nbBitsBaseline, U16 baseSeq)
|
||||
U32 nbBitsBaseline, U16 baseSeq, U32* wksp, size_t wkspSize)
|
||||
{
|
||||
HUF_DEltX2 DElt;
|
||||
U32 rankVal[HUF_TABLELOG_MAX + 1];
|
||||
U32* rankVal = wksp;
|
||||
|
||||
assert(wkspSize >= HUF_TABLELOG_MAX + 1);
|
||||
(void)wkspSize;
|
||||
/* get pre-calculated rankVal */
|
||||
ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal));
|
||||
ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
|
||||
|
||||
/* fill skipped values */
|
||||
if (minWeight>1) {
|
||||
@@ -569,14 +571,18 @@ static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 co
|
||||
static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
|
||||
const sortedSymbol_t* sortedList, const U32 sortedListSize,
|
||||
const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
|
||||
const U32 nbBitsBaseline)
|
||||
const U32 nbBitsBaseline, U32* wksp, size_t wkspSize)
|
||||
{
|
||||
U32 rankVal[HUF_TABLELOG_MAX + 1];
|
||||
U32* rankVal = wksp;
|
||||
const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
|
||||
const U32 minBits = nbBitsBaseline - maxWeight;
|
||||
U32 s;
|
||||
|
||||
ZSTD_memcpy(rankVal, rankValOrigin, sizeof(rankVal));
|
||||
assert(wkspSize >= HUF_TABLELOG_MAX + 1);
|
||||
wksp += HUF_TABLELOG_MAX + 1;
|
||||
wkspSize -= HUF_TABLELOG_MAX + 1;
|
||||
|
||||
ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1));
|
||||
|
||||
/* fill DTable */
|
||||
for (s=0; s<sortedListSize; s++) {
|
||||
@@ -594,7 +600,7 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
|
||||
HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits,
|
||||
rankValOrigin[nbBits], minWeight,
|
||||
sortedList+sortedRank, sortedListSize-sortedRank,
|
||||
nbBitsBaseline, symbol);
|
||||
nbBitsBaseline, symbol, wksp, wkspSize);
|
||||
} else {
|
||||
HUF_DEltX2 DElt;
|
||||
MEM_writeLE16(&(DElt.sequence), symbol);
|
||||
@@ -608,6 +614,15 @@ static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
rankValCol_t rankVal[HUF_TABLELOG_MAX];
|
||||
U32 rankStats[HUF_TABLELOG_MAX + 1];
|
||||
U32 rankStart0[HUF_TABLELOG_MAX + 2];
|
||||
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
|
||||
BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
|
||||
U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
|
||||
} HUF_ReadDTableX2_Workspace;
|
||||
|
||||
size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
|
||||
const void* src, size_t srcSize,
|
||||
void* workSpace, size_t wkspSize)
|
||||
@@ -620,47 +635,32 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
|
||||
HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
|
||||
U32 *rankStart;
|
||||
|
||||
rankValCol_t* rankVal;
|
||||
U32* rankStats;
|
||||
U32* rankStart0;
|
||||
sortedSymbol_t* sortedSymbol;
|
||||
BYTE* weightList;
|
||||
size_t spaceUsed32 = 0;
|
||||
HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
|
||||
|
||||
rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32);
|
||||
spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;
|
||||
rankStats = (U32 *)workSpace + spaceUsed32;
|
||||
spaceUsed32 += HUF_TABLELOG_MAX + 1;
|
||||
rankStart0 = (U32 *)workSpace + spaceUsed32;
|
||||
spaceUsed32 += HUF_TABLELOG_MAX + 2;
|
||||
sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t);
|
||||
spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;
|
||||
weightList = (BYTE *)((U32 *)workSpace + spaceUsed32);
|
||||
spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
|
||||
if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
|
||||
|
||||
if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);
|
||||
|
||||
rankStart = rankStart0 + 1;
|
||||
ZSTD_memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
|
||||
rankStart = wksp->rankStart0 + 1;
|
||||
ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
|
||||
ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
|
||||
|
||||
DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
|
||||
if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
|
||||
/* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
|
||||
|
||||
iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
|
||||
iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), /* bmi2 */ 0);
|
||||
if (HUF_isError(iSize)) return iSize;
|
||||
|
||||
/* check result */
|
||||
if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
|
||||
|
||||
/* find maxWeight */
|
||||
for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
||||
for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
|
||||
|
||||
/* Get start index of each weight */
|
||||
{ U32 w, nextRankStart = 0;
|
||||
for (w=1; w<maxW+1; w++) {
|
||||
U32 curr = nextRankStart;
|
||||
nextRankStart += rankStats[w];
|
||||
nextRankStart += wksp->rankStats[w];
|
||||
rankStart[w] = curr;
|
||||
}
|
||||
rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
|
||||
@@ -670,37 +670,38 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
|
||||
/* sort symbols by weight */
|
||||
{ U32 s;
|
||||
for (s=0; s<nbSymbols; s++) {
|
||||
U32 const w = weightList[s];
|
||||
U32 const w = wksp->weightList[s];
|
||||
U32 const r = rankStart[w]++;
|
||||
sortedSymbol[r].symbol = (BYTE)s;
|
||||
sortedSymbol[r].weight = (BYTE)w;
|
||||
wksp->sortedSymbol[r].symbol = (BYTE)s;
|
||||
wksp->sortedSymbol[r].weight = (BYTE)w;
|
||||
}
|
||||
rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
|
||||
}
|
||||
|
||||
/* Build rankVal */
|
||||
{ U32* const rankVal0 = rankVal[0];
|
||||
{ U32* const rankVal0 = wksp->rankVal[0];
|
||||
{ int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
|
||||
U32 nextRankVal = 0;
|
||||
U32 w;
|
||||
for (w=1; w<maxW+1; w++) {
|
||||
U32 curr = nextRankVal;
|
||||
nextRankVal += rankStats[w] << (w+rescale);
|
||||
nextRankVal += wksp->rankStats[w] << (w+rescale);
|
||||
rankVal0[w] = curr;
|
||||
} }
|
||||
{ U32 const minBits = tableLog+1 - maxW;
|
||||
U32 consumed;
|
||||
for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
|
||||
U32* const rankValPtr = rankVal[consumed];
|
||||
U32* const rankValPtr = wksp->rankVal[consumed];
|
||||
U32 w;
|
||||
for (w = 1; w < maxW+1; w++) {
|
||||
rankValPtr[w] = rankVal0[w] >> consumed;
|
||||
} } } }
|
||||
|
||||
HUF_fillDTableX2(dt, maxTableLog,
|
||||
sortedSymbol, sizeOfSort,
|
||||
rankStart0, rankVal, maxW,
|
||||
tableLog+1);
|
||||
wksp->sortedSymbol, sizeOfSort,
|
||||
wksp->rankStart0, wksp->rankVal, maxW,
|
||||
tableLog+1,
|
||||
wksp->calleeWksp, sizeof(wksp->calleeWksp) / sizeof(U32));
|
||||
|
||||
dtd.tableLog = (BYTE)maxTableLog;
|
||||
dtd.tableType = 1;
|
||||
@@ -885,7 +886,7 @@ HUF_decompress4X2_usingDTable_internal_body(
|
||||
HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
|
||||
HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
|
||||
HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
|
||||
endSignal = (U32)LIKELY(
|
||||
endSignal = (U32)LIKELY((U32)
|
||||
(BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
|
||||
& (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
|
||||
& (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
|
||||
@@ -1225,7 +1226,7 @@ size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cS
|
||||
HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
|
||||
return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HUF_FORCE_DECOMPRESS_X1
|
||||
size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "../common/fse.h"
|
||||
#define HUF_STATIC_LINKING_ONLY
|
||||
#include "../common/huf.h"
|
||||
#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
|
||||
#include "../common/zstd_internal.h" /* blockProperties_t */
|
||||
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
||||
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
||||
@@ -72,6 +73,147 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
* Multiple DDicts Hashset internals *
|
||||
*************************************/
|
||||
|
||||
#define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
|
||||
#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
|
||||
* Currently, that means a 0.75 load factor.
|
||||
* So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
|
||||
* the load factor of the ddict hash set.
|
||||
*/
|
||||
|
||||
#define DDICT_HASHSET_TABLE_BASE_SIZE 64
|
||||
#define DDICT_HASHSET_RESIZE_FACTOR 2
|
||||
|
||||
/* Hash function to determine starting position of dict insertion within the table
|
||||
* Returns an index between [0, hashSet->ddictPtrTableSize]
|
||||
*/
|
||||
static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet* hashSet, U32 dictID) {
|
||||
const U64 hash = XXH64(&dictID, sizeof(U32), 0);
|
||||
/* DDict ptr table size is a multiple of 2, use size - 1 as mask to get index within [0, hashSet->ddictPtrTableSize) */
|
||||
return hash & (hashSet->ddictPtrTableSize - 1);
|
||||
}
|
||||
|
||||
/* Adds DDict to a hashset without resizing it.
|
||||
* If inserting a DDict with a dictID that already exists in the set, replaces the one in the set.
|
||||
* Returns 0 if successful, or a zstd error code if something went wrong.
|
||||
*/
|
||||
static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict) {
|
||||
const U32 dictID = ZSTD_getDictID_fromDDict(ddict);
|
||||
size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
|
||||
const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
|
||||
RETURN_ERROR_IF(hashSet->ddictPtrCount == hashSet->ddictPtrTableSize, GENERIC, "Hash set is full!");
|
||||
DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
|
||||
while (hashSet->ddictPtrTable[idx] != NULL) {
|
||||
/* Replace existing ddict if inserting ddict with same dictID */
|
||||
if (ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]) == dictID) {
|
||||
DEBUGLOG(4, "DictID already exists, replacing rather than adding");
|
||||
hashSet->ddictPtrTable[idx] = ddict;
|
||||
return 0;
|
||||
}
|
||||
idx &= idxRangeMask;
|
||||
idx++;
|
||||
}
|
||||
DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
|
||||
hashSet->ddictPtrTable[idx] = ddict;
|
||||
hashSet->ddictPtrCount++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Expands hash table by factor of DDICT_HASHSET_RESIZE_FACTOR and
|
||||
* rehashes all values, allocates new table, frees old table.
|
||||
* Returns 0 on success, otherwise a zstd error code.
|
||||
*/
|
||||
static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
|
||||
size_t newTableSize = hashSet->ddictPtrTableSize * DDICT_HASHSET_RESIZE_FACTOR;
|
||||
const ZSTD_DDict** newTable = (const ZSTD_DDict**)ZSTD_customCalloc(sizeof(ZSTD_DDict*) * newTableSize, customMem);
|
||||
const ZSTD_DDict** oldTable = hashSet->ddictPtrTable;
|
||||
size_t oldTableSize = hashSet->ddictPtrTableSize;
|
||||
size_t i;
|
||||
|
||||
DEBUGLOG(4, "Expanding DDict hash table! Old size: %zu new size: %zu", oldTableSize, newTableSize);
|
||||
RETURN_ERROR_IF(!newTable, memory_allocation, "Expanded hashset allocation failed!");
|
||||
hashSet->ddictPtrTable = newTable;
|
||||
hashSet->ddictPtrTableSize = newTableSize;
|
||||
hashSet->ddictPtrCount = 0;
|
||||
for (i = 0; i < oldTableSize; ++i) {
|
||||
if (oldTable[i] != NULL) {
|
||||
FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, oldTable[i]), "");
|
||||
}
|
||||
}
|
||||
ZSTD_customFree((void*)oldTable, customMem);
|
||||
DEBUGLOG(4, "Finished re-hash");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fetches a DDict with the given dictID
|
||||
* Returns the ZSTD_DDict* with the requested dictID. If it doesn't exist, then returns NULL.
|
||||
*/
|
||||
static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, U32 dictID) {
|
||||
size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
|
||||
const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
|
||||
DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
|
||||
for (;;) {
|
||||
size_t currDictID = ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]);
|
||||
if (currDictID == dictID || currDictID == 0) {
|
||||
/* currDictID == 0 implies a NULL ddict entry */
|
||||
break;
|
||||
} else {
|
||||
idx &= idxRangeMask; /* Goes to start of table when we reach the end */
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
|
||||
return hashSet->ddictPtrTable[idx];
|
||||
}
|
||||
|
||||
/* Allocates space for and returns a ddict hash set
|
||||
* The hash set's ZSTD_DDict* table has all values automatically set to NULL to begin with.
|
||||
* Returns NULL if allocation failed.
|
||||
*/
|
||||
static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
|
||||
ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem);
|
||||
DEBUGLOG(4, "Allocating new hash set");
|
||||
if (!ret)
|
||||
return NULL;
|
||||
ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
|
||||
if (!ret->ddictPtrTable) {
|
||||
ZSTD_customFree(ret, customMem);
|
||||
return NULL;
|
||||
}
|
||||
ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
|
||||
ret->ddictPtrCount = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Frees the table of ZSTD_DDict* within a hashset, then frees the hashset itself.
|
||||
* Note: The ZSTD_DDict* within the table are NOT freed.
|
||||
*/
|
||||
static void ZSTD_freeDDictHashSet(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
|
||||
DEBUGLOG(4, "Freeing ddict hash set");
|
||||
if (hashSet && hashSet->ddictPtrTable) {
|
||||
ZSTD_customFree((void*)hashSet->ddictPtrTable, customMem);
|
||||
}
|
||||
if (hashSet) {
|
||||
ZSTD_customFree(hashSet, customMem);
|
||||
}
|
||||
}
|
||||
|
||||
/* Public function: Adds a DDict into the ZSTD_DDictHashSet, possibly triggering a resize of the hash set.
|
||||
* Returns 0 on success, or a ZSTD error.
|
||||
*/
|
||||
static size_t ZSTD_DDictHashSet_addDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict, ZSTD_customMem customMem) {
|
||||
DEBUGLOG(4, "Adding dict ID: %u to hashset with - Count: %zu Tablesize: %zu", ZSTD_getDictID_fromDDict(ddict), hashSet->ddictPtrCount, hashSet->ddictPtrTableSize);
|
||||
if (hashSet->ddictPtrCount * DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT / hashSet->ddictPtrTableSize * DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT != 0) {
|
||||
FORWARD_IF_ERROR(ZSTD_DDictHashSet_expand(hashSet, customMem), "");
|
||||
}
|
||||
FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, ddict), "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-*************************************************************
|
||||
* Context management
|
||||
***************************************************************/
|
||||
@@ -101,6 +243,7 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
|
||||
dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
|
||||
dctx->outBufferMode = ZSTD_bm_buffered;
|
||||
dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
|
||||
dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
|
||||
}
|
||||
|
||||
static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
||||
@@ -120,8 +263,8 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
||||
dctx->noForwardProgress = 0;
|
||||
dctx->oversizedDuration = 0;
|
||||
dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
||||
dctx->ddictSet = NULL;
|
||||
ZSTD_DCtx_resetParameters(dctx);
|
||||
dctx->validateChecksum = 1;
|
||||
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
dctx->dictContentEndForFuzzing = NULL;
|
||||
#endif
|
||||
@@ -178,6 +321,10 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
||||
if (dctx->legacyContext)
|
||||
ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
|
||||
#endif
|
||||
if (dctx->ddictSet) {
|
||||
ZSTD_freeDDictHashSet(dctx->ddictSet, cMem);
|
||||
dctx->ddictSet = NULL;
|
||||
}
|
||||
ZSTD_customFree(dctx, cMem);
|
||||
return 0;
|
||||
}
|
||||
@@ -190,6 +337,29 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
||||
ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */
|
||||
}
|
||||
|
||||
/* Given a dctx with a digested frame params, re-selects the correct ZSTD_DDict based on
|
||||
* the requested dict ID from the frame. If there exists a reference to the correct ZSTD_DDict, then
|
||||
* accordingly sets the ddict to be used to decompress the frame.
|
||||
*
|
||||
* If no DDict is found, then no action is taken, and the ZSTD_DCtx::ddict remains as-is.
|
||||
*
|
||||
* ZSTD_d_refMultipleDDicts must be enabled for this function to be called.
|
||||
*/
|
||||
static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx* dctx) {
|
||||
assert(dctx->refMultipleDDicts && dctx->ddictSet);
|
||||
DEBUGLOG(4, "Adjusting DDict based on requested dict ID from frame");
|
||||
if (dctx->ddict) {
|
||||
const ZSTD_DDict* frameDDict = ZSTD_DDictHashSet_getDDict(dctx->ddictSet, dctx->fParams.dictID);
|
||||
if (frameDDict) {
|
||||
DEBUGLOG(4, "DDict found!");
|
||||
ZSTD_clearDict(dctx);
|
||||
dctx->dictID = dctx->fParams.dictID;
|
||||
dctx->ddict = frameDDict;
|
||||
dctx->dictUses = ZSTD_use_indefinitely;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-*************************************************************
|
||||
* Frame header decoding
|
||||
@@ -299,7 +469,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
||||
}
|
||||
switch(dictIDSizeCode)
|
||||
{
|
||||
default: assert(0); /* impossible */
|
||||
default:
|
||||
assert(0); /* impossible */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 0 : break;
|
||||
case 1 : dictID = ip[pos]; pos++; break;
|
||||
case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
|
||||
@@ -307,7 +479,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
||||
}
|
||||
switch(fcsID)
|
||||
{
|
||||
default: assert(0); /* impossible */
|
||||
default:
|
||||
assert(0); /* impossible */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
|
||||
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
|
||||
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
|
||||
@@ -441,12 +615,19 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
|
||||
|
||||
/** ZSTD_decodeFrameHeader() :
|
||||
* `headerSize` must be the size provided by ZSTD_frameHeaderSize().
|
||||
* If multiple DDict references are enabled, also will choose the correct DDict to use.
|
||||
* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
|
||||
static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
|
||||
{
|
||||
size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
|
||||
if (ZSTD_isError(result)) return result; /* invalid header */
|
||||
RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small");
|
||||
|
||||
/* Reference DDict requested by frame if dctx references multiple ddicts */
|
||||
if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts && dctx->ddictSet) {
|
||||
ZSTD_DCtx_selectFrameDDict(dctx);
|
||||
}
|
||||
|
||||
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||
/* Skip the dictID check in fuzzing mode, because it makes the search
|
||||
* harder.
|
||||
@@ -456,6 +637,7 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t he
|
||||
#endif
|
||||
dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0;
|
||||
if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0);
|
||||
dctx->processedCSize += headerSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -578,7 +760,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
|
||||
size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
|
||||
{
|
||||
DEBUGLOG(5, "ZSTD_insertBlock: %u bytes", (unsigned)blockSize);
|
||||
ZSTD_checkContinuity(dctx, blockStart);
|
||||
ZSTD_checkContinuity(dctx, blockStart, blockSize);
|
||||
dctx->previousDstEnd = (const char*)blockStart + blockSize;
|
||||
return blockSize;
|
||||
}
|
||||
@@ -610,6 +792,32 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
|
||||
return regenSize;
|
||||
}
|
||||
|
||||
static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
|
||||
{
|
||||
#if ZSTD_TRACE
|
||||
if (dctx->traceCtx) {
|
||||
ZSTD_Trace trace;
|
||||
ZSTD_memset(&trace, 0, sizeof(trace));
|
||||
trace.version = ZSTD_VERSION_NUMBER;
|
||||
trace.streaming = streaming;
|
||||
if (dctx->ddict) {
|
||||
trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict);
|
||||
trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict);
|
||||
trace.dictionaryIsCold = dctx->ddictIsCold;
|
||||
}
|
||||
trace.uncompressedSize = (size_t)uncompressedSize;
|
||||
trace.compressedSize = (size_t)compressedSize;
|
||||
trace.dctx = dctx;
|
||||
ZSTD_trace_decompress_end(dctx->traceCtx, &trace);
|
||||
}
|
||||
#else
|
||||
(void)dctx;
|
||||
(void)uncompressedSize;
|
||||
(void)compressedSize;
|
||||
(void)streaming;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*! ZSTD_decompressFrame() :
|
||||
* @dctx must be properly initialized
|
||||
@@ -619,8 +827,9 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void** srcPtr, size_t *srcSizePtr)
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)(*srcPtr);
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
const BYTE* const istart = (const BYTE*)(*srcPtr);
|
||||
const BYTE* ip = istart;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart;
|
||||
BYTE* op = ostart;
|
||||
size_t remainingSrcSize = *srcSizePtr;
|
||||
@@ -695,7 +904,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
||||
ip += 4;
|
||||
remainingSrcSize -= 4;
|
||||
}
|
||||
|
||||
ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
|
||||
/* Allow caller to get size read */
|
||||
*srcPtr = ip;
|
||||
*srcSizePtr = remainingSrcSize;
|
||||
@@ -764,7 +973,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
||||
* use this in all cases but ddict */
|
||||
FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), "");
|
||||
}
|
||||
ZSTD_checkContinuity(dctx, dst);
|
||||
ZSTD_checkContinuity(dctx, dst, dstCapacity);
|
||||
|
||||
{ const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
|
||||
&src, &srcSize);
|
||||
@@ -807,7 +1016,7 @@ static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
|
||||
switch (dctx->dictUses) {
|
||||
default:
|
||||
assert(0 /* Impossible */);
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
case ZSTD_dont_use:
|
||||
ZSTD_clearDict(dctx);
|
||||
return NULL;
|
||||
@@ -871,7 +1080,9 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
||||
{
|
||||
default: /* should not happen */
|
||||
assert(0);
|
||||
ZSTD_FALLTHROUGH;
|
||||
case ZSTDds_getFrameHeaderSize:
|
||||
ZSTD_FALLTHROUGH;
|
||||
case ZSTDds_decodeFrameHeader:
|
||||
return ZSTDnit_frameHeader;
|
||||
case ZSTDds_decodeBlockHeader:
|
||||
@@ -883,6 +1094,7 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
||||
case ZSTDds_checkChecksum:
|
||||
return ZSTDnit_checksum;
|
||||
case ZSTDds_decodeSkippableHeader:
|
||||
ZSTD_FALLTHROUGH;
|
||||
case ZSTDds_skipFrame:
|
||||
return ZSTDnit_skippableFrame;
|
||||
}
|
||||
@@ -899,7 +1111,9 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
||||
DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
|
||||
/* Sanity check */
|
||||
RETURN_ERROR_IF(srcSize != ZSTD_nextSrcSizeToDecompressWithInputSize(dctx, srcSize), srcSize_wrong, "not allowed");
|
||||
if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
|
||||
ZSTD_checkContinuity(dctx, dst, dstCapacity);
|
||||
|
||||
dctx->processedCSize += srcSize;
|
||||
|
||||
switch (dctx->stage)
|
||||
{
|
||||
@@ -1004,6 +1218,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
||||
dctx->expected = 4;
|
||||
dctx->stage = ZSTDds_checkChecksum;
|
||||
} else {
|
||||
ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
|
||||
dctx->expected = 0; /* ends here */
|
||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||
}
|
||||
@@ -1023,6 +1238,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
||||
DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
|
||||
RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
|
||||
}
|
||||
ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
|
||||
dctx->expected = 0;
|
||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||
return 0;
|
||||
@@ -1176,8 +1392,12 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
|
||||
size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
||||
{
|
||||
assert(dctx != NULL);
|
||||
#if ZSTD_TRACE
|
||||
dctx->traceCtx = ZSTD_trace_decompress_begin(dctx);
|
||||
#endif
|
||||
dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */
|
||||
dctx->stage = ZSTDds_getFrameHeaderSize;
|
||||
dctx->processedCSize = 0;
|
||||
dctx->decodedSize = 0;
|
||||
dctx->previousDstEnd = NULL;
|
||||
dctx->prefixStart = NULL;
|
||||
@@ -1391,6 +1611,16 @@ size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
|
||||
if (ddict) {
|
||||
dctx->ddict = ddict;
|
||||
dctx->dictUses = ZSTD_use_indefinitely;
|
||||
if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts) {
|
||||
if (dctx->ddictSet == NULL) {
|
||||
dctx->ddictSet = ZSTD_createDDictHashSet(dctx->customMem);
|
||||
if (!dctx->ddictSet) {
|
||||
RETURN_ERROR(memory_allocation, "Failed to allocate memory for hash set!");
|
||||
}
|
||||
}
|
||||
assert(!dctx->staticSize); /* Impossible: ddictSet cannot have been allocated if static dctx */
|
||||
FORWARD_IF_ERROR(ZSTD_DDictHashSet_addDDict(dctx->ddictSet, ddict, dctx->customMem), "");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1436,6 +1666,10 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
|
||||
bounds.lowerBound = (int)ZSTD_d_validateChecksum;
|
||||
bounds.upperBound = (int)ZSTD_d_ignoreChecksum;
|
||||
return bounds;
|
||||
case ZSTD_d_refMultipleDDicts:
|
||||
bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
|
||||
bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
|
||||
return bounds;
|
||||
default:;
|
||||
}
|
||||
bounds.error = ERROR(parameter_unsupported);
|
||||
@@ -1473,6 +1707,9 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value
|
||||
case ZSTD_d_forceIgnoreChecksum:
|
||||
*value = (int)dctx->forceIgnoreChecksum;
|
||||
return 0;
|
||||
case ZSTD_d_refMultipleDDicts:
|
||||
*value = (int)dctx->refMultipleDDicts;
|
||||
return 0;
|
||||
default:;
|
||||
}
|
||||
RETURN_ERROR(parameter_unsupported, "");
|
||||
@@ -1499,6 +1736,13 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
|
||||
CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value);
|
||||
dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value;
|
||||
return 0;
|
||||
case ZSTD_d_refMultipleDDicts:
|
||||
CHECK_DBOUNDS(ZSTD_d_refMultipleDDicts, value);
|
||||
if (dctx->staticSize != 0) {
|
||||
RETURN_ERROR(parameter_unsupported, "Static dctx does not support multiple DDicts!");
|
||||
}
|
||||
dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
|
||||
return 0;
|
||||
default:;
|
||||
}
|
||||
RETURN_ERROR(parameter_unsupported, "");
|
||||
@@ -1666,7 +1910,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||
zds->legacyVersion = 0;
|
||||
zds->hostageByte = 0;
|
||||
zds->expectedOutBuffer = *output;
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case zdss_loadHeader :
|
||||
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
|
||||
@@ -1680,6 +1924,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||
} }
|
||||
#endif
|
||||
{ size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
|
||||
if (zds->refMultipleDDicts && zds->ddictSet) {
|
||||
ZSTD_DCtx_selectFrameDDict(zds);
|
||||
}
|
||||
DEBUGLOG(5, "header size : %u", (U32)hSize);
|
||||
if (ZSTD_isError(hSize)) {
|
||||
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
||||
@@ -1801,7 +2048,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||
zds->outBuffSize = neededOutBuffSize;
|
||||
} } }
|
||||
zds->streamStage = zdss_read;
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case zdss_read:
|
||||
DEBUGLOG(5, "stage zdss_read");
|
||||
@@ -1820,7 +2067,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||
} }
|
||||
if (ip==iend) { someMoreWork = 0; break; } /* no more input */
|
||||
zds->streamStage = zdss_load;
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case zdss_load:
|
||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -90,7 +90,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||
case set_repeat:
|
||||
DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
|
||||
RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
|
||||
/* fall-through */
|
||||
ZSTD_FALLTHROUGH;
|
||||
|
||||
case set_compressed:
|
||||
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
|
||||
@@ -236,7 +236,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||
|
||||
/* Default FSE distribution tables.
|
||||
* These are pre-calculated FSE decoding tables using default distributions as defined in specification :
|
||||
* https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions
|
||||
* https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
|
||||
* They were generated programmatically with following method :
|
||||
* - start from default distributions, present in /lib/common/zstd_internal.h
|
||||
* - generate tables normally, using ZSTD_buildFSETable()
|
||||
@@ -577,7 +577,7 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb
|
||||
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
const BYTE* const istart = (const BYTE* const)src;
|
||||
const BYTE* const istart = (const BYTE*)src;
|
||||
const BYTE* const iend = istart + srcSize;
|
||||
const BYTE* ip = istart;
|
||||
int nbSeq;
|
||||
@@ -1108,7 +1108,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
BYTE* op = ostart;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
@@ -1242,7 +1242,7 @@ ZSTD_decompressSequencesLong_body(
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
BYTE* op = ostart;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
@@ -1517,9 +1517,9 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
||||
}
|
||||
|
||||
|
||||
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
|
||||
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
|
||||
{
|
||||
if (dst != dctx->previousDstEnd) { /* not contiguous */
|
||||
if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */
|
||||
dctx->dictEnd = dctx->previousDstEnd;
|
||||
dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
|
||||
dctx->prefixStart = dst;
|
||||
@@ -1533,7 +1533,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
size_t dSize;
|
||||
ZSTD_checkContinuity(dctx, dst);
|
||||
ZSTD_checkContinuity(dctx, dst, dstCapacity);
|
||||
dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0);
|
||||
dctx->previousDstEnd = (char*)dst + dSize;
|
||||
return dSize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -99,6 +99,13 @@ typedef enum {
|
||||
ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */
|
||||
} ZSTD_dictUses_e;
|
||||
|
||||
/* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */
|
||||
typedef struct {
|
||||
const ZSTD_DDict** ddictPtrTable;
|
||||
size_t ddictPtrTableSize;
|
||||
size_t ddictPtrCount;
|
||||
} ZSTD_DDictHashSet;
|
||||
|
||||
struct ZSTD_DCtx_s
|
||||
{
|
||||
const ZSTD_seqSymbol* LLTptr;
|
||||
@@ -113,6 +120,7 @@ struct ZSTD_DCtx_s
|
||||
const void* dictEnd; /* end of previous segment */
|
||||
size_t expected;
|
||||
ZSTD_frameHeader fParams;
|
||||
U64 processedCSize;
|
||||
U64 decodedSize;
|
||||
blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
|
||||
ZSTD_dStage stage;
|
||||
@@ -136,6 +144,8 @@ struct ZSTD_DCtx_s
|
||||
U32 dictID;
|
||||
int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */
|
||||
ZSTD_dictUses_e dictUses;
|
||||
ZSTD_DDictHashSet* ddictSet; /* Hash set for multiple ddicts */
|
||||
ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */
|
||||
|
||||
/* streaming */
|
||||
ZSTD_dStreamStage streamStage;
|
||||
@@ -166,6 +176,11 @@ struct ZSTD_DCtx_s
|
||||
void const* dictContentBeginForFuzzing;
|
||||
void const* dictContentEndForFuzzing;
|
||||
#endif
|
||||
|
||||
/* Tracing */
|
||||
#if ZSTD_TRACE
|
||||
ZSTD_TraceCtx traceCtx;
|
||||
#endif
|
||||
}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
|
||||
|
||||
|
||||
@@ -184,7 +199,7 @@ size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
||||
* If yes, do nothing (continue on current segment).
|
||||
* If not, classify previous segment as "external dictionary", and start a new segment.
|
||||
* This function cannot fail. */
|
||||
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst);
|
||||
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize);
|
||||
|
||||
|
||||
#endif /* ZSTD_DECOMPRESS_INTERNAL_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+11
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -1062,18 +1062,19 @@ typedef struct COVER_tryParameters_data_s {
|
||||
* This function is thread safe if zstd is compiled with multithreaded support.
|
||||
* It takes its parameters as an *OWNING* opaque pointer to support threading.
|
||||
*/
|
||||
static void COVER_tryParameters(void *opaque) {
|
||||
static void COVER_tryParameters(void *opaque)
|
||||
{
|
||||
/* Save parameters as local variables */
|
||||
COVER_tryParameters_data_t *const data = (COVER_tryParameters_data_t *)opaque;
|
||||
COVER_tryParameters_data_t *const data = (COVER_tryParameters_data_t*)opaque;
|
||||
const COVER_ctx_t *const ctx = data->ctx;
|
||||
const ZDICT_cover_params_t parameters = data->parameters;
|
||||
size_t dictBufferCapacity = data->dictBufferCapacity;
|
||||
size_t totalCompressedSize = ERROR(GENERIC);
|
||||
/* Allocate space for hash table, dict, and freqs */
|
||||
COVER_map_t activeDmers;
|
||||
BYTE *const dict = (BYTE * const)malloc(dictBufferCapacity);
|
||||
BYTE* const dict = (BYTE*)malloc(dictBufferCapacity);
|
||||
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
||||
U32 *freqs = (U32 *)malloc(ctx->suffixSize * sizeof(U32));
|
||||
U32* const freqs = (U32*)malloc(ctx->suffixSize * sizeof(U32));
|
||||
if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
|
||||
DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
|
||||
goto _cleanup;
|
||||
@@ -1103,15 +1104,14 @@ _cleanup:
|
||||
free(data);
|
||||
COVER_map_destroy(&activeDmers);
|
||||
COVER_dictSelectionFree(selection);
|
||||
if (freqs) {
|
||||
free(freqs);
|
||||
}
|
||||
free(freqs);
|
||||
}
|
||||
|
||||
ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
|
||||
void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
|
||||
const size_t *samplesSizes, unsigned nbSamples,
|
||||
ZDICT_cover_params_t *parameters) {
|
||||
void* dictBuffer, size_t dictBufferCapacity, const void* samplesBuffer,
|
||||
const size_t* samplesSizes, unsigned nbSamples,
|
||||
ZDICT_cover_params_t* parameters)
|
||||
{
|
||||
/* constants */
|
||||
const unsigned nbThreads = parameters->nbThreads;
|
||||
const double splitPoint =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1576,7 +1576,7 @@ note:
|
||||
/* Construct the inverse suffix array of type B* suffixes using trsort. */
|
||||
trsort(ISAb, SA, m, 1);
|
||||
|
||||
/* Set the sorted order of tyoe B* suffixes. */
|
||||
/* Set the sorted order of type B* suffixes. */
|
||||
for(i = n - 1, j = m, c0 = T[n - 1]; 0 <= i;) {
|
||||
for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) >= c1); --i, c1 = c0) { }
|
||||
if(0 <= i) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -462,20 +462,20 @@ typedef struct FASTCOVER_tryParameters_data_s {
|
||||
* This function is thread safe if zstd is compiled with multithreaded support.
|
||||
* It takes its parameters as an *OWNING* opaque pointer to support threading.
|
||||
*/
|
||||
static void FASTCOVER_tryParameters(void *opaque)
|
||||
static void FASTCOVER_tryParameters(void* opaque)
|
||||
{
|
||||
/* Save parameters as local variables */
|
||||
FASTCOVER_tryParameters_data_t *const data = (FASTCOVER_tryParameters_data_t *)opaque;
|
||||
FASTCOVER_tryParameters_data_t *const data = (FASTCOVER_tryParameters_data_t*)opaque;
|
||||
const FASTCOVER_ctx_t *const ctx = data->ctx;
|
||||
const ZDICT_cover_params_t parameters = data->parameters;
|
||||
size_t dictBufferCapacity = data->dictBufferCapacity;
|
||||
size_t totalCompressedSize = ERROR(GENERIC);
|
||||
/* Initialize array to keep track of frequency of dmer within activeSegment */
|
||||
U16* segmentFreqs = (U16 *)calloc(((U64)1 << ctx->f), sizeof(U16));
|
||||
U16* segmentFreqs = (U16*)calloc(((U64)1 << ctx->f), sizeof(U16));
|
||||
/* Allocate space for hash table, dict, and freqs */
|
||||
BYTE *const dict = (BYTE * const)malloc(dictBufferCapacity);
|
||||
BYTE *const dict = (BYTE*)malloc(dictBufferCapacity);
|
||||
COVER_dictSelection_t selection = COVER_dictSelectionError(ERROR(GENERIC));
|
||||
U32 *freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32));
|
||||
U32* freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32));
|
||||
if (!segmentFreqs || !dict || !freqs) {
|
||||
DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n");
|
||||
goto _cleanup;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -23,9 +23,13 @@
|
||||
/* Unix Large Files support (>4GB) */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#if (defined(__sun__) && (!defined(__LP64__))) /* Sun Solaris 32-bits requires specific definitions */
|
||||
# ifndef _LARGEFILE_SOURCE
|
||||
# define _LARGEFILE_SOURCE
|
||||
# endif
|
||||
#elif ! defined(__LP64__) /* No point defining Large file for 64 bit */
|
||||
# ifndef _LARGEFILE64_SOURCE
|
||||
# define _LARGEFILE64_SOURCE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -967,16 +971,11 @@ static size_t ZDICT_addEntropyTablesFromBuffer_advanced(
|
||||
return MIN(dictBufferCapacity, hSize+dictContentSize);
|
||||
}
|
||||
|
||||
/* Hidden declaration for dbio.c */
|
||||
size_t ZDICT_trainFromBuffer_unsafe_legacy(
|
||||
void* dictBuffer, size_t maxDictSize,
|
||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||
ZDICT_legacy_params_t params);
|
||||
/*! ZDICT_trainFromBuffer_unsafe_legacy() :
|
||||
* Warning : `samplesBuffer` must be followed by noisy guard band.
|
||||
* Warning : `samplesBuffer` must be followed by noisy guard band !!!
|
||||
* @return : size of dictionary, or an error code which can be tested with ZDICT_isError()
|
||||
*/
|
||||
size_t ZDICT_trainFromBuffer_unsafe_legacy(
|
||||
static size_t ZDICT_trainFromBuffer_unsafe_legacy(
|
||||
void* dictBuffer, size_t maxDictSize,
|
||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||
ZDICT_legacy_params_t params)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -264,10 +264,11 @@ typedef struct {
|
||||
* Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0.
|
||||
*/
|
||||
ZDICTLIB_API size_t ZDICT_trainFromBuffer_legacy(
|
||||
void *dictBuffer, size_t dictBufferCapacity,
|
||||
const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples,
|
||||
void* dictBuffer, size_t dictBufferCapacity,
|
||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||
ZDICT_legacy_params_t parameters);
|
||||
|
||||
|
||||
/* Deprecation warnings */
|
||||
/* It is generally possible to disable deprecation warnings from compiler,
|
||||
for example with -Wno-deprecated-declarations for gcc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -2833,7 +2833,7 @@ static size_t ZSTDv05_decodeFrameHeader_Part2(ZSTDv05_DCtx* zc, const void* src,
|
||||
|
||||
static size_t ZSTDv05_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
||||
{
|
||||
const BYTE* const in = (const BYTE* const)src;
|
||||
const BYTE* const in = (const BYTE*)src;
|
||||
BYTE headerFlags;
|
||||
U32 cSize;
|
||||
|
||||
@@ -3002,7 +3002,7 @@ static size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t
|
||||
FSEv05_DTable* DTableLL, FSEv05_DTable* DTableML, FSEv05_DTable* DTableOffb,
|
||||
const void* src, size_t srcSize, U32 flagStaticTable)
|
||||
{
|
||||
const BYTE* const istart = (const BYTE* const)src;
|
||||
const BYTE* const istart = (const BYTE*)src;
|
||||
const BYTE* ip = istart;
|
||||
const BYTE* const iend = istart + srcSize;
|
||||
U32 LLtype, Offtype, MLtype;
|
||||
@@ -3310,7 +3310,7 @@ static size_t ZSTDv05_decompressSequences(
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* op = ostart;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
size_t errorCode, dumpsLength=0;
|
||||
@@ -3423,7 +3423,7 @@ static size_t ZSTDv05_decompress_continueDCtx(ZSTDv05_DCtx* dctx,
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)src;
|
||||
const BYTE* iend = ip + srcSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* op = ostart;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
size_t remainingSize = srcSize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -3029,7 +3029,7 @@ typedef struct
|
||||
* Provides the size of compressed block from block header `src` */
|
||||
static size_t ZSTDv06_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
||||
{
|
||||
const BYTE* const in = (const BYTE* const)src;
|
||||
const BYTE* const in = (const BYTE*)src;
|
||||
U32 cSize;
|
||||
|
||||
if (srcSize < ZSTDv06_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||
@@ -3223,7 +3223,7 @@ static size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
|
||||
FSEv06_DTable* DTableLL, FSEv06_DTable* DTableML, FSEv06_DTable* DTableOffb, U32 flagRepeatTable,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
const BYTE* const istart = (const BYTE* const)src;
|
||||
const BYTE* const istart = (const BYTE*)src;
|
||||
const BYTE* const iend = istart + srcSize;
|
||||
const BYTE* ip = istart;
|
||||
|
||||
@@ -3445,7 +3445,7 @@ static size_t ZSTDv06_decompressSequences(
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
BYTE* op = ostart;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
@@ -3561,7 +3561,7 @@ static size_t ZSTDv06_decompressFrame(ZSTDv06_DCtx* dctx,
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)src;
|
||||
const BYTE* const iend = ip + srcSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* op = ostart;
|
||||
BYTE* const oend = ostart + dstCapacity;
|
||||
size_t remainingSize = srcSize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -3258,7 +3258,7 @@ typedef struct
|
||||
* Provides the size of compressed block from block header `src` */
|
||||
static size_t ZSTDv07_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
|
||||
{
|
||||
const BYTE* const in = (const BYTE* const)src;
|
||||
const BYTE* const in = (const BYTE*)src;
|
||||
U32 cSize;
|
||||
|
||||
if (srcSize < ZSTDv07_blockHeaderSize) return ERROR(srcSize_wrong);
|
||||
@@ -3453,7 +3453,7 @@ static size_t ZSTDv07_decodeSeqHeaders(int* nbSeqPtr,
|
||||
FSEv07_DTable* DTableLL, FSEv07_DTable* DTableML, FSEv07_DTable* DTableOffb, U32 flagRepeatTable,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
const BYTE* const istart = (const BYTE* const)src;
|
||||
const BYTE* const istart = (const BYTE*)src;
|
||||
const BYTE* const iend = istart + srcSize;
|
||||
const BYTE* ip = istart;
|
||||
|
||||
@@ -3672,7 +3672,7 @@ static size_t ZSTDv07_decompressSequences(
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)seqStart;
|
||||
const BYTE* const iend = ip + seqSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = ostart + maxDstSize;
|
||||
BYTE* op = ostart;
|
||||
const BYTE* litPtr = dctx->litPtr;
|
||||
@@ -3799,7 +3799,7 @@ static size_t ZSTDv07_decompressFrame(ZSTDv07_DCtx* dctx,
|
||||
{
|
||||
const BYTE* ip = (const BYTE*)src;
|
||||
const BYTE* const iend = ip + srcSize;
|
||||
BYTE* const ostart = (BYTE* const)dst;
|
||||
BYTE* const ostart = (BYTE*)dst;
|
||||
BYTE* const oend = ostart + dstCapacity;
|
||||
BYTE* op = ostart;
|
||||
size_t remainingSize = srcSize;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+82
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -72,7 +72,7 @@ extern "C" {
|
||||
/*------ Version ------*/
|
||||
#define ZSTD_VERSION_MAJOR 1
|
||||
#define ZSTD_VERSION_MINOR 4
|
||||
#define ZSTD_VERSION_RELEASE 7
|
||||
#define ZSTD_VERSION_RELEASE 10
|
||||
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
|
||||
|
||||
/*! ZSTD_versionNumber() :
|
||||
@@ -199,7 +199,7 @@ ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compres
|
||||
*/
|
||||
typedef struct ZSTD_CCtx_s ZSTD_CCtx;
|
||||
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
||||
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
||||
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /* accept NULL pointer */
|
||||
|
||||
/*! ZSTD_compressCCtx() :
|
||||
* Same as ZSTD_compress(), using an explicit ZSTD_CCtx.
|
||||
@@ -222,7 +222,7 @@ ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
|
||||
* Use one context per thread for parallel execution. */
|
||||
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
||||
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
||||
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
||||
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */
|
||||
|
||||
/*! ZSTD_decompressDCtx() :
|
||||
* Same as ZSTD_decompress(),
|
||||
@@ -546,12 +546,14 @@ typedef enum {
|
||||
* ZSTD_d_format
|
||||
* ZSTD_d_stableOutBuffer
|
||||
* ZSTD_d_forceIgnoreChecksum
|
||||
* ZSTD_d_refMultipleDDicts
|
||||
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
|
||||
* note : never ever use experimentalParam? names directly
|
||||
*/
|
||||
ZSTD_d_experimentalParam1=1000,
|
||||
ZSTD_d_experimentalParam2=1001,
|
||||
ZSTD_d_experimentalParam3=1002
|
||||
ZSTD_d_experimentalParam3=1002,
|
||||
ZSTD_d_experimentalParam4=1003
|
||||
|
||||
} ZSTD_dParameter;
|
||||
|
||||
@@ -665,7 +667,7 @@ typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are now effectively same
|
||||
/* Continue to distinguish them for compatibility with older versions <= v1.2.0 */
|
||||
/*===== ZSTD_CStream management functions =====*/
|
||||
ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);
|
||||
ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
|
||||
ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); /* accept NULL pointer */
|
||||
|
||||
/*===== Streaming compression functions =====*/
|
||||
typedef enum {
|
||||
@@ -786,7 +788,7 @@ typedef ZSTD_DCtx ZSTD_DStream; /**< DCtx and DStream are now effectively same
|
||||
/* For compatibility with versions <= v1.2.0, prefer differentiating them. */
|
||||
/*===== ZSTD_DStream management functions =====*/
|
||||
ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
|
||||
ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
|
||||
ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); /* accept NULL pointer */
|
||||
|
||||
/*===== Streaming decompression functions =====*/
|
||||
|
||||
@@ -852,7 +854,8 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize
|
||||
int compressionLevel);
|
||||
|
||||
/*! ZSTD_freeCDict() :
|
||||
* Function frees memory allocated by ZSTD_createCDict(). */
|
||||
* Function frees memory allocated by ZSTD_createCDict().
|
||||
* If a NULL pointer is passed, no operation is performed. */
|
||||
ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
|
||||
|
||||
/*! ZSTD_compress_usingCDict() :
|
||||
@@ -874,7 +877,8 @@ typedef struct ZSTD_DDict_s ZSTD_DDict;
|
||||
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
|
||||
|
||||
/*! ZSTD_freeDDict() :
|
||||
* Function frees memory allocated with ZSTD_createDDict() */
|
||||
* Function frees memory allocated with ZSTD_createDDict()
|
||||
* If a NULL pointer is passed, no operation is performed. */
|
||||
ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
|
||||
|
||||
/*! ZSTD_decompress_usingDDict() :
|
||||
@@ -948,7 +952,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
|
||||
* Reference a prepared dictionary, to be used for all next compressed frames.
|
||||
* Note that compression parameters are enforced from within CDict,
|
||||
* and supersede any compression parameter previously set within CCtx.
|
||||
* The parameters ignored are labled as "superseded-by-cdict" in the ZSTD_cParameter enum docs.
|
||||
* The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs.
|
||||
* The ignored parameters will be used again if the CCtx is returned to no-dictionary mode.
|
||||
* The dictionary will remain valid for future compressed frames using same CCtx.
|
||||
* @result : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
@@ -999,6 +1003,13 @@ ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, s
|
||||
/*! ZSTD_DCtx_refDDict() :
|
||||
* Reference a prepared dictionary, to be used to decompress next frames.
|
||||
* The dictionary remains active for decompression of future frames using same DCtx.
|
||||
*
|
||||
* If called with ZSTD_d_refMultipleDDicts enabled, repeated calls of this function
|
||||
* will store the DDict references in a table, and the DDict used for decompression
|
||||
* will be determined at decompression time, as per the dict ID in the frame.
|
||||
* The memory for the table is allocated on the first call to refDDict, and can be
|
||||
* freed with ZSTD_freeDCtx().
|
||||
*
|
||||
* @result : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
* Note 1 : Currently, only one dictionary can be managed.
|
||||
* Referencing a new dictionary effectively "discards" any previous one.
|
||||
@@ -1205,6 +1216,12 @@ typedef enum {
|
||||
ZSTD_d_ignoreChecksum = 1
|
||||
} ZSTD_forceIgnoreChecksum_e;
|
||||
|
||||
typedef enum {
|
||||
/* Note: this enum controls ZSTD_d_refMultipleDDicts */
|
||||
ZSTD_rmd_refSingleDDict = 0,
|
||||
ZSTD_rmd_refMultipleDDicts = 1
|
||||
} ZSTD_refMultipleDDicts_e;
|
||||
|
||||
typedef enum {
|
||||
/* Note: this enum and the behavior it controls are effectively internal
|
||||
* implementation details of the compressor. They are expected to continue
|
||||
@@ -1286,7 +1303,7 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t
|
||||
* `srcSize` must be the _exact_ size of this series
|
||||
* (i.e. there should be a frame boundary at `src + srcSize`)
|
||||
* @return : - upper-bound for the decompressed size of all data in all successive frames
|
||||
* - if an error occured: ZSTD_CONTENTSIZE_ERROR
|
||||
* - if an error occurred: ZSTD_CONTENTSIZE_ERROR
|
||||
*
|
||||
* note 1 : an error can occur if `src` contains an invalid or incorrectly formatted frame.
|
||||
* note 2 : the upper-bound is exact when the decompressed size field is available in every ZSTD encoded frame of `src`.
|
||||
@@ -1372,6 +1389,23 @@ ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size
|
||||
const void* src, size_t srcSize);
|
||||
|
||||
|
||||
/*! ZSTD_writeSkippableFrame() :
|
||||
* Generates a zstd skippable frame containing data given by src, and writes it to dst buffer.
|
||||
*
|
||||
* Skippable frames begin with a 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.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* @return : number of bytes written or a ZSTD error.
|
||||
*/
|
||||
ZSTDLIB_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize, unsigned magicVariant);
|
||||
|
||||
|
||||
/***************************************
|
||||
* Memory management
|
||||
***************************************/
|
||||
@@ -1506,13 +1540,14 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS
|
||||
* Note that the lifetime of such pool must exist while being used.
|
||||
* ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value
|
||||
* to use an internal thread pool).
|
||||
* ZSTD_freeThreadPool frees a thread pool.
|
||||
* ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer.
|
||||
*/
|
||||
typedef struct POOL_ctx_s ZSTD_threadPool;
|
||||
ZSTDLIB_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
|
||||
ZSTDLIB_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool);
|
||||
ZSTDLIB_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */
|
||||
ZSTDLIB_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
|
||||
|
||||
|
||||
/*
|
||||
* This API is temporary and is expected to change or disappear in the future!
|
||||
*/
|
||||
@@ -1523,10 +1558,12 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
|
||||
const ZSTD_CCtx_params* cctxParams,
|
||||
ZSTD_customMem customMem);
|
||||
|
||||
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
|
||||
ZSTD_dictLoadMethod_e dictLoadMethod,
|
||||
ZSTD_dictContentType_e dictContentType,
|
||||
ZSTD_customMem customMem);
|
||||
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(
|
||||
const void* dict, size_t dictSize,
|
||||
ZSTD_dictLoadMethod_e dictLoadMethod,
|
||||
ZSTD_dictContentType_e dictContentType,
|
||||
ZSTD_customMem customMem);
|
||||
|
||||
|
||||
/***************************************
|
||||
* Advanced compression functions
|
||||
@@ -1802,7 +1839,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
|
||||
* and store it into int* value.
|
||||
* @return : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
*/
|
||||
ZSTDLIB_API size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
|
||||
ZSTDLIB_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
|
||||
|
||||
|
||||
/*! ZSTD_CCtx_params :
|
||||
@@ -1817,13 +1854,13 @@ ZSTDLIB_API size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param
|
||||
* These parameters will be applied to
|
||||
* all subsequent frames.
|
||||
* - ZSTD_compressStream2() : Do compression using the CCtx.
|
||||
* - ZSTD_freeCCtxParams() : Free the memory.
|
||||
* - ZSTD_freeCCtxParams() : Free the memory, accept NULL pointer.
|
||||
*
|
||||
* This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams()
|
||||
* for static allocation of CCtx for single-threaded compression.
|
||||
*/
|
||||
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
|
||||
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
|
||||
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */
|
||||
|
||||
/*! ZSTD_CCtxParams_reset() :
|
||||
* Reset params to default values.
|
||||
@@ -1857,7 +1894,7 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_c
|
||||
* Get the requested value of one compression parameter, selected by enum ZSTD_cParameter.
|
||||
* @result : 0, or an error code (which can be tested with ZSTD_isError()).
|
||||
*/
|
||||
ZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
|
||||
ZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
|
||||
|
||||
/*! ZSTD_CCtx_setParametersUsingCCtxParams() :
|
||||
* Apply a set of ZSTD_CCtx_params to the compression context.
|
||||
@@ -1983,6 +2020,30 @@ ZSTDLIB_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param
|
||||
*/
|
||||
#define ZSTD_d_forceIgnoreChecksum ZSTD_d_experimentalParam3
|
||||
|
||||
/* ZSTD_d_refMultipleDDicts
|
||||
* Experimental parameter.
|
||||
* Default is 0 == disabled. Set to 1 to enable
|
||||
*
|
||||
* If enabled and dctx is allocated on the heap, then additional memory will be allocated
|
||||
* to store references to multiple ZSTD_DDict. That is, multiple calls of ZSTD_refDDict()
|
||||
* using a given ZSTD_DCtx, rather than overwriting the previous DDict reference, will instead
|
||||
* store all references. At decompression time, the appropriate dictID is selected
|
||||
* from the set of DDicts based on the dictID in the frame.
|
||||
*
|
||||
* Usage is simply calling ZSTD_refDDict() on multiple dict buffers.
|
||||
*
|
||||
* Param has values of byte ZSTD_refMultipleDDicts_e
|
||||
*
|
||||
* WARNING: Enabling this parameter and calling ZSTD_DCtx_refDDict(), will trigger memory
|
||||
* allocation for the hash table. ZSTD_freeDCtx() also frees this memory.
|
||||
* Memory is allocated as per ZSTD_DCtx::customMem.
|
||||
*
|
||||
* Although this function allocates memory for the table, the user is still responsible for
|
||||
* memory management of the underlying ZSTD_DDict* themselves.
|
||||
*/
|
||||
#define ZSTD_d_refMultipleDDicts ZSTD_d_experimentalParam4
|
||||
|
||||
|
||||
/*! ZSTD_DCtx_setFormat() :
|
||||
* Instruct the decoder context about what kind of data to decode next.
|
||||
* This instruction is mandatory to decode data without a fully-formed header,
|
||||
|
||||
@@ -8,6 +8,7 @@ zstd-frugal
|
||||
zstd-small
|
||||
zstd-nolegacy
|
||||
zstd-dictBuilder
|
||||
zstd-dll
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
|
||||
+30
-27
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -61,8 +61,10 @@ DEBUGFLAGS+=-Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
|
||||
-Wstrict-prototypes -Wundef -Wpointer-arith \
|
||||
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
|
||||
-Wredundant-decls -Wmissing-prototypes -Wc++-compat
|
||||
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
|
||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
CFLAGS += $(DEBUGFLAGS)
|
||||
CPPFLAGS += $(MOREFLAGS)
|
||||
LDFLAGS += $(MOREFLAGS)
|
||||
FLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
||||
|
||||
ZSTDLIB_COMMON := $(ZSTDDIR)/common
|
||||
ZSTDLIB_COMPRESS := $(ZSTDDIR)/compress
|
||||
@@ -88,13 +90,13 @@ endif
|
||||
|
||||
# Sort files in alphabetical order for reproducible builds
|
||||
ZSTDLIB_FULL_SRC = $(sort $(ZSTDLIB_CORE_SRC) $(ZSTDLEGACY_SRC) $(ZDICT_SRC))
|
||||
ZSTDLIB_LOCAL_SRC := $(notdir $(ZSTDLIB_FULL_SRC))
|
||||
ZSTDLIB_LOCAL_SRC = $(notdir $(ZSTDLIB_FULL_SRC))
|
||||
ZSTDLIB_LOCAL_OBJ := $(ZSTDLIB_LOCAL_SRC:.c=.o)
|
||||
|
||||
ZSTD_CLI_SRC := $(wildcard *.c)
|
||||
ZSTD_CLI_OBJ := $(ZSTD_CLI_SRC:.c=.o)
|
||||
|
||||
ZSTD_ALL_SRC := $(ZSTDLIB_LOCAL_SRC) $(ZSTD_CLI_SRC)
|
||||
ZSTD_ALL_SRC = $(ZSTDLIB_LOCAL_SRC) $(ZSTD_CLI_SRC)
|
||||
ZSTD_ALL_OBJ := $(ZSTD_ALL_SRC:.c=.o)
|
||||
|
||||
UNAME := $(shell uname)
|
||||
@@ -102,6 +104,8 @@ ifeq ($(UNAME), Darwin)
|
||||
HASH ?= md5
|
||||
else ifeq ($(UNAME), FreeBSD)
|
||||
HASH ?= gmd5sum
|
||||
else ifeq ($(UNAME), NetBSD)
|
||||
HASH ?= md5 -n
|
||||
else ifeq ($(UNAME), OpenBSD)
|
||||
HASH ?= md5
|
||||
endif
|
||||
@@ -109,7 +113,7 @@ HASH ?= md5sum
|
||||
HAVE_HASH :=$(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0)
|
||||
|
||||
ifndef BUILD_DIR
|
||||
HASH_DIR = conf_$(shell echo $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ZSTD_FILES) | $(HASH) | cut -f 1 -d " ")
|
||||
HASH_DIR = conf_$(shell echo $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(ZSTD_FILES) | $(HASH) | cut -f 1 -d " ")
|
||||
ifeq ($(HAVE_HASH),0)
|
||||
$(info warning : could not find HASH ($(HASH)), needed to differentiate builds using different flags)
|
||||
BUILD_DIR := obj/generic_noconf
|
||||
@@ -192,11 +196,13 @@ endif
|
||||
endif
|
||||
|
||||
SET_CACHE_DIRECTORY = \
|
||||
$(MAKE) --no-print-directory $@ \
|
||||
+$(MAKE) --no-print-directory $@ \
|
||||
BUILD_DIR=obj/$(HASH_DIR) \
|
||||
CPPFLAGS="$(CPPFLAGS)" \
|
||||
CFLAGS="$(CFLAGS)" \
|
||||
LDFLAGS="$(LDFLAGS)"
|
||||
LDFLAGS="$(LDFLAGS)" \
|
||||
LDLIBS="$(LDLIBS)" \
|
||||
ZSTD_ALL_SRC="$(ZSTD_ALL_SRC)"
|
||||
|
||||
|
||||
.PHONY: all
|
||||
@@ -207,7 +213,8 @@ allVariants: zstd zstd-compress zstd-decompress zstd-small zstd-nolegacy zstd-di
|
||||
|
||||
.PHONY: zstd # must always be run
|
||||
zstd : CPPFLAGS += $(THREAD_CPP) $(ZLIBCPP) $(LZMACPP) $(LZ4CPP)
|
||||
zstd : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAGS_LD)
|
||||
zstd : LDFLAGS += $(THREAD_LD) $(DEBUGFLAGS_LD)
|
||||
zstd : LDLIBS += $(ZLIBLD) $(LZMALD) $(LZ4LD)
|
||||
zstd : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
|
||||
ifneq (,$(filter Windows%,$(OS)))
|
||||
zstd : $(RES_FILE)
|
||||
@@ -229,7 +236,7 @@ $(BUILD_DIR)/zstd : $(ZSTD_OBJ)
|
||||
@echo "$(LZMA_MSG)"
|
||||
@echo "$(LZ4_MSG)"
|
||||
@echo LINK $@
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS)
|
||||
$(CC) $(FLAGS) $^ $(LDLIBS) -o $@$(EXT)
|
||||
|
||||
ifeq ($(HAVE_HASH),1)
|
||||
SRCBIN_HASH = $(shell cat $(BUILD_DIR)/zstd 2> $(VOID) | $(HASH) | cut -f 1 -d " ")
|
||||
@@ -284,18 +291,12 @@ zstd-noxz : LZMALD :=
|
||||
zstd-noxz : LZMA_MSG := - xz/lzma support is disabled
|
||||
zstd-noxz : zstd
|
||||
|
||||
## zstd-dll: zstd executable linked to dynamic library libzstd (must already exist)
|
||||
# note : the following target doesn't link
|
||||
# because zstd uses non-public symbols from libzstd
|
||||
# such as XXH64 (for benchmark),
|
||||
# ZDICT_trainFromBuffer_unsafe_legacy (for dictionary builder)
|
||||
# and ZSTD_cycleLog (likely for --patch-from).
|
||||
# It's unclear at this stage if this is a scenario that must be supported
|
||||
## zstd-dll: zstd executable linked to dynamic library libzstd (must have same version)
|
||||
.PHONY: zstd-dll
|
||||
zstd-dll : LDFLAGS+= -L$(ZSTDDIR) -lzstd
|
||||
zstd-dll : ZSTDLIB_FULL_SRC =
|
||||
zstd-dll : $(ZSTD_CLI_OBJ)
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS)
|
||||
zstd-dll : LDFLAGS+= -L$(ZSTDDIR)
|
||||
zstd-dll : LDLIBS += -lzstd
|
||||
zstd-dll : ZSTDLIB_LOCAL_SRC = xxhash.c
|
||||
zstd-dll : zstd
|
||||
|
||||
|
||||
## zstd-pgo: zstd executable optimized with PGO.
|
||||
@@ -315,16 +316,16 @@ zstd-pgo :
|
||||
## zstd-small: minimal target, supporting only zstd compression and decompression. no bench. no legacy. no other format.
|
||||
zstd-small: CFLAGS = -Os -s
|
||||
zstd-frugal zstd-small: $(ZSTDLIB_CORE_SRC) zstdcli.c util.c timefn.c fileio.c
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT $^ -o $@$(EXT)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOTRACE $^ -o $@$(EXT)
|
||||
|
||||
zstd-decompress: $(ZSTDLIB_COMMON_C) $(ZSTDLIB_DECOMPRESS_C) zstdcli.c util.c timefn.c fileio.c
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS $^ -o $@$(EXT)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT)
|
||||
|
||||
zstd-compress: $(ZSTDLIB_COMMON_C) $(ZSTDLIB_COMPRESS_C) zstdcli.c util.c timefn.c fileio.c
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT)
|
||||
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT)
|
||||
|
||||
## zstd-dictBuilder: executable supporting dictionary creation and compression (only)
|
||||
zstd-dictBuilder: CPPFLAGS += -DZSTD_NOBENCH -DZSTD_NODECOMPRESS
|
||||
zstd-dictBuilder: CPPFLAGS += -DZSTD_NOBENCH -DZSTD_NODECOMPRESS -DZSTD_NOTRACE
|
||||
zstd-dictBuilder: $(ZSTDLIB_COMMON_C) $(ZSTDLIB_COMPRESS_C) $(ZDICT_SRC) zstdcli.c util.c timefn.c fileio.c dibio.c
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||
|
||||
@@ -346,9 +347,11 @@ endif
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) core *.o tmp* result* *.gcda dictionary *.zst \
|
||||
zstd$(EXT) zstd32$(EXT) zstd-compress$(EXT) zstd-decompress$(EXT) \
|
||||
zstd$(EXT) zstd32$(EXT) zstd-dll$(EXT) \
|
||||
zstd-compress$(EXT) zstd-decompress$(EXT) \
|
||||
zstd-small$(EXT) zstd-frugal$(EXT) zstd-nolegacy$(EXT) zstd4$(EXT) \
|
||||
zstd-dictBuilder$(EXT) *.gcda default*.profraw default.profdata have_zlib$(EXT)
|
||||
zstd-dictBuilder$(EXT) \
|
||||
*.gcda default*.profraw default.profdata have_zlib$(EXT)
|
||||
$(RM) -r obj/*
|
||||
@echo Cleaning completed
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+4
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -255,18 +255,6 @@ static fileStats DiB_fileStats(const char** fileNamesTable, unsigned nbFiles, si
|
||||
}
|
||||
|
||||
|
||||
/*! ZDICT_trainFromBuffer_unsafe_legacy() :
|
||||
Strictly Internal use only !!
|
||||
Same as ZDICT_trainFromBuffer_legacy(), but does not control `samplesBuffer`.
|
||||
`samplesBuffer` must be followed by noisy guard band to avoid out-of-buffer reads.
|
||||
@return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
|
||||
or an error code.
|
||||
*/
|
||||
size_t ZDICT_trainFromBuffer_unsafe_legacy(void* dictBuffer, size_t dictBufferCapacity,
|
||||
const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
|
||||
ZDICT_legacy_params_t parameters);
|
||||
|
||||
|
||||
int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
|
||||
const char** fileNamesTable, unsigned nbFiles, size_t chunkSize,
|
||||
ZDICT_legacy_params_t* params, ZDICT_cover_params_t* coverParams,
|
||||
@@ -319,9 +307,9 @@ int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
|
||||
{ size_t dictSize;
|
||||
if (params) {
|
||||
DiB_fillNoise((char*)srcBuffer + loadedSize, NOISELENGTH); /* guard band, for end of buffer condition */
|
||||
dictSize = ZDICT_trainFromBuffer_unsafe_legacy(dictBuffer, maxDictSize,
|
||||
srcBuffer, sampleSizes, fs.nbSamples,
|
||||
*params);
|
||||
dictSize = ZDICT_trainFromBuffer_legacy(dictBuffer, maxDictSize,
|
||||
srcBuffer, sampleSizes, fs.nbSamples,
|
||||
*params);
|
||||
} else if (coverParams) {
|
||||
if (optimize) {
|
||||
dictSize = ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, maxDictSize,
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+34
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -45,7 +45,6 @@
|
||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */
|
||||
#include "../lib/zstd.h"
|
||||
#include "../lib/common/zstd_errors.h" /* ZSTD_error_frameParameter_windowTooLarge */
|
||||
#include "../lib/compress/zstd_compress_internal.h"
|
||||
|
||||
#if defined(ZSTD_GZCOMPRESS) || defined(ZSTD_GZDECOMPRESS)
|
||||
# include <zlib.h>
|
||||
@@ -77,6 +76,11 @@
|
||||
/*-*************************************
|
||||
* Macros
|
||||
***************************************/
|
||||
#define KB *(1 <<10)
|
||||
#define MB *(1 <<20)
|
||||
#define GB *(1U<<30)
|
||||
#undef MAX
|
||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
|
||||
struct FIO_display_prefs_s {
|
||||
int displayLevel; /* 0 : no display; 1: errors; 2: + result + interaction + warnings; 3: + progression; 4: + information */
|
||||
@@ -675,14 +679,11 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
|
||||
FIO_removeFile(dstFileName);
|
||||
} }
|
||||
|
||||
{ FILE* const f = fopen( dstFileName, "wb" );
|
||||
{ const int old_umask = UTIL_umask(0177); /* u-x,go-rwx */
|
||||
FILE* const f = fopen( dstFileName, "wb" );
|
||||
UTIL_umask(old_umask);
|
||||
if (f == NULL) {
|
||||
DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
|
||||
} else if (srcFileName != NULL
|
||||
&& strcmp (srcFileName, stdinmark)
|
||||
&& strcmp(dstFileName, nulmark) ) {
|
||||
/* reduce rights on newly created dst file while compression is ongoing */
|
||||
UTIL_chmod(dstFileName, NULL, 00600);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
@@ -840,7 +841,7 @@ static void FIO_adjustMemLimitForPatchFromMode(FIO_prefs_t* const prefs,
|
||||
/* FIO_removeMultiFilesWarning() :
|
||||
* Returns 1 if the console should abort, 0 if console should proceed.
|
||||
* This function handles logic when processing multiple files with -o, displaying the appropriate warnings/prompts.
|
||||
*
|
||||
*
|
||||
* If -f is specified, or there is just 1 file, zstd will always proceed as usual.
|
||||
* If --rm is specified, there will be a prompt asking for user confirmation.
|
||||
* If -f is specified with --rm, zstd will proceed as usual
|
||||
@@ -897,6 +898,15 @@ typedef struct {
|
||||
ZSTD_CStream* cctx;
|
||||
} cRess_t;
|
||||
|
||||
/** ZSTD_cycleLog() :
|
||||
* condition for correct operation : hashLog > 1 */
|
||||
static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
|
||||
{
|
||||
U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
|
||||
assert(hashLog > 1);
|
||||
return hashLog - btScale;
|
||||
}
|
||||
|
||||
static void FIO_adjustParamsForPatchFromMode(FIO_prefs_t* const prefs,
|
||||
ZSTD_compressionParameters* comprParams,
|
||||
unsigned long long const dictSize,
|
||||
@@ -983,7 +993,7 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_searchLog, (int)comprParams.searchLog) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_minMatch, (int)comprParams.minMatch) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_targetLength, (int)comprParams.targetLength) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_strategy, comprParams.strategy) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_strategy, (int)comprParams.strategy) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_literalCompressionMode, (int)prefs->literalCompressionMode) );
|
||||
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_enableDedicatedDictSearch, 1) );
|
||||
/* multi-threading */
|
||||
@@ -1350,7 +1360,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
|
||||
/* display notification; and adapt compression level */
|
||||
if (READY_FOR_UPDATE()) {
|
||||
ZSTD_frameProgression const zfp = ZSTD_getFrameProgression(ress.cctx);
|
||||
double const cShare = (double)zfp.produced / (zfp.consumed + !zfp.consumed/*avoid div0*/) * 100;
|
||||
double const cShare = (double)zfp.produced / (double)(zfp.consumed + !zfp.consumed/*avoid div0*/) * 100;
|
||||
|
||||
/* display progress notifications */
|
||||
if (g_display_prefs.displayLevel >= 3) {
|
||||
@@ -1499,7 +1509,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
||||
U64 readsize = 0;
|
||||
U64 compressedfilesize = 0;
|
||||
U64 const fileSize = UTIL_getFileSize(srcFileName);
|
||||
DISPLAYLEVEL(5, "%s: %u bytes \n", srcFileName, (unsigned)fileSize);
|
||||
DISPLAYLEVEL(5, "%s: %llu bytes \n", srcFileName, (unsigned long long)fileSize);
|
||||
|
||||
/* compression format selection */
|
||||
switch (prefs->compressionType) {
|
||||
@@ -1545,7 +1555,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
||||
fCtx->totalBytesOutput += (size_t)compressedfilesize;
|
||||
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||
if (g_display_prefs.displayLevel >= 2 &&
|
||||
!fCtx->hasStdoutOutput &&
|
||||
!fCtx->hasStdoutOutput &&
|
||||
(g_display_prefs.displayLevel >= 3 || fCtx->nbFilesTotal <= 1)) {
|
||||
if (readsize == 0) {
|
||||
DISPLAYLEVEL(2,"%-20s : (%6llu => %6llu bytes, %s) \n",
|
||||
@@ -1555,7 +1565,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx,
|
||||
} else {
|
||||
DISPLAYLEVEL(2,"%-20s :%6.2f%% (%6llu => %6llu bytes, %s) \n",
|
||||
srcFileName,
|
||||
(double)compressedfilesize / readsize * 100,
|
||||
(double)compressedfilesize / (double)readsize * 100,
|
||||
(unsigned long long)readsize, (unsigned long long) compressedfilesize,
|
||||
dstFileName);
|
||||
}
|
||||
@@ -1795,7 +1805,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
int status;
|
||||
int error = 0;
|
||||
cRess_t ress = FIO_createCResources(prefs, dictFileName,
|
||||
FIO_getLargestFileSize(inFileNamesTable, fCtx->nbFilesTotal),
|
||||
FIO_getLargestFileSize(inFileNamesTable, (unsigned)fCtx->nbFilesTotal),
|
||||
compressionLevel, comprParams);
|
||||
|
||||
/* init */
|
||||
@@ -1821,7 +1831,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
}
|
||||
} else {
|
||||
if (outMirroredRootDirName)
|
||||
UTIL_mirrorSourceFilesDirectories(inFileNamesTable, fCtx->nbFilesTotal, outMirroredRootDirName);
|
||||
UTIL_mirrorSourceFilesDirectories(inFileNamesTable, (unsigned)fCtx->nbFilesTotal, outMirroredRootDirName);
|
||||
|
||||
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; ++fCtx->currFileIdx) {
|
||||
const char* const srcFileName = inFileNamesTable[fCtx->currFileIdx];
|
||||
@@ -1845,7 +1855,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
}
|
||||
|
||||
if (outDirName)
|
||||
FIO_checkFilenameCollisions(inFileNamesTable , fCtx->nbFilesTotal);
|
||||
FIO_checkFilenameCollisions(inFileNamesTable , (unsigned)fCtx->nbFilesTotal);
|
||||
}
|
||||
|
||||
if (fCtx->nbFilesProcessed >= 1 && fCtx->nbFilesTotal > 1 && fCtx->totalBytesInput != 0) {
|
||||
@@ -1892,7 +1902,7 @@ static dRess_t FIO_createDResources(FIO_prefs_t* const prefs, const char* dictFi
|
||||
EXM_THROW(60, "Error: %s : can't create ZSTD_DStream", strerror(errno));
|
||||
CHECK( ZSTD_DCtx_setMaxWindowSize(ress.dctx, prefs->memLimit) );
|
||||
CHECK( ZSTD_DCtx_setParameter(ress.dctx, ZSTD_d_forceIgnoreChecksum, !prefs->checksumFlag));
|
||||
|
||||
|
||||
ress.srcBufferSize = ZSTD_DStreamInSize();
|
||||
ress.srcBuffer = malloc(ress.srcBufferSize);
|
||||
ress.dstBufferSize = ZSTD_DStreamOutSize();
|
||||
@@ -2099,7 +2109,7 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput,
|
||||
if (srcFileLength>20) srcFileName += srcFileLength-20;
|
||||
}
|
||||
|
||||
ZSTD_resetDStream(ress->dctx);
|
||||
ZSTD_DCtx_reset(ress->dctx, ZSTD_reset_session_only);
|
||||
|
||||
/* Header loading : ensures ZSTD_getFrameHeader() will succeed */
|
||||
{ size_t const toDecode = ZSTD_FRAMEHEADERSIZE_MAX;
|
||||
@@ -2747,7 +2757,7 @@ FIO_decompressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
strerror(errno));
|
||||
} else {
|
||||
if (outMirroredRootDirName)
|
||||
UTIL_mirrorSourceFilesDirectories(srcNamesTable, fCtx->nbFilesTotal, outMirroredRootDirName);
|
||||
UTIL_mirrorSourceFilesDirectories(srcNamesTable, (unsigned)fCtx->nbFilesTotal, outMirroredRootDirName);
|
||||
|
||||
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; fCtx->currFileIdx++) { /* create dstFileName */
|
||||
const char* const srcFileName = srcNamesTable[fCtx->currFileIdx];
|
||||
@@ -2769,9 +2779,9 @@ FIO_decompressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
error |= status;
|
||||
}
|
||||
if (outDirName)
|
||||
FIO_checkFilenameCollisions(srcNamesTable , fCtx->nbFilesTotal);
|
||||
FIO_checkFilenameCollisions(srcNamesTable , (unsigned)fCtx->nbFilesTotal);
|
||||
}
|
||||
|
||||
|
||||
if (fCtx->nbFilesProcessed >= 1 && fCtx->nbFilesTotal > 1 && fCtx->totalBytesOutput != 0)
|
||||
DISPLAYLEVEL(2, "%d files decompressed : %6zu bytes total \n", fCtx->nbFilesProcessed, fCtx->totalBytesOutput);
|
||||
|
||||
@@ -2938,7 +2948,7 @@ displayInfo(const char* inFileName, const fileInfo_t* info, int displayLevel)
|
||||
double const windowSizeUnit = (double)info->windowSize / unit;
|
||||
double const compressedSizeUnit = (double)info->compressedSize / unit;
|
||||
double const decompressedSizeUnit = (double)info->decompressedSize / unit;
|
||||
double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/info->compressedSize;
|
||||
double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/(double)info->compressedSize;
|
||||
const char* const checkString = (info->usesCheck ? "XXH64" : "None");
|
||||
if (displayLevel <= 2) {
|
||||
if (!info->decompUnavailable) {
|
||||
@@ -3059,7 +3069,7 @@ int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int dis
|
||||
const char* const unitStr = total.compressedSize < (1 MB) ? "KB" : "MB";
|
||||
double const compressedSizeUnit = (double)total.compressedSize / unit;
|
||||
double const decompressedSizeUnit = (double)total.decompressedSize / unit;
|
||||
double const ratio = (total.compressedSize == 0) ? 0 : ((double)total.decompressedSize)/total.compressedSize;
|
||||
double const ratio = (total.compressedSize == 0) ? 0 : ((double)total.decompressedSize)/(double)total.compressedSize;
|
||||
const char* const checkString = (total.usesCheck ? "XXH64" : "");
|
||||
DISPLAYOUT("----------------------------------------------------------------- \n");
|
||||
if (total.decompUnavailable) {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+38
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -159,6 +159,15 @@ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions)
|
||||
return chmod(filename, permissions);
|
||||
}
|
||||
|
||||
int UTIL_umask(int mode) {
|
||||
#if PLATFORM_POSIX_VERSION > 0
|
||||
return umask(mode);
|
||||
#else
|
||||
/* do nothing, fake return value */
|
||||
return mode;
|
||||
#endif
|
||||
}
|
||||
|
||||
int UTIL_setFileStat(const char *filename, const stat_t *statbuf)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -670,7 +679,27 @@ const char* UTIL_getFileExtension(const char* infilename)
|
||||
|
||||
static int pathnameHas2Dots(const char *pathname)
|
||||
{
|
||||
return NULL != strstr(pathname, "..");
|
||||
/* We need to figure out whether any ".." present in the path is a whole
|
||||
* path token, which is the case if it is bordered on both sides by either
|
||||
* the beginning/end of the path or by a directory separator.
|
||||
*/
|
||||
const char *needle = pathname;
|
||||
while (1) {
|
||||
needle = strstr(needle, "..");
|
||||
|
||||
if (needle == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((needle == pathname || needle[-1] == PATH_SEP)
|
||||
&& (needle[2] == '\0' || needle[2] == PATH_SEP)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* increment so we search for the next match */
|
||||
needle++;
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isFileNameValidForMirroredOutput(const char *filename)
|
||||
@@ -1183,12 +1212,17 @@ int UTIL_countPhysicalCores(void)
|
||||
/* fall back on the sysconf value */
|
||||
goto failed;
|
||||
} }
|
||||
if (siblings && cpu_cores) {
|
||||
if (siblings && cpu_cores && siblings > cpu_cores) {
|
||||
ratio = siblings / cpu_cores;
|
||||
}
|
||||
|
||||
if (ratio && numPhysicalCores > ratio) {
|
||||
numPhysicalCores = numPhysicalCores / ratio;
|
||||
}
|
||||
|
||||
failed:
|
||||
fclose(cpuinfo);
|
||||
return numPhysicalCores = numPhysicalCores / ratio;
|
||||
return numPhysicalCores;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -22,7 +22,7 @@ extern "C" {
|
||||
#include "platform.h" /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */
|
||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||
#include <sys/types.h> /* stat, utime */
|
||||
#include <sys/stat.h> /* stat, chmod */
|
||||
#include <sys/stat.h> /* stat, chmod, umask */
|
||||
#include "../lib/common/mem.h" /* U64 */
|
||||
|
||||
|
||||
@@ -152,6 +152,11 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf);
|
||||
*/
|
||||
int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions);
|
||||
|
||||
/**
|
||||
* Wraps umask(). Does nothing when the platform doesn't have that concept.
|
||||
*/
|
||||
int UTIL_umask(int mode);
|
||||
|
||||
/*
|
||||
* In the absence of a pre-existing stat result on the file in question, these
|
||||
* functions will do a stat() call internally and then use that result to
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
.
|
||||
.TH "ZSTD" "1" "December 2020" "zstd 1.4.7" "User Commands"
|
||||
.TH "ZSTD" "1" "December 2020" "zstd 1.4.8" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
|
||||
|
||||
+2
-1
@@ -201,7 +201,8 @@ the last one takes effect.
|
||||
* `-o FILE`:
|
||||
save result into `FILE`
|
||||
* `-f`, `--force`:
|
||||
overwrite output without prompting, and (de)compress symbolic links
|
||||
disable input and output checks. Allows overwriting existing files, input
|
||||
from console, output to stdout, operating on links, etc.
|
||||
* `-c`, `--stdout`:
|
||||
force write to standard output, even if it is the console
|
||||
* `--[no-]sparse`:
|
||||
|
||||
+45
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -42,6 +42,9 @@
|
||||
#ifndef ZSTD_NODICT
|
||||
# include "dibio.h" /* ZDICT_cover_params_t, DiB_trainFromFiles() */
|
||||
#endif
|
||||
#ifndef ZSTD_NOTRACE
|
||||
# include "zstdcli_trace.h"
|
||||
#endif
|
||||
#include "../lib/zstd.h" /* ZSTD_VERSION_STRING, ZSTD_minCLevel, ZSTD_maxCLevel */
|
||||
|
||||
|
||||
@@ -103,6 +106,24 @@ typedef enum { cover, fastCover, legacy } dictType;
|
||||
static int g_displayLevel = DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Check Version (when CLI linked to dynamic library)
|
||||
**************************************/
|
||||
|
||||
/* Due to usage of experimental symbols and capabilities by the CLI,
|
||||
* the CLI must be linked against a dynamic library of same version */
|
||||
static void checkLibVersion(void)
|
||||
{
|
||||
if (strcmp(ZSTD_VERSION_STRING, ZSTD_versionString())) {
|
||||
DISPLAYLEVEL(1, "Error : incorrect library version (expecting : %s ; actual : %s ) \n",
|
||||
ZSTD_VERSION_STRING, ZSTD_versionString());
|
||||
DISPLAYLEVEL(1, "Please update library to version %s, or use stand-alone zstd binary \n",
|
||||
ZSTD_VERSION_STRING);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Command Line
|
||||
**************************************/
|
||||
@@ -126,7 +147,8 @@ static void usage(FILE* f, const char* programName)
|
||||
#endif
|
||||
DISPLAY_F(f, " -D DICT: use DICT as Dictionary for compression or decompression \n");
|
||||
DISPLAY_F(f, " -o file: result stored into `file` (only 1 output file) \n");
|
||||
DISPLAY_F(f, " -f : overwrite output without prompting, also (de)compress links \n");
|
||||
DISPLAY_F(f, " -f : disable input and output checks. Allows overwriting existing files,\n");
|
||||
DISPLAY_F(f, " input from console, output to stdout, operating on links, etc.\n");
|
||||
DISPLAY_F(f, "--rm : remove source file(s) after successful de/compression \n");
|
||||
DISPLAY_F(f, " -k : preserve source file(s) (default) \n");
|
||||
DISPLAY_F(f, " -h/-H : display help/long help and exit \n");
|
||||
@@ -167,6 +189,11 @@ static void usage_advanced(const char* programName)
|
||||
DISPLAYOUT( "--[no-]check : during decompression, ignore/validate checksums in compressed frame (default: validate).");
|
||||
#endif
|
||||
#endif /* ZSTD_NOCOMPRESS */
|
||||
|
||||
#ifndef ZSTD_NOTRACE
|
||||
DISPLAYOUT( "\n");
|
||||
DISPLAYOUT( "--trace FILE : log tracing information to FILE.");
|
||||
#endif
|
||||
DISPLAYOUT( "\n");
|
||||
|
||||
DISPLAYOUT( "-- : All arguments after \"--\" are treated as files \n");
|
||||
@@ -696,6 +723,7 @@ int main(int const argCount, const char* argv[])
|
||||
{
|
||||
int argNb,
|
||||
followLinks = 0,
|
||||
forceStdin = 0,
|
||||
forceStdout = 0,
|
||||
hasStdout = 0,
|
||||
ldmFlag = 0,
|
||||
@@ -753,6 +781,7 @@ int main(int const argCount, const char* argv[])
|
||||
|
||||
|
||||
/* init */
|
||||
checkLibVersion();
|
||||
(void)recursive; (void)cLevelLast; /* not used when ZSTD_NOBENCH set */
|
||||
(void)memLimit;
|
||||
assert(argCount >= 1);
|
||||
@@ -807,7 +836,7 @@ int main(int const argCount, const char* argv[])
|
||||
if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; }
|
||||
if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; }
|
||||
if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; }
|
||||
if (!strcmp(argument, "--force")) { FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; continue; }
|
||||
if (!strcmp(argument, "--force")) { FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; continue; }
|
||||
if (!strcmp(argument, "--version")) { printVersion(); CLEAN_RETURN(0); }
|
||||
if (!strcmp(argument, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); }
|
||||
if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; }
|
||||
@@ -897,6 +926,9 @@ int main(int const argCount, const char* argv[])
|
||||
if (longCommandWArg(&argument, "--output-dir-flat")) { NEXT_FIELD(outDirName); continue; }
|
||||
#ifdef UTIL_HAS_MIRRORFILELIST
|
||||
if (longCommandWArg(&argument, "--output-dir-mirror")) { NEXT_FIELD(outMirroredDirName); continue; }
|
||||
#endif
|
||||
#ifndef ZSTD_NOTRACE
|
||||
if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; }
|
||||
#endif
|
||||
if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); continue; }
|
||||
if (longCommandWArg(&argument, "--long")) {
|
||||
@@ -988,7 +1020,7 @@ int main(int const argCount, const char* argv[])
|
||||
case 'D': argument++; NEXT_FIELD(dictFileName); break;
|
||||
|
||||
/* Overwrite */
|
||||
case 'f': FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; argument++; break;
|
||||
case 'f': FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; argument++; break;
|
||||
|
||||
/* Verbose mode */
|
||||
case 'v': g_displayLevel++; argument++; break;
|
||||
@@ -1243,7 +1275,9 @@ int main(int const argCount, const char* argv[])
|
||||
outFileName = stdoutmark; /* when input is stdin, default output is stdout */
|
||||
|
||||
/* Check if input/output defined as console; trigger an error in this case */
|
||||
if (!strcmp(filenames->fileNames[0], stdinmark) && IS_CONSOLE(stdin) ) {
|
||||
if (!forceStdin
|
||||
&& !strcmp(filenames->fileNames[0], stdinmark)
|
||||
&& IS_CONSOLE(stdin) ) {
|
||||
DISPLAYLEVEL(1, "stdin is a console, aborting\n");
|
||||
CLEAN_RETURN(1);
|
||||
}
|
||||
@@ -1281,15 +1315,15 @@ int main(int const argCount, const char* argv[])
|
||||
DISPLAY("error : can't use --patch-from=# on multiple files \n");
|
||||
CLEAN_RETURN(1);
|
||||
}
|
||||
|
||||
/* No status message in pipe mode (stdin - stdout) */
|
||||
|
||||
/* No status message in pipe mode (stdin - stdout) */
|
||||
hasStdout = outFileName && !strcmp(outFileName,stdoutmark);
|
||||
|
||||
if (hasStdout && (g_displayLevel==2)) g_displayLevel=1;
|
||||
|
||||
/* IO Stream/File */
|
||||
FIO_setHasStdoutOutput(fCtx, hasStdout);
|
||||
FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize);
|
||||
FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize);
|
||||
FIO_determineHasStdinInput(fCtx, filenames);
|
||||
FIO_setNotificationLevel(g_displayLevel);
|
||||
FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL);
|
||||
@@ -1374,6 +1408,9 @@ _end:
|
||||
if (main_pause) waitEnter();
|
||||
UTIL_freeFileNamesTable(filenames);
|
||||
UTIL_freeFileNamesTable(file_of_names);
|
||||
#ifndef ZSTD_NOTRACE
|
||||
TRACE_finish();
|
||||
#endif
|
||||
|
||||
return operationResult;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include "zstdcli_trace.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "timefn.h"
|
||||
#include "util.h"
|
||||
|
||||
#define ZSTD_STATIC_LINKING_ONLY
|
||||
#include "../lib/zstd.h"
|
||||
/* We depend on the trace header to avoid duplicating the ZSTD_trace struct.
|
||||
* But, we check the version so it is compatible with dynamic linking.
|
||||
*/
|
||||
#include "../lib/common/zstd_trace.h"
|
||||
/* We only use macros from threading.h so it is compatible with dynamic linking */
|
||||
#include "../lib/common/threading.h"
|
||||
|
||||
#if ZSTD_TRACE
|
||||
|
||||
static FILE* g_traceFile = NULL;
|
||||
static int g_mutexInit = 0;
|
||||
static ZSTD_pthread_mutex_t g_mutex;
|
||||
static UTIL_time_t g_enableTime = UTIL_TIME_INITIALIZER;
|
||||
|
||||
void TRACE_enable(char const* filename)
|
||||
{
|
||||
int const writeHeader = !UTIL_isRegularFile(filename);
|
||||
if (g_traceFile)
|
||||
fclose(g_traceFile);
|
||||
g_traceFile = fopen(filename, "a");
|
||||
if (g_traceFile && writeHeader) {
|
||||
/* Fields:
|
||||
* algorithm
|
||||
* version
|
||||
* method
|
||||
* streaming
|
||||
* level
|
||||
* workers
|
||||
* dictionary size
|
||||
* uncompressed size
|
||||
* compressed size
|
||||
* duration nanos
|
||||
* compression ratio
|
||||
* speed MB/s
|
||||
*/
|
||||
fprintf(g_traceFile, "Algorithm, Version, Method, Mode, Level, Workers, Dictionary Size, Uncompressed Size, Compressed Size, Duration Nanos, Compression Ratio, Speed MB/s\n");
|
||||
}
|
||||
g_enableTime = UTIL_getTime();
|
||||
if (!g_mutexInit) {
|
||||
if (!ZSTD_pthread_mutex_init(&g_mutex, NULL)) {
|
||||
g_mutexInit = 1;
|
||||
} else {
|
||||
TRACE_finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TRACE_finish(void)
|
||||
{
|
||||
if (g_traceFile) {
|
||||
fclose(g_traceFile);
|
||||
}
|
||||
g_traceFile = NULL;
|
||||
if (g_mutexInit) {
|
||||
ZSTD_pthread_mutex_destroy(&g_mutex);
|
||||
g_mutexInit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void TRACE_log(char const* method, PTime duration, ZSTD_Trace const* trace)
|
||||
{
|
||||
int level = 0;
|
||||
int workers = 0;
|
||||
double const ratio = (double)trace->uncompressedSize / (double)trace->compressedSize;
|
||||
double const speed = ((double)trace->uncompressedSize * 1000) / (double)duration;
|
||||
if (trace->params) {
|
||||
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_compressionLevel, &level);
|
||||
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_nbWorkers, &workers);
|
||||
}
|
||||
assert(g_traceFile != NULL);
|
||||
|
||||
ZSTD_pthread_mutex_lock(&g_mutex);
|
||||
/* Fields:
|
||||
* algorithm
|
||||
* version
|
||||
* method
|
||||
* streaming
|
||||
* level
|
||||
* workers
|
||||
* dictionary size
|
||||
* uncompressed size
|
||||
* compressed size
|
||||
* duration nanos
|
||||
* compression ratio
|
||||
* speed MB/s
|
||||
*/
|
||||
fprintf(g_traceFile,
|
||||
"zstd, %u, %s, %s, %d, %d, %llu, %llu, %llu, %llu, %.2f, %.2f\n",
|
||||
trace->version,
|
||||
method,
|
||||
trace->streaming ? "streaming" : "single-pass",
|
||||
level,
|
||||
workers,
|
||||
(unsigned long long)trace->dictionarySize,
|
||||
(unsigned long long)trace->uncompressedSize,
|
||||
(unsigned long long)trace->compressedSize,
|
||||
(unsigned long long)duration,
|
||||
ratio,
|
||||
speed);
|
||||
ZSTD_pthread_mutex_unlock(&g_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* These symbols override the weak symbols provided by the library.
|
||||
*/
|
||||
|
||||
ZSTD_TraceCtx ZSTD_trace_compress_begin(ZSTD_CCtx const* cctx)
|
||||
{
|
||||
(void)cctx;
|
||||
if (g_traceFile == NULL)
|
||||
return 0;
|
||||
return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
|
||||
}
|
||||
|
||||
void ZSTD_trace_compress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
|
||||
{
|
||||
PTime const beginNanos = (PTime)ctx;
|
||||
PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
|
||||
PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
|
||||
assert(g_traceFile != NULL);
|
||||
assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
|
||||
TRACE_log("compress", durationNanos, trace);
|
||||
}
|
||||
|
||||
ZSTD_TraceCtx ZSTD_trace_decompress_begin(ZSTD_DCtx const* dctx)
|
||||
{
|
||||
(void)dctx;
|
||||
if (g_traceFile == NULL)
|
||||
return 0;
|
||||
return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
|
||||
}
|
||||
|
||||
void ZSTD_trace_decompress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
|
||||
{
|
||||
PTime const beginNanos = (PTime)ctx;
|
||||
PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
|
||||
PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
|
||||
assert(g_traceFile != NULL);
|
||||
assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
|
||||
TRACE_log("decompress", durationNanos, trace);
|
||||
}
|
||||
|
||||
#else /* ZSTD_TRACE */
|
||||
|
||||
void TRACE_enable(char const* filename)
|
||||
{
|
||||
(void)filename;
|
||||
}
|
||||
|
||||
void TRACE_finish(void) {}
|
||||
|
||||
#endif /* ZSTD_TRACE */
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef ZSTDCLI_TRACE_H
|
||||
#define ZSTDCLI_TRACE_H
|
||||
|
||||
/**
|
||||
* Enable tracing - log to filename.
|
||||
*/
|
||||
void TRACE_enable(char const* filename);
|
||||
|
||||
/**
|
||||
* Shut down the tracing library.
|
||||
*/
|
||||
void TRACE_finish(void);
|
||||
|
||||
#endif /* ZSTDCLI_TRACE_H */
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
.
|
||||
.TH "ZSTDGREP" "1" "December 2020" "zstd 1.4.7" "User Commands"
|
||||
.TH "ZSTDGREP" "1" "December 2020" "zstd 1.4.8" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
.
|
||||
.TH "ZSTDLESS" "1" "December 2020" "zstd 1.4.7" "User Commands"
|
||||
.TH "ZSTDLESS" "1" "December 2020" "zstd 1.4.8" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstdless\fR \- view zstandard\-compressed files
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# THIS BENCHMARK IS BEING REPLACED BY automated-bencmarking.py
|
||||
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+5
-6
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -38,8 +38,8 @@ CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
|
||||
-Wstrict-prototypes -Wundef \
|
||||
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
|
||||
-Wredundant-decls -Wmissing-prototypes
|
||||
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
|
||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
CFLAGS += $(DEBUGFLAGS)
|
||||
CPPFLAGS += $(MOREFLAGS)
|
||||
|
||||
|
||||
ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c
|
||||
@@ -107,7 +107,6 @@ libzstd :
|
||||
%-dll : libzstd
|
||||
%-dll : LDFLAGS += -L$(ZSTDDIR) -lzstd
|
||||
|
||||
.PHONY: $(ZSTDDIR)/libzstd.a
|
||||
$(ZSTDDIR)/libzstd.a :
|
||||
$(MAKE) -C $(ZSTDDIR) libzstd.a
|
||||
|
||||
@@ -146,7 +145,7 @@ fullbench-lib : $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR
|
||||
# note : broken : requires symbols unavailable from dynamic library
|
||||
fullbench-dll: $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/benchfn.c $(PRGDIR)/timefn.c fullbench.c
|
||||
# $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll
|
||||
$(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT)
|
||||
$(LINK.c) $^ $(LDLIBS) -o $@$(EXT)
|
||||
|
||||
fuzzer : CPPFLAGS += $(MULTITHREAD_CPP)
|
||||
fuzzer : LDFLAGS += $(MULTITHREAD_LD)
|
||||
@@ -165,7 +164,7 @@ zbufftest zbufftest32 zbufftest-dll : CPPFLAGS += -I$(ZSTDDIR)/deprecated
|
||||
zbufftest zbufftest32 zbufftest-dll : CFLAGS += -Wno-deprecated-declarations # required to silence deprecation warnings
|
||||
zbufftest32 : CFLAGS += -m32
|
||||
zbufftest zbufftest32 : $(ZSTD_OBJECTS) $(ZBUFF_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c zbufftest.c
|
||||
$(CC) $(FLAGS) $^ -o $@$(EXT)
|
||||
$(LINK.c) $^ -o $@$(EXT)
|
||||
|
||||
zbufftest-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c zbufftest.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ desktop machine for every pull request that is made to the zstd repo but can als
|
||||
be run on any machine via the command line interface.
|
||||
|
||||
There are three modes of usage for this script: fastmode will just run a minimal single
|
||||
build comparison (between facebook:dev and facebook:master), onetime will pull all the current
|
||||
build comparison (between facebook:dev and facebook:release), onetime will pull all the current
|
||||
pull requests from the zstd repo and compare facebook:dev to all of them once, continuous
|
||||
will continuously get pull requests from the zstd repo and run benchmarks against facebook:dev.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2020-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -20,7 +20,7 @@ import urllib.request
|
||||
|
||||
GITHUB_API_PR_URL = "https://api.github.com/repos/facebook/zstd/pulls?state=open"
|
||||
GITHUB_URL_TEMPLATE = "https://github.com/{}/zstd"
|
||||
MASTER_BUILD = {"user": "facebook", "branch": "dev", "hash": None}
|
||||
RELEASE_BUILD = {"user": "facebook", "branch": "dev", "hash": None}
|
||||
|
||||
# check to see if there are any new PRs every minute
|
||||
DEFAULT_MAX_API_CALL_FREQUENCY_SEC = 60
|
||||
@@ -264,11 +264,11 @@ def main(filenames, levels, iterations, builds=None, emails=None, continuous=Fal
|
||||
for test_build in builds:
|
||||
if dictionary_filename == None:
|
||||
regressions = get_regressions(
|
||||
MASTER_BUILD, test_build, iterations, filenames, levels
|
||||
RELEASE_BUILD, test_build, iterations, filenames, levels
|
||||
)
|
||||
else:
|
||||
regressions = get_regressions_dictionary(
|
||||
MASTER_BUILD, test_build, filenames, dictionary_filename, levels, iterations
|
||||
RELEASE_BUILD, test_build, filenames, dictionary_filename, levels, iterations
|
||||
)
|
||||
body = "\n".join(regressions)
|
||||
if len(regressions) > 0:
|
||||
@@ -320,7 +320,7 @@ if __name__ == "__main__":
|
||||
builds = [{"user": None, "branch": "None", "hash": None}]
|
||||
main(filenames, levels, iterations, builds, frequency=frequency, dictionary_filename=dictionary_filename)
|
||||
elif mode == "fastmode":
|
||||
builds = [{"user": "facebook", "branch": "master", "hash": None}]
|
||||
builds = [{"user": "facebook", "branch": "release", "hash": None}]
|
||||
main(filenames, levels, iterations, builds, frequency=frequency, dictionary_filename=dictionary_filename)
|
||||
else:
|
||||
main(filenames, levels, iterations, None, emails, True, frequency=frequency, dictionary_filename=dictionary_filename)
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+6
-5
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -180,14 +180,15 @@ def compiler_version(cc, cxx):
|
||||
cxx_version_bytes = subprocess.check_output([cxx, "--version"])
|
||||
compiler = None
|
||||
version = None
|
||||
print("{} --version:\n{}".format(cc, cc_version_bytes.decode('ascii')))
|
||||
if b'clang' in cc_version_bytes:
|
||||
assert(b'clang' in cxx_version_bytes)
|
||||
compiler = 'clang'
|
||||
elif b'gcc' in cc_version_bytes:
|
||||
elif b'gcc' in cc_version_bytes or b'GCC' in cc_version_bytes:
|
||||
assert(b'gcc' in cxx_version_bytes or b'g++' in cxx_version_bytes)
|
||||
compiler = 'gcc'
|
||||
if compiler is not None:
|
||||
version_regex = b'([0-9])+\.([0-9])+\.([0-9])+'
|
||||
version_regex = b'([0-9]+)\.([0-9]+)\.([0-9]+)'
|
||||
version_match = re.search(version_regex, cc_version_bytes)
|
||||
version = tuple(int(version_match.group(i)) for i in range(1, 4))
|
||||
return compiler, version
|
||||
@@ -195,9 +196,9 @@ def compiler_version(cc, cxx):
|
||||
|
||||
def overflow_ubsan_flags(cc, cxx):
|
||||
compiler, version = compiler_version(cc, cxx)
|
||||
if compiler == 'gcc':
|
||||
if compiler == 'gcc' and version < (8, 0, 0):
|
||||
return ['-fno-sanitize=signed-integer-overflow']
|
||||
if compiler == 'clang' and version >= (5, 0, 0):
|
||||
if compiler == 'gcc' or (compiler == 'clang' and version >= (5, 0, 0)):
|
||||
return ['-fno-sanitize=pointer-overflow']
|
||||
return []
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -29,4 +29,4 @@ int FUZZ_memcmp(void const* lhs, void const* rhs, size_t size)
|
||||
return 0;
|
||||
}
|
||||
return memcmp(lhs, rhs, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+198
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -675,6 +675,41 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
{
|
||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||
ZSTD_CDict* const cdict = ZSTD_createCDict(CNBuffer, 100, 1);
|
||||
ZSTD_parameters const params = ZSTD_getParams(1, 0, 0);
|
||||
CHECK_Z( ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless) );
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_compressCCtx() doesn't use advanced parameters", testNb++);
|
||||
CHECK_Z(ZSTD_compressCCtx(cctx, compressedBuffer, compressedBufferSize, NULL, 0, 1));
|
||||
if (MEM_readLE32(compressedBuffer) != ZSTD_MAGICNUMBER) goto _output_error;
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_compress_usingDict() doesn't use advanced parameters: ", testNb++);
|
||||
CHECK_Z(ZSTD_compress_usingDict(cctx, compressedBuffer, compressedBufferSize, NULL, 0, NULL, 0, 1));
|
||||
if (MEM_readLE32(compressedBuffer) != ZSTD_MAGICNUMBER) goto _output_error;
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_compress_usingCDict() doesn't use advanced parameters: ", testNb++);
|
||||
CHECK_Z(ZSTD_compress_usingCDict(cctx, compressedBuffer, compressedBufferSize, NULL, 0, cdict));
|
||||
if (MEM_readLE32(compressedBuffer) != ZSTD_MAGICNUMBER) goto _output_error;
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_compress_advanced() doesn't use advanced parameters: ", testNb++);
|
||||
CHECK_Z(ZSTD_compress_advanced(cctx, compressedBuffer, compressedBufferSize, NULL, 0, NULL, 0, params));
|
||||
if (MEM_readLE32(compressedBuffer) != ZSTD_MAGICNUMBER) goto _output_error;
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_compress_usingCDict_advanced() doesn't use advanced parameters: ", testNb++);
|
||||
CHECK_Z(ZSTD_compress_usingCDict_advanced(cctx, compressedBuffer, compressedBufferSize, NULL, 0, cdict, params.fParams));
|
||||
if (MEM_readLE32(compressedBuffer) != ZSTD_MAGICNUMBER) goto _output_error;
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
ZSTD_freeCDict(cdict);
|
||||
ZSTD_freeCCtx(cctx);
|
||||
}
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ldm fill dict out-of-bounds check", testNb++);
|
||||
{
|
||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||
@@ -1570,6 +1605,11 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
int const segs = 4;
|
||||
/* only use the first half so we don't push against size limit of compressedBuffer */
|
||||
size_t const segSize = (CNBuffSize / 2) / segs;
|
||||
|
||||
const U32 skipLen = 129 KB;
|
||||
char* const skipBuff = (char*)malloc(skipLen);
|
||||
assert(skipBuff != NULL);
|
||||
memset(skipBuff, 0, skipLen);
|
||||
for (i = 0; i < segs; i++) {
|
||||
CHECK_NEWV(r, ZSTD_compress(
|
||||
(BYTE*)compressedBuffer + off, CNBuffSize - off,
|
||||
@@ -1578,13 +1618,15 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
off += r;
|
||||
if (i == segs/2) {
|
||||
/* insert skippable frame */
|
||||
const U32 skipLen = 129 KB;
|
||||
MEM_writeLE32((BYTE*)compressedBuffer + off, ZSTD_MAGIC_SKIPPABLE_START);
|
||||
MEM_writeLE32((BYTE*)compressedBuffer + off + 4, skipLen);
|
||||
off += skipLen + ZSTD_SKIPPABLEHEADERSIZE;
|
||||
size_t const skippableSize =
|
||||
ZSTD_writeSkippableFrame((BYTE*)compressedBuffer + off, compressedBufferSize,
|
||||
skipBuff, skipLen, seed % 15);
|
||||
CHECK_Z(skippableSize);
|
||||
off += skippableSize;
|
||||
}
|
||||
}
|
||||
cSize = off;
|
||||
free(skipBuff);
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
@@ -1763,6 +1805,19 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
size_t dictSize;
|
||||
U32 dictID;
|
||||
size_t dictHeaderSize;
|
||||
size_t dictBufferFixedSize = 144;
|
||||
unsigned char const dictBufferFixed[144] = {0x37, 0xa4, 0x30, 0xec, 0x63, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x1f,
|
||||
0x0f, 0x00, 0x28, 0xe5, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x0f, 0x9e, 0x0f, 0x00, 0x00, 0x24, 0x40, 0x80, 0x00, 0x01,
|
||||
0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xde, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0xbc, 0xe1, 0x4b, 0x92, 0x0e, 0xb4, 0x7b, 0x18,
|
||||
0x86, 0x61, 0x18, 0xc6, 0x18, 0x63, 0x8c, 0x31, 0xc6, 0x18, 0x63, 0x8c,
|
||||
0x31, 0x66, 0x66, 0x66, 0x66, 0xb6, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x73, 0x6f, 0x64, 0x61,
|
||||
0x6c, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x72, 0x74, 0x6f, 0x72, 0x20, 0x65,
|
||||
0x6c, 0x65, 0x69, 0x66, 0x65, 0x6e, 0x64, 0x2e, 0x20, 0x41, 0x6c, 0x69};
|
||||
|
||||
if (dictBuffer==NULL || samplesSizes==NULL) {
|
||||
free(dictBuffer);
|
||||
@@ -1858,19 +1913,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
DISPLAYLEVEL(3, "OK : %u \n", (unsigned)dictHeaderSize);
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : check dict header size correctness : ", testNb++);
|
||||
{ unsigned char const dictBufferFixed[144] = { 0x37, 0xa4, 0x30, 0xec, 0x63, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x1f,
|
||||
0x0f, 0x00, 0x28, 0xe5, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0x0f, 0x9e, 0x0f, 0x00, 0x00, 0x24, 0x40, 0x80, 0x00, 0x01,
|
||||
0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xde, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x08, 0x08, 0xbc, 0xe1, 0x4b, 0x92, 0x0e, 0xb4, 0x7b, 0x18,
|
||||
0x86, 0x61, 0x18, 0xc6, 0x18, 0x63, 0x8c, 0x31, 0xc6, 0x18, 0x63, 0x8c,
|
||||
0x31, 0x66, 0x66, 0x66, 0x66, 0xb6, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x73, 0x6f, 0x64, 0x61,
|
||||
0x6c, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x72, 0x74, 0x6f, 0x72, 0x20, 0x65,
|
||||
0x6c, 0x65, 0x69, 0x66, 0x65, 0x6e, 0x64, 0x2e, 0x20, 0x41, 0x6c, 0x69 };
|
||||
dictHeaderSize = ZDICT_getDictHeaderSize(dictBufferFixed, 144);
|
||||
{ dictHeaderSize = ZDICT_getDictHeaderSize(dictBufferFixed, dictBufferFixedSize);
|
||||
if (dictHeaderSize != 115) goto _output_error;
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK : %u \n", (unsigned)dictHeaderSize);
|
||||
@@ -2324,6 +2367,74 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_decompressDCtx() with multiple ddicts : ", testNb++);
|
||||
{
|
||||
const size_t numDicts = 128;
|
||||
const size_t numFrames = 4;
|
||||
size_t i;
|
||||
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
||||
ZSTD_DDict** ddictTable = (ZSTD_DDict**)malloc(sizeof(ZSTD_DDict*)*numDicts);
|
||||
ZSTD_CDict** cdictTable = (ZSTD_CDict**)malloc(sizeof(ZSTD_CDict*)*numDicts);
|
||||
U32 dictIDSeed = seed;
|
||||
/* Create new compressed buffer that will hold frames with differing dictIDs */
|
||||
char* dictBufferMulti = (char*)malloc(sizeof(char) * dictBufferFixedSize); /* Modifiable copy of fixed full dict buffer */
|
||||
|
||||
ZSTD_memcpy(dictBufferMulti, dictBufferFixed, dictBufferFixedSize);
|
||||
/* Create a bunch of DDicts with random dict IDs */
|
||||
for (i = 0; i < numDicts; ++i) {
|
||||
U32 currDictID = FUZ_rand(&dictIDSeed);
|
||||
MEM_writeLE32(dictBufferMulti+ZSTD_FRAMEIDSIZE, currDictID);
|
||||
ddictTable[i] = ZSTD_createDDict(dictBufferMulti, dictBufferFixedSize);
|
||||
cdictTable[i] = ZSTD_createCDict(dictBufferMulti, dictBufferFixedSize, 3);
|
||||
if (!ddictTable[i] || !cdictTable[i] || ZSTD_getDictID_fromCDict(cdictTable[i]) != ZSTD_getDictID_fromDDict(ddictTable[i])) {
|
||||
goto _output_error;
|
||||
}
|
||||
}
|
||||
/* Compress a few frames using random CDicts */
|
||||
{
|
||||
size_t off = 0;
|
||||
/* only use the first half so we don't push against size limit of compressedBuffer */
|
||||
size_t const segSize = (CNBuffSize / 2) / numFrames;
|
||||
for (i = 0; i < numFrames; i++) {
|
||||
size_t dictIdx = FUZ_rand(&dictIDSeed) % numDicts;
|
||||
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
|
||||
{ CHECK_NEWV(r, ZSTD_compress_usingCDict(cctx,
|
||||
(BYTE*)compressedBuffer + off, CNBuffSize - off,
|
||||
(BYTE*)CNBuffer + segSize * (size_t)i, segSize,
|
||||
cdictTable[dictIdx]));
|
||||
off += r;
|
||||
}
|
||||
}
|
||||
cSize = off;
|
||||
}
|
||||
|
||||
/* We should succeed to decompression even though different dicts were used on different frames */
|
||||
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_and_parameters);
|
||||
ZSTD_DCtx_setParameter(dctx, ZSTD_d_refMultipleDDicts, ZSTD_rmd_refMultipleDDicts);
|
||||
/* Reference every single ddict we made */
|
||||
for (i = 0; i < numDicts; ++i) {
|
||||
CHECK_Z( ZSTD_DCtx_refDDict(dctx, ddictTable[i]));
|
||||
}
|
||||
CHECK_Z( ZSTD_decompressDCtx(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize) );
|
||||
/* Streaming decompression should also work */
|
||||
{
|
||||
ZSTD_inBuffer in = {compressedBuffer, cSize, 0};
|
||||
ZSTD_outBuffer out = {decodedBuffer, CNBuffSize, 0};
|
||||
while (in.pos < in.size) {
|
||||
CHECK_Z(ZSTD_decompressStream(dctx, &out, &in));
|
||||
}
|
||||
}
|
||||
ZSTD_freeDCtx(dctx);
|
||||
for (i = 0; i < numDicts; ++i) {
|
||||
ZSTD_freeCDict(cdictTable[i]);
|
||||
ZSTD_freeDDict(ddictTable[i]);
|
||||
}
|
||||
free(dictBufferMulti);
|
||||
free(ddictTable);
|
||||
free(cdictTable);
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
ZSTD_freeCCtx(cctx);
|
||||
free(dictBuffer);
|
||||
free(samplesSizes);
|
||||
@@ -2739,7 +2850,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
free(seqs);
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_getSequences followed by ZSTD_compressSequences : ", testNb++);
|
||||
{
|
||||
size_t srcSize = 500 KB;
|
||||
@@ -3044,6 +3155,74 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
free(dict);
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_getCParams() + dictionary ", testNb++);
|
||||
{
|
||||
ZSTD_compressionParameters const medium = ZSTD_getCParams(1, 16*1024-1, 0);
|
||||
ZSTD_compressionParameters const large = ZSTD_getCParams(1, 128*1024-1, 0);
|
||||
ZSTD_compressionParameters const smallDict = ZSTD_getCParams(1, 0, 400);
|
||||
ZSTD_compressionParameters const mediumDict = ZSTD_getCParams(1, 0, 10000);
|
||||
ZSTD_compressionParameters const largeDict = ZSTD_getCParams(1, 0, 100000);
|
||||
|
||||
assert(!memcmp(&smallDict, &mediumDict, sizeof(smallDict)));
|
||||
assert(!memcmp(&medium, &mediumDict, sizeof(medium)));
|
||||
assert(!memcmp(&large, &largeDict, sizeof(large)));
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : ZSTD_adjustCParams() + dictionary ", testNb++);
|
||||
{
|
||||
ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, 0, 0);
|
||||
ZSTD_compressionParameters const smallDict = ZSTD_adjustCParams(cParams, 0, 400);
|
||||
ZSTD_compressionParameters const smallSrcAndDict = ZSTD_adjustCParams(cParams, 500, 400);
|
||||
|
||||
assert(smallSrcAndDict.windowLog == 10);
|
||||
assert(!memcmp(&cParams, &smallDict, sizeof(cParams)));
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : check compression mem usage monotonicity over levels for estimateCCtxSize() : ", testNb++);
|
||||
{
|
||||
int level = 1;
|
||||
size_t prevSize = 0;
|
||||
for (; level < ZSTD_maxCLevel(); ++level) {
|
||||
size_t const currSize = ZSTD_estimateCCtxSize(level);
|
||||
if (prevSize > currSize) {
|
||||
DISPLAYLEVEL(3, "Error! previous cctx size: %zu at level: %d is larger than current cctx size: %zu at level: %d",
|
||||
prevSize, level-1, currSize, level);
|
||||
goto _output_error;
|
||||
}
|
||||
prevSize = currSize;
|
||||
}
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(3, "test%3i : check estimateCCtxSize() always larger or equal to ZSTD_estimateCCtxSize_usingCParams() : ", testNb++);
|
||||
{
|
||||
size_t const kSizeIncrement = 2 KB;
|
||||
int level = -3;
|
||||
|
||||
for (; level <= ZSTD_maxCLevel(); ++level) {
|
||||
size_t dictSize = 0;
|
||||
for (; dictSize <= 256 KB; dictSize += 8 * kSizeIncrement) {
|
||||
size_t srcSize = 2 KB;
|
||||
for (; srcSize < 300 KB; srcSize += kSizeIncrement) {
|
||||
ZSTD_compressionParameters const cParams = ZSTD_getCParams(level, srcSize, dictSize);
|
||||
size_t const cctxSizeUsingCParams = ZSTD_estimateCCtxSize_usingCParams(cParams);
|
||||
size_t const cctxSizeUsingLevel = ZSTD_estimateCCtxSize(level);
|
||||
if (cctxSizeUsingLevel < cctxSizeUsingCParams
|
||||
|| ZSTD_isError(cctxSizeUsingCParams)
|
||||
|| ZSTD_isError(cctxSizeUsingLevel)) {
|
||||
DISPLAYLEVEL(3, "error! l: %d dict: %zu srcSize: %zu cctx size cpar: %zu, cctx size level: %zu\n",
|
||||
level, dictSize, srcSize, cctxSizeUsingCParams, cctxSizeUsingLevel);
|
||||
goto _output_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
|
||||
#endif
|
||||
|
||||
_end:
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2017-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+31
-12
@@ -114,13 +114,14 @@ esac
|
||||
case "$UNAME" in
|
||||
Darwin) MD5SUM="md5 -r" ;;
|
||||
FreeBSD) MD5SUM="gmd5sum" ;;
|
||||
NetBSD) MD5SUM="md5 -n" ;;
|
||||
OpenBSD) MD5SUM="md5" ;;
|
||||
*) MD5SUM="md5sum" ;;
|
||||
esac
|
||||
|
||||
MTIME="stat -c %Y"
|
||||
case "$UNAME" in
|
||||
Darwin | FreeBSD | OpenBSD) MTIME="stat -f %m" ;;
|
||||
Darwin | FreeBSD | OpenBSD | NetBSD) MTIME="stat -f %m" ;;
|
||||
esac
|
||||
|
||||
DIFF="diff"
|
||||
@@ -485,23 +486,29 @@ rm -rf tmp*
|
||||
if [ "$isWindows" = false ] ; then
|
||||
println "\n===> compress multiple files into an output directory and mirror input folder, --output-dir-mirror"
|
||||
println "test --output-dir-mirror" > tmp1
|
||||
mkdir -p tmpInputTestDir/we/must/go/deeper
|
||||
println cool > tmpInputTestDir/we/must/go/deeper/tmp2
|
||||
mkdir -p tmpInputTestDir/we/.../..must/go/deeper..
|
||||
println cool > tmpInputTestDir/we/.../..must/go/deeper../tmp2
|
||||
zstd tmp1 -r tmpInputTestDir --output-dir-mirror tmpOutDir
|
||||
test -f tmpOutDir/tmp1.zst
|
||||
test -f tmpOutDir/tmpInputTestDir/we/must/go/deeper/tmp2.zst
|
||||
test -f tmpOutDir/tmpInputTestDir/we/.../..must/go/deeper../tmp2.zst
|
||||
|
||||
println "test: compress input dir will be ignored if it has '..'"
|
||||
zstd -r tmpInputTestDir/we/must/../must --output-dir-mirror non-exist && die "input cannot contain '..'"
|
||||
zstd -r tmpInputTestDir/we/.../..must/../..mustgo/deeper.. --output-dir-mirror non-exist && die "input cannot contain '..'"
|
||||
zstd -r tmpInputTestDir/we/.../..must/deeper../.. --output-dir-mirror non-exist && die "input cannot contain '..'"
|
||||
zstd -r ../tests/tmpInputTestDir/we/.../..must/deeper.. --output-dir-mirror non-exist && die "input cannot contain '..'"
|
||||
test ! -d non-exist
|
||||
|
||||
println "test: compress input dir should succeed with benign uses of '..'"
|
||||
zstd -r tmpInputTestDir/we/.../..must/go/deeper.. --output-dir-mirror tmpout
|
||||
test -d tmpout
|
||||
|
||||
println "test : decompress multiple files into an output directory, --output-dir-mirror"
|
||||
zstd tmpOutDir -r -d --output-dir-mirror tmpOutDirDecomp
|
||||
test -f tmpOutDirDecomp/tmpOutDir/tmp1
|
||||
test -f tmpOutDirDecomp/tmpOutDir/tmpInputTestDir/we/must/go/deeper/tmp2
|
||||
test -f tmpOutDirDecomp/tmpOutDir/tmpInputTestDir/we/.../..must/go/deeper../tmp2
|
||||
|
||||
println "test: decompress input dir will be ignored if it has '..'"
|
||||
zstd -r tmpOutDir/tmpInputTestDir/we/must/../must --output-dir-mirror non-exist && die "input cannot contain '..'"
|
||||
zstd -r tmpOutDir/tmpInputTestDir/we/.../..must/../..must --output-dir-mirror non-exist && die "input cannot contain '..'"
|
||||
test ! -d non-exist
|
||||
|
||||
rm -rf tmp*
|
||||
@@ -798,6 +805,8 @@ println "- Dictionary compression roundtrip"
|
||||
zstd -f tmp -D tmpDict
|
||||
zstd -d tmp.zst -D tmpDict -fo result
|
||||
$DIFF "$TESTFILE" result
|
||||
println "- Dictionary compression with hlog < clog"
|
||||
zstd -6f tmp -D tmpDict --zstd=clog=25,hlog=23
|
||||
println "- Dictionary compression with btlazy2 strategy"
|
||||
zstd -f tmp -D tmpDict --zstd=strategy=6
|
||||
zstd -d tmp.zst -D tmpDict -fo result
|
||||
@@ -1322,6 +1331,21 @@ zstd -f --no-check tmp1
|
||||
zstd -l tmp1.zst
|
||||
zstd -lv tmp1.zst
|
||||
|
||||
println "\n===> zstd trace tests "
|
||||
zstd -f --trace tmp.trace tmp1
|
||||
zstd -f --trace tmp.trace tmp1 tmp2 tmp3
|
||||
zstd -f --trace tmp.trace tmp1 tmp2 tmp3 -o /dev/null
|
||||
zstd -f --trace tmp.trace tmp1 tmp2 tmp3 --single-thread
|
||||
zstd -f --trace tmp.trace -D tmp1 tmp2 tmp3 -o /dev/null
|
||||
zstd -f --trace tmp.trace -D tmp1 tmp2 tmp3 -o /dev/null --single-thread
|
||||
zstd --trace tmp.trace -t tmp1.zst
|
||||
zstd --trace tmp.trace -t tmp1.zst tmp2.zst
|
||||
zstd -f --trace tmp.trace -d tmp1.zst
|
||||
zstd -f --trace tmp.trace -d tmp1.zst tmp2.zst tmp3.zst
|
||||
zstd -D tmp1 tmp2 -c | zstd --trace tmp.trace -t -D tmp1
|
||||
zstd -b1e10i0 --trace tmp.trace tmp1
|
||||
zstd -b1e10i0 --trace tmp.trace tmp1 tmp2 tmp3
|
||||
|
||||
rm tmp*
|
||||
|
||||
|
||||
@@ -1342,8 +1366,6 @@ optCSize19=$(datagen -g2M | zstd -19 -c | wc -c)
|
||||
longCSize19=$(datagen -g2M | zstd -19 --long -c | wc -c)
|
||||
optCSize19wlog23=$(datagen -g2M | zstd -19 -c --zstd=wlog=23 | wc -c)
|
||||
longCSize19wlog23=$(datagen -g2M | zstd -19 -c --long=23 | wc -c)
|
||||
optCSize22=$(datagen -g900K | zstd -22 --ultra -c | wc -c)
|
||||
longCSize22=$(datagen -g900K | zstd -22 --ultra --long -c | wc -c)
|
||||
if [ "$longCSize16" -gt "$optCSize16" ]; then
|
||||
echo using --long on compression level 16 should not cause compressed size regression
|
||||
exit 1
|
||||
@@ -1353,9 +1375,6 @@ elif [ "$longCSize19" -gt "$optCSize19" ]; then
|
||||
elif [ "$longCSize19wlog23" -gt "$optCSize19wlog23" ]; then
|
||||
echo using --long on compression level 19 with wLog=23 should not cause compressed size regression
|
||||
exit 1
|
||||
elif [ "$longCSize22" -gt "$optCSize22" ]; then
|
||||
echo using --long on compression level 22 should not cause compressed size regression
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# ################################################################
|
||||
# Copyright (c) 2018-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# ################################################################
|
||||
# Copyright (c) 2015-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -59,6 +59,14 @@ static config_t no_pledged_src_size = {
|
||||
.no_pledged_src_size = 1,
|
||||
};
|
||||
|
||||
static config_t no_pledged_src_size_with_dict = {
|
||||
.name = "no source size with dict",
|
||||
.cli_args = "",
|
||||
.param_values = PARAM_VALUES(level_0_param_values),
|
||||
.no_pledged_src_size = 1,
|
||||
.use_dictionary = 1,
|
||||
};
|
||||
|
||||
static param_value_t const ldm_param_values[] = {
|
||||
{.param = ZSTD_c_enableLongDistanceMatching, .value = 1},
|
||||
};
|
||||
@@ -192,6 +200,7 @@ static config_t const* g_configs[] = {
|
||||
#undef FAST_LEVEL
|
||||
|
||||
&no_pledged_src_size,
|
||||
&no_pledged_src_size_with_dict,
|
||||
&ldm,
|
||||
&mt,
|
||||
&mt_ldm,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+18
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -67,10 +67,27 @@ data_t github = {
|
||||
},
|
||||
};
|
||||
|
||||
data_t github_tar = {
|
||||
.name = "github.tar",
|
||||
.type = data_type_file,
|
||||
.data =
|
||||
{
|
||||
.url = REGRESSION_RELEASE("github.tar.zst"),
|
||||
.xxhash64 = 0xa9b1b44b020df292LL,
|
||||
},
|
||||
.dict =
|
||||
{
|
||||
.url = REGRESSION_RELEASE("github.dict.zst"),
|
||||
.xxhash64 = 0x1eddc6f737d3cb53LL,
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
static data_t* g_data[] = {
|
||||
&silesia,
|
||||
&silesia_tar,
|
||||
&github,
|
||||
&github_tar,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+314
-22
@@ -16,6 +16,23 @@ silesia.tar, level 19, compress
|
||||
silesia.tar, uncompressed literals, compress simple, 4861425
|
||||
silesia.tar, uncompressed literals optimal, compress simple, 4281605
|
||||
silesia.tar, huffman literals, compress simple, 6186042
|
||||
github.tar, level -5, compress simple, 46856
|
||||
github.tar, level -3, compress simple, 43754
|
||||
github.tar, level -1, compress simple, 42490
|
||||
github.tar, level 0, compress simple, 38441
|
||||
github.tar, level 1, compress simple, 39265
|
||||
github.tar, level 3, compress simple, 38441
|
||||
github.tar, level 4, compress simple, 38467
|
||||
github.tar, level 5, compress simple, 39788
|
||||
github.tar, level 6, compress simple, 39603
|
||||
github.tar, level 7, compress simple, 39206
|
||||
github.tar, level 9, compress simple, 36717
|
||||
github.tar, level 13, compress simple, 35621
|
||||
github.tar, level 16, compress simple, 40255
|
||||
github.tar, level 19, compress simple, 32837
|
||||
github.tar, uncompressed literals, compress simple, 38441
|
||||
github.tar, uncompressed literals optimal, compress simple, 32837
|
||||
github.tar, huffman literals, compress simple, 42490
|
||||
silesia, level -5, compress cctx, 6737607
|
||||
silesia, level -3, compress cctx, 6444677
|
||||
silesia, level -1, compress cctx, 6178460
|
||||
@@ -94,9 +111,9 @@ silesia, level 9, zstdcli,
|
||||
silesia, level 13, zstdcli, 4482183
|
||||
silesia, level 16, zstdcli, 4377513
|
||||
silesia, level 19, zstdcli, 4293378
|
||||
silesia, long distance mode, zstdcli, 4839756
|
||||
silesia, long distance mode, zstdcli, 4840792
|
||||
silesia, multithreaded, zstdcli, 4849600
|
||||
silesia, multithreaded long distance mode, zstdcli, 4839756
|
||||
silesia, multithreaded long distance mode, zstdcli, 4840792
|
||||
silesia, small window log, zstdcli, 7111012
|
||||
silesia, small hash log, zstdcli, 6555069
|
||||
silesia, small chain log, zstdcli, 4931196
|
||||
@@ -120,9 +137,9 @@ silesia.tar, level 13, zstdcli,
|
||||
silesia.tar, level 16, zstdcli, 4381336
|
||||
silesia.tar, level 19, zstdcli, 4281609
|
||||
silesia.tar, no source size, zstdcli, 4861508
|
||||
silesia.tar, long distance mode, zstdcli, 4853190
|
||||
silesia.tar, long distance mode, zstdcli, 4853153
|
||||
silesia.tar, multithreaded, zstdcli, 4861512
|
||||
silesia.tar, multithreaded long distance mode, zstdcli, 4853190
|
||||
silesia.tar, multithreaded long distance mode, zstdcli, 4853153
|
||||
silesia.tar, small window log, zstdcli, 7101576
|
||||
silesia.tar, small hash log, zstdcli, 6587959
|
||||
silesia.tar, small chain log, zstdcli, 4943310
|
||||
@@ -154,7 +171,7 @@ github, level 7 with dict, zstdcli,
|
||||
github, level 9, zstdcli, 137122
|
||||
github, level 9 with dict, zstdcli, 41332
|
||||
github, level 13, zstdcli, 136064
|
||||
github, level 13 with dict, zstdcli, 41743
|
||||
github, level 13 with dict, zstdcli, 41900
|
||||
github, level 16, zstdcli, 136064
|
||||
github, level 16 with dict, zstdcli, 39577
|
||||
github, level 19, zstdcli, 136064
|
||||
@@ -170,6 +187,47 @@ github, uncompressed literals, zstdcli,
|
||||
github, uncompressed literals optimal, zstdcli, 159227
|
||||
github, huffman literals, zstdcli, 144465
|
||||
github, multithreaded with advanced params, zstdcli, 167915
|
||||
github.tar, level -5, zstdcli, 46751
|
||||
github.tar, level -5 with dict, zstdcli, 43975
|
||||
github.tar, level -3, zstdcli, 43541
|
||||
github.tar, level -3 with dict, zstdcli, 40809
|
||||
github.tar, level -1, zstdcli, 42469
|
||||
github.tar, level -1 with dict, zstdcli, 41126
|
||||
github.tar, level 0, zstdcli, 38445
|
||||
github.tar, level 0 with dict, zstdcli, 37999
|
||||
github.tar, level 1, zstdcli, 39346
|
||||
github.tar, level 1 with dict, zstdcli, 38313
|
||||
github.tar, level 3, zstdcli, 38445
|
||||
github.tar, level 3 with dict, zstdcli, 37999
|
||||
github.tar, level 4, zstdcli, 38471
|
||||
github.tar, level 4 with dict, zstdcli, 37952
|
||||
github.tar, level 5, zstdcli, 39792
|
||||
github.tar, level 5 with dict, zstdcli, 39231
|
||||
github.tar, level 6, zstdcli, 39607
|
||||
github.tar, level 6 with dict, zstdcli, 38669
|
||||
github.tar, level 7, zstdcli, 39210
|
||||
github.tar, level 7 with dict, zstdcli, 37958
|
||||
github.tar, level 9, zstdcli, 36721
|
||||
github.tar, level 9 with dict, zstdcli, 36886
|
||||
github.tar, level 13, zstdcli, 35625
|
||||
github.tar, level 13 with dict, zstdcli, 38730
|
||||
github.tar, level 16, zstdcli, 40259
|
||||
github.tar, level 16 with dict, zstdcli, 33643
|
||||
github.tar, level 19, zstdcli, 32841
|
||||
github.tar, level 19 with dict, zstdcli, 32899
|
||||
github.tar, no source size, zstdcli, 38442
|
||||
github.tar, no source size with dict, zstdcli, 38004
|
||||
github.tar, long distance mode, zstdcli, 39726
|
||||
github.tar, multithreaded, zstdcli, 38445
|
||||
github.tar, multithreaded long distance mode, zstdcli, 39726
|
||||
github.tar, small window log, zstdcli, 199432
|
||||
github.tar, small hash log, zstdcli, 129874
|
||||
github.tar, small chain log, zstdcli, 41673
|
||||
github.tar, explicit params, zstdcli, 41199
|
||||
github.tar, uncompressed literals, zstdcli, 41126
|
||||
github.tar, uncompressed literals optimal, zstdcli, 35392
|
||||
github.tar, huffman literals, zstdcli, 38804
|
||||
github.tar, multithreaded with advanced params, zstdcli, 41126
|
||||
silesia, level -5, advanced one pass, 6737607
|
||||
silesia, level -3, advanced one pass, 6444677
|
||||
silesia, level -1, advanced one pass, 6178460
|
||||
@@ -185,9 +243,9 @@ silesia, level 13, advanced
|
||||
silesia, level 16, advanced one pass, 4377465
|
||||
silesia, level 19, advanced one pass, 4293330
|
||||
silesia, no source size, advanced one pass, 4849552
|
||||
silesia, long distance mode, advanced one pass, 4839708
|
||||
silesia, long distance mode, advanced one pass, 4840744
|
||||
silesia, multithreaded, advanced one pass, 4849552
|
||||
silesia, multithreaded long distance mode, advanced one pass, 4839708
|
||||
silesia, multithreaded long distance mode, advanced one pass, 4840744
|
||||
silesia, small window log, advanced one pass, 7095919
|
||||
silesia, small hash log, advanced one pass, 6555021
|
||||
silesia, small chain log, advanced one pass, 4931148
|
||||
@@ -211,9 +269,9 @@ silesia.tar, level 13, advanced
|
||||
silesia.tar, level 16, advanced one pass, 4381332
|
||||
silesia.tar, level 19, advanced one pass, 4281605
|
||||
silesia.tar, no source size, advanced one pass, 4861425
|
||||
silesia.tar, long distance mode, advanced one pass, 4848098
|
||||
silesia.tar, long distance mode, advanced one pass, 4847735
|
||||
silesia.tar, multithreaded, advanced one pass, 4861508
|
||||
silesia.tar, multithreaded long distance mode, advanced one pass, 4853186
|
||||
silesia.tar, multithreaded long distance mode, advanced one pass, 4853149
|
||||
silesia.tar, small window log, advanced one pass, 7101530
|
||||
silesia.tar, small hash log, advanced one pass, 6587951
|
||||
silesia.tar, small chain log, advanced one pass, 4943307
|
||||
@@ -245,12 +303,13 @@ github, level 7 with dict, advanced
|
||||
github, level 9, advanced one pass, 135122
|
||||
github, level 9 with dict, advanced one pass, 39332
|
||||
github, level 13, advanced one pass, 134064
|
||||
github, level 13 with dict, advanced one pass, 39743
|
||||
github, level 13 with dict, advanced one pass, 39900
|
||||
github, level 16, advanced one pass, 134064
|
||||
github, level 16 with dict, advanced one pass, 37577
|
||||
github, level 19, advanced one pass, 134064
|
||||
github, level 19 with dict, advanced one pass, 37576
|
||||
github, no source size, advanced one pass, 136335
|
||||
github, no source size with dict, advanced one pass, 41148
|
||||
github, long distance mode, advanced one pass, 136335
|
||||
github, multithreaded, advanced one pass, 136335
|
||||
github, multithreaded long distance mode, advanced one pass, 136335
|
||||
@@ -262,6 +321,47 @@ github, uncompressed literals, advanced
|
||||
github, uncompressed literals optimal, advanced one pass, 157227
|
||||
github, huffman literals, advanced one pass, 142465
|
||||
github, multithreaded with advanced params, advanced one pass, 165915
|
||||
github.tar, level -5, advanced one pass, 46856
|
||||
github.tar, level -5 with dict, advanced one pass, 43971
|
||||
github.tar, level -3, advanced one pass, 43754
|
||||
github.tar, level -3 with dict, advanced one pass, 40805
|
||||
github.tar, level -1, advanced one pass, 42490
|
||||
github.tar, level -1 with dict, advanced one pass, 41122
|
||||
github.tar, level 0, advanced one pass, 38441
|
||||
github.tar, level 0 with dict, advanced one pass, 37995
|
||||
github.tar, level 1, advanced one pass, 39265
|
||||
github.tar, level 1 with dict, advanced one pass, 38309
|
||||
github.tar, level 3, advanced one pass, 38441
|
||||
github.tar, level 3 with dict, advanced one pass, 37995
|
||||
github.tar, level 4, advanced one pass, 38467
|
||||
github.tar, level 4 with dict, advanced one pass, 37948
|
||||
github.tar, level 5, advanced one pass, 39788
|
||||
github.tar, level 5 with dict, advanced one pass, 39715
|
||||
github.tar, level 6, advanced one pass, 39603
|
||||
github.tar, level 6 with dict, advanced one pass, 38800
|
||||
github.tar, level 7, advanced one pass, 39206
|
||||
github.tar, level 7 with dict, advanced one pass, 38071
|
||||
github.tar, level 9, advanced one pass, 36717
|
||||
github.tar, level 9 with dict, advanced one pass, 36898
|
||||
github.tar, level 13, advanced one pass, 35621
|
||||
github.tar, level 13 with dict, advanced one pass, 38726
|
||||
github.tar, level 16, advanced one pass, 40255
|
||||
github.tar, level 16 with dict, advanced one pass, 33639
|
||||
github.tar, level 19, advanced one pass, 32837
|
||||
github.tar, level 19 with dict, advanced one pass, 32895
|
||||
github.tar, no source size, advanced one pass, 38441
|
||||
github.tar, no source size with dict, advanced one pass, 37995
|
||||
github.tar, long distance mode, advanced one pass, 39722
|
||||
github.tar, multithreaded, advanced one pass, 38441
|
||||
github.tar, multithreaded long distance mode, advanced one pass, 39722
|
||||
github.tar, small window log, advanced one pass, 198540
|
||||
github.tar, small hash log, advanced one pass, 129870
|
||||
github.tar, small chain log, advanced one pass, 41669
|
||||
github.tar, explicit params, advanced one pass, 41199
|
||||
github.tar, uncompressed literals, advanced one pass, 41122
|
||||
github.tar, uncompressed literals optimal, advanced one pass, 35388
|
||||
github.tar, huffman literals, advanced one pass, 38777
|
||||
github.tar, multithreaded with advanced params, advanced one pass, 41122
|
||||
silesia, level -5, advanced one pass small out, 6737607
|
||||
silesia, level -3, advanced one pass small out, 6444677
|
||||
silesia, level -1, advanced one pass small out, 6178460
|
||||
@@ -277,9 +377,9 @@ silesia, level 13, advanced
|
||||
silesia, level 16, advanced one pass small out, 4377465
|
||||
silesia, level 19, advanced one pass small out, 4293330
|
||||
silesia, no source size, advanced one pass small out, 4849552
|
||||
silesia, long distance mode, advanced one pass small out, 4839708
|
||||
silesia, long distance mode, advanced one pass small out, 4840744
|
||||
silesia, multithreaded, advanced one pass small out, 4849552
|
||||
silesia, multithreaded long distance mode, advanced one pass small out, 4839708
|
||||
silesia, multithreaded long distance mode, advanced one pass small out, 4840744
|
||||
silesia, small window log, advanced one pass small out, 7095919
|
||||
silesia, small hash log, advanced one pass small out, 6555021
|
||||
silesia, small chain log, advanced one pass small out, 4931148
|
||||
@@ -303,9 +403,9 @@ silesia.tar, level 13, advanced
|
||||
silesia.tar, level 16, advanced one pass small out, 4381332
|
||||
silesia.tar, level 19, advanced one pass small out, 4281605
|
||||
silesia.tar, no source size, advanced one pass small out, 4861425
|
||||
silesia.tar, long distance mode, advanced one pass small out, 4848098
|
||||
silesia.tar, long distance mode, advanced one pass small out, 4847735
|
||||
silesia.tar, multithreaded, advanced one pass small out, 4861508
|
||||
silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853186
|
||||
silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853149
|
||||
silesia.tar, small window log, advanced one pass small out, 7101530
|
||||
silesia.tar, small hash log, advanced one pass small out, 6587951
|
||||
silesia.tar, small chain log, advanced one pass small out, 4943307
|
||||
@@ -337,12 +437,13 @@ github, level 7 with dict, advanced
|
||||
github, level 9, advanced one pass small out, 135122
|
||||
github, level 9 with dict, advanced one pass small out, 39332
|
||||
github, level 13, advanced one pass small out, 134064
|
||||
github, level 13 with dict, advanced one pass small out, 39743
|
||||
github, level 13 with dict, advanced one pass small out, 39900
|
||||
github, level 16, advanced one pass small out, 134064
|
||||
github, level 16 with dict, advanced one pass small out, 37577
|
||||
github, level 19, advanced one pass small out, 134064
|
||||
github, level 19 with dict, advanced one pass small out, 37576
|
||||
github, no source size, advanced one pass small out, 136335
|
||||
github, no source size with dict, advanced one pass small out, 41148
|
||||
github, long distance mode, advanced one pass small out, 136335
|
||||
github, multithreaded, advanced one pass small out, 136335
|
||||
github, multithreaded long distance mode, advanced one pass small out, 136335
|
||||
@@ -354,6 +455,47 @@ github, uncompressed literals, advanced
|
||||
github, uncompressed literals optimal, advanced one pass small out, 157227
|
||||
github, huffman literals, advanced one pass small out, 142465
|
||||
github, multithreaded with advanced params, advanced one pass small out, 165915
|
||||
github.tar, level -5, advanced one pass small out, 46856
|
||||
github.tar, level -5 with dict, advanced one pass small out, 43971
|
||||
github.tar, level -3, advanced one pass small out, 43754
|
||||
github.tar, level -3 with dict, advanced one pass small out, 40805
|
||||
github.tar, level -1, advanced one pass small out, 42490
|
||||
github.tar, level -1 with dict, advanced one pass small out, 41122
|
||||
github.tar, level 0, advanced one pass small out, 38441
|
||||
github.tar, level 0 with dict, advanced one pass small out, 37995
|
||||
github.tar, level 1, advanced one pass small out, 39265
|
||||
github.tar, level 1 with dict, advanced one pass small out, 38309
|
||||
github.tar, level 3, advanced one pass small out, 38441
|
||||
github.tar, level 3 with dict, advanced one pass small out, 37995
|
||||
github.tar, level 4, advanced one pass small out, 38467
|
||||
github.tar, level 4 with dict, advanced one pass small out, 37948
|
||||
github.tar, level 5, advanced one pass small out, 39788
|
||||
github.tar, level 5 with dict, advanced one pass small out, 39715
|
||||
github.tar, level 6, advanced one pass small out, 39603
|
||||
github.tar, level 6 with dict, advanced one pass small out, 38800
|
||||
github.tar, level 7, advanced one pass small out, 39206
|
||||
github.tar, level 7 with dict, advanced one pass small out, 38071
|
||||
github.tar, level 9, advanced one pass small out, 36717
|
||||
github.tar, level 9 with dict, advanced one pass small out, 36898
|
||||
github.tar, level 13, advanced one pass small out, 35621
|
||||
github.tar, level 13 with dict, advanced one pass small out, 38726
|
||||
github.tar, level 16, advanced one pass small out, 40255
|
||||
github.tar, level 16 with dict, advanced one pass small out, 33639
|
||||
github.tar, level 19, advanced one pass small out, 32837
|
||||
github.tar, level 19 with dict, advanced one pass small out, 32895
|
||||
github.tar, no source size, advanced one pass small out, 38441
|
||||
github.tar, no source size with dict, advanced one pass small out, 37995
|
||||
github.tar, long distance mode, advanced one pass small out, 39722
|
||||
github.tar, multithreaded, advanced one pass small out, 38441
|
||||
github.tar, multithreaded long distance mode, advanced one pass small out, 39722
|
||||
github.tar, small window log, advanced one pass small out, 198540
|
||||
github.tar, small hash log, advanced one pass small out, 129870
|
||||
github.tar, small chain log, advanced one pass small out, 41669
|
||||
github.tar, explicit params, advanced one pass small out, 41199
|
||||
github.tar, uncompressed literals, advanced one pass small out, 41122
|
||||
github.tar, uncompressed literals optimal, advanced one pass small out, 35388
|
||||
github.tar, huffman literals, advanced one pass small out, 38777
|
||||
github.tar, multithreaded with advanced params, advanced one pass small out, 41122
|
||||
silesia, level -5, advanced streaming, 6882505
|
||||
silesia, level -3, advanced streaming, 6568376
|
||||
silesia, level -1, advanced streaming, 6183403
|
||||
@@ -369,9 +511,9 @@ silesia, level 13, advanced
|
||||
silesia, level 16, advanced streaming, 4377465
|
||||
silesia, level 19, advanced streaming, 4293330
|
||||
silesia, no source size, advanced streaming, 4849516
|
||||
silesia, long distance mode, advanced streaming, 4839708
|
||||
silesia, long distance mode, advanced streaming, 4840744
|
||||
silesia, multithreaded, advanced streaming, 4849552
|
||||
silesia, multithreaded long distance mode, advanced streaming, 4839708
|
||||
silesia, multithreaded long distance mode, advanced streaming, 4840744
|
||||
silesia, small window log, advanced streaming, 7112062
|
||||
silesia, small hash log, advanced streaming, 6555021
|
||||
silesia, small chain log, advanced streaming, 4931148
|
||||
@@ -395,9 +537,9 @@ silesia.tar, level 13, advanced
|
||||
silesia.tar, level 16, advanced streaming, 4381350
|
||||
silesia.tar, level 19, advanced streaming, 4281562
|
||||
silesia.tar, no source size, advanced streaming, 4861423
|
||||
silesia.tar, long distance mode, advanced streaming, 4848098
|
||||
silesia.tar, long distance mode, advanced streaming, 4847735
|
||||
silesia.tar, multithreaded, advanced streaming, 4861508
|
||||
silesia.tar, multithreaded long distance mode, advanced streaming, 4853186
|
||||
silesia.tar, multithreaded long distance mode, advanced streaming, 4853149
|
||||
silesia.tar, small window log, advanced streaming, 7118769
|
||||
silesia.tar, small hash log, advanced streaming, 6587952
|
||||
silesia.tar, small chain log, advanced streaming, 4943312
|
||||
@@ -429,12 +571,13 @@ github, level 7 with dict, advanced
|
||||
github, level 9, advanced streaming, 135122
|
||||
github, level 9 with dict, advanced streaming, 39332
|
||||
github, level 13, advanced streaming, 134064
|
||||
github, level 13 with dict, advanced streaming, 39743
|
||||
github, level 13 with dict, advanced streaming, 39900
|
||||
github, level 16, advanced streaming, 134064
|
||||
github, level 16 with dict, advanced streaming, 37577
|
||||
github, level 19, advanced streaming, 134064
|
||||
github, level 19 with dict, advanced streaming, 37576
|
||||
github, no source size, advanced streaming, 136335
|
||||
github, no source size with dict, advanced streaming, 41148
|
||||
github, long distance mode, advanced streaming, 136335
|
||||
github, multithreaded, advanced streaming, 136335
|
||||
github, multithreaded long distance mode, advanced streaming, 136335
|
||||
@@ -446,6 +589,47 @@ github, uncompressed literals, advanced
|
||||
github, uncompressed literals optimal, advanced streaming, 157227
|
||||
github, huffman literals, advanced streaming, 142465
|
||||
github, multithreaded with advanced params, advanced streaming, 165915
|
||||
github.tar, level -5, advanced streaming, 46747
|
||||
github.tar, level -5 with dict, advanced streaming, 43971
|
||||
github.tar, level -3, advanced streaming, 43537
|
||||
github.tar, level -3 with dict, advanced streaming, 40805
|
||||
github.tar, level -1, advanced streaming, 42465
|
||||
github.tar, level -1 with dict, advanced streaming, 41122
|
||||
github.tar, level 0, advanced streaming, 38441
|
||||
github.tar, level 0 with dict, advanced streaming, 37995
|
||||
github.tar, level 1, advanced streaming, 39342
|
||||
github.tar, level 1 with dict, advanced streaming, 38309
|
||||
github.tar, level 3, advanced streaming, 38441
|
||||
github.tar, level 3 with dict, advanced streaming, 37995
|
||||
github.tar, level 4, advanced streaming, 38467
|
||||
github.tar, level 4 with dict, advanced streaming, 37948
|
||||
github.tar, level 5, advanced streaming, 39788
|
||||
github.tar, level 5 with dict, advanced streaming, 39715
|
||||
github.tar, level 6, advanced streaming, 39603
|
||||
github.tar, level 6 with dict, advanced streaming, 38800
|
||||
github.tar, level 7, advanced streaming, 39206
|
||||
github.tar, level 7 with dict, advanced streaming, 38071
|
||||
github.tar, level 9, advanced streaming, 36717
|
||||
github.tar, level 9 with dict, advanced streaming, 36898
|
||||
github.tar, level 13, advanced streaming, 35621
|
||||
github.tar, level 13 with dict, advanced streaming, 38726
|
||||
github.tar, level 16, advanced streaming, 40255
|
||||
github.tar, level 16 with dict, advanced streaming, 33639
|
||||
github.tar, level 19, advanced streaming, 32837
|
||||
github.tar, level 19 with dict, advanced streaming, 32895
|
||||
github.tar, no source size, advanced streaming, 38438
|
||||
github.tar, no source size with dict, advanced streaming, 38000
|
||||
github.tar, long distance mode, advanced streaming, 39722
|
||||
github.tar, multithreaded, advanced streaming, 38441
|
||||
github.tar, multithreaded long distance mode, advanced streaming, 39722
|
||||
github.tar, small window log, advanced streaming, 199558
|
||||
github.tar, small hash log, advanced streaming, 129870
|
||||
github.tar, small chain log, advanced streaming, 41669
|
||||
github.tar, explicit params, advanced streaming, 41199
|
||||
github.tar, uncompressed literals, advanced streaming, 41122
|
||||
github.tar, uncompressed literals optimal, advanced streaming, 35388
|
||||
github.tar, huffman literals, advanced streaming, 38800
|
||||
github.tar, multithreaded with advanced params, advanced streaming, 41122
|
||||
silesia, level -5, old streaming, 6882505
|
||||
silesia, level -3, old streaming, 6568376
|
||||
silesia, level -1, old streaming, 6183403
|
||||
@@ -505,15 +689,49 @@ github, level 7 with dict, old stre
|
||||
github, level 9, old streaming, 135122
|
||||
github, level 9 with dict, old streaming, 39332
|
||||
github, level 13, old streaming, 134064
|
||||
github, level 13 with dict, old streaming, 39743
|
||||
github, level 13 with dict, old streaming, 39900
|
||||
github, level 16, old streaming, 134064
|
||||
github, level 16 with dict, old streaming, 37577
|
||||
github, level 19, old streaming, 134064
|
||||
github, level 19 with dict, old streaming, 37576
|
||||
github, no source size, old streaming, 140632
|
||||
github, no source size with dict, old streaming, 40654
|
||||
github, uncompressed literals, old streaming, 136335
|
||||
github, uncompressed literals optimal, old streaming, 134064
|
||||
github, huffman literals, old streaming, 175568
|
||||
github.tar, level -5, old streaming, 46747
|
||||
github.tar, level -5 with dict, old streaming, 43971
|
||||
github.tar, level -3, old streaming, 43537
|
||||
github.tar, level -3 with dict, old streaming, 40805
|
||||
github.tar, level -1, old streaming, 42465
|
||||
github.tar, level -1 with dict, old streaming, 41122
|
||||
github.tar, level 0, old streaming, 38441
|
||||
github.tar, level 0 with dict, old streaming, 37995
|
||||
github.tar, level 1, old streaming, 39342
|
||||
github.tar, level 1 with dict, old streaming, 38309
|
||||
github.tar, level 3, old streaming, 38441
|
||||
github.tar, level 3 with dict, old streaming, 37995
|
||||
github.tar, level 4, old streaming, 38467
|
||||
github.tar, level 4 with dict, old streaming, 37948
|
||||
github.tar, level 5, old streaming, 39788
|
||||
github.tar, level 5 with dict, old streaming, 39715
|
||||
github.tar, level 6, old streaming, 39603
|
||||
github.tar, level 6 with dict, old streaming, 38800
|
||||
github.tar, level 7, old streaming, 39206
|
||||
github.tar, level 7 with dict, old streaming, 38071
|
||||
github.tar, level 9, old streaming, 36717
|
||||
github.tar, level 9 with dict, old streaming, 36898
|
||||
github.tar, level 13, old streaming, 35621
|
||||
github.tar, level 13 with dict, old streaming, 38726
|
||||
github.tar, level 16, old streaming, 40255
|
||||
github.tar, level 16 with dict, old streaming, 33639
|
||||
github.tar, level 19, old streaming, 32837
|
||||
github.tar, level 19 with dict, old streaming, 32895
|
||||
github.tar, no source size, old streaming, 38438
|
||||
github.tar, no source size with dict, old streaming, 38000
|
||||
github.tar, uncompressed literals, old streaming, 38441
|
||||
github.tar, uncompressed literals optimal, old streaming, 32837
|
||||
github.tar, huffman literals, old streaming, 42465
|
||||
silesia, level -5, old streaming advanced, 6882505
|
||||
silesia, level -3, old streaming advanced, 6568376
|
||||
silesia, level -1, old streaming advanced, 6183403
|
||||
@@ -595,6 +813,7 @@ github, level 16 with dict, old stre
|
||||
github, level 19, old streaming advanced, 134064
|
||||
github, level 19 with dict, old streaming advanced, 37576
|
||||
github, no source size, old streaming advanced, 140632
|
||||
github, no source size with dict, old streaming advanced, 40608
|
||||
github, long distance mode, old streaming advanced, 141104
|
||||
github, multithreaded, old streaming advanced, 141104
|
||||
github, multithreaded long distance mode, old streaming advanced, 141104
|
||||
@@ -606,6 +825,47 @@ github, uncompressed literals, old stre
|
||||
github, uncompressed literals optimal, old streaming advanced, 134064
|
||||
github, huffman literals, old streaming advanced, 181108
|
||||
github, multithreaded with advanced params, old streaming advanced, 141104
|
||||
github.tar, level -5, old streaming advanced, 46747
|
||||
github.tar, level -5 with dict, old streaming advanced, 44824
|
||||
github.tar, level -3, old streaming advanced, 43537
|
||||
github.tar, level -3 with dict, old streaming advanced, 41800
|
||||
github.tar, level -1, old streaming advanced, 42465
|
||||
github.tar, level -1 with dict, old streaming advanced, 41471
|
||||
github.tar, level 0, old streaming advanced, 38441
|
||||
github.tar, level 0 with dict, old streaming advanced, 38013
|
||||
github.tar, level 1, old streaming advanced, 39342
|
||||
github.tar, level 1 with dict, old streaming advanced, 38940
|
||||
github.tar, level 3, old streaming advanced, 38441
|
||||
github.tar, level 3 with dict, old streaming advanced, 38013
|
||||
github.tar, level 4, old streaming advanced, 38467
|
||||
github.tar, level 4 with dict, old streaming advanced, 38063
|
||||
github.tar, level 5, old streaming advanced, 39788
|
||||
github.tar, level 5 with dict, old streaming advanced, 39310
|
||||
github.tar, level 6, old streaming advanced, 39603
|
||||
github.tar, level 6 with dict, old streaming advanced, 39279
|
||||
github.tar, level 7, old streaming advanced, 39206
|
||||
github.tar, level 7 with dict, old streaming advanced, 38728
|
||||
github.tar, level 9, old streaming advanced, 36717
|
||||
github.tar, level 9 with dict, old streaming advanced, 36504
|
||||
github.tar, level 13, old streaming advanced, 35621
|
||||
github.tar, level 13 with dict, old streaming advanced, 36035
|
||||
github.tar, level 16, old streaming advanced, 40255
|
||||
github.tar, level 16 with dict, old streaming advanced, 38736
|
||||
github.tar, level 19, old streaming advanced, 32837
|
||||
github.tar, level 19 with dict, old streaming advanced, 32876
|
||||
github.tar, no source size, old streaming advanced, 38438
|
||||
github.tar, no source size with dict, old streaming advanced, 38015
|
||||
github.tar, long distance mode, old streaming advanced, 38441
|
||||
github.tar, multithreaded, old streaming advanced, 38441
|
||||
github.tar, multithreaded long distance mode, old streaming advanced, 38441
|
||||
github.tar, small window log, old streaming advanced, 199561
|
||||
github.tar, small hash log, old streaming advanced, 129870
|
||||
github.tar, small chain log, old streaming advanced, 41669
|
||||
github.tar, explicit params, old streaming advanced, 41199
|
||||
github.tar, uncompressed literals, old streaming advanced, 38441
|
||||
github.tar, uncompressed literals optimal, old streaming advanced, 32837
|
||||
github.tar, huffman literals, old streaming advanced, 42465
|
||||
github.tar, multithreaded with advanced params, old streaming advanced, 38441
|
||||
github, level -5 with dict, old streaming cdcit, 46718
|
||||
github, level -3 with dict, old streaming cdcit, 45395
|
||||
github, level -1 with dict, old streaming cdcit, 43170
|
||||
@@ -617,9 +877,25 @@ github, level 5 with dict, old stre
|
||||
github, level 6 with dict, old streaming cdcit, 38632
|
||||
github, level 7 with dict, old streaming cdcit, 38771
|
||||
github, level 9 with dict, old streaming cdcit, 39332
|
||||
github, level 13 with dict, old streaming cdcit, 39743
|
||||
github, level 13 with dict, old streaming cdcit, 39900
|
||||
github, level 16 with dict, old streaming cdcit, 37577
|
||||
github, level 19 with dict, old streaming cdcit, 37576
|
||||
github, no source size with dict, old streaming cdcit, 40654
|
||||
github.tar, level -5 with dict, old streaming cdcit, 45018
|
||||
github.tar, level -3 with dict, old streaming cdcit, 41886
|
||||
github.tar, level -1 with dict, old streaming cdcit, 41636
|
||||
github.tar, level 0 with dict, old streaming cdcit, 37956
|
||||
github.tar, level 1 with dict, old streaming cdcit, 38766
|
||||
github.tar, level 3 with dict, old streaming cdcit, 37956
|
||||
github.tar, level 4 with dict, old streaming cdcit, 37927
|
||||
github.tar, level 5 with dict, old streaming cdcit, 39209
|
||||
github.tar, level 6 with dict, old streaming cdcit, 38983
|
||||
github.tar, level 7 with dict, old streaming cdcit, 38584
|
||||
github.tar, level 9 with dict, old streaming cdcit, 36363
|
||||
github.tar, level 13 with dict, old streaming cdcit, 36372
|
||||
github.tar, level 16 with dict, old streaming cdcit, 39353
|
||||
github.tar, level 19 with dict, old streaming cdcit, 32676
|
||||
github.tar, no source size with dict, old streaming cdcit, 38000
|
||||
github, level -5 with dict, old streaming advanced cdict, 49562
|
||||
github, level -3 with dict, old streaming advanced cdict, 44956
|
||||
github, level -1 with dict, old streaming advanced cdict, 42383
|
||||
@@ -634,3 +910,19 @@ github, level 9 with dict, old stre
|
||||
github, level 13 with dict, old streaming advanced cdict, 39731
|
||||
github, level 16 with dict, old streaming advanced cdict, 40789
|
||||
github, level 19 with dict, old streaming advanced cdict, 37576
|
||||
github, no source size with dict, old streaming advanced cdict, 40608
|
||||
github.tar, level -5 with dict, old streaming advanced cdict, 44307
|
||||
github.tar, level -3 with dict, old streaming advanced cdict, 41359
|
||||
github.tar, level -1 with dict, old streaming advanced cdict, 41322
|
||||
github.tar, level 0 with dict, old streaming advanced cdict, 38013
|
||||
github.tar, level 1 with dict, old streaming advanced cdict, 39002
|
||||
github.tar, level 3 with dict, old streaming advanced cdict, 38013
|
||||
github.tar, level 4 with dict, old streaming advanced cdict, 38063
|
||||
github.tar, level 5 with dict, old streaming advanced cdict, 39310
|
||||
github.tar, level 6 with dict, old streaming advanced cdict, 39279
|
||||
github.tar, level 7 with dict, old streaming advanced cdict, 38728
|
||||
github.tar, level 9 with dict, old streaming advanced cdict, 36504
|
||||
github.tar, level 13 with dict, old streaming advanced cdict, 36035
|
||||
github.tar, level 16 with dict, old streaming advanced cdict, 38736
|
||||
github.tar, level 19 with dict, old streaming advanced cdict, 32876
|
||||
github.tar, no source size with dict, old streaming advanced cdict, 38015
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, Facebook, Inc.
|
||||
* Copyright (c) Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+44
-30
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Facebook, Inc.
|
||||
# Copyright (c) Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -10,16 +10,12 @@
|
||||
# You may select, at your option, one of the above-listed licenses.
|
||||
# ################################################################
|
||||
|
||||
import datetime
|
||||
import enum
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
YEAR = datetime.datetime.now().year
|
||||
|
||||
YEAR_STR = str(YEAR)
|
||||
|
||||
ROOT = os.path.join(os.path.dirname(__file__), "..")
|
||||
|
||||
RELDIRS = [
|
||||
@@ -28,22 +24,26 @@ RELDIRS = [
|
||||
"lib",
|
||||
"programs",
|
||||
"tests",
|
||||
"contrib/linux-kernel",
|
||||
]
|
||||
|
||||
DIRS = [os.path.join(ROOT, d) for d in RELDIRS]
|
||||
REL_EXCLUDES = [
|
||||
"contrib/linux-kernel/test/include",
|
||||
]
|
||||
|
||||
class File(enum.Enum):
|
||||
C = 1
|
||||
H = 2
|
||||
MAKE = 3
|
||||
PY = 4
|
||||
def to_abs(d):
|
||||
return os.path.normpath(os.path.join(ROOT, d)) + "/"
|
||||
|
||||
SUFFIX = {
|
||||
File.C: ".c",
|
||||
File.H: ".h",
|
||||
File.MAKE: "Makefile",
|
||||
File.PY: ".py",
|
||||
}
|
||||
DIRS = [to_abs(d) for d in RELDIRS]
|
||||
EXCLUDES = [to_abs(d) for d in REL_EXCLUDES]
|
||||
|
||||
SUFFIXES = [
|
||||
".c",
|
||||
".h",
|
||||
"Makefile",
|
||||
".mk",
|
||||
".py",
|
||||
]
|
||||
|
||||
# License should certainly be in the first 10 KB.
|
||||
MAX_BYTES = 10000
|
||||
@@ -69,10 +69,13 @@ LICENSE_EXCEPTIONS = {
|
||||
# From divsufsort
|
||||
"divsufsort.c",
|
||||
"divsufsort.h",
|
||||
# License is slightly different because it references GitHub
|
||||
"linux_zstd.h",
|
||||
}
|
||||
|
||||
|
||||
def valid_copyright(lines):
|
||||
YEAR_REGEX = re.compile("\d\d\d\d|present")
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if "Copyright" not in line:
|
||||
@@ -81,8 +84,9 @@ def valid_copyright(lines):
|
||||
return (False, f"Copyright line '{line}' contains 'present'!")
|
||||
if "Facebook, Inc" not in line:
|
||||
return (False, f"Copyright line '{line}' does not contain 'Facebook, Inc'")
|
||||
if YEAR_STR not in line:
|
||||
return (False, f"Copyright line '{line}' does not contain {YEAR}")
|
||||
year = YEAR_REGEX.search(line)
|
||||
if year is not None:
|
||||
return (False, f"Copyright line '{line}' contains {year.group(0)}; it should be yearless")
|
||||
if " (c) " not in line:
|
||||
return (False, f"Copyright line '{line}' does not contain ' (c) '!")
|
||||
return (True, "")
|
||||
@@ -107,35 +111,45 @@ def valid_file(filename):
|
||||
with open(filename, "r") as f:
|
||||
lines = f.readlines(MAX_BYTES)
|
||||
lines = lines[:min(len(lines), MAX_LINES)]
|
||||
|
||||
|
||||
ok = True
|
||||
if os.path.basename(filename) not in COPYRIGHT_EXCEPTIONS:
|
||||
c_ok, c_msg = valid_copyright(lines)
|
||||
if not c_ok:
|
||||
print(f"{filename}: {c_msg}")
|
||||
print(f"{filename}: {c_msg}", file=sys.stderr)
|
||||
ok = False
|
||||
if os.path.basename(filename) not in LICENSE_EXCEPTIONS:
|
||||
l_ok, l_msg = valid_license(lines)
|
||||
if not l_ok:
|
||||
print(f"{filename}: {l_msg}")
|
||||
print(f"{filename}: {l_msg}", file=sys.stderr)
|
||||
ok = False
|
||||
return ok
|
||||
|
||||
|
||||
def exclude(filename):
|
||||
for x in EXCLUDES:
|
||||
if filename.startswith(x):
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
invalid_files = []
|
||||
for directory in DIRS:
|
||||
for suffix in SUFFIX.values():
|
||||
files = set(glob.glob(f"{directory}/*{suffix}"))
|
||||
files |= set(glob.glob(f"{directory}/**/*{suffix}"))
|
||||
for suffix in SUFFIXES:
|
||||
files = set(glob.glob(f"{directory}/**/*{suffix}", recursive=True))
|
||||
for filename in files:
|
||||
if exclude(filename):
|
||||
continue
|
||||
if not valid_file(filename):
|
||||
invalid_files.append(filename)
|
||||
if len(invalid_files) > 0:
|
||||
print(f"Invalid files: {invalid_files}")
|
||||
print("Fail!", file=sys.stderr)
|
||||
for f in invalid_files:
|
||||
print(f)
|
||||
return 1
|
||||
else:
|
||||
print("Pass!")
|
||||
return len(invalid_files)
|
||||
print("Pass!", file=sys.stderr)
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""Test zstd interoperability between versions"""
|
||||
|
||||
# ################################################################
|
||||
# Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
# Copyright (c) Yann Collet, Facebook, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
+22
-22
@@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
# Paths to static and dynamic zlib and zstd libraries
|
||||
# Use "make ZLIB_PATH=path/to/zlib ZLIB_LIBRARY=path/to/libz.a" to select a path to library
|
||||
# Use "make ZLIB_PATH=path/to/zlib ZLIB_LIBRARY=path/to/libz.so" to select a path to library
|
||||
ZLIB_LIBRARY ?= -lz
|
||||
ZLIB_PATH ?= .
|
||||
|
||||
@@ -18,7 +18,8 @@ EXAMPLE_PATH = examples
|
||||
PROGRAMS_PATH = ../programs
|
||||
TEST_FILE = ../doc/zstd_compression_format.md
|
||||
|
||||
VPATH = $(PROGRAMS_PATH)
|
||||
vpath %.c $(PROGRAMS_PATH) $(EXAMPLE_PATH) $(ZLIBWRAPPER_PATH)
|
||||
|
||||
|
||||
CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) \
|
||||
-I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH)
|
||||
@@ -28,7 +29,9 @@ DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum \
|
||||
-Wdeclaration-after-statement -Wstrict-prototypes -Wundef \
|
||||
-Wstrict-aliasing=1
|
||||
CFLAGS ?= -O3
|
||||
CFLAGS += $(STDFLAGS) $(DEBUGFLAGS) $(MOREFLAGS)
|
||||
CFLAGS += $(STDFLAGS) $(DEBUGFLAGS)
|
||||
CPPFLAGS += $(MOREFLAGS)
|
||||
LDLIBS += $(ZLIB_LIBRARY)
|
||||
|
||||
# Define *.exe as extension for Windows systems
|
||||
ifneq (,$(filter Windows%,$(OS)))
|
||||
@@ -61,7 +64,7 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip minigzip_zstd
|
||||
./minigzip_zstd -d example$(EXT).gz
|
||||
@echo ---- minigzip end ----
|
||||
./zwrapbench -qi1b3B1K $(TEST_FILE)
|
||||
./zwrapbench -rqi1b1e5 ../lib ../programs ../tests
|
||||
./zwrapbench -rqi1b1e3 ../lib
|
||||
|
||||
#valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so
|
||||
valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1
|
||||
@@ -79,35 +82,32 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench
|
||||
#.c.o:
|
||||
# $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
minigzip: $(EXAMPLE_PATH)/minigzip.o zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -o $@
|
||||
minigzip: minigzip.o zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
|
||||
minigzip_zstd: $(EXAMPLE_PATH)/minigzip.o zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZSTDLIBRARY) $(ZLIB_LIBRARY) -o $@
|
||||
minigzip_zstd: minigzip.o zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
$(LINK.o) $^ $(LDLIBS) $(OUTPUT_OPTION)
|
||||
|
||||
example: $(EXAMPLE_PATH)/example.o zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@
|
||||
example: example.o zstd_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
|
||||
example_zstd: $(EXAMPLE_PATH)/example.o zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@
|
||||
example_zstd: example.o zstdTurnedOn_zlibwrapper.o $(GZFILES) $(ZSTDLIBRARY)
|
||||
$(LINK.o) $^ $(LDLIBS) $(OUTPUT_OPTION)
|
||||
|
||||
fitblk: $(EXAMPLE_PATH)/fitblk.o zstd_zlibwrapper.o $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@
|
||||
fitblk: fitblk.o zstd_zlibwrapper.o $(ZSTDLIBRARY)
|
||||
|
||||
fitblk_zstd: $(EXAMPLE_PATH)/fitblk.o zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@
|
||||
fitblk_zstd: fitblk.o zstdTurnedOn_zlibwrapper.o $(ZSTDLIBRARY)
|
||||
$(LINK.o) $^ $(LDLIBS) $(OUTPUT_OPTION)
|
||||
|
||||
zwrapbench: $(EXAMPLE_PATH)/zwrapbench.o zstd_zlibwrapper.o util.o timefn.o datagen.o $(ZSTDLIBRARY)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $^ $(ZLIB_LIBRARY) -o $@
|
||||
zwrapbench: zwrapbench.o zstd_zlibwrapper.o util.o timefn.o datagen.o $(ZSTDLIBRARY)
|
||||
|
||||
|
||||
zstd_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
||||
zstd_zlibwrapper.o: zstd_zlibwrapper.h
|
||||
|
||||
zstdTurnedOn_zlibwrapper.o: CPPFLAGS += -DZWRAP_USE_ZSTD=1
|
||||
zstdTurnedOn_zlibwrapper.o: $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.c $(ZLIBWRAPPER_PATH)/zstd_zlibwrapper.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $< -c -o $@
|
||||
zstdTurnedOn_zlibwrapper.o: zstd_zlibwrapper.c zstd_zlibwrapper.h
|
||||
$(COMPILE.c) $< $(OUTPUT_OPTION)
|
||||
|
||||
$(ZSTDLIBDIR)/libzstd.a:
|
||||
|
||||
$(ZSTDLIBRARY):
|
||||
$(MAKE) -C $(ZSTDLIBDIR) libzstd.a
|
||||
|
||||
$(ZSTDLIBDIR)/libzstd.so:
|
||||
|
||||
@@ -270,8 +270,10 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
|
||||
do {
|
||||
U32 blockNb;
|
||||
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||
rSize = ZSTD_resetCStream(zbc, blockTable[blockNb].srcSize);
|
||||
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_resetCStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||
rSize = ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only);
|
||||
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_CCtx_reset() failed : %s", ZSTD_getErrorName(rSize));
|
||||
rSize = ZSTD_CCtx_setPledgedSrcSize(zbc, blockTable[blockNb].srcSize);
|
||||
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_CCtx_setPledgedSrcSize() failed : %s", ZSTD_getErrorName(rSize));
|
||||
inBuffer.src = blockTable[blockNb].srcPtr;
|
||||
inBuffer.size = blockTable[blockNb].srcSize;
|
||||
inBuffer.pos = 0;
|
||||
@@ -418,8 +420,8 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
|
||||
do {
|
||||
U32 blockNb;
|
||||
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||
rSize = ZSTD_resetDStream(zbd);
|
||||
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_resetDStream() failed : %s", ZSTD_getErrorName(rSize));
|
||||
rSize = ZSTD_DCtx_reset(zbd, ZSTD_reset_session_only);
|
||||
if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_DCtx_reset() failed : %s", ZSTD_getErrorName(rSize));
|
||||
inBuffer.src = blockTable[blockNb].cPtr;
|
||||
inBuffer.size = blockTable[blockNb].cSize;
|
||||
inBuffer.pos = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
@@ -372,9 +372,15 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
|
||||
} else {
|
||||
if (zwc->totalInBytes == 0) {
|
||||
if (zwc->comprState == ZWRAP_useReset) {
|
||||
size_t const resetErr = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize);
|
||||
size_t resetErr = ZSTD_CCtx_reset(zwc->zbc, ZSTD_reset_session_only);
|
||||
if (ZSTD_isError(resetErr)) {
|
||||
LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n",
|
||||
LOG_WRAPPERC("ERROR: ZSTD_CCtx_reset errorCode=%s\n",
|
||||
ZSTD_getErrorName(resetErr));
|
||||
return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||
}
|
||||
resetErr = ZSTD_CCtx_setPledgedSrcSize(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize);
|
||||
if (ZSTD_isError(resetErr)) {
|
||||
LOG_WRAPPERC("ERROR: ZSTD_CCtx_setPledgedSrcSize errorCode=%s\n",
|
||||
ZSTD_getErrorName(resetErr));
|
||||
return ZWRAPC_finishWithError(zwc, strm, 0);
|
||||
}
|
||||
@@ -829,7 +835,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
size_t const resetErr = ZSTD_resetDStream(zwd->zbd);
|
||||
size_t const resetErr = ZSTD_DCtx_reset(zwd->zbd, ZSTD_reset_session_only);
|
||||
if (ZSTD_isError(resetErr)) goto error;
|
||||
}
|
||||
} else {
|
||||
@@ -849,7 +855,7 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
size_t const resetErr = ZSTD_resetDStream(zwd->zbd);
|
||||
size_t const resetErr = ZSTD_DCtx_reset(zwd->zbd, ZSTD_reset_session_only);
|
||||
if (ZSTD_isError(resetErr)) goto error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* Copyright (c) 2016-2021, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
|
||||
Reference in New Issue
Block a user