Compare commits

..
17 Commits
Author SHA1 Message Date
Nick Terrell b53da1f6f4 Add extra space to match linux kernel 2022-02-22 19:58:18 -08:00
Nick Terrell 693aa7bad2 Add comment to unused variable suppression 2021-11-17 13:46:09 -08:00
Nick Terrell 1eba76a2d1 [linux-kernel] Don't add -O3 to CFLAGS
It is no longer necessary to get good performance, there is only a small
speed difference between -O2 and -O3, so just stick to the default of
-O2.

This also fixes the stack space usage on parisc. The compiler was buggy
for -O3 and used ~3KB of stack space for several functions. With -O2 the
problem is completely resolved, and stack space is back to a few hundred
bytes.

Additionally, we get a large code size win on gcc:

| Compiler | Before (Bytes) | After (Bytes) | Delta (Bytes) |
|----------|----------------|---------------|---------------|
| gcc-11   |         952754 |        738954 |       -213800 |
| clang-12 |         976290 |        938826 |        -37464 |
2021-11-16 14:29:35 -08:00
Nick Terrell b9302410bf [linux-kernel] Don't inline function in zstd_opt.c
The optimal parser is unlikely to be used in the linux kernel in
practice. There is no reason these functions should be force inlined,
since we aren't gaining anything, and are losing build size.

| Compiler | Before (Bytes) | After (Bytes) | Delta (Bytes) |
|----------|----------------|---------------|---------------|
| gcc-11   |        1142090 |        952754 |       -189336 |
| clang-12 |        1228402 |        976290 |       -252112 |

This is a temporary solution pending the resolution of Issue #2862 in
the `dev` branch.
2021-11-15 20:37:58 -08:00
Nick Terrell 0118fe65ff Fix unused variable warning
`litLengthSum` is unused when asserts are disabled. Already fixed in `dev` by
PR#2838. Found by the Kernel test robot [0].

[0] https://lore.kernel.org/linux-mm/202111120312.833wII4i-lkp@intel.com/T/

Reported-by: kernel test robot <lkp@intel.com>
2021-11-15 16:55:59 -08:00
Nick Terrell 608bacf6cb Backport zstd patch from LKML
Credit to Nathan Chancellor for the bug fix and Nick Desaulniers for the
bug report.

Link: ClangBuiltLinux/linux#1486
Link: https://lore.kernel.org/all/20211021202353.2356400-1-nathan@kernel.org/
2021-11-11 12:18:35 -08:00
Nick Terrell c0c38ba1db [binary-tree] Fix underflow of nbCompares
Fix underflow of `nbCompares` by switching to an `int` and comparing
`nbCompares > 0`. This is a minimal fix, because I don't want to change
the logic. These loops seem to be doing `nbCompares + 1` comparisons.

The bug was reported by Dan Carpenter and found by Smatch static
checker.

https://lore.kernel.org/all/20211008063704.GA5370@kili/
2021-10-11 15:57:35 -07:00
Nick Terrell 5a3e16f0c2 [ldm] Fix ZSTD_c_ldmHashRateLog bounds check
There is no minimum value check, so the parameter could be negative.
Switch to the standard pattern of using `BOUNDCHECK()`.

The bug was reported by Dan Carpenter and found by Smatch static
checker.

https://lore.kernel.org/all/20211008063704.GA5370@kili/
2021-10-11 15:43:57 -07:00
Nick Terrell 2c94f9fc61 [nit] Fix buggy indentation
The bug was reported by Dan Carpenter and found by Smatch static
checker.

https://lore.kernel.org/all/20211008063704.GA5370@kili/
2021-10-11 15:43:33 -07:00
Nick Terrell 695181c2e0 [multiple-ddicts] Fix NULL checks
The bug was reported by Dan Carpenter and found by Smatch static
checker.

https://lore.kernel.org/all/20211008063704.GA5370@kili/
2021-10-11 15:42:45 -07:00
Nick Terrell 20821a46f4 [lib] Make lib compatible with -Wfall-through excepting legacy
Switch to a macro `ZSTD_FALLTHROUGH;` instead of a comment. On supported
compilers this uses an attribute, otherwise it becomes a comment.

This is necessary to be compatible with clang's `-Wfall-through`, and
gcc's `-Wfall-through=2` which don't support comments. Without this the
linux build emits a bunch of warnings.
2021-09-23 11:54:14 -07:00
Nick Terrell 1715601e55 [contrib][linux] Reduce stack usage by 80 bytes
Instead of calling `ZSTD_compress_advanced()` and
`ZSTD_initCStream_advanced()`, which each take a `ZSTD_parameters` by
value, use the new advanced API.

Stack usage went from 2024 -> 1944.
2021-09-22 18:18:20 -07:00
Nick Terrell 07d7ebe448 [contrib][linux] Fix up SPDX license identifiers
Correctly identify that we are GPL v2+ or BSD 3 clause, as pointed out
in issue #2663.
2021-09-22 15:06:08 -07:00
Nick Terrell 67a426c322 [linux-kernel] Replace kernel-style comments
Replace kernel-style comments with regular comments.

E.g.

```
/** Before */

/* After */

/**
 * Before
 */

/*
 * After
 */

/***********************************
 * Before
 ***********************************/

/* *********************************
 * After
 ***********************************/
```
2021-04-29 15:53:38 -07:00
Nick Terrell 4432dac93b [contrib][linux-kernel] Add zstd_min_clevel() and zstd_max_clevel() 2021-03-30 10:37:45 -07:00
Nick Terrell de9de869a3 [copyright][license] Switch to yearless copyright and some cleanup in the linux-kernel files
* Switch to yearless copyright per FB policy
* Fix up SPDX-License-Identifier lines in `contrib/linux-kernel` sources
* Add zstd copyright/license header to the `contrib/linux-kernel` sources
* Update the `tests/test-license.py` to check for yearless copyright
* Improvements to `tests/test-license.py`
* Check `contrib/linux-kernel` in `tests/test-license.py`
2021-03-30 10:37:39 -07:00
Nick Terrell c1a244d534 Merge pull request #2539 from terrelln/linux-kernel-fixes
Fixes for the next linux kernel patch version
2021-03-24 16:29:38 -07:00
142 changed files with 2522 additions and 5300 deletions
+2 -13
View File
@@ -30,9 +30,6 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
DEVNULLRIGHTS: 1
READFROMBLOCKDEVICE: 1
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: make test - name: make test
@@ -58,9 +55,11 @@ jobs:
CC=gcc-7 CFLAGS=-Werror make -j all CC=gcc-7 CFLAGS=-Werror make -j all
make clean make clean
LDFLAGS=-Wl,--no-undefined make -C lib libzstd-mt LDFLAGS=-Wl,--no-undefined make -C lib libzstd-mt
make -C tests zbufftest-dll
# candidate test (to check) : underlink test # candidate test (to check) : underlink test
# LDFLAGS=-Wl,--no-undefined : will make the linker fail if dll is underlinked # LDFLAGS=-Wl,--no-undefined : will make the linker fail if dll is underlinked
# zbufftest-dll : test that a user program can link to multi-threaded libzstd without specifying -pthread
gcc-8-asan-ubsan-testzstd: gcc-8-asan-ubsan-testzstd:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -127,16 +126,6 @@ jobs:
make libc6install make libc6install
CFLAGS="-O2 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest CFLAGS="-O2 -m32" FUZZER_FLAGS="--long-tests" make uasan-fuzztest
clang-msan-fuzz:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: clang + MSan + Fuzz Test
run: |
sudo apt-get update
sudo apt-get install clang
CC=clang FUZZER_FLAGS="--long-tests" make clean msan-fuzztest
asan-ubsan-msan-regression: asan-ubsan-msan-regression:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
+8
View File
@@ -25,6 +25,14 @@ jobs:
make test make test
# make -c lib all (need to fix. not working right now) # make -c lib all (need to fix. not working right now)
zbuff:
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v2
- name: zbuff test
run: |
make -C tests test-zbuff
tsan: tsan:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
-2
View File
@@ -50,5 +50,3 @@ googletest/
*.code-workspace *.code-workspace
compile_commands.json compile_commands.json
.clangd .clangd
perf.data
perf.data.old
+1 -1
View File
@@ -125,7 +125,7 @@ matrix:
# meson dedicated test # meson dedicated test
- name: Xenial (Meson + clang) # ~15mn - name: Xenial (Meson + clang) # ~15mn
if: branch = release if: branch = release
dist: bionic dist: xenial
language: cpp language: cpp
compiler: clang compiler: clang
install: install:
-56
View File
@@ -1,59 +1,3 @@
v1.5.0 (May 11, 2021)
api: Various functions promoted from experimental to stable API: (#2579-2581, @senhuang42)
`ZSTD_defaultCLevel()`
`ZSTD_getDictID_fromCDict()`
api: Several experimental functions have been deprecated and will emit a compiler warning (#2582, @senhuang42)
`ZSTD_compress_advanced()`
`ZSTD_compress_usingCDict_advanced()`
`ZSTD_compressBegin_advanced()`
`ZSTD_compressBegin_usingCDict_advanced()`
`ZSTD_initCStream_srcSize()`
`ZSTD_initCStream_usingDict()`
`ZSTD_initCStream_usingCDict()`
`ZSTD_initCStream_advanced()`
`ZSTD_initCStream_usingCDict_advanced()`
`ZSTD_resetCStream()`
api: ZSTDMT_NBWORKERS_MAX reduced to 64 for 32-bit environments (@Cyan4973)
perf: Significant speed improvements for middle compression levels (#2494, @senhuang42 @terrelln)
perf: Block splitter to improve compression ratio, enabled by default for high compression levels (#2447, @senhuang42)
perf: Decompression loop refactor, speed improvements on `clang` and for `--long` modes (#2614 #2630, @Cyan4973)
perf: Reduced stack usage during compression and decompression entropy stage (#2522 #2524, @terrelln)
bug: Improve setting permissions of created files (#2525, @felixhandte)
bug: Fix large dictionary non-determinism (#2607, @terrelln)
bug: Fix non-determinism test failures on Linux i686 (#2606, @terrelln)
bug: Fix various dedicated dictionary search bugs (#2540 #2586, @senhuang42 @felixhandte)
bug: Ensure `ZSTD_estimateCCtxSize*() `monotonically increases with compression level (#2538, @senhuang42)
bug: Fix --patch-from mode parameter bound bug with small files (#2637, @occivink)
bug: Fix UBSAN error in decompression (#2625, @terrelln)
bug: Fix superblock compression divide by zero bug (#2592, @senhuang42)
bug: Make the number of physical CPU cores detection more robust (#2517, @PaulBone)
doc: Improve `zdict.h` dictionary training API documentation (#2622, @terrelln)
doc: Note that public `ZSTD_free*()` functions accept NULL pointers (#2521, @animalize)
doc: Add style guide docs for open source contributors (#2626, @Cyan4973)
tests: Better regression test coverage for different dictionary modes (#2559, @senhuang42)
tests: Better test coverage of index reduction (#2603, @terrelln)
tests: OSS-Fuzz coverage for seekable format (#2617, @senhuang42)
tests: Test coverage for ZSTD threadpool API (#2604, @senhuang42)
build: Dynamic library built multithreaded by default (#2584, @senhuang42)
build: Move `zstd_errors.h` and `zdict.h` to `lib/` root (#2597, @terrelln)
build: Allow `ZSTDMT_JOBSIZE_MIN` to be configured at compile-time, reduce default to 512KB (#2611, @Cyan4973)
build: Single file library build script moved to `build/` directory (#2618, @felixhandte)
build: `ZBUFF_*()` is no longer built by default (#2583, @senhuang42)
build: Fixed Meson build (#2548, @SupervisedThinking @kloczek)
build: Fix excessive compiler warnings with clang-cl and CMake (#2600, @nickhutchinson)
build: Detect presence of `md5` on Darwin (#2609, @felixhandte)
build: Avoid SIGBUS on armv6 (#2633, @bmwiedmann)
cli: `--progress` flag added to always display progress bar (#2595, @senhuang42)
cli: Allow reading from block devices with `--force` (#2613, @felixhandte)
cli: Fix CLI filesize display bug (#2550, @Cyan4973)
cli: Fix windows CLI `--filelist` end-of-line bug (#2620, @Cyan4973)
contrib: Various fixes for linux kernel patch (#2539, @terrelln)
contrib: Seekable format - Decompression hanging edge case fix (#2516, @senhuang42)
contrib: Seekable format - New seek table-only API (#2113 #2518, @mdittmer @Cyan4973)
contrib: Seekable format - Fix seek table descriptor check when loading (#2534, @foxeng)
contrib: Seekable format - Decompression fix for large offsets, (#2594, @azat)
misc: Automatically published release tarballs available on Github (#2535, @felixhandte)
v1.4.9 (Mar 1, 2021) v1.4.9 (Mar 1, 2021)
bug: Use `umask()` to Constrain Created File Permissions (#2495, @felixhandte) bug: Use `umask()` to Constrain Created File Permissions (#2495, @felixhandte)
bug: Make Simple Single-Pass Functions Ignore Advanced Parameters (#2498, @terrelln) bug: Make Simple Single-Pass Functions Ignore Advanced Parameters (#2498, @terrelln)
-98
View File
@@ -399,105 +399,7 @@ disclosure of security bugs. In those cases, please go through the process
outlined on that page and do not file a public issue. outlined on that page and do not file a public issue.
## Coding Style ## Coding Style
It's a pretty long topic, which is difficult to summarize in a single paragraph.
As a rule of thumbs, try to imitate the coding style of
similar lines of codes around your contribution.
The following is a non-exhaustive list of rules employed in zstd code base:
### C90
This code base is following strict C90 standard,
with 2 extensions : 64-bit `long long` types, and variadic macros.
This rule is applied strictly to code within `lib/` and `programs/`.
Sub-project in `contrib/` are allowed to use other conventions.
### C++ direct compatibility : symbol mangling
All public symbol declarations must be wrapped in `extern “C” { … }`,
so that this project can be compiled as C++98 code,
and linked into C++ applications.
### Minimal Frugal
This design requirement is fundamental to preserve the portability of the code base.
#### Dependencies
- Reduce dependencies to the minimum possible level.
Any dependency should be considered “bad” by default,
and only tolerated because it provides a service in a better way than can be achieved locally.
The only external dependencies this repository tolerates are
standard C libraries, and in rare cases, system level headers.
- Within `lib/`, this policy is even more drastic.
The only external dependencies allowed are `<assert.h>`, `<stdlib.h>`, `<string.h>`,
and even then, not directly.
In particular, no function shall ever allocate on heap directly,
and must use instead `ZSTD_malloc()` and equivalent.
Other accepted non-symbol headers are `<stddef.h>` and `<limits.h>`.
- Within the project, there is a strict hierarchy of dependencies that must be respected.
`programs/` is allowed to depend on `lib/`, but only its public API.
Within `lib/`, `lib/common` doesn't depend on any other directory.
`lib/compress` and `lib/decompress` shall not depend on each other.
`lib/dictBuilder` can depend on `lib/common` and `lib/compress`, but not `lib/decompress`.
#### Resources
- Functions in `lib/` must use very little stack space,
several dozens of bytes max.
Everything larger must use the heap allocator,
or require a scratch buffer to be emplaced manually.
### Naming
* All public symbols are prefixed with `ZSTD_`
+ private symbols, with a scope limited to their own unit, are free of this restriction.
However, since `libzstd` source code can be amalgamated,
each symbol name must attempt to be (and remain) unique.
Avoid too generic names that could become ground for future collisions.
This generally implies usage of some form of prefix.
* For symbols (functions and variables), naming convention is `PREFIX_camelCase`.
+ In some advanced cases, one can also find :
- `PREFIX_prefix2_camelCase`
- `PREFIX_camelCase_extendedQualifier`
* Multi-words names generally consist of an action followed by object:
- for example : `ZSTD_createCCtx()`
* Prefer positive actions
- `goBackward` rather than `notGoForward`
* Type names (`struct`, etc.) follow similar convention,
except that they are allowed and even invited to start by an Uppercase letter.
Example : `ZSTD_CCtx`, `ZSTD_CDict`
* Macro names are all Capital letters.
The same composition rules (`PREFIX_NAME_QUALIFIER`) apply.
* File names are all lowercase letters.
The convention is `snake_case`.
File names **must** be unique across the entire code base,
even when they stand in clearly separated directories.
### Qualifiers
* This code base is `const` friendly, if not `const` fanatical.
Any variable that can be `const` (aka. read-only) **must** be `const`.
Any pointer which content will not be modified must be `const`.
This property is then controlled at compiler level.
`const` variables are an important signal to readers that this variable isnt modified.
Conversely, non-const variables are a signal to readers to watch out for modifications later on in the function.
* If a function must be inlined, mention it explicitly,
using project's own portable macros, such as `FORCE_INLINE_ATTR`,
defined in `lib/common/compiler.h`.
### Debugging
* **Assertions** are welcome, and should be used very liberally,
to control any condition the code expects for its correct execution.
These assertion checks will be run in debug builds, and disabled in production.
* For traces, this project provides its own debug macros,
in particular `DEBUGLOG(level, ...)`, defined in `lib/common/debug.h`.
### Code documentation
* Avoid code documentation that merely repeats what the code is already stating.
Whenever applicable, prefer employing the code as the primary way to convey explanations.
Example 1 : `int nbTokens = n;` instead of `int i = n; /* i is a nb of tokens *./`.
Example 2 : `assert(size > 0);` instead of `/* here, size should be positive */`.
* At declaration level, the documentation explains how to use the function or variable
and when applicable why it's needed, of the scenarios where it can be useful.
* At implementation level, the documentation explains the general outline of the algorithm employed,
and when applicable why this specific choice was preferred.
### General layout
* 4 spaces for indentation rather than tabs * 4 spaces for indentation rather than tabs
* Code documentation shall directly precede function declaration or implementation
* Function implementations and its code documentation should be preceded and followed by an empty line
## License ## License
By contributing to Zstandard, you agree that your contributions will be licensed By contributing to Zstandard, you agree that your contributions will be licensed
+13 -15
View File
@@ -57,8 +57,8 @@ all32:
$(MAKE) -C $(PRGDIR) zstd32 $(MAKE) -C $(PRGDIR) zstd32
$(MAKE) -C $(TESTDIR) all32 $(MAKE) -C $(TESTDIR) all32
.PHONY: lib lib-release lib-mt lib-nomt .PHONY: lib lib-release
lib lib-release lib-mt lib-nomt: lib lib-release :
$(Q)$(MAKE) -C $(ZSTDDIR) $@ $(Q)$(MAKE) -C $(ZSTDDIR) $@
.PHONY: zstd zstd-release .PHONY: zstd zstd-release
@@ -122,8 +122,8 @@ contrib: lib
$(MAKE) -C contrib/seekable_format/examples all $(MAKE) -C contrib/seekable_format/examples all
$(MAKE) -C contrib/seekable_format/tests test $(MAKE) -C contrib/seekable_format/tests test
$(MAKE) -C contrib/largeNbDicts all $(MAKE) -C contrib/largeNbDicts all
cd build/single_file_libs/ ; ./build_decoder_test.sh cd contrib/single_file_libs/ ; ./build_decoder_test.sh
cd build/single_file_libs/ ; ./build_library_test.sh cd contrib/single_file_libs/ ; ./build_library_test.sh
.PHONY: cleanTabs .PHONY: cleanTabs
cleanTabs: cleanTabs:
@@ -151,6 +151,7 @@ clean:
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT Haiku)) ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT Haiku))
HOST_OS = POSIX HOST_OS = POSIX
CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON -DCMAKE_BUILD_TYPE=Release
HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0)
EGREP_OPTIONS ?= EGREP_OPTIONS ?=
@@ -178,7 +179,7 @@ list:
done \ done \
} | column -t -s $$'\t' } | column -t -s $$'\t'
.PHONY: install armtest usan asan uasan msan asan32 .PHONY: install armtest usan asan uasan
install: install:
$(Q)$(MAKE) -C $(ZSTDDIR) $@ $(Q)$(MAKE) -C $(ZSTDDIR) $@
$(Q)$(MAKE) -C $(PRGDIR) $@ $(Q)$(MAKE) -C $(PRGDIR) $@
@@ -192,19 +193,22 @@ uninstall:
travis-install: travis-install:
$(MAKE) install PREFIX=~/install_test_dir $(MAKE) install PREFIX=~/install_test_dir
.PHONY: gcc5build gcc6build gcc7build clangbuild m32build armbuild aarch64build ppcbuild ppc64build .PHONY: gcc5build
gcc5build: clean gcc5build: clean
gcc-5 -v gcc-5 -v
CC=gcc-5 $(MAKE) all MOREFLAGS="-Werror" CC=gcc-5 $(MAKE) all MOREFLAGS="-Werror"
.PHONY: gcc6build
gcc6build: clean gcc6build: clean
gcc-6 -v gcc-6 -v
CC=gcc-6 $(MAKE) all MOREFLAGS="-Werror" CC=gcc-6 $(MAKE) all MOREFLAGS="-Werror"
.PHONY: gcc7build
gcc7build: clean gcc7build: clean
gcc-7 -v gcc-7 -v
CC=gcc-7 $(MAKE) all MOREFLAGS="-Werror" CC=gcc-7 $(MAKE) all MOREFLAGS="-Werror"
.PHONY: clangbuild
clangbuild: clean clangbuild: clean
clang -v clang -v
CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation" $(MAKE) all CXX=clang++ CC=clang CFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation" $(MAKE) all
@@ -225,7 +229,6 @@ ppcbuild: clean
ppc64build: clean ppc64build: clean
CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) -j allzstd CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) -j allzstd
.PHONY: armfuzz aarch64fuzz ppcfuzz ppc64fuzz
armfuzz: clean armfuzz: clean
CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest
@@ -239,7 +242,7 @@ ppcfuzz: clean
ppc64fuzz: clean ppc64fuzz: clean
CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static MOREFLAGS="-m64 -static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static MOREFLAGS="-m64 -static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest
.PHONY: cxxtest gcc5test gcc6test armtest aarch64test ppctest ppc64test .PHONY: cxxtest
cxxtest: CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror cxxtest: CXXFLAGS += -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror
cxxtest: clean cxxtest: clean
$(MAKE) -C $(PRGDIR) all CC="$(CXX) -Wno-deprecated" CFLAGS="$(CXXFLAGS)" # adding -Wno-deprecated to avoid clang++ warning on dealing with C files directly $(MAKE) -C $(PRGDIR) all CC="$(CXX) -Wno-deprecated" CFLAGS="$(CXXFLAGS)" # adding -Wno-deprecated to avoid clang++ warning on dealing with C files directly
@@ -268,7 +271,6 @@ ppc64test: clean
$(MAKE) -C $(TESTDIR) datagen # use native, faster $(MAKE) -C $(TESTDIR) datagen # use native, faster
$(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) test CC=powerpc-linux-gnu-gcc QEMU_SYS=qemu-ppc64-static ZSTDRTTEST= MOREFLAGS="-m64 -static" FUZZER_FLAGS=--no-big-tests
.PHONY: arm-ppc-compilation
arm-ppc-compilation: arm-ppc-compilation:
$(MAKE) -C $(PRGDIR) clean zstd CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static" $(MAKE) -C $(PRGDIR) clean zstd CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static ZSTDRTTEST= MOREFLAGS="-Werror -static"
$(MAKE) -C $(PRGDIR) clean zstd CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static" $(MAKE) -C $(PRGDIR) clean zstd CC=aarch64-linux-gnu-gcc QEMU_SYS=qemu-aarch64-static ZSTDRTTEST= MOREFLAGS="-Werror -static"
@@ -286,6 +288,7 @@ msanregressiontest:
# run UBsan with -fsanitize-recover=pointer-overflow # run UBsan with -fsanitize-recover=pointer-overflow
# this only works with recent compilers such as gcc 8+ # this only works with recent compilers such as gcc 8+
usan: clean usan: clean
$(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=undefined -Werror" $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=pointer-overflow -fsanitize=undefined -Werror"
@@ -313,16 +316,13 @@ uasan-%: clean
tsan-%: clean tsan-%: clean
LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread -Werror" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS=--no-big-tests LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread -Werror" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS=--no-big-tests
.PHONY: apt-install
apt-install: apt-install:
sudo apt-get -yq --no-install-suggests --no-install-recommends --force-yes install $(APT_PACKAGES) sudo apt-get -yq --no-install-suggests --no-install-recommends --force-yes install $(APT_PACKAGES)
.PHONY: apt-add-repo
apt-add-repo: apt-add-repo:
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update -y -qq sudo apt-get update -y -qq
.PHONY: ppcinstall arminstall valgrindinstall libc6install gcc6install gcc7install gcc8install gpp6install clang38install lz4install
ppcinstall: ppcinstall:
APT_PACKAGES="qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu" $(MAKE) apt-install APT_PACKAGES="qemu-system-ppc qemu-user-static gcc-powerpc-linux-gnu" $(MAKE) apt-install
@@ -357,18 +357,16 @@ lz4install:
endif endif
CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON -DCMAKE_BUILD_TYPE=Release
ifneq (,$(filter MSYS%,$(shell uname))) ifneq (,$(filter MSYS%,$(shell uname)))
HOST_OS = MSYS HOST_OS = MSYS
CMAKE_PARAMS = -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON CMAKE_PARAMS = -G"MSYS Makefiles" -DCMAKE_BUILD_TYPE=Debug -DZSTD_MULTITHREAD_SUPPORT:BOOL=OFF -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON
endif endif
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# target specific tests # target specific tests
#------------------------------------------------------------------------ #------------------------------------------------------------------------
ifneq (,$(filter $(HOST_OS),MSYS POSIX)) ifneq (,$(filter $(HOST_OS),MSYS POSIX))
.PHONY: cmakebuild c89build gnu90build c99build gnu99build c11build bmix64build bmix32build bmi32build staticAnalyze
cmakebuild: cmakebuild:
cmake --version cmake --version
$(RM) -r $(BUILDIR)/cmake/build $(RM) -r $(BUILDIR)/cmake/build
+1
View File
@@ -40,4 +40,5 @@ They consist of the following tests:
- Versions test (ensuring `zstd` can decode files from all previous versions) - Versions test (ensuring `zstd` can decode files from all previous versions)
- `pzstd` with asan and tsan, as well as in 32-bits mode - `pzstd` with asan and tsan, as well as in 32-bits mode
- Testing `zstd` with legacy mode off - Testing `zstd` with legacy mode off
- Testing `zbuff` (old streaming API)
- Entire test suite and make install on macOS - Entire test suite and make install on macOS
+3 -38
View File
@@ -52,15 +52,6 @@
PLATFORM: "Win32" PLATFORM: "Win32"
CONFIGURATION: "Release" CONFIGURATION: "Release"
- COMPILER: "clang-cl"
HOST: "cmake-visual"
PLATFORM: "x64"
CONFIGURATION: "Release"
CMAKE_GENERATOR: "Visual Studio 15 2017"
CMAKE_GENERATOR_PLATFORM: "x64"
CMAKE_GENERATOR_TOOLSET: "LLVM"
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
install: install:
- ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION% - ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION%
- SET PATH_ORIGINAL=%PATH% - SET PATH_ORIGINAL=%PATH%
@@ -163,15 +154,6 @@
COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe &&
COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\
) )
- if [%HOST%]==[cmake-visual] (
ECHO *** &&
ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% &&
PUSHD build\cmake &&
cmake -DBUILD_TESTING=ON . &&
cmake --build . --config %CONFIGURATION% -j4 &&
POPD &&
ECHO ***
)
test_script: test_script:
- ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION% - ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION%
@@ -241,21 +223,13 @@
PLATFORM: "Win32" PLATFORM: "Win32"
CONFIGURATION: "Release" CONFIGURATION: "Release"
- COMPILER: "clang-cl"
HOST: "cmake-visual"
PLATFORM: "x64"
CONFIGURATION: "Release"
CMAKE_GENERATOR: "Visual Studio 15 2017"
CMAKE_GENERATOR_PLATFORM: "x64"
CMAKE_GENERATOR_TOOLSET: "LLVM"
APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017"
install: install:
- ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION% - ECHO Installing %COMPILER% %PLATFORM% %CONFIGURATION%
- SET PATH_ORIGINAL=%PATH% - SET PATH_ORIGINAL=%PATH%
- if [%HOST%]==[cygwin] ( - if [%HOST%]==[cygwin] (
ECHO Installing Cygwin Packages && ECHO Installing Cygwin Packages &&
C:\cygwin64\setup-x86_64.exe -qnNdO -R "C:\cygwin64" -g -P ^ C:\cygwin64\setup-x86_64.exe -qnNdO -R "C:\cygwin64" -g -P ^
gcc-g++,^
gcc,^ gcc,^
cmake,^ cmake,^
make make
@@ -278,8 +252,8 @@
C:\cygwin64\bin\bash --login -c " C:\cygwin64\bin\bash --login -c "
set -e; set -e;
cd build/cmake; cd build/cmake;
CFLAGS='-Werror' cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_FUZZER_FLAGS=-T20s -DZSTD_ZSTREAM_FLAGS=-T20s -DZSTD_FULLBENCH_FLAGS=-i0 .; CFLAGS='-Werror' cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_FUZZER_FLAGS=-T30s -DZSTD_ZSTREAM_FLAGS=-T30s .;
make VERBOSE=1 -j; make -j4;
ctest -V -L Medium; ctest -V -L Medium;
" "
) )
@@ -307,15 +281,6 @@
COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe &&
COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\
) )
- if [%HOST%]==[cmake-visual] (
ECHO *** &&
ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% &&
PUSHD build\cmake &&
cmake -DBUILD_TESTING=ON . &&
cmake --build . --config %CONFIGURATION% -j4 &&
POPD &&
ECHO ***
)
test_script: test_script:
+1 -1
View File
@@ -463,7 +463,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
+2 -2
View File
@@ -483,7 +483,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
@@ -511,7 +511,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zdict.h" RelativePath="..\..\..\lib\dictBuilder\zdict.h"
> >
</File> </File>
<File <File
+2 -2
View File
@@ -559,7 +559,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zdict.h" RelativePath="..\..\..\lib\dictBuilder\zdict.h"
> >
</File> </File>
<File <File
@@ -575,7 +575,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
+2 -2
View File
@@ -495,7 +495,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
@@ -523,7 +523,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zdict.h" RelativePath="..\..\..\lib\dictBuilder\zdict.h"
> >
</File> </File>
<File <File
+1 -1
View File
@@ -190,7 +190,7 @@
<ClInclude Include="..\..\..\lib\zstd.h" /> <ClInclude Include="..\..\..\lib\zstd.h" />
<ClInclude Include="..\..\..\lib\common\fse.h" /> <ClInclude Include="..\..\..\lib\common\fse.h" />
<ClInclude Include="..\..\..\lib\common\huf.h" /> <ClInclude Include="..\..\..\lib\common\huf.h" />
<ClInclude Include="..\..\..\lib\zstd_errors.h" /> <ClInclude Include="..\..\..\lib\common\zstd_errors.h" />
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" /> <ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
<ClInclude Include="..\..\..\lib\common\pool.h" /> <ClInclude Include="..\..\..\lib\common\pool.h" />
<ClInclude Include="..\..\..\lib\common\threading.h" /> <ClInclude Include="..\..\..\lib\common\threading.h" />
+2 -2
View File
@@ -196,7 +196,7 @@
<ClInclude Include="..\..\..\lib\common\huf.h" /> <ClInclude Include="..\..\..\lib\common\huf.h" />
<ClInclude Include="..\..\..\lib\common\xxhash.h" /> <ClInclude Include="..\..\..\lib\common\xxhash.h" />
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" /> <ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
<ClInclude Include="..\..\..\lib\zstd_errors.h" /> <ClInclude Include="..\..\..\lib\common\zstd_errors.h" />
<ClInclude Include="..\..\..\lib\zstd.h" /> <ClInclude Include="..\..\..\lib\zstd.h" />
<ClInclude Include="..\..\..\lib\compress\zstd_compress.h" /> <ClInclude Include="..\..\..\lib\compress\zstd_compress.h" />
<ClInclude Include="..\..\..\lib\compress\zstd_compress_literals.h" /> <ClInclude Include="..\..\..\lib\compress\zstd_compress_literals.h" />
@@ -211,7 +211,7 @@
<ClInclude Include="..\..\..\lib\compress\zstdmt_compress.h" /> <ClInclude Include="..\..\..\lib\compress\zstdmt_compress.h" />
<ClInclude Include="..\..\..\lib\decompress\zstd_ddict.h" /> <ClInclude Include="..\..\..\lib\decompress\zstd_ddict.h" />
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" /> <ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" />
<ClInclude Include="..\..\..\lib\zdict.h" /> <ClInclude Include="..\..\..\lib\dictBuilder\zdict.h" />
<ClInclude Include="..\..\..\lib\dictBuilder\cover.h" /> <ClInclude Include="..\..\..\lib\dictBuilder\cover.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
<ClInclude Include="..\..\..\programs\datagen.h" /> <ClInclude Include="..\..\..\programs\datagen.h" />
+5 -1
View File
@@ -44,6 +44,9 @@
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" /> <ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress_block.c" /> <ClCompile Include="..\..\..\lib\decompress\zstd_decompress_block.c" />
<ClCompile Include="..\..\..\lib\decompress\zstd_ddict.c" /> <ClCompile Include="..\..\..\lib\decompress\zstd_ddict.c" />
<ClCompile Include="..\..\..\lib\deprecated\zbuff_common.c" />
<ClCompile Include="..\..\..\lib\deprecated\zbuff_compress.c" />
<ClCompile Include="..\..\..\lib\deprecated\zbuff_decompress.c" />
<ClCompile Include="..\..\..\lib\dictBuilder\cover.c" /> <ClCompile Include="..\..\..\lib\dictBuilder\cover.c" />
<ClCompile Include="..\..\..\lib\dictBuilder\fastcover.c" /> <ClCompile Include="..\..\..\lib\dictBuilder\fastcover.c" />
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" /> <ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
@@ -61,11 +64,12 @@
<ClInclude Include="..\..\..\lib\common\threading.h" /> <ClInclude Include="..\..\..\lib\common\threading.h" />
<ClInclude Include="..\..\..\lib\common\bitstream.h" /> <ClInclude Include="..\..\..\lib\common\bitstream.h" />
<ClInclude Include="..\..\..\lib\common\error_private.h" /> <ClInclude Include="..\..\..\lib\common\error_private.h" />
<ClInclude Include="..\..\..\lib\zstd_errors.h" /> <ClInclude Include="..\..\..\lib\common\zstd_errors.h" />
<ClInclude Include="..\..\..\lib\common\mem.h" /> <ClInclude Include="..\..\..\lib\common\mem.h" />
<ClInclude Include="..\..\..\lib\common\fse.h" /> <ClInclude Include="..\..\..\lib\common\fse.h" />
<ClInclude Include="..\..\..\lib\common\huf.h" /> <ClInclude Include="..\..\..\lib\common\huf.h" />
<ClInclude Include="..\..\..\lib\common\xxhash.h" /> <ClInclude Include="..\..\..\lib\common\xxhash.h" />
<ClInclude Include="..\..\..\lib\deprecated\zbuff.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_v02.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_v02.h" />
+5 -1
View File
@@ -44,6 +44,9 @@
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" /> <ClCompile Include="..\..\..\lib\decompress\zstd_decompress.c" />
<ClCompile Include="..\..\..\lib\decompress\zstd_decompress_block.c" /> <ClCompile Include="..\..\..\lib\decompress\zstd_decompress_block.c" />
<ClCompile Include="..\..\..\lib\decompress\zstd_ddict.c" /> <ClCompile Include="..\..\..\lib\decompress\zstd_ddict.c" />
<ClCompile Include="..\..\..\lib\deprecated\zbuff_common.c" />
<ClCompile Include="..\..\..\lib\deprecated\zbuff_compress.c" />
<ClCompile Include="..\..\..\lib\deprecated\zbuff_decompress.c" />
<ClCompile Include="..\..\..\lib\dictBuilder\cover.c" /> <ClCompile Include="..\..\..\lib\dictBuilder\cover.c" />
<ClCompile Include="..\..\..\lib\dictBuilder\fastcover.c" /> <ClCompile Include="..\..\..\lib\dictBuilder\fastcover.c" />
<ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" /> <ClCompile Include="..\..\..\lib\dictBuilder\divsufsort.c" />
@@ -61,11 +64,12 @@
<ClInclude Include="..\..\..\lib\common\threading.h" /> <ClInclude Include="..\..\..\lib\common\threading.h" />
<ClInclude Include="..\..\..\lib\common\bitstream.h" /> <ClInclude Include="..\..\..\lib\common\bitstream.h" />
<ClInclude Include="..\..\..\lib\common\error_private.h" /> <ClInclude Include="..\..\..\lib\common\error_private.h" />
<ClInclude Include="..\..\..\lib\zstd_errors.h" /> <ClInclude Include="..\..\..\lib\common\zstd_errors.h" />
<ClInclude Include="..\..\..\lib\common\mem.h" /> <ClInclude Include="..\..\..\lib\common\mem.h" />
<ClInclude Include="..\..\..\lib\common\fse.h" /> <ClInclude Include="..\..\..\lib\common\fse.h" />
<ClInclude Include="..\..\..\lib\common\huf.h" /> <ClInclude Include="..\..\..\lib\common\huf.h" />
<ClInclude Include="..\..\..\lib\common\xxhash.h" /> <ClInclude Include="..\..\..\lib\common\xxhash.h" />
<ClInclude Include="..\..\..\lib\deprecated\zbuff.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_legacy.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_v01.h" />
<ClInclude Include="..\..\..\lib\legacy\zstd_v02.h" /> <ClInclude Include="..\..\..\lib\legacy\zstd_v02.h" />
+2 -2
View File
@@ -70,14 +70,14 @@
<ClInclude Include="..\..\..\lib\common\threading.h" /> <ClInclude Include="..\..\..\lib\common\threading.h" />
<ClInclude Include="..\..\..\lib\common\xxhash.h" /> <ClInclude Include="..\..\..\lib\common\xxhash.h" />
<ClInclude Include="..\..\..\lib\compress\zstdmt_compress.h" /> <ClInclude Include="..\..\..\lib\compress\zstdmt_compress.h" />
<ClInclude Include="..\..\..\lib\zdict.h" /> <ClInclude Include="..\..\..\lib\dictBuilder\zdict.h" />
<ClInclude Include="..\..\..\lib\dictBuilder\cover.h" /> <ClInclude Include="..\..\..\lib\dictBuilder\cover.h" />
<ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" /> <ClInclude Include="..\..\..\lib\dictBuilder\divsufsort.h" />
<ClInclude Include="..\..\..\lib\common\fse.h" /> <ClInclude Include="..\..\..\lib\common\fse.h" />
<ClInclude Include="..\..\..\lib\common\huf.h" /> <ClInclude Include="..\..\..\lib\common\huf.h" />
<ClInclude Include="..\..\..\lib\zstd.h" /> <ClInclude Include="..\..\..\lib\zstd.h" />
<ClInclude Include="..\..\..\lib\common\zstd_internal.h" /> <ClInclude Include="..\..\..\lib\common\zstd_internal.h" />
<ClInclude Include="..\..\..\lib\zstd_errors.h" /> <ClInclude Include="..\..\..\lib\common\zstd_errors.h" />
<ClInclude Include="..\..\..\lib\compress\zstd_compress.h" /> <ClInclude Include="..\..\..\lib\compress\zstd_compress.h" />
<ClInclude Include="..\..\..\lib\compress\zstd_compress_literals.h" /> <ClInclude Include="..\..\..\lib\compress\zstd_compress_literals.h" />
<ClInclude Include="..\..\..\lib\compress\zstd_compress_sequences.h" /> <ClInclude Include="..\..\..\lib\compress\zstd_compress_sequences.h" />
@@ -26,12 +26,7 @@ macro(ADD_ZSTD_COMPILATION_FLAGS)
EnableCompilerFlag("-std=c++11" false true) EnableCompilerFlag("-std=c++11" false true)
#Set c99 by default #Set c99 by default
EnableCompilerFlag("-std=c99" true false) EnableCompilerFlag("-std=c99" true false)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC) EnableCompilerFlag("-Wall" true true)
# clang-cl normally maps -Wall to -Weverything.
EnableCompilerFlag("/clang:-Wall" true true)
else ()
EnableCompilerFlag("-Wall" true true)
endif ()
EnableCompilerFlag("-Wextra" true true) EnableCompilerFlag("-Wextra" true true)
EnableCompilerFlag("-Wundef" true true) EnableCompilerFlag("-Wundef" true true)
EnableCompilerFlag("-Wshadow" true true) EnableCompilerFlag("-Wshadow" true true)
+8 -4
View File
@@ -24,24 +24,28 @@ file(GLOB CommonSources ${LIBRARY_DIR}/common/*.c)
file(GLOB CompressSources ${LIBRARY_DIR}/compress/*.c) file(GLOB CompressSources ${LIBRARY_DIR}/compress/*.c)
file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c) file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c)
file(GLOB DictBuilderSources ${LIBRARY_DIR}/dictBuilder/*.c) file(GLOB DictBuilderSources ${LIBRARY_DIR}/dictBuilder/*.c)
file(GLOB DeprecatedSources ${LIBRARY_DIR}/deprecated/*.c)
set(Sources set(Sources
${CommonSources} ${CommonSources}
${CompressSources} ${CompressSources}
${DecompressSources} ${DecompressSources}
${DictBuilderSources}) ${DictBuilderSources}
${DeprecatedSources})
file(GLOB CommonHeaders ${LIBRARY_DIR}/common/*.h) file(GLOB CommonHeaders ${LIBRARY_DIR}/common/*.h)
file(GLOB CompressHeaders ${LIBRARY_DIR}/compress/*.h) file(GLOB CompressHeaders ${LIBRARY_DIR}/compress/*.h)
file(GLOB DecompressHeaders ${LIBRARY_DIR}/decompress/*.h) file(GLOB DecompressHeaders ${LIBRARY_DIR}/decompress/*.h)
file(GLOB DictBuilderHeaders ${LIBRARY_DIR}/dictBuilder/*.h) file(GLOB DictBuilderHeaders ${LIBRARY_DIR}/dictBuilder/*.h)
file(GLOB DeprecatedHeaders ${LIBRARY_DIR}/deprecated/*.h)
set(Headers set(Headers
${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/zstd.h
${CommonHeaders} ${CommonHeaders}
${CompressHeaders} ${CompressHeaders}
${DecompressHeaders} ${DecompressHeaders}
${DictBuilderHeaders}) ${DictBuilderHeaders}
${DeprecatedHeaders})
if (ZSTD_LEGACY_SUPPORT) if (ZSTD_LEGACY_SUPPORT)
set(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy) set(LIBRARY_LEGACY_DIR ${LIBRARY_DIR}/legacy)
@@ -158,8 +162,8 @@ endif ()
# install target # install target
install(FILES install(FILES
"${LIBRARY_DIR}/zstd.h" "${LIBRARY_DIR}/zstd.h"
"${LIBRARY_DIR}/zdict.h" "${LIBRARY_DIR}/dictBuilder/zdict.h"
"${LIBRARY_DIR}/zstd_errors.h" "${LIBRARY_DIR}/common/zstd_errors.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(TARGETS ${library_targets} install(TARGETS ${library_targets}
+1
View File
@@ -3,4 +3,5 @@ datagen
fullbench fullbench
fuzzer fuzzer
paramgrill paramgrill
zbufftest
+1 -4
View File
@@ -57,15 +57,13 @@ target_link_libraries(datagen libzstd_static)
# fullbench # fullbench
# #
add_executable(fullbench ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${TESTS_DIR}/fullbench.c) add_executable(fullbench ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${PROGRAMS_DIR}/benchfn.c ${PROGRAMS_DIR}/benchzstd.c ${TESTS_DIR}/fullbench.c)
set_property(TARGET fullbench APPEND PROPERTY COMPILE_OPTIONS "-Wno-deprecated-declarations")
target_link_libraries(fullbench libzstd_static) target_link_libraries(fullbench libzstd_static)
add_test(NAME fullbench COMMAND fullbench ${ZSTD_FULLBENCH_FLAGS}) add_test(NAME fullbench COMMAND fullbench)
# #
# fuzzer # fuzzer
# #
add_executable(fuzzer ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/fuzzer.c) add_executable(fuzzer ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/fuzzer.c)
set_property(TARGET fuzzer APPEND PROPERTY COMPILE_OPTIONS "-Wno-deprecated-declarations")
target_link_libraries(fuzzer libzstd_static) target_link_libraries(fuzzer libzstd_static)
AddTestFlagsOption(ZSTD_FUZZER_FLAGS "$ENV{FUZZERTEST} $ENV{FUZZER_FLAGS}" AddTestFlagsOption(ZSTD_FUZZER_FLAGS "$ENV{FUZZERTEST} $ENV{FUZZER_FLAGS}"
"Semicolon-separated list of flags to pass to the fuzzer test (see `fuzzer -h` for usage)") "Semicolon-separated list of flags to pass to the fuzzer test (see `fuzzer -h` for usage)")
@@ -78,7 +76,6 @@ add_test(NAME fuzzer COMMAND fuzzer ${ZSTD_FUZZER_FLAGS})
# zstreamtest # zstreamtest
# #
add_executable(zstreamtest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/seqgen.c ${TESTS_DIR}/zstreamtest.c) add_executable(zstreamtest ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/util.c ${PROGRAMS_DIR}/timefn.c ${TESTS_DIR}/seqgen.c ${TESTS_DIR}/zstreamtest.c)
set_property(TARGET zstreamtest APPEND PROPERTY COMPILE_OPTIONS "-Wno-deprecated-declarations")
target_link_libraries(zstreamtest libzstd_static) target_link_libraries(zstreamtest libzstd_static)
AddTestFlagsOption(ZSTD_ZSTREAM_FLAGS "$ENV{ZSTREAM_TESTTIME} $ENV{FUZZER_FLAGS}" AddTestFlagsOption(ZSTD_ZSTREAM_FLAGS "$ENV{ZSTREAM_TESTTIME} $ENV{FUZZER_FLAGS}"
"Semicolon-separated list of flags to pass to the zstreamtest test (see `zstreamtest -h` for usage)") "Semicolon-separated list of flags to pass to the zstreamtest test (see `zstreamtest -h` for usage)")
+1 -1
View File
@@ -18,7 +18,7 @@ pzstd_sources = [join_paths(zstd_rootdir, 'programs/util.c'),
join_paths(zstd_rootdir, 'contrib/pzstd/SkippableFrame.cpp')] join_paths(zstd_rootdir, 'contrib/pzstd/SkippableFrame.cpp')]
pzstd = executable('pzstd', pzstd = executable('pzstd',
pzstd_sources, pzstd_sources,
cpp_args: [ '-DNDEBUG', '-Wno-shadow', '-pedantic', '-Wno-deprecated-declarations' ], cpp_args: [ '-DNDEBUG', '-Wno-shadow', '-pedantic' ],
include_directories: pzstd_includes, include_directories: pzstd_includes,
dependencies: [ libzstd_dep, thread_dep ], dependencies: [ libzstd_dep, thread_dep ],
install: true) install: true)
+9 -4
View File
@@ -14,13 +14,15 @@ libzstd_includes = [include_directories(join_paths(zstd_rootdir,'lib'),
join_paths(zstd_rootdir, 'lib/common'), join_paths(zstd_rootdir, 'lib/common'),
join_paths(zstd_rootdir, 'lib/compress'), join_paths(zstd_rootdir, 'lib/compress'),
join_paths(zstd_rootdir, 'lib/decompress'), join_paths(zstd_rootdir, 'lib/decompress'),
join_paths(zstd_rootdir, 'lib/dictBuilder'))] join_paths(zstd_rootdir, 'lib/dictBuilder'),
join_paths(zstd_rootdir, 'lib/deprecated'))]
libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'), libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'),
join_paths(zstd_rootdir, 'lib/common/fse_decompress.c'), join_paths(zstd_rootdir, 'lib/common/fse_decompress.c'),
join_paths(zstd_rootdir, 'lib/common/threading.c'), join_paths(zstd_rootdir, 'lib/common/threading.c'),
join_paths(zstd_rootdir, 'lib/common/pool.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_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/error_private.c'),
join_paths(zstd_rootdir, 'lib/common/xxhash.c'), join_paths(zstd_rootdir, 'lib/common/xxhash.c'),
join_paths(zstd_rootdir, 'lib/compress/hist.c'), join_paths(zstd_rootdir, 'lib/compress/hist.c'),
@@ -43,7 +45,10 @@ libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'),
join_paths(zstd_rootdir, 'lib/dictBuilder/cover.c'), join_paths(zstd_rootdir, 'lib/dictBuilder/cover.c'),
join_paths(zstd_rootdir, 'lib/dictBuilder/fastcover.c'), join_paths(zstd_rootdir, 'lib/dictBuilder/fastcover.c'),
join_paths(zstd_rootdir, 'lib/dictBuilder/divsufsort.c'), join_paths(zstd_rootdir, 'lib/dictBuilder/divsufsort.c'),
join_paths(zstd_rootdir, 'lib/dictBuilder/zdict.c')] join_paths(zstd_rootdir, 'lib/dictBuilder/zdict.c'),
join_paths(zstd_rootdir, 'lib/deprecated/zbuff_common.c'),
join_paths(zstd_rootdir, 'lib/deprecated/zbuff_compress.c'),
join_paths(zstd_rootdir, 'lib/deprecated/zbuff_decompress.c')]
# Explicit define legacy support # Explicit define legacy support
add_project_arguments('-DZSTD_LEGACY_SUPPORT=@0@'.format(legacy_level), add_project_arguments('-DZSTD_LEGACY_SUPPORT=@0@'.format(legacy_level),
@@ -123,5 +128,5 @@ pkgconfig.generate(libzstd,
url: 'http://www.zstd.net/') url: 'http://www.zstd.net/')
install_headers(join_paths(zstd_rootdir, 'lib/zstd.h'), install_headers(join_paths(zstd_rootdir, 'lib/zstd.h'),
join_paths(zstd_rootdir, 'lib/zdict.h'), join_paths(zstd_rootdir, 'lib/dictBuilder/zdict.h'),
join_paths(zstd_rootdir, 'lib/zstd_errors.h')) join_paths(zstd_rootdir, 'lib/common/zstd_errors.h'))
+1 -1
View File
@@ -57,7 +57,7 @@ fuzzer_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'),
fuzzer = executable('fuzzer', fuzzer = executable('fuzzer',
fuzzer_sources, fuzzer_sources,
include_directories: test_includes, include_directories: test_includes,
dependencies: [ libzstd_dep, thread_dep ], dependencies: libzstd_dep,
install: false) install: false)
zstreamtest_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), zstreamtest_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'),
+1 -1
View File
@@ -390,7 +390,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
+2 -2
View File
@@ -426,7 +426,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
@@ -454,7 +454,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zdict.h" RelativePath="..\..\..\lib\dictBuilder\zdict.h"
> >
</File> </File>
<File <File
+2 -2
View File
@@ -454,7 +454,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
@@ -482,7 +482,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zdict.h" RelativePath="..\..\..\lib\dictBuilder\zdict.h"
> >
</File> </File>
<File <File
+18 -2
View File
@@ -371,6 +371,18 @@
RelativePath="..\..\..\lib\common\xxhash.c" RelativePath="..\..\..\lib\common\xxhash.c"
> >
</File> </File>
<File
RelativePath="..\..\..\lib\deprecated\zbuff_common.c"
>
</File>
<File
RelativePath="..\..\..\lib\deprecated\zbuff_compress.c"
>
</File>
<File
RelativePath="..\..\..\lib\deprecated\zbuff_decompress.c"
>
</File>
<File <File
RelativePath="..\..\..\lib\dictBuilder\zdict.c" RelativePath="..\..\..\lib\dictBuilder\zdict.c"
> >
@@ -446,7 +458,7 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zstd_errors.h" RelativePath="..\..\..\lib\common\zstd_errors.h"
> >
</File> </File>
<File <File
@@ -474,7 +486,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\lib\zdict.h" RelativePath="..\..\..\lib\common\zbuff.h"
>
</File>
<File
RelativePath="..\..\..\lib\dictBuilder\zdict.h"
> >
</File> </File>
<File <File
-1
View File
@@ -481,7 +481,6 @@ class Freestanding(object):
assert os.path.exists(self._src_lib) assert os.path.exists(self._src_lib)
os.makedirs(self._dst_lib, exist_ok=True) os.makedirs(self._dst_lib, exist_ok=True)
self._copy_file("zstd.h") self._copy_file("zstd.h")
self._copy_file("zstd_errors.h")
for subdir in INCLUDED_SUBDIRS: for subdir in INCLUDED_SUBDIRS:
src_dir = os.path.join(self._src_lib, subdir) src_dir = os.path.join(self._src_lib, subdir)
dst_dir = os.path.join(self._dst_lib, subdir) dst_dir = os.path.join(self._dst_lib, subdir)
+6 -5
View File
@@ -23,7 +23,7 @@ libzstd:
--rewrite-include '<limits\.h>=<linux/limits.h>' \ --rewrite-include '<limits\.h>=<linux/limits.h>' \
--rewrite-include '<stddef\.h>=<linux/types.h>' \ --rewrite-include '<stddef\.h>=<linux/types.h>' \
--rewrite-include '"\.\./zstd.h"=<linux/zstd.h>' \ --rewrite-include '"\.\./zstd.h"=<linux/zstd.h>' \
--rewrite-include '"(\.\./)?zstd_errors.h"=<linux/zstd_errors.h>' \ --rewrite-include '"(\.\./common/)?zstd_errors.h"=<linux/zstd_errors.h>' \
--sed 's,/\*\*\*,/* *,g' \ --sed 's,/\*\*\*,/* *,g' \
--sed 's,/\*\*,/*,g' \ --sed 's,/\*\*,/*,g' \
-DZSTD_NO_INTRINSICS \ -DZSTD_NO_INTRINSICS \
@@ -39,7 +39,6 @@ libzstd:
-DZSTD_ADDRESS_SANITIZER=0 \ -DZSTD_ADDRESS_SANITIZER=0 \
-DZSTD_MEMORY_SANITIZER=0 \ -DZSTD_MEMORY_SANITIZER=0 \
-DZSTD_COMPRESS_HEAPMODE=1 \ -DZSTD_COMPRESS_HEAPMODE=1 \
-UZSTD_NO_INLINE \
-UNO_PREFETCH \ -UNO_PREFETCH \
-U__cplusplus \ -U__cplusplus \
-UZSTD_DLL_EXPORT \ -UZSTD_DLL_EXPORT \
@@ -50,11 +49,13 @@ libzstd:
-U_WIN32 \ -U_WIN32 \
-RZSTDLIB_VISIBILITY= \ -RZSTDLIB_VISIBILITY= \
-RZSTDERRORLIB_VISIBILITY= \ -RZSTDERRORLIB_VISIBILITY= \
-RZSTD_FALLTHROUGH=fallthrough \
-DZSTD_HAVE_WEAK_SYMBOLS=0 \ -DZSTD_HAVE_WEAK_SYMBOLS=0 \
-DZSTD_TRACE=0 \ -DZSTD_TRACE=0 \
-DZSTD_NO_TRACE -DZSTD_NO_TRACE \
-DZSTD_LINUX_KERNEL
mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h
mv linux/lib/zstd/zstd_errors.h linux/include/linux/ mv linux/lib/zstd/common/zstd_errors.h linux/include/linux/
cp linux_zstd.h linux/include/linux/zstd.h cp linux_zstd.h linux/include/linux/zstd.h
cp zstd_compress_module.c linux/lib/zstd cp zstd_compress_module.c linux/lib/zstd
cp zstd_decompress_module.c linux/lib/zstd cp zstd_decompress_module.c linux/lib/zstd
@@ -80,7 +81,7 @@ import-upstream:
cp -r ../../lib/common $(LINUX)/lib/zstd cp -r ../../lib/common $(LINUX)/lib/zstd
cp -r ../../lib/compress $(LINUX)/lib/zstd cp -r ../../lib/compress $(LINUX)/lib/zstd
cp -r ../../lib/decompress $(LINUX)/lib/zstd cp -r ../../lib/decompress $(LINUX)/lib/zstd
mv $(LINUX)/lib/zstd/zstd_errors.h $(LINUX)/include/linux mv $(LINUX)/lib/zstd/common/zstd_errors.h $(LINUX)/include/linux
rm $(LINUX)/lib/zstd/common/threading.* rm $(LINUX)/lib/zstd/common/threading.*
rm $(LINUX)/lib/zstd/common/pool.* rm $(LINUX)/lib/zstd/common/pool.*
rm $(LINUX)/lib/zstd/common/xxhash.* rm $(LINUX)/lib/zstd/common/xxhash.*
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Facebook, Inc.
* All rights reserved. * All rights reserved.
+1 -3
View File
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
# ################################################################ # ################################################################
# Copyright (c) Facebook, Inc. # Copyright (c) Facebook, Inc.
# All rights reserved. # All rights reserved.
@@ -11,8 +11,6 @@
obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
ccflags-y += -O3
zstd_compress-y := \ zstd_compress-y := \
zstd_compress_module.o \ zstd_compress_module.o \
common/debug.o \ common/debug.o \
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Yann Collet, Facebook, Inc. * Copyright (c) Yann Collet, Facebook, Inc.
* All rights reserved. * All rights reserved.
+1 -1
View File
@@ -11,7 +11,7 @@
LINUX := ../linux LINUX := ../linux
LINUX_ZSTDLIB := $(LINUX)/lib/zstd LINUX_ZSTDLIB := $(LINUX)/lib/zstd
CPPFLAGS += -I$(LINUX)/include -I$(LINUX_ZSTDLIB) -Iinclude -DNDEBUG -Wno-deprecated-declarations CPPFLAGS += -I$(LINUX)/include -I$(LINUX_ZSTDLIB) -Iinclude -DNDEBUG
# Don't poison the workspace, it currently doesn't work with static allocation and workspace reuse # Don't poison the workspace, it currently doesn't work with static allocation and workspace reuse
CPPFLAGS += -DZSTD_ASAN_DONT_POISON_WORKSPACE CPPFLAGS += -DZSTD_ASAN_DONT_POISON_WORKSPACE
@@ -18,4 +18,8 @@
#define noinline __attribute__((noinline)) #define noinline __attribute__((noinline))
#endif #endif
#ifndef fallthrough
#define fallthrough __attribute__((__fallthrough__))
#endif
#endif #endif
-1
View File
@@ -36,7 +36,6 @@ test_not_present "ZSTD_NO_INTRINSICS"
test_not_present "ZSTD_NO_UNUSED_FUNCTIONS" test_not_present "ZSTD_NO_UNUSED_FUNCTIONS"
test_not_present "ZSTD_LEGACY_SUPPORT" test_not_present "ZSTD_LEGACY_SUPPORT"
test_not_present "STATIC_BMI2" test_not_present "STATIC_BMI2"
test_not_present "ZSTD_NO_INLINE"
test_not_present "ZSTD_DLL_EXPORT" test_not_present "ZSTD_DLL_EXPORT"
test_not_present "ZSTD_DLL_IMPORT" test_not_present "ZSTD_DLL_IMPORT"
test_not_present "__ICCARM__" test_not_present "__ICCARM__"
+41 -5
View File
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Facebook, Inc.
* All rights reserved. * All rights reserved.
@@ -17,6 +17,43 @@
#include "common/zstd_deps.h" #include "common/zstd_deps.h"
#include "common/zstd_internal.h" #include "common/zstd_internal.h"
#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) int zstd_min_clevel(void)
{ {
return ZSTD_minCLevel(); return ZSTD_minCLevel();
@@ -59,7 +96,8 @@ EXPORT_SYMBOL(zstd_init_cctx);
size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity,
const void *src, size_t src_size, const zstd_parameters *parameters) const void *src, size_t src_size, const zstd_parameters *parameters)
{ {
return ZSTD_compress_advanced(cctx, dst, dst_capacity, src, src_size, NULL, 0, *parameters); 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); EXPORT_SYMBOL(zstd_compress_cctx);
@@ -73,7 +111,6 @@ zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters,
unsigned long long pledged_src_size, void *workspace, size_t workspace_size) unsigned long long pledged_src_size, void *workspace, size_t workspace_size)
{ {
zstd_cstream *cstream; zstd_cstream *cstream;
size_t ret;
if (workspace == NULL) if (workspace == NULL)
return NULL; return NULL;
@@ -86,8 +123,7 @@ zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters,
if (pledged_src_size == 0) if (pledged_src_size == 0)
pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN;
ret = ZSTD_initCStream_advanced(cstream, NULL, 0, *parameters, pledged_src_size); if (ZSTD_isError(zstd_cctx_init(cstream, parameters, pledged_src_size)))
if (ZSTD_isError(ret))
return NULL; return NULL;
return cstream; return cstream;
@@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Facebook, Inc.
* All rights reserved. * All rights reserved.
+1 -1
View File
@@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
/* /*
* Copyright (c) Facebook, Inc. * Copyright (c) Facebook, Inc.
* All rights reserved. * All rights reserved.
-3
View File
@@ -30,9 +30,6 @@ CXXFLAGS ?= -O3 -Wall -Wextra -pedantic
CPPFLAGS ?= CPPFLAGS ?=
LDFLAGS ?= LDFLAGS ?=
# PZstd uses legacy APIs
CFLAGS += -Wno-deprecated-declarations
# Include flags # Include flags
PZSTD_INC = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I. PZSTD_INC = -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(PROGDIR) -I.
GTEST_INC = -isystem googletest/googletest/include GTEST_INC = -isystem googletest/googletest/include
-3
View File
@@ -9,9 +9,6 @@
#pragma once #pragma once
#define ZSTD_STATIC_LINKING_ONLY #define ZSTD_STATIC_LINKING_ONLY
#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, pzstd itself is deprecated
* and uses deprecated functions
*/
#include "zstd.h" #include "zstd.h"
#undef ZSTD_STATIC_LINKING_ONLY #undef ZSTD_STATIC_LINKING_ONLY
-3
View File
@@ -17,9 +17,6 @@
#include "utils/ThreadPool.h" #include "utils/ThreadPool.h"
#include "utils/WorkQueue.h" #include "utils/WorkQueue.h"
#define ZSTD_STATIC_LINKING_ONLY #define ZSTD_STATIC_LINKING_ONLY
#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, pzstd itself is deprecated
* and uses deprecated functions
*/
#include "zstd.h" #include "zstd.h"
#undef ZSTD_STATIC_LINKING_ONLY #undef ZSTD_STATIC_LINKING_ONLY
+1 -1
View File
@@ -13,7 +13,7 @@ ZSTDLIB_PATH = ../../../lib
ZSTDLIB_NAME = libzstd.a ZSTDLIB_NAME = libzstd.a
ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME) ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME)
CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I../../../lib -I../../../lib/common CPPFLAGS += -I../ -I../../../lib -I../../../lib/common
CFLAGS ?= -O3 CFLAGS ?= -O3
CFLAGS += -g CFLAGS += -g
@@ -21,6 +21,7 @@
# define SLEEP(x) usleep(x * 1000) # define SLEEP(x) usleep(x * 1000)
#endif #endif
#define XXH_NAMESPACE ZSTD_
#include "xxhash.h" #include "xxhash.h"
#include "pool.h" // use zstd thread pool for demo #include "pool.h" // use zstd thread pool for demo
@@ -99,9 +99,6 @@ static void decompressFile_orDie(const char* fname, off_t startOffset, off_t end
while (startOffset < endOffset) { while (startOffset < endOffset) {
size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset); size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset);
if (!result) {
break;
}
if (ZSTD_isError(result)) { if (ZSTD_isError(result)) {
fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n", fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n",
@@ -104,9 +104,6 @@ static void decompressFile_orDie(const char* fname, off_t startOffset, off_t end
while (startOffset < endOffset) { while (startOffset < endOffset) {
size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset); size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset);
if (!result) {
break;
}
if (ZSTD_isError(result)) { if (ZSTD_isError(result)) {
fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n", fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n",
+1 -1
View File
@@ -13,7 +13,7 @@ ZSTDLIB_PATH = ../../../lib
ZSTDLIB_NAME = libzstd.a ZSTDLIB_NAME = libzstd.a
ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME) ZSTDLIB = $(ZSTDLIB_PATH)/$(ZSTDLIB_NAME)
CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -I../ -I$(ZSTDLIB_PATH) -I$(ZSTDLIB_PATH)/common CPPFLAGS += -I../ -I$(ZSTDLIB_PATH) -I$(ZSTDLIB_PATH)/common
CFLAGS ?= -O3 CFLAGS ?= -O3
CFLAGS += -g -Wall -Wextra -Wcast-qual -Wcast-align -Wconversion \ CFLAGS += -g -Wall -Wextra -Wcast-qual -Wcast-align -Wconversion \
+4 -3
View File
@@ -12,6 +12,7 @@
#include <assert.h> #include <assert.h>
#define XXH_STATIC_LINKING_ONLY #define XXH_STATIC_LINKING_ONLY
#define XXH_NAMESPACE ZSTD_
#include "xxhash.h" #include "xxhash.h"
#define ZSTD_STATIC_LINKING_ONLY #define ZSTD_STATIC_LINKING_ONLY
@@ -82,7 +83,7 @@ static size_t ZSTD_seekable_frameLog_freeVec(ZSTD_frameLog* fl)
ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag) ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag)
{ {
ZSTD_frameLog* const fl = (ZSTD_frameLog*)malloc(sizeof(ZSTD_frameLog)); ZSTD_frameLog* const fl = malloc(sizeof(ZSTD_frameLog));
if (fl == NULL) return NULL; if (fl == NULL) return NULL;
if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(fl))) { if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(fl))) {
@@ -107,7 +108,7 @@ size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl)
ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void) ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void)
{ {
ZSTD_seekable_CStream* const zcs = (ZSTD_seekable_CStream*)malloc(sizeof(ZSTD_seekable_CStream)); ZSTD_seekable_CStream* const zcs = malloc(sizeof(ZSTD_seekable_CStream));
if (zcs == NULL) return NULL; if (zcs == NULL) return NULL;
memset(zcs, 0, sizeof(*zcs)); memset(zcs, 0, sizeof(*zcs));
@@ -176,7 +177,7 @@ size_t ZSTD_seekable_logFrame(ZSTD_frameLog* fl,
if (fl->size == fl->capacity) { if (fl->size == fl->capacity) {
/* exponential size increase for constant amortized runtime */ /* exponential size increase for constant amortized runtime */
size_t const newCapacity = fl->capacity * 2; size_t const newCapacity = fl->capacity * 2;
framelogEntry_t* const newEntries = (framelogEntry_t*)realloc(fl->entries, framelogEntry_t* const newEntries = realloc(fl->entries,
sizeof(framelogEntry_t) * newCapacity); sizeof(framelogEntry_t) * newCapacity);
if (newEntries == NULL) return ERROR(memory_allocation); if (newEntries == NULL) return ERROR(memory_allocation);
+4 -10
View File
@@ -60,6 +60,7 @@
#include <assert.h> #include <assert.h>
#define XXH_STATIC_LINKING_ONLY #define XXH_STATIC_LINKING_ONLY
#define XXH_NAMESPACE ZSTD_
#include "xxhash.h" #include "xxhash.h"
#define ZSTD_STATIC_LINKING_ONLY #define ZSTD_STATIC_LINKING_ONLY
@@ -175,7 +176,7 @@ struct ZSTD_seekable_s {
ZSTD_seekable* ZSTD_seekable_create(void) ZSTD_seekable* ZSTD_seekable_create(void)
{ {
ZSTD_seekable* const zs = (ZSTD_seekable*)malloc(sizeof(ZSTD_seekable)); ZSTD_seekable* const zs = malloc(sizeof(ZSTD_seekable));
if (zs == NULL) return NULL; if (zs == NULL) return NULL;
/* also initializes stage to zsds_init */ /* also initializes stage to zsds_init */
@@ -201,7 +202,7 @@ size_t ZSTD_seekable_free(ZSTD_seekable* zs)
ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs) ZSTD_seekTable* ZSTD_seekTable_create_fromSeekable(const ZSTD_seekable* zs)
{ {
ZSTD_seekTable* const st = (ZSTD_seekTable*)malloc(sizeof(ZSTD_seekTable)); ZSTD_seekTable* const st = malloc(sizeof(ZSTD_seekTable));
if (st==NULL) return NULL; if (st==NULL) return NULL;
st->checksumFlag = zs->seekTable.checksumFlag; st->checksumFlag = zs->seekTable.checksumFlag;
@@ -432,11 +433,6 @@ size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile sr
size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsigned long long offset) size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsigned long long offset)
{ {
unsigned long long const eos = zs->seekTable.entries[zs->seekTable.tableLen].dOffset;
if (offset + len > eos) {
len = eos - offset;
}
U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset); U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset);
U32 noOutputProgressCount = 0; U32 noOutputProgressCount = 0;
size_t srcBytesRead = 0; size_t srcBytesRead = 0;
@@ -453,7 +449,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0}; zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0};
XXH64_reset(&zs->xxhState, 0); XXH64_reset(&zs->xxhState, 0);
ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only); ZSTD_DCtx_reset(zs->dstream, ZSTD_reset_session_only);
if (zs->buffWrapper.size && srcBytesRead > zs->buffWrapper.size) { if (srcBytesRead > zs->buffWrapper.size) {
return ERROR(seekableIO); return ERROR(seekableIO);
} }
} }
@@ -506,8 +502,6 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, unsign
if (zs->decompressedOffset < offset + len) { if (zs->decompressedOffset < offset + len) {
/* go back to the start and force a reset of the stream */ /* go back to the start and force a reset of the stream */
targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, zs->decompressedOffset); targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, zs->decompressedOffset);
/* in this case it will fail later with corruption_detected, since last block does not have checksum */
assert(targetFrame != zs->seekTable.tableLen);
} }
break; break;
} }
@@ -11,7 +11,7 @@ This is the most common use case. The decompression library is small, adding, fo
Create `zstddeclib.c` from the Zstd source using: Create `zstddeclib.c` from the Zstd source using:
``` ```
cd zstd/build/single_file_libs cd zstd/contrib/single_file_libs
./combine.sh -r ../../lib -o zstddeclib.c zstddeclib-in.c ./combine.sh -r ../../lib -o zstddeclib.c zstddeclib-in.c
``` ```
Then add the resulting file to your project (see the [example files](examples)). Then add the resulting file to your project (see the [example files](examples)).
@@ -25,7 +25,7 @@ The same tool can amalgamate the entire Zstd library for ease of adding both com
Create `zstd.c` from the Zstd source using: Create `zstd.c` from the Zstd source using:
``` ```
cd zstd/build/single_file_libs cd zstd/contrib/single_file_libs
./combine.sh -r ../../lib -o zstd.c zstd-in.c ./combine.sh -r ../../lib -o zstd.c zstd-in.c
``` ```
It's possible to create a compressor-only library but since the decompressor is so small in comparison this doesn't bring much of a gain (but for the curious, simply remove the files in the _decompress_ section at the end of `zstd-in.c`). It's possible to create a compressor-only library but since the decompressor is so small in comparison this doesn't bring much of a gain (but for the curious, simply remove the files in the _decompress_ section at the end of `zstd-in.c`).

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

+60 -81
View File
@@ -1,10 +1,10 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>zstd 1.5.0 Manual</title> <title>zstd 1.4.9 Manual</title>
</head> </head>
<body> <body>
<h1>zstd 1.5.0 Manual</h1> <h1>zstd 1.4.9 Manual</h1>
<hr> <hr>
<a name="Contents"></a><h2>Contents</h2> <a name="Contents"></a><h2>Contents</h2>
<ol> <ol>
@@ -12,15 +12,15 @@
<li><a href="#Chapter2">Version</a></li> <li><a href="#Chapter2">Version</a></li>
<li><a href="#Chapter3">Simple API</a></li> <li><a href="#Chapter3">Simple API</a></li>
<li><a href="#Chapter4">Explicit context</a></li> <li><a href="#Chapter4">Explicit context</a></li>
<li><a href="#Chapter5">Advanced compression API (Requires v1.4.0+)</a></li> <li><a href="#Chapter5">Advanced compression API</a></li>
<li><a href="#Chapter6">Advanced decompression API (Requires v1.4.0+)</a></li> <li><a href="#Chapter6">Advanced decompression API</a></li>
<li><a href="#Chapter7">Streaming</a></li> <li><a href="#Chapter7">Streaming</a></li>
<li><a href="#Chapter8">Streaming compression - HowTo</a></li> <li><a href="#Chapter8">Streaming compression - HowTo</a></li>
<li><a href="#Chapter9">Streaming decompression - HowTo</a></li> <li><a href="#Chapter9">Streaming decompression - HowTo</a></li>
<li><a href="#Chapter10">Simple dictionary API</a></li> <li><a href="#Chapter10">Simple dictionary API</a></li>
<li><a href="#Chapter11">Bulk processing dictionary API</a></li> <li><a href="#Chapter11">Bulk processing dictionary API</a></li>
<li><a href="#Chapter12">Dictionary helper functions</a></li> <li><a href="#Chapter12">Dictionary helper functions</a></li>
<li><a href="#Chapter13">Advanced dictionary and prefix API (Requires v1.4.0+)</a></li> <li><a href="#Chapter13">Advanced dictionary and prefix API</a></li>
<li><a href="#Chapter14">experimental API (static linking only)</a></li> <li><a href="#Chapter14">experimental API (static linking only)</a></li>
<li><a href="#Chapter15">Frame size functions</a></li> <li><a href="#Chapter15">Frame size functions</a></li>
<li><a href="#Chapter16">Memory management</a></li> <li><a href="#Chapter16">Memory management</a></li>
@@ -141,9 +141,8 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
size_t ZSTD_compressBound(size_t srcSize); </b>/*!< maximum compressed size in worst case single-pass scenario */<b> size_t ZSTD_compressBound(size_t srcSize); </b>/*!< maximum compressed size in worst case single-pass scenario */<b>
unsigned ZSTD_isError(size_t code); </b>/*!< tells if a `size_t` function result is an error code */<b> unsigned ZSTD_isError(size_t code); </b>/*!< tells if a `size_t` function result is an error code */<b>
const char* ZSTD_getErrorName(size_t code); </b>/*!< provides readable string from an error code */<b> const char* ZSTD_getErrorName(size_t code); </b>/*!< provides readable string from an error code */<b>
int ZSTD_minCLevel(void); </b>/*!< minimum negative compression level allowed, requires v1.4.0+ */<b> int ZSTD_minCLevel(void); </b>/*!< minimum negative compression level allowed */<b>
int ZSTD_maxCLevel(void); </b>/*!< maximum compression level available */<b> int ZSTD_maxCLevel(void); </b>/*!< maximum compression level available */<b>
int ZSTD_defaultCLevel(void); </b>/*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */<b>
</pre></b><BR> </pre></b><BR>
<a name="Chapter4"></a><h2>Explicit context</h2><pre></pre> <a name="Chapter4"></a><h2>Explicit context</h2><pre></pre>
@@ -158,7 +157,7 @@ int ZSTD_defaultCLevel(void); </b>/*!< default compression lev
</pre><b><pre>typedef struct ZSTD_CCtx_s ZSTD_CCtx; </pre><b><pre>typedef struct ZSTD_CCtx_s ZSTD_CCtx;
ZSTD_CCtx* ZSTD_createCCtx(void); ZSTD_CCtx* ZSTD_createCCtx(void);
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); </b>/* accept NULL pointer */<b> size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
</pre></b><BR> </pre></b><BR>
<pre><b>size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, <pre><b>size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
@@ -180,7 +179,7 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); </b>/* accept NULL pointer */<b>
Use one context per thread for parallel execution. Use one context per thread for parallel execution.
</pre><b><pre>typedef struct ZSTD_DCtx_s ZSTD_DCtx; </pre><b><pre>typedef struct ZSTD_DCtx_s ZSTD_DCtx;
ZSTD_DCtx* ZSTD_createDCtx(void); ZSTD_DCtx* ZSTD_createDCtx(void);
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b> size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
</pre></b><BR> </pre></b><BR>
<pre><b>size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, <pre><b>size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
@@ -191,7 +190,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
</p></pre><BR> </p></pre><BR>
<a name="Chapter5"></a><h2>Advanced compression API (Requires v1.4.0+)</h2><pre></pre> <a name="Chapter5"></a><h2>Advanced compression API</h2><pre></pre>
<pre><b>typedef enum { ZSTD_fast=1, <pre><b>typedef enum { ZSTD_fast=1,
ZSTD_dfast=2, ZSTD_dfast=2,
@@ -271,6 +270,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
* The higher the value of selected strategy, the more complex it is, * The higher the value of selected strategy, the more complex it is,
* resulting in stronger and slower compression. * resulting in stronger and slower compression.
* Special: value 0 means "use default strategy". */ * Special: value 0 means "use default strategy". */
</b>/* LDM mode parameters */<b> </b>/* LDM mode parameters */<b>
ZSTD_c_enableLongDistanceMatching=160, </b>/* Enable long distance matching.<b> ZSTD_c_enableLongDistanceMatching=160, </b>/* Enable long distance matching.<b>
* This parameter is designed to improve compression ratio * This parameter is designed to improve compression ratio
@@ -327,7 +327,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
ZSTD_c_jobSize=401, </b>/* Size of a compression job. This value is enforced only when nbWorkers >= 1.<b> ZSTD_c_jobSize=401, </b>/* Size of a compression job. This value is enforced only when nbWorkers >= 1.<b>
* Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads. * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads.
* 0 means default, which is dynamically determined based on compression parameters. * 0 means default, which is dynamically determined based on compression parameters.
* Job size must be a minimum of overlap size, or ZSTDMT_JOBSIZE_MIN (= 512 KB), whichever is largest. * Job size must be a minimum of overlap size, or 1 MB, whichever is largest.
* The minimum size is automatically and transparently enforced. */ * The minimum size is automatically and transparently enforced. */
ZSTD_c_overlapLog=402, </b>/* Control the overlap size, as a fraction of window size.<b> ZSTD_c_overlapLog=402, </b>/* Control the overlap size, as a fraction of window size.<b>
* The overlap size is an amount of data reloaded from previous job at the beginning of a new job. * The overlap size is an amount of data reloaded from previous job at the beginning of a new job.
@@ -357,8 +357,6 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
* ZSTD_c_stableOutBuffer * ZSTD_c_stableOutBuffer
* ZSTD_c_blockDelimiters * ZSTD_c_blockDelimiters
* ZSTD_c_validateSequences * ZSTD_c_validateSequences
* ZSTD_c_splitBlocks
* ZSTD_c_useRowMatchFinder
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly; * note : never ever use experimentalParam? names directly;
* also, the enums values themselves are unstable and can still change. * also, the enums values themselves are unstable and can still change.
@@ -374,10 +372,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
ZSTD_c_experimentalParam9=1006, ZSTD_c_experimentalParam9=1006,
ZSTD_c_experimentalParam10=1007, ZSTD_c_experimentalParam10=1007,
ZSTD_c_experimentalParam11=1008, ZSTD_c_experimentalParam11=1008,
ZSTD_c_experimentalParam12=1009, ZSTD_c_experimentalParam12=1009
ZSTD_c_experimentalParam13=1010,
ZSTD_c_experimentalParam14=1011,
ZSTD_c_experimentalParam15=1012
} ZSTD_cParameter; } ZSTD_cParameter;
</b></pre><BR> </b></pre><BR>
<pre><b>typedef struct { <pre><b>typedef struct {
@@ -461,7 +456,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
</p></pre><BR> </p></pre><BR>
<a name="Chapter6"></a><h2>Advanced decompression API (Requires v1.4.0+)</h2><pre></pre> <a name="Chapter6"></a><h2>Advanced decompression API</h2><pre></pre>
<pre><b>typedef enum { <pre><b>typedef enum {
@@ -592,7 +587,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); </b>/* accept NULL pointer */<b>
<pre><b>typedef ZSTD_CCtx ZSTD_CStream; </b>/**< CCtx and CStream are now effectively same object (>= v1.3.0) */<b> <pre><b>typedef ZSTD_CCtx ZSTD_CStream; </b>/**< CCtx and CStream are now effectively same object (>= v1.3.0) */<b>
</b></pre><BR> </b></pre><BR>
<h3>ZSTD_CStream management functions</h3><pre></pre><b><pre>ZSTD_CStream* ZSTD_createCStream(void); <h3>ZSTD_CStream management functions</h3><pre></pre><b><pre>ZSTD_CStream* ZSTD_createCStream(void);
size_t ZSTD_freeCStream(ZSTD_CStream* zcs); </b>/* accept NULL pointer */<b> size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
</pre></b><BR> </pre></b><BR>
<h3>Streaming compression functions</h3><pre></pre><b><pre>typedef enum { <h3>Streaming compression functions</h3><pre></pre><b><pre>typedef enum {
ZSTD_e_continue=0, </b>/* collect more data, encoder decides when to output compressed result, for optimal compression ratio */<b> ZSTD_e_continue=0, </b>/* collect more data, encoder decides when to output compressed result, for optimal compression ratio */<b>
@@ -686,7 +681,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
<pre><b>typedef ZSTD_DCtx ZSTD_DStream; </b>/**< DCtx and DStream are now effectively same object (>= v1.3.0) */<b> <pre><b>typedef ZSTD_DCtx ZSTD_DStream; </b>/**< DCtx and DStream are now effectively same object (>= v1.3.0) */<b>
</b></pre><BR> </b></pre><BR>
<h3>ZSTD_DStream management functions</h3><pre></pre><b><pre>ZSTD_DStream* ZSTD_createDStream(void); <h3>ZSTD_DStream management functions</h3><pre></pre><b><pre>ZSTD_DStream* ZSTD_createDStream(void);
size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b> size_t ZSTD_freeDStream(ZSTD_DStream* zds);
</pre></b><BR> </pre></b><BR>
<h3>Streaming decompression functions</h3><pre></pre><b><pre></pre></b><BR> <h3>Streaming decompression functions</h3><pre></pre><b><pre></pre></b><BR>
<pre><b>size_t ZSTD_DStreamInSize(void); </b>/*!< recommended size for input buffer */<b> <pre><b>size_t ZSTD_DStreamInSize(void); </b>/*!< recommended size for input buffer */<b>
@@ -702,7 +697,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b>
int compressionLevel); int compressionLevel);
</b><p> Compression at an explicit compression level using a Dictionary. </b><p> Compression at an explicit compression level using a Dictionary.
A dictionary can be any arbitrary data segment (also called a prefix), A dictionary can be any arbitrary data segment (also called a prefix),
or a buffer with specified information (see zdict.h). or a buffer with specified information (see dictBuilder/zdict.h).
Note : This function loads the dictionary, resulting in significant startup delay. Note : This function loads the dictionary, resulting in significant startup delay.
It's intended for a dictionary used only once. It's intended for a dictionary used only once.
Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used.
@@ -737,8 +732,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b>
</p></pre><BR> </p></pre><BR>
<pre><b>size_t ZSTD_freeCDict(ZSTD_CDict* CDict); <pre><b>size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
</b><p> Function frees memory allocated by ZSTD_createCDict(). </b><p> Function frees memory allocated by ZSTD_createCDict().
If a NULL pointer is passed, no operation is performed.
</p></pre><BR> </p></pre><BR>
<pre><b>size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, <pre><b>size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
@@ -757,8 +751,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b>
</p></pre><BR> </p></pre><BR>
<pre><b>size_t ZSTD_freeDDict(ZSTD_DDict* ddict); <pre><b>size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
</b><p> Function frees memory allocated with ZSTD_createDDict() </b><p> Function frees memory allocated with ZSTD_createDDict()
If a NULL pointer is passed, no operation is performed.
</p></pre><BR> </p></pre><BR>
<pre><b>size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, <pre><b>size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
@@ -777,12 +770,6 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b>
It can still be loaded, but as a content-only dictionary. It can still be loaded, but as a content-only dictionary.
</p></pre><BR> </p></pre><BR>
<pre><b>unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
</b><p> Provides the dictID of the dictionary loaded into `cdict`.
If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
Non-conformant dictionaries can still be loaded, but as content-only dictionaries.
</p></pre><BR>
<pre><b>unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); <pre><b>unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
</b><p> Provides the dictID of the dictionary loaded into `ddict`. </b><p> Provides the dictID of the dictionary loaded into `ddict`.
If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
@@ -801,7 +788,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); </b>/* accept NULL pointer */<b>
When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code.
</p></pre><BR> </p></pre><BR>
<a name="Chapter13"></a><h2>Advanced dictionary and prefix API (Requires v1.4.0+)</h2><pre> <a name="Chapter13"></a><h2>Advanced dictionary and prefix API</h2><pre>
This API allows dictionaries to be used with ZSTD_compress2(), This API allows dictionaries to be used with ZSTD_compress2(),
ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and
only reset with the context is reset with ZSTD_reset_parameters or only reset with the context is reset with ZSTD_reset_parameters or
@@ -1071,12 +1058,6 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
ZSTD_lcm_uncompressed = 2 </b>/**< Always emit uncompressed literals. */<b> ZSTD_lcm_uncompressed = 2 </b>/**< Always emit uncompressed literals. */<b>
} ZSTD_literalCompressionMode_e; } ZSTD_literalCompressionMode_e;
</b></pre><BR> </b></pre><BR>
<pre><b>typedef enum {
ZSTD_urm_auto = 0, </b>/* Automatically determine whether or not we use row matchfinder */<b>
ZSTD_urm_disableRowMatchFinder = 1, </b>/* Never use row matchfinder */<b>
ZSTD_urm_enableRowMatchFinder = 2 </b>/* Always use row matchfinder when applicable */<b>
} ZSTD_useRowMatchFinderMode_e;
</b></pre><BR>
<a name="Chapter15"></a><h2>Frame size functions</h2><pre></pre> <a name="Chapter15"></a><h2>Frame size functions</h2><pre></pre>
<pre><b>unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); <pre><b>unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
@@ -1313,6 +1294,12 @@ ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; </b>/**< this con
note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef
</p></pre><BR> </p></pre><BR>
<pre><b>unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
</b><p> Provides the dictID of the dictionary loaded into `cdict`.
If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
Non-conformant dictionaries can still be loaded, but as content-only dictionaries.
</p></pre><BR>
<pre><b>ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); <pre><b>ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
</b><p> @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. </b><p> @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
`estimatedSrcSize` value is optional, select 0 if not known `estimatedSrcSize` value is optional, select 0 if not known
@@ -1336,26 +1323,24 @@ ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; </b>/**< this con
This function never fails (wide contract) This function never fails (wide contract)
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_compress2") <pre><b>size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const void* dict,size_t dictSize, const void* dict,size_t dictSize,
ZSTD_parameters params); ZSTD_parameters params);
</b><p> Note : this function is now DEPRECATED. </b><p> Note : this function is now DEPRECATED.
It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters.
This prototype will generate compilation warnings. This prototype will be marked as deprecated and generate compilation warning on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_compress2 with ZSTD_CCtx_loadDictionary") <pre><b>size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const ZSTD_CDict* cdict, const ZSTD_CDict* cdict,
ZSTD_frameParameters fParams); ZSTD_frameParameters fParams);
</b><p> Note : this function is now DEPRECATED. </b><p> Note : this function is now REDUNDANT.
It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters. It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters.
This prototype will generate compilation warnings. This prototype will be marked as deprecated and generate compilation warning in some future version
</p></pre><BR> </p></pre><BR>
<pre><b>size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); <pre><b>size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
@@ -1382,7 +1367,7 @@ size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_CCtx_params* ZSTD_createCCtxParams(void); <pre><b>ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); </b>/* accept NULL pointer */<b> size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
</b><p> Quick howto : </b><p> Quick howto :
- ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
- ZSTD_CCtxParams_setParameter() : Push parameters one by one into - ZSTD_CCtxParams_setParameter() : Push parameters one by one into
@@ -1394,7 +1379,7 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); </b>/* accept NULL pointe
These parameters will be applied to These parameters will be applied to
all subsequent frames. all subsequent frames.
- ZSTD_compressStream2() : Do compression using the CCtx. - ZSTD_compressStream2() : Do compression using the CCtx.
- ZSTD_freeCCtxParams() : Free the memory, accept NULL pointer. - ZSTD_freeCCtxParams() : Free the memory.
This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams()
for static allocation of CCtx for single-threaded compression. for static allocation of CCtx for single-threaded compression.
@@ -1508,10 +1493,8 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); </b>/* accept NULL pointe
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_DCtx_setParameter() instead") <pre><b>size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); </b><p> Instruct the decoder context about what kind of data to decode next.
</b><p> This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter().
Instruct the decoder context about what kind of data to decode next.
This instruction is mandatory to decode data without a fully-formed header, This instruction is mandatory to decode data without a fully-formed header,
such ZSTD_f_zstd1_magicless for example. such ZSTD_f_zstd1_magicless for example.
@return : 0, or an error code (which can be tested using ZSTD_isError()). @return : 0, or an error code (which can be tested using ZSTD_isError()).
@@ -1534,11 +1517,11 @@ size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
<BR></pre> <BR></pre>
<h3>Advanced Streaming compression functions</h3><pre></pre><b><pre></pre></b><BR> <h3>Advanced Streaming compression functions</h3><pre></pre><b><pre></pre></b><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") <pre><b>size_t
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
int compressionLevel, int compressionLevel,
unsigned long long pledgedSrcSize); unsigned long long pledgedSrcSize);
</b><p> This function is DEPRECATED, and equivalent to: </b><p> This function is deprecated, and equivalent to:
ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any) ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)
ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
@@ -1547,15 +1530,15 @@ size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
pledgedSrcSize must be correct. If it is not known at init time, use pledgedSrcSize must be correct. If it is not known at init time, use
ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs,
"0" also disables frame content size field. It may be enabled in the future. "0" also disables frame content size field. It may be enabled in the future.
This prototype will generate compilation warnings. Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") <pre><b>size_t
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
const void* dict, size_t dictSize, const void* dict, size_t dictSize,
int compressionLevel); int compressionLevel);
</b><p> This function is DEPRECATED, and is equivalent to: </b><p> This function is deprecated, and is equivalent to:
ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
ZSTD_CCtx_loadDictionary(zcs, dict, dictSize); ZSTD_CCtx_loadDictionary(zcs, dict, dictSize);
@@ -1564,16 +1547,16 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
dict == NULL or dictSize < 8, in which case no dict is used. dict == NULL or dictSize < 8, in which case no dict is used.
Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if
it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy. it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.
This prototype will generate compilation warnings. Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") <pre><b>size_t
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
const void* dict, size_t dictSize, const void* dict, size_t dictSize,
ZSTD_parameters params, ZSTD_parameters params,
unsigned long long pledgedSrcSize); unsigned long long pledgedSrcSize);
</b><p> This function is DEPRECATED, and is approximately equivalent to: </b><p> This function is deprecated, and is approximately equivalent to:
ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
// Pseudocode: Set each zstd parameter and leave the rest as-is. // Pseudocode: Set each zstd parameter and leave the rest as-is.
for ((param, value) : params) { for ((param, value) : params) {
@@ -1585,23 +1568,22 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy. dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy.
pledgedSrcSize must be correct. pledgedSrcSize must be correct.
If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
This prototype will generate compilation warnings. Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions") <pre><b>size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); </b><p> This function is deprecated, and equivalent to:
</b><p> This function is DEPRECATED, and equivalent to:
ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
ZSTD_CCtx_refCDict(zcs, cdict); ZSTD_CCtx_refCDict(zcs, cdict);
note : cdict will just be referenced, and must outlive compression session note : cdict will just be referenced, and must outlive compression session
This prototype will generate compilation warnings. Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions") <pre><b>size_t
size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
const ZSTD_CDict* cdict, const ZSTD_CDict* cdict,
ZSTD_frameParameters fParams, ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize); unsigned long long pledgedSrcSize);
@@ -1617,18 +1599,14 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
same as ZSTD_initCStream_usingCDict(), with control over frame parameters. same as ZSTD_initCStream_usingCDict(), with control over frame parameters.
pledgedSrcSize must be correct. If srcSize is not known at init time, use pledgedSrcSize must be correct. If srcSize is not known at init time, use
value ZSTD_CONTENTSIZE_UNKNOWN. value ZSTD_CONTENTSIZE_UNKNOWN.
This prototype will generate compilation warnings. Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
<pre><b>ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") <pre><b>size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); </b><p> This function is deprecated, and is equivalent to:
</b><p> This function is DEPRECATED, and is equivalent to:
ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);
Note: ZSTD_resetCStream() interprets pledgedSrcSize == 0 as ZSTD_CONTENTSIZE_UNKNOWN, but
ZSTD_CCtx_setPledgedSrcSize() does not do the same, so ZSTD_CONTENTSIZE_UNKNOWN must be
explicitly specified.
start a new frame, using same parameters from previous frame. start a new frame, using same parameters from previous frame.
This is typically useful to skip dictionary loading stage, since it will re-use it in-place. This is typically useful to skip dictionary loading stage, since it will re-use it in-place.
@@ -1638,7 +1616,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs, For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs,
but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead. but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead.
@return : 0, or an error code (which can be tested using ZSTD_isError()) @return : 0, or an error code (which can be tested using ZSTD_isError())
This prototype will generate compilation warnings. Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
</p></pre><BR> </p></pre><BR>
@@ -1709,7 +1687,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
ZSTD_CCtx object can be re-used multiple times within successive compression operations. ZSTD_CCtx object can be re-used multiple times within successive compression operations.
Start by initializing a context. Start by initializing a context.
Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression. Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
or ZSTD_compressBegin_advanced(), for finer parameter control.
It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx() It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
Then, consume your input using ZSTD_compressContinue(). Then, consume your input using ZSTD_compressContinue().
@@ -1733,11 +1712,11 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
<h3>Buffer-less streaming compression functions</h3><pre></pre><b><pre>size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); <h3>Buffer-less streaming compression functions</h3><pre></pre><b><pre>size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */<b>
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); </b>/**< note: fails if cdict==NULL */<b> size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); </b>/**< note: fails if cdict==NULL */<b>
size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); </b>/* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */<b>
size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); </b>/**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */<b> size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); </b>/**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */<b>
</pre></b><BR> </pre></b><BR>
<pre><b>size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */<b>
</b></pre><BR>
<a name="Chapter22"></a><h2>Buffer-less streaming decompression (synchronous mode)</h2><pre> <a name="Chapter22"></a><h2>Buffer-less streaming decompression (synchronous mode)</h2><pre>
A ZSTD_DCtx object is required to track streaming operations. A ZSTD_DCtx object is required to track streaming operations.
Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
+7 -5
View File
@@ -65,7 +65,9 @@ cxx_library(
name='zdict', name='zdict',
header_namespace='', header_namespace='',
visibility=['PUBLIC'], visibility=['PUBLIC'],
exported_headers=['zdict.h'], exported_headers=subdir_glob([
('dictBuilder', 'zdict.h'),
]),
headers=subdir_glob([ headers=subdir_glob([
('dictBuilder', 'divsufsort.h'), ('dictBuilder', 'divsufsort.h'),
('dictBuilder', 'cover.h'), ('dictBuilder', 'cover.h'),
@@ -129,10 +131,10 @@ cxx_library(
name='errors', name='errors',
header_namespace='', header_namespace='',
visibility=['PUBLIC'], visibility=['PUBLIC'],
exported_headers=[ exported_headers=subdir_glob([
'zstd_errors.h', ('common', 'error_private.h'),
'common/error_private.h', ('common', 'zstd_errors.h'),
] ]),
srcs=['common/error_private.c'], srcs=['common/error_private.c'],
) )
+12 -41
View File
@@ -8,9 +8,6 @@
# You may select, at your option, one of the above-listed licenses. # You may select, at your option, one of the above-listed licenses.
# ################################################################ # ################################################################
# Note: by default, the static library is built single-threaded and dynamic library is built
# multi-threaded. It is possible to force multi or single threaded builds by appending
# -mt or -nomt to the build target (like lib-mt for multi-threaded, lib-nomt for single-threaded).
.PHONY: default .PHONY: default
default: lib-release default: lib-release
@@ -71,10 +68,6 @@ DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
FLAGS = $(CPPFLAGS) $(CFLAGS) FLAGS = $(CPPFLAGS) $(CFLAGS)
CPPFLAGS_DYNLIB = -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded
LDFLAGS_DYNLIB = -pthread
CPPFLAGS_STATLIB = # static library build defaults to single-threaded
HAVE_COLORNEVER = $(shell echo a | grep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) HAVE_COLORNEVER = $(shell echo a | grep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0)
GREP_OPTIONS ?= GREP_OPTIONS ?=
ifeq ($HAVE_COLORNEVER, 1) ifeq ($HAVE_COLORNEVER, 1)
@@ -98,7 +91,7 @@ endif
ZSTD_LIB_COMPRESSION ?= 1 ZSTD_LIB_COMPRESSION ?= 1
ZSTD_LIB_DECOMPRESSION ?= 1 ZSTD_LIB_DECOMPRESSION ?= 1
ZSTD_LIB_DICTBUILDER ?= 1 ZSTD_LIB_DICTBUILDER ?= 1
ZSTD_LIB_DEPRECATED ?= 0 ZSTD_LIB_DEPRECATED ?= 1
# Legacy support # Legacy support
ZSTD_LEGACY_SUPPORT ?= 5 ZSTD_LEGACY_SUPPORT ?= 5
@@ -183,9 +176,7 @@ UNAME := $(shell uname)
ifndef BUILD_DIR ifndef BUILD_DIR
ifeq ($(UNAME), Darwin) ifeq ($(UNAME), Darwin)
ifeq ($(shell md5 < /dev/null > /dev/null; echo $$?), 0) HASH ?= md5
HASH ?= md5
endif
else ifeq ($(UNAME), FreeBSD) else ifeq ($(UNAME), FreeBSD)
HASH ?= gmd5sum HASH ?= gmd5sum
else ifeq ($(UNAME), NetBSD) else ifeq ($(UNAME), NetBSD)
@@ -231,7 +222,6 @@ all: lib
.PHONY: libzstd.a # must be run every time .PHONY: libzstd.a # must be run every time
libzstd.a: CPPFLAGS += $(CPPFLAGS_STATLIB)
ifndef BUILD_DIR ifndef BUILD_DIR
# determine BUILD_DIR from compilation flags # determine BUILD_DIR from compilation flags
@@ -248,10 +238,7 @@ ZSTD_STATLIB_OBJ := $(addprefix $(ZSTD_STATLIB_DIR)/,$(ZSTD_LOCAL_OBJ))
$(ZSTD_STATLIB): ARFLAGS = rcs $(ZSTD_STATLIB): ARFLAGS = rcs
$(ZSTD_STATLIB): | $(ZSTD_STATLIB_DIR) $(ZSTD_STATLIB): | $(ZSTD_STATLIB_DIR)
$(ZSTD_STATLIB): $(ZSTD_STATLIB_OBJ) $(ZSTD_STATLIB): $(ZSTD_STATLIB_OBJ)
# Check for multithread flag at target execution time @echo compiling static library
$(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\
@echo compiling multi-threaded static library $(LIBVER),\
@echo compiling single-threaded static library $(LIBVER))
$(AR) $(ARFLAGS) $@ $^ $(AR) $(ARFLAGS) $@ $^
libzstd.a: $(ZSTD_STATLIB) libzstd.a: $(ZSTD_STATLIB)
@@ -270,9 +257,8 @@ else # not Windows
LIBZSTD = libzstd.$(SHARED_EXT_VER) LIBZSTD = libzstd.$(SHARED_EXT_VER)
.PHONY: $(LIBZSTD) # must be run every time .PHONY: $(LIBZSTD) # must be run every time
$(LIBZSTD): CPPFLAGS += $(CPPFLAGS_DYNLIB) $(LIBZSTD): CFLAGS += -fPIC -fvisibility=hidden
$(LIBZSTD): CFLAGS += -fPIC -fvisibility=hidden $(LIBZSTD): LDFLAGS += -shared
$(LIBZSTD): LDFLAGS += -shared $(LDFLAGS_DYNLIB)
ifndef BUILD_DIR ifndef BUILD_DIR
# determine BUILD_DIR from compilation flags # determine BUILD_DIR from compilation flags
@@ -289,10 +275,7 @@ ZSTD_DYNLIB_OBJ := $(addprefix $(ZSTD_DYNLIB_DIR)/,$(ZSTD_LOCAL_OBJ))
$(ZSTD_DYNLIB): | $(ZSTD_DYNLIB_DIR) $(ZSTD_DYNLIB): | $(ZSTD_DYNLIB_DIR)
$(ZSTD_DYNLIB): $(ZSTD_DYNLIB_OBJ) $(ZSTD_DYNLIB): $(ZSTD_DYNLIB_OBJ)
# Check for multithread flag at target execution time @echo compiling dynamic library $(LIBVER)
$(if $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)),\
@echo compiling multi-threaded dynamic library $(LIBVER),\
@echo compiling single-threaded dynamic library $(LIBVER))
$(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@ $(CC) $(FLAGS) $^ $(LDFLAGS) $(SONAME_FLAGS) -o $@
@echo creating versioned links @echo creating versioned links
ln -sf $@ libzstd.$(SHARED_EXT_MAJOR) ln -sf $@ libzstd.$(SHARED_EXT_MAJOR)
@@ -314,17 +297,10 @@ lib : libzstd.a libzstd
# note : do not define lib-mt or lib-release as .PHONY # note : do not define lib-mt or lib-release as .PHONY
# make does not consider implicit pattern rule for .PHONY target # make does not consider implicit pattern rule for .PHONY target
%-mt : CPPFLAGS_DYNLIB := -DZSTD_MULTITHREAD %-mt : CPPFLAGS += -DZSTD_MULTITHREAD
%-mt : CPPFLAGS_STATLIB := -DZSTD_MULTITHREAD %-mt : LDFLAGS += -pthread
%-mt : LDFLAGS_DYNLIB := -pthread
%-mt : % %-mt : %
@echo multi-threaded build completed @echo multi-threading build completed
%-nomt : CPPFLAGS_DYNLIB :=
%-nomt : LDFLAGS_DYNLIB :=
%-nomt : CPPFLAGS_STATLIB :=
%-nomt : %
@echo single-threaded build completed
%-release : DEBUGFLAGS := %-release : DEBUGFLAGS :=
%-release : % %-release : %
@@ -356,8 +332,7 @@ include $(wildcard $(DEPFILES))
# Special case : building library in single-thread mode _and_ without zstdmt_compress.c # Special case : building library in single-thread mode _and_ without zstdmt_compress.c
ZSTDMT_FILES = compress/zstdmt_compress.c ZSTDMT_FILES = compress/zstdmt_compress.c
ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(ZSTD_FILES)) ZSTD_NOMT_FILES = $(filter-out $(ZSTDMT_FILES),$(ZSTD_FILES))
libzstd-nomt: CFLAGS += -fPIC -fvisibility=hidden libzstd-nomt: LDFLAGS += -shared -fPIC -fvisibility=hidden
libzstd-nomt: LDFLAGS += -shared
libzstd-nomt: $(ZSTD_NOMT_FILES) libzstd-nomt: $(ZSTD_NOMT_FILES)
@echo compiling single-thread dynamic library $(LIBVER) @echo compiling single-thread dynamic library $(LIBVER)
@echo files : $(ZSTD_NOMT_FILES) @echo files : $(ZSTD_NOMT_FILES)
@@ -436,12 +411,10 @@ libzstd.pc: libzstd.pc.in
install: install-pc install-static install-shared install-includes install: install-pc install-static install-shared install-includes
@echo zstd static and shared library installed @echo zstd static and shared library installed
.PHONY: install-pc
install-pc: libzstd.pc install-pc: libzstd.pc
[ -e $(DESTDIR)$(PKGCONFIGDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/ [ -e $(DESTDIR)$(PKGCONFIGDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/
$(INSTALL_DATA) libzstd.pc $(DESTDIR)$(PKGCONFIGDIR)/ $(INSTALL_DATA) libzstd.pc $(DESTDIR)$(PKGCONFIGDIR)/
.PHONY: install-static
install-static: install-static:
# only generate libzstd.a if it's not already present # only generate libzstd.a if it's not already present
[ -e libzstd.a ] || $(MAKE) libzstd.a-release [ -e libzstd.a ] || $(MAKE) libzstd.a-release
@@ -449,7 +422,6 @@ install-static:
@echo Installing static library @echo Installing static library
$(INSTALL_DATA) libzstd.a $(DESTDIR)$(LIBDIR) $(INSTALL_DATA) libzstd.a $(DESTDIR)$(LIBDIR)
.PHONY: install-shared
install-shared: install-shared:
# only generate libzstd.so if it's not already present # only generate libzstd.so if it's not already present
[ -e $(LIBZSTD) ] || $(MAKE) libzstd-release [ -e $(LIBZSTD) ] || $(MAKE) libzstd-release
@@ -459,13 +431,12 @@ install-shared:
ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR)
ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT) ln -sf $(LIBZSTD) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT)
.PHONY: install-includes
install-includes: install-includes:
[ -e $(DESTDIR)$(INCLUDEDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)/ [ -e $(DESTDIR)$(INCLUDEDIR) ] || $(INSTALL) -d -m 755 $(DESTDIR)$(INCLUDEDIR)/
@echo Installing includes @echo Installing includes
$(INSTALL_DATA) zstd.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) zstd.h $(DESTDIR)$(INCLUDEDIR)
$(INSTALL_DATA) zstd_errors.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) common/zstd_errors.h $(DESTDIR)$(INCLUDEDIR)
$(INSTALL_DATA) zdict.h $(DESTDIR)$(INCLUDEDIR) $(INSTALL_DATA) dictBuilder/zdict.h $(DESTDIR)$(INCLUDEDIR)
.PHONY: uninstall .PHONY: uninstall
uninstall: uninstall:
+4 -8
View File
@@ -19,16 +19,12 @@ The scope can be reduced on demand (see paragraph _modular build_).
#### Multithreading support #### Multithreading support
When building with `make`, by default the dynamic library is multithreaded and static library is single-threaded (for compatibility reasons). Multithreading is disabled by default when building with `make`.
Enabling multithreading requires 2 conditions : Enabling multithreading requires 2 conditions :
- set build macro `ZSTD_MULTITHREAD` (`-DZSTD_MULTITHREAD` for `gcc`) - set build macro `ZSTD_MULTITHREAD` (`-DZSTD_MULTITHREAD` for `gcc`)
- for POSIX systems : compile with pthread (`-pthread` compilation flag for `gcc`) - for POSIX systems : compile with pthread (`-pthread` compilation flag for `gcc`)
For convenience, we provide a build target to generate multi and single threaded libraries: Both conditions are automatically applied when invoking `make lib-mt` target.
- Force enable multithreading on both dynamic and static libraries by appending `-mt` to the target, e.g. `make lib-mt`.
- Force disable multithreading on both dynamic and static libraries by appending `-nomt` to the target, e.g. `make lib-nomt`.
- By default, as mentioned before, dynamic library is multithreaded, and static library is single-threaded, e.g. `make lib`.
When linking a POSIX program with a multithreaded version of `libzstd`, When linking a POSIX program with a multithreaded version of `libzstd`,
note that it's necessary to invoke the `-pthread` flag during link stage. note that it's necessary to invoke the `-pthread` flag during link stage.
@@ -46,8 +42,8 @@ Zstandard's stable API is exposed within [lib/zstd.h](zstd.h).
Optional advanced features are exposed via : Optional advanced features are exposed via :
- `lib/zstd_errors.h` : translates `size_t` function results - `lib/common/zstd_errors.h` : translates `size_t` function results
into a `ZSTD_ErrorCode`, for accurate error handling. into a `ZSTD_ErrorCode`, for accurate error handling.
- `ZSTD_STATIC_LINKING_ONLY` : if this macro is defined _before_ including `zstd.h`, - `ZSTD_STATIC_LINKING_ONLY` : if this macro is defined _before_ including `zstd.h`,
it unlocks access to the experimental API, it unlocks access to the experimental API,
+6 -6
View File
@@ -293,22 +293,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
switch(srcSize) switch(srcSize)
{ {
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); 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); 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); 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; 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; 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; case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
/* fall-through */ ZSTD_FALLTHROUGH;
default: break; default: break;
} }
+33
View File
@@ -207,6 +207,39 @@
# define __has_feature(x) 0 # define __has_feature(x) 0
#endif #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 */ /* detects whether we are being compiled under msan */
#ifndef ZSTD_MEMORY_SANITIZER #ifndef ZSTD_MEMORY_SANITIZER
# if __has_feature(memory_sanitizer) # if __has_feature(memory_sanitizer)
+2 -2
View File
@@ -21,8 +21,8 @@ extern "C" {
/* **************************************** /* ****************************************
* Dependencies * Dependencies
******************************************/ ******************************************/
#include "../zstd_errors.h" /* enum list */ #include "zstd_deps.h" /* size_t */
#include "zstd_deps.h" /* size_t */ #include "zstd_errors.h" /* enum list */
/* **************************************** /* ****************************************
+3 -1
View File
@@ -143,7 +143,9 @@ MEM_STATIC size_t MEM_swapST(size_t in);
* Prefer these methods in priority order (0 > 1 > 2) * Prefer these methods in priority order (0 > 1 > 2)
*/ */
#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
# define MEM_FORCE_MEMORY_ACCESS 2
# elif defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)
# define MEM_FORCE_MEMORY_ACCESS 1 # define MEM_FORCE_MEMORY_ACCESS 1
# endif # endif
#endif #endif
+3 -1
View File
@@ -30,7 +30,9 @@
* Prefer these methods in priority order (0 > 1 > 2) * Prefer these methods in priority order (0 > 1 > 2)
*/ */
#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
# if (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
# define XXH_FORCE_MEMORY_ACCESS 2
# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \
(defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) || \ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) || \
defined(__ICCARM__) defined(__ICCARM__)
# define XXH_FORCE_MEMORY_ACCESS 1 # define XXH_FORCE_MEMORY_ACCESS 1
+7 -14
View File
@@ -352,18 +352,11 @@ typedef enum {
* Private declarations * Private declarations
*********************************************/ *********************************************/
typedef struct seqDef_s { typedef struct seqDef_s {
U32 offset; /* offset == rawOffset + ZSTD_REP_NUM, or equivalently, offCode + 1 */ U32 offset; /* Offset code of the sequence */
U16 litLength; U16 litLength;
U16 matchLength; U16 matchLength;
} seqDef; } seqDef;
/* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */
typedef enum {
ZSTD_llt_none = 0, /* no longLengthType */
ZSTD_llt_literalLength = 1, /* represents a long literal */
ZSTD_llt_matchLength = 2 /* represents a long match */
} ZSTD_longLengthType_e;
typedef struct { typedef struct {
seqDef* sequencesStart; seqDef* sequencesStart;
seqDef* sequences; /* ptr to end of sequences */ seqDef* sequences; /* ptr to end of sequences */
@@ -375,12 +368,12 @@ typedef struct {
size_t maxNbSeq; size_t maxNbSeq;
size_t maxNbLit; size_t maxNbLit;
/* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength /* 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 * 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.
*/ */
ZSTD_longLengthType_e longLengthType; 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 */ U32 longLengthPos; /* Index of the sequence to apply long length modification to */
} seqStore_t; } seqStore_t;
typedef struct { typedef struct {
@@ -390,7 +383,7 @@ typedef struct {
/** /**
* Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
* indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength. * indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.
*/ */
MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq) MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
{ {
@@ -398,10 +391,10 @@ MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore
seqLen.litLength = seq->litLength; seqLen.litLength = seq->litLength;
seqLen.matchLength = seq->matchLength + MINMATCH; seqLen.matchLength = seq->matchLength + MINMATCH;
if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) { if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
if (seqStore->longLengthType == ZSTD_llt_literalLength) { if (seqStore->longLengthID == 1) {
seqLen.litLength += 0xFFFF; seqLen.litLength += 0xFFFF;
} }
if (seqStore->longLengthType == ZSTD_llt_matchLength) { if (seqStore->longLengthID == 2) {
seqLen.matchLength += 0xFFFF; seqLen.matchLength += 0xFFFF;
} }
} }
+42
View File
@@ -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
+4 -6
View File
@@ -114,15 +114,14 @@ typedef unsigned long long ZSTD_TraceCtx;
* @returns Non-zero if tracing is enabled. The return value is * @returns Non-zero if tracing is enabled. The return value is
* passed to ZSTD_trace_compress_end(). * passed to ZSTD_trace_compress_end().
*/ */
ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin( ZSTD_TraceCtx ZSTD_trace_compress_begin(struct ZSTD_CCtx_s const* cctx);
struct ZSTD_CCtx_s const* cctx);
/** /**
* Trace the end of a compression call. * Trace the end of a compression call.
* @param ctx The return value of ZSTD_trace_compress_begin(). * @param ctx The return value of ZSTD_trace_compress_begin().
* @param trace The zstd tracing info. * @param trace The zstd tracing info.
*/ */
ZSTD_WEAK_ATTR void ZSTD_trace_compress_end( void ZSTD_trace_compress_end(
ZSTD_TraceCtx ctx, ZSTD_TraceCtx ctx,
ZSTD_Trace const* trace); ZSTD_Trace const* trace);
@@ -133,15 +132,14 @@ ZSTD_WEAK_ATTR void ZSTD_trace_compress_end(
* @returns Non-zero if tracing is enabled. The return value is * @returns Non-zero if tracing is enabled. The return value is
* passed to ZSTD_trace_compress_end(). * passed to ZSTD_trace_compress_end().
*/ */
ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin( ZSTD_TraceCtx ZSTD_trace_decompress_begin(struct ZSTD_DCtx_s const* dctx);
struct ZSTD_DCtx_s const* dctx);
/** /**
* Trace the end of a decompression call. * Trace the end of a decompression call.
* @param ctx The return value of ZSTD_trace_decompress_begin(). * @param ctx The return value of ZSTD_trace_decompress_begin().
* @param trace The zstd tracing info. * @param trace The zstd tracing info.
*/ */
ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end( void ZSTD_trace_decompress_end(
ZSTD_TraceCtx ctx, ZSTD_TraceCtx ctx,
ZSTD_Trace const* trace); ZSTD_Trace const* trace);
+13 -10
View File
@@ -596,16 +596,19 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
n = srcSize & ~3; /* join to mod 4 */ n = srcSize & ~3; /* join to mod 4 */
switch (srcSize & 3) switch (srcSize & 3)
{ {
case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable); case 3:
HUF_FLUSHBITS_2(&bitC); HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
/* fall-through */ HUF_FLUSHBITS_2(&bitC);
case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable); ZSTD_FALLTHROUGH;
HUF_FLUSHBITS_1(&bitC); case 2:
/* fall-through */ HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable); HUF_FLUSHBITS_1(&bitC);
HUF_FLUSHBITS(&bitC); ZSTD_FALLTHROUGH;
/* fall-through */ case 1:
case 0 : /* fall-through */ HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
HUF_FLUSHBITS(&bitC);
ZSTD_FALLTHROUGH;
case 0: ZSTD_FALLTHROUGH;
default: break; default: break;
} }
+282 -1366
View File
@@ -72,10 +72,6 @@ struct ZSTD_CDict_s {
ZSTD_customMem customMem; ZSTD_customMem customMem;
U32 dictID; U32 dictID;
int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */ int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
ZSTD_useRowMatchFinderMode_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
* row-based matchfinder. Unless the cdict is reloaded, we will use
* the same greedy/lazy matchfinder at compression time.
*/
}; /* typedef'd to ZSTD_CDict within "zstd.h" */ }; /* typedef'd to ZSTD_CDict within "zstd.h" */
ZSTD_CCtx* ZSTD_createCCtx(void) ZSTD_CCtx* ZSTD_createCCtx(void)
@@ -206,49 +202,6 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
/* private API call, for dictBuilder only */ /* private API call, for dictBuilder only */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
/* Returns true if the strategy supports using a row based matchfinder */
static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
return (strategy >= ZSTD_greedy && strategy <= ZSTD_lazy2);
}
/* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder
* for this compression.
*/
static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_useRowMatchFinderMode_e mode) {
assert(mode != ZSTD_urm_auto);
return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_urm_enableRowMatchFinder);
}
/* Returns row matchfinder usage enum given an initial mode and cParams */
static ZSTD_useRowMatchFinderMode_e ZSTD_resolveRowMatchFinderMode(ZSTD_useRowMatchFinderMode_e mode,
const ZSTD_compressionParameters* const cParams) {
#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(__ARM_NEON))
int const kHasSIMD128 = 1;
#else
int const kHasSIMD128 = 0;
#endif
if (mode != ZSTD_urm_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
mode = ZSTD_urm_disableRowMatchFinder;
if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
if (kHasSIMD128) {
if (cParams->windowLog > 14) mode = ZSTD_urm_enableRowMatchFinder;
} else {
if (cParams->windowLog > 17) mode = ZSTD_urm_enableRowMatchFinder;
}
return mode;
}
/* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */
static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
const U32 forDDSDict) {
assert(useRowMatchFinder != ZSTD_urm_auto);
/* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate.
* We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder.
*/
return forDDSDict || ((strategy != ZSTD_fast) && !ZSTD_rowMatchFinderUsed(strategy, useRowMatchFinder));
}
/* Returns 1 if compression parameters are such that we should /* Returns 1 if compression parameters are such that we should
* enable long distance matching (wlog >= 27, strategy >= btopt). * enable long distance matching (wlog >= 27, strategy >= btopt).
* Returns 0 otherwise. * Returns 0 otherwise.
@@ -257,14 +210,6 @@ static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const
return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27; return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27;
} }
/* Returns 1 if compression parameters are such that we should
* enable blockSplitter (wlog >= 17, strategy >= btopt).
* Returns 0 otherwise.
*/
static U32 ZSTD_CParams_useBlockSplitter(const ZSTD_compressionParameters* const cParams) {
return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17;
}
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
ZSTD_compressionParameters cParams) ZSTD_compressionParameters cParams)
{ {
@@ -273,7 +218,6 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT); ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT);
cctxParams.cParams = cParams; cctxParams.cParams = cParams;
/* Adjust advanced params according to cParams */
if (ZSTD_CParams_shouldEnableLdm(&cParams)) { if (ZSTD_CParams_shouldEnableLdm(&cParams)) {
DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params"); DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params");
cctxParams.ldmParams.enableLdm = 1; cctxParams.ldmParams.enableLdm = 1;
@@ -283,12 +227,6 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
assert(cctxParams.ldmParams.hashRateLog < 32); assert(cctxParams.ldmParams.hashRateLog < 32);
} }
if (ZSTD_CParams_useBlockSplitter(&cParams)) {
DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including block splitting into cctx params");
cctxParams.splitBlocks = 1;
}
cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
assert(!ZSTD_checkCParams(cParams)); assert(!ZSTD_checkCParams(cParams));
return cctxParams; return cctxParams;
} }
@@ -347,8 +285,6 @@ static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_par
* But, set it for tracing anyway. * But, set it for tracing anyway.
*/ */
cctxParams->compressionLevel = compressionLevel; cctxParams->compressionLevel = compressionLevel;
cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, &params->cParams);
DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d", cctxParams->useRowMatchFinder);
} }
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
@@ -549,21 +485,6 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
bounds.upperBound = 1; bounds.upperBound = 1;
return bounds; return bounds;
case ZSTD_c_splitBlocks:
bounds.lowerBound = 0;
bounds.upperBound = 1;
return bounds;
case ZSTD_c_useRowMatchFinder:
bounds.lowerBound = (int)ZSTD_urm_auto;
bounds.upperBound = (int)ZSTD_urm_enableRowMatchFinder;
return bounds;
case ZSTD_c_deterministicRefPrefix:
bounds.lowerBound = 0;
bounds.upperBound = 1;
return bounds;
default: default:
bounds.error = ERROR(parameter_unsupported); bounds.error = ERROR(parameter_unsupported);
return bounds; return bounds;
@@ -625,9 +546,6 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
case ZSTD_c_stableOutBuffer: case ZSTD_c_stableOutBuffer:
case ZSTD_c_blockDelimiters: case ZSTD_c_blockDelimiters:
case ZSTD_c_validateSequences: case ZSTD_c_validateSequences:
case ZSTD_c_splitBlocks:
case ZSTD_c_useRowMatchFinder:
case ZSTD_c_deterministicRefPrefix:
default: default:
return 0; return 0;
} }
@@ -680,9 +598,6 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
case ZSTD_c_stableOutBuffer: case ZSTD_c_stableOutBuffer:
case ZSTD_c_blockDelimiters: case ZSTD_c_blockDelimiters:
case ZSTD_c_validateSequences: case ZSTD_c_validateSequences:
case ZSTD_c_splitBlocks:
case ZSTD_c_useRowMatchFinder:
case ZSTD_c_deterministicRefPrefix:
break; break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
@@ -857,8 +772,8 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
return CCtxParams->ldmParams.bucketSizeLog; return CCtxParams->ldmParams.bucketSizeLog;
case ZSTD_c_ldmHashRateLog : case ZSTD_c_ldmHashRateLog :
RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN, if (value!=0) /* 0 ==> default */
parameter_outOfBound, "Param out of bounds!"); BOUNDCHECK(ZSTD_c_ldmHashRateLog, value);
CCtxParams->ldmParams.hashRateLog = value; CCtxParams->ldmParams.hashRateLog = value;
return CCtxParams->ldmParams.hashRateLog; return CCtxParams->ldmParams.hashRateLog;
@@ -894,21 +809,6 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
CCtxParams->validateSequences = value; CCtxParams->validateSequences = value;
return CCtxParams->validateSequences; return CCtxParams->validateSequences;
case ZSTD_c_splitBlocks:
BOUNDCHECK(ZSTD_c_splitBlocks, value);
CCtxParams->splitBlocks = value;
return CCtxParams->splitBlocks;
case ZSTD_c_useRowMatchFinder:
BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
CCtxParams->useRowMatchFinder = (ZSTD_useRowMatchFinderMode_e)value;
return CCtxParams->useRowMatchFinder;
case ZSTD_c_deterministicRefPrefix:
BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value);
CCtxParams->deterministicRefPrefix = !!value;
return CCtxParams->deterministicRefPrefix;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
} }
} }
@@ -1032,15 +932,6 @@ size_t ZSTD_CCtxParams_getParameter(
case ZSTD_c_validateSequences : case ZSTD_c_validateSequences :
*value = (int)CCtxParams->validateSequences; *value = (int)CCtxParams->validateSequences;
break; break;
case ZSTD_c_splitBlocks :
*value = (int)CCtxParams->splitBlocks;
break;
case ZSTD_c_useRowMatchFinder :
*value = (int)CCtxParams->useRowMatchFinder;
break;
case ZSTD_c_deterministicRefPrefix:
*value = (int)CCtxParams->deterministicRefPrefix;
break;
default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
} }
return 0; return 0;
@@ -1407,14 +1298,9 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
static size_t static size_t
ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
const U32 enableDedicatedDictSearch,
const U32 forCCtx) const U32 forCCtx)
{ {
/* chain table size should be 0 for fast or row-hash strategies */ size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, enableDedicatedDictSearch && !forCCtx)
? ((size_t)1 << cParams->chainLog)
: 0;
size_t const hSize = ((size_t)1) << cParams->hashLog; size_t const hSize = ((size_t)1) << cParams->hashLog;
U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
@@ -1424,34 +1310,24 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
+ hSize * sizeof(U32) + hSize * sizeof(U32)
+ h3Size * sizeof(U32); + h3Size * sizeof(U32);
size_t const optPotentialSpace = size_t const optPotentialSpace =
ZSTD_cwksp_aligned_alloc_size((MaxML+1) * sizeof(U32)) ZSTD_cwksp_alloc_size((MaxML+1) * sizeof(U32))
+ ZSTD_cwksp_aligned_alloc_size((MaxLL+1) * sizeof(U32)) + ZSTD_cwksp_alloc_size((MaxLL+1) * sizeof(U32))
+ ZSTD_cwksp_aligned_alloc_size((MaxOff+1) * sizeof(U32)) + ZSTD_cwksp_alloc_size((MaxOff+1) * sizeof(U32))
+ ZSTD_cwksp_aligned_alloc_size((1<<Litbits) * sizeof(U32)) + ZSTD_cwksp_alloc_size((1<<Litbits) * sizeof(U32))
+ ZSTD_cwksp_aligned_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t)) + ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t))
+ ZSTD_cwksp_aligned_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t)); + ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
size_t const lazyAdditionalSpace = ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)
? ZSTD_cwksp_aligned_alloc_size(hSize*sizeof(U16))
: 0;
size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt)) size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
? optPotentialSpace ? optPotentialSpace
: 0; : 0;
size_t const slackSpace = ZSTD_cwksp_slack_space_required();
/* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */
ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4);
assert(useRowMatchFinder != ZSTD_urm_auto);
DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u", DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
(U32)chainSize, (U32)hSize, (U32)h3Size); (U32)chainSize, (U32)hSize, (U32)h3Size);
return tableSpace + optSpace + slackSpace + lazyAdditionalSpace; return tableSpace + optSpace;
} }
static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
const ZSTD_compressionParameters* cParams, const ZSTD_compressionParameters* cParams,
const ldmParams_t* ldmParams, const ldmParams_t* ldmParams,
const int isStatic, const int isStatic,
const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
const size_t buffInSize, const size_t buffInSize,
const size_t buffOutSize, const size_t buffOutSize,
const U64 pledgedSrcSize) const U64 pledgedSrcSize)
@@ -1461,16 +1337,16 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
U32 const divider = (cParams->minMatch==3) ? 3 : 4; U32 const divider = (cParams->minMatch==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider; size_t const maxNbSeq = blockSize / divider;
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
+ ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef)) + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
+ 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE); size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1); size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, /* forCCtx */ 1);
size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams); size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize); size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
size_t const ldmSeqSpace = ldmParams->enableLdm ? size_t const ldmSeqSpace = ldmParams->enableLdm ?
ZSTD_cwksp_aligned_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0; ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
@@ -1496,32 +1372,19 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
{ {
ZSTD_compressionParameters const cParams = ZSTD_compressionParameters const cParams =
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
&cParams);
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
/* estimateCCtxSize is for one-shot compression. So no buffers should /* estimateCCtxSize is for one-shot compression. So no buffers should
* be needed. However, we still allocate two 0-sized buffers, which can * be needed. However, we still allocate two 0-sized buffers, which can
* take space under ASAN. */ * take space under ASAN. */
return ZSTD_estimateCCtxSize_usingCCtxParams_internal( return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&cParams, &params->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN); &cParams, &params->ldmParams, 1, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN);
} }
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
{ {
ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams); ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
if (ZSTD_rowMatchFinderSupported(cParams.strategy)) { return ZSTD_estimateCCtxSize_usingCCtxParams(&params);
/* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */
size_t noRowCCtxSize;
size_t rowCCtxSize;
initialParams.useRowMatchFinder = ZSTD_urm_disableRowMatchFinder;
noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
initialParams.useRowMatchFinder = ZSTD_urm_enableRowMatchFinder;
rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
return MAX(noRowCCtxSize, rowCCtxSize);
} else {
return ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
}
} }
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel) static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
@@ -1561,29 +1424,17 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered) size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
? ZSTD_compressBound(blockSize) + 1 ? ZSTD_compressBound(blockSize) + 1
: 0; : 0;
ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
return ZSTD_estimateCCtxSize_usingCCtxParams_internal( return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize, &cParams, &params->ldmParams, 1, inBuffSize, outBuffSize,
ZSTD_CONTENTSIZE_UNKNOWN); ZSTD_CONTENTSIZE_UNKNOWN);
} }
} }
size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams) size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
{ {
ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams); ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
if (ZSTD_rowMatchFinderSupported(cParams.strategy)) { return ZSTD_estimateCStreamSize_usingCCtxParams(&params);
/* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */
size_t noRowCCtxSize;
size_t rowCCtxSize;
initialParams.useRowMatchFinder = ZSTD_urm_disableRowMatchFinder;
noRowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
initialParams.useRowMatchFinder = ZSTD_urm_enableRowMatchFinder;
rowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
return MAX(noRowCCtxSize, rowCCtxSize);
} else {
return ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
}
} }
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
@@ -1708,27 +1559,20 @@ typedef enum {
ZSTD_resetTarget_CCtx ZSTD_resetTarget_CCtx
} ZSTD_resetTarget_e; } ZSTD_resetTarget_e;
static size_t static size_t
ZSTD_reset_matchState(ZSTD_matchState_t* ms, ZSTD_reset_matchState(ZSTD_matchState_t* ms,
ZSTD_cwksp* ws, ZSTD_cwksp* ws,
const ZSTD_compressionParameters* cParams, const ZSTD_compressionParameters* cParams,
const ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
const ZSTD_compResetPolicy_e crp, const ZSTD_compResetPolicy_e crp,
const ZSTD_indexResetPolicy_e forceResetIndex, const ZSTD_indexResetPolicy_e forceResetIndex,
const ZSTD_resetTarget_e forWho) const ZSTD_resetTarget_e forWho)
{ {
/* disable chain table allocation for fast or row-based strategies */ size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder,
ms->dedicatedDictSearch && (forWho == ZSTD_resetTarget_CDict))
? ((size_t)1 << cParams->chainLog)
: 0;
size_t const hSize = ((size_t)1) << cParams->hashLog; size_t const hSize = ((size_t)1) << cParams->hashLog;
U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset); DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
assert(useRowMatchFinder != ZSTD_urm_auto);
if (forceResetIndex == ZSTDirp_reset) { if (forceResetIndex == ZSTDirp_reset) {
ZSTD_window_init(&ms->window); ZSTD_window_init(&ms->window);
ZSTD_cwksp_mark_tables_dirty(ws); ZSTD_cwksp_mark_tables_dirty(ws);
@@ -1767,23 +1611,11 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t)); ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
} }
if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) {
{ /* Row match finder needs an additional table of hashes ("tags") */
size_t const tagTableSize = hSize*sizeof(U16);
ms->tagTable = (U16*)ZSTD_cwksp_reserve_aligned(ws, tagTableSize);
if (ms->tagTable) ZSTD_memset(ms->tagTable, 0, tagTableSize);
}
{ /* Switch to 32-entry rows if searchLog is 5 (or more) */
U32 const rowLog = cParams->searchLog < 5 ? 4 : 5;
assert(cParams->hashLog > rowLog);
ms->rowHashLog = cParams->hashLog - rowLog;
}
}
ms->cParams = *cParams; ms->cParams = *cParams;
RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
"failed a workspace allocation in ZSTD_reset_matchState"); "failed a workspace allocation in ZSTD_reset_matchState");
return 0; return 0;
} }
@@ -1800,85 +1632,61 @@ static int ZSTD_indexTooCloseToMax(ZSTD_window_t w)
return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN); return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);
} }
/** ZSTD_dictTooBig():
* When dictionaries are larger than ZSTD_CHUNKSIZE_MAX they can't be loaded in
* one go generically. So we ensure that in that case we reset the tables to zero,
* so that we can load as much of the dictionary as possible.
*/
static int ZSTD_dictTooBig(size_t const loadedDictSize)
{
return loadedDictSize > ZSTD_CHUNKSIZE_MAX;
}
/*! ZSTD_resetCCtx_internal() : /*! ZSTD_resetCCtx_internal() :
* @param loadedDictSize The size of the dictionary to be loaded note : `params` are assumed fully validated at this stage */
* into the context, if any. If no dictionary is used, or the
* dictionary is being attached / copied, then pass 0.
* note : `params` are assumed fully validated at this stage.
*/
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ZSTD_CCtx_params const* params, ZSTD_CCtx_params params,
U64 const pledgedSrcSize, U64 const pledgedSrcSize,
size_t const loadedDictSize,
ZSTD_compResetPolicy_e const crp, ZSTD_compResetPolicy_e const crp,
ZSTD_buffered_policy_e const zbuff) ZSTD_buffered_policy_e const zbuff)
{ {
ZSTD_cwksp* const ws = &zc->workspace; ZSTD_cwksp* const ws = &zc->workspace;
DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d", DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
(U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder); (U32)pledgedSrcSize, params.cParams.windowLog);
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
zc->isFirstBlock = 1; zc->isFirstBlock = 1;
/* Set applied params early so we can modify them for LDM, if (params.ldmParams.enableLdm) {
* and point params at the applied params.
*/
zc->appliedParams = *params;
params = &zc->appliedParams;
assert(params->useRowMatchFinder != ZSTD_urm_auto);
if (params->ldmParams.enableLdm) {
/* Adjust long distance matching parameters */ /* Adjust long distance matching parameters */
ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, &params->cParams); ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog); assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
assert(params->ldmParams.hashRateLog < 32); assert(params.ldmParams.hashRateLog < 32);
} }
{ size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize)); { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
U32 const divider = (params->cParams.minMatch==3) ? 3 : 4; U32 const divider = (params.cParams.minMatch==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider; size_t const maxNbSeq = blockSize / divider;
size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered) size_t const buffOutSize = (zbuff == ZSTDb_buffered && params.outBufferMode == ZSTD_bm_buffered)
? ZSTD_compressBound(blockSize) + 1 ? ZSTD_compressBound(blockSize) + 1
: 0; : 0;
size_t const buffInSize = (zbuff == ZSTDb_buffered && params->inBufferMode == ZSTD_bm_buffered) size_t const buffInSize = (zbuff == ZSTDb_buffered && params.inBufferMode == ZSTD_bm_buffered)
? windowSize + blockSize ? windowSize + blockSize
: 0; : 0;
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize); size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window); int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window);
int const dictTooBig = ZSTD_dictTooBig(loadedDictSize);
ZSTD_indexResetPolicy_e needsIndexReset = ZSTD_indexResetPolicy_e needsIndexReset =
(indexTooClose || dictTooBig || !zc->initialized) ? ZSTDirp_reset : ZSTDirp_continue; (!indexTooClose && zc->initialized) ? ZSTDirp_continue : ZSTDirp_reset;
size_t const neededSpace = size_t const neededSpace =
ZSTD_estimateCCtxSize_usingCCtxParams_internal( ZSTD_estimateCCtxSize_usingCCtxParams_internal(
&params->cParams, &params->ldmParams, zc->staticSize != 0, params->useRowMatchFinder, &params.cParams, &params.ldmParams, zc->staticSize != 0,
buffInSize, buffOutSize, pledgedSrcSize); buffInSize, buffOutSize, pledgedSrcSize);
int resizeWorkspace;
FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!");
if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0); if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
{ /* Check if workspace is large enough, alloc a new one if needed */ /* Check if workspace is large enough, alloc a new one if needed */
{
int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace; int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace); int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
resizeWorkspace = workspaceTooSmall || workspaceWasteful;
DEBUGLOG(4, "Need %zu B workspace", neededSpace); DEBUGLOG(4, "Need %zu B workspace", neededSpace);
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
if (resizeWorkspace) { if (workspaceTooSmall || workspaceWasteful) {
DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB", DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB",
ZSTD_cwksp_sizeof(ws) >> 10, ZSTD_cwksp_sizeof(ws) >> 10,
neededSpace >> 10); neededSpace >> 10);
@@ -1906,7 +1714,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ZSTD_cwksp_clear(ws); ZSTD_cwksp_clear(ws);
/* init params */ /* init params */
zc->blockState.matchState.cParams = params->cParams; zc->appliedParams = params;
zc->blockState.matchState.cParams = params.cParams;
zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
zc->consumedSrcSize = 0; zc->consumedSrcSize = 0;
zc->producedCSize = 0; zc->producedCSize = 0;
@@ -1937,11 +1746,11 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize); zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);
/* ldm bucketOffsets table */ /* ldm bucketOffsets table */
if (params->ldmParams.enableLdm) { if (params.ldmParams.enableLdm) {
/* TODO: avoid memset? */ /* TODO: avoid memset? */
size_t const numBuckets = size_t const numBuckets =
((size_t)1) << (params->ldmParams.hashLog - ((size_t)1) << (params.ldmParams.hashLog -
params->ldmParams.bucketSizeLog); params.ldmParams.bucketSizeLog);
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets); zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets);
ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets); ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets);
} }
@@ -1957,28 +1766,32 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
FORWARD_IF_ERROR(ZSTD_reset_matchState( FORWARD_IF_ERROR(ZSTD_reset_matchState(
&zc->blockState.matchState, &zc->blockState.matchState,
ws, ws,
&params->cParams, &params.cParams,
params->useRowMatchFinder,
crp, crp,
needsIndexReset, needsIndexReset,
ZSTD_resetTarget_CCtx), ""); ZSTD_resetTarget_CCtx), "");
/* ldm hash table */ /* ldm hash table */
if (params->ldmParams.enableLdm) { if (params.ldmParams.enableLdm) {
/* TODO: avoid memset? */ /* TODO: avoid memset? */
size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t)); zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq)); zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
zc->maxNbLdmSequences = maxNbLdmSeq; zc->maxNbLdmSequences = maxNbLdmSeq;
ZSTD_window_init(&zc->ldmState.window); ZSTD_window_init(&zc->ldmState.window);
ZSTD_window_clear(&zc->ldmState.window);
zc->ldmState.loadedDictEnd = 0; zc->ldmState.loadedDictEnd = 0;
} }
assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace)); /* Due to alignment, when reusing a workspace, we can actually consume
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); * up to 3 extra bytes for alignment. See the comments in zstd_cwksp.h
*/
assert(ZSTD_cwksp_used(ws) >= neededSpace &&
ZSTD_cwksp_used(ws) <= neededSpace + 3);
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
zc->initialized = 1; zc->initialized = 1;
return 0; return 0;
@@ -2034,8 +1847,6 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
U64 pledgedSrcSize, U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff) ZSTD_buffered_policy_e zbuff)
{ {
DEBUGLOG(4, "ZSTD_resetCCtx_byAttachingCDict() pledgedSrcSize=%llu",
(unsigned long long)pledgedSrcSize);
{ {
ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams; ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams;
unsigned const windowLog = params.cParams.windowLog; unsigned const windowLog = params.cParams.windowLog;
@@ -2051,9 +1862,7 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize, params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize,
cdict->dictContentSize, ZSTD_cpm_attachDict); cdict->dictContentSize, ZSTD_cpm_attachDict);
params.cParams.windowLog = windowLog; params.cParams.windowLog = windowLog;
params.useRowMatchFinder = cdict->useRowMatchFinder; /* cdict overrides */ FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, &params, pledgedSrcSize,
/* loadedDictSize */ 0,
ZSTDcrp_makeClean, zbuff), ""); ZSTDcrp_makeClean, zbuff), "");
assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy); assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy);
} }
@@ -2097,17 +1906,15 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
assert(!cdict->matchState.dedicatedDictSearch); assert(!cdict->matchState.dedicatedDictSearch);
DEBUGLOG(4, "ZSTD_resetCCtx_byCopyingCDict() pledgedSrcSize=%llu",
(unsigned long long)pledgedSrcSize); DEBUGLOG(4, "copying dictionary into context");
{ unsigned const windowLog = params.cParams.windowLog; { unsigned const windowLog = params.cParams.windowLog;
assert(windowLog != 0); assert(windowLog != 0);
/* Copy only compression parameters related to tables. */ /* Copy only compression parameters related to tables. */
params.cParams = *cdict_cParams; params.cParams = *cdict_cParams;
params.cParams.windowLog = windowLog; params.cParams.windowLog = windowLog;
params.useRowMatchFinder = cdict->useRowMatchFinder; FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, &params, pledgedSrcSize,
/* loadedDictSize */ 0,
ZSTDcrp_leaveDirty, zbuff), ""); ZSTDcrp_leaveDirty, zbuff), "");
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog); assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
@@ -2115,30 +1922,17 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
} }
ZSTD_cwksp_mark_tables_dirty(&cctx->workspace); ZSTD_cwksp_mark_tables_dirty(&cctx->workspace);
assert(params.useRowMatchFinder != ZSTD_urm_auto);
/* copy tables */ /* copy tables */
{ size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */) { size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
? ((size_t)1 << cdict_cParams->chainLog)
: 0;
size_t const hSize = (size_t)1 << cdict_cParams->hashLog; size_t const hSize = (size_t)1 << cdict_cParams->hashLog;
ZSTD_memcpy(cctx->blockState.matchState.hashTable, ZSTD_memcpy(cctx->blockState.matchState.hashTable,
cdict->matchState.hashTable, cdict->matchState.hashTable,
hSize * sizeof(U32)); hSize * sizeof(U32));
/* Do not copy cdict's chainTable if cctx has parameters such that it would not use chainTable */ ZSTD_memcpy(cctx->blockState.matchState.chainTable,
if (ZSTD_allocateChainTable(cctx->appliedParams.cParams.strategy, cctx->appliedParams.useRowMatchFinder, 0 /* forDDSDict */)) {
ZSTD_memcpy(cctx->blockState.matchState.chainTable,
cdict->matchState.chainTable, cdict->matchState.chainTable,
chainSize * sizeof(U32)); chainSize * sizeof(U32));
}
/* copy tag table */
if (ZSTD_rowMatchFinderUsed(cdict_cParams->strategy, cdict->useRowMatchFinder)) {
size_t const tagTableSize = hSize*sizeof(U16);
ZSTD_memcpy(cctx->blockState.matchState.tagTable,
cdict->matchState.tagTable,
tagTableSize);
}
} }
/* Zero the hashTable3, since the cdict never fills it */ /* Zero the hashTable3, since the cdict never fills it */
@@ -2202,18 +1996,16 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
U64 pledgedSrcSize, U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff) ZSTD_buffered_policy_e zbuff)
{ {
DEBUGLOG(5, "ZSTD_copyCCtx_internal");
RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong, RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong,
"Can't copy a ctx that's not in init stage."); "Can't copy a ctx that's not in init stage.");
DEBUGLOG(5, "ZSTD_copyCCtx_internal");
ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
{ ZSTD_CCtx_params params = dstCCtx->requestedParams; { ZSTD_CCtx_params params = dstCCtx->requestedParams;
/* Copy only compression parameters related to tables. */ /* Copy only compression parameters related to tables. */
params.cParams = srcCCtx->appliedParams.cParams; params.cParams = srcCCtx->appliedParams.cParams;
assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_urm_auto);
params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder;
params.fParams = fParams; params.fParams = fParams;
ZSTD_resetCCtx_internal(dstCCtx, &params, pledgedSrcSize, ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
/* loadedDictSize */ 0,
ZSTDcrp_leaveDirty, zbuff); ZSTDcrp_leaveDirty, zbuff);
assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog); assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog);
assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy); assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy);
@@ -2225,11 +2017,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace); ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace);
/* copy tables */ /* copy tables */
{ size_t const chainSize = ZSTD_allocateChainTable(srcCCtx->appliedParams.cParams.strategy, { size_t const chainSize = (srcCCtx->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog);
srcCCtx->appliedParams.useRowMatchFinder,
0 /* forDDSDict */)
? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog)
: 0;
size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog; size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
int const h3log = srcCCtx->blockState.matchState.hashLog3; int const h3log = srcCCtx->blockState.matchState.hashLog3;
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
@@ -2343,7 +2131,7 @@ static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* par
ZSTD_reduceTable(ms->hashTable, hSize, reducerValue); ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
} }
if (ZSTD_allocateChainTable(params->cParams.strategy, params->useRowMatchFinder, (U32)ms->dedicatedDictSearch)) { if (params->cParams.strategy != ZSTD_fast) {
U32 const chainSize = (U32)1 << params->cParams.chainLog; U32 const chainSize = (U32)1 << params->cParams.chainLog;
if (params->cParams.strategy == ZSTD_btlazy2) if (params->cParams.strategy == ZSTD_btlazy2)
ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue); ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);
@@ -2380,9 +2168,9 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset); ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv); mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv);
} }
if (seqStorePtr->longLengthType==ZSTD_llt_literalLength) if (seqStorePtr->longLengthID==1)
llCodeTable[seqStorePtr->longLengthPos] = MaxLL; llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
if (seqStorePtr->longLengthType==ZSTD_llt_matchLength) if (seqStorePtr->longLengthID==2)
mlCodeTable[seqStorePtr->longLengthPos] = MaxML; mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
} }
@@ -2396,158 +2184,10 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
return (cctxParams->targetCBlockSize != 0); return (cctxParams->targetCBlockSize != 0);
} }
/* ZSTD_blockSplitterEnabled(): /* ZSTD_entropyCompressSequences_internal():
* Returns if block splitting param is being used * actually compresses both literals and sequences */
* If used, compression will do best effort to split a block in order to improve compression ratio.
* Returns 1 if true, 0 otherwise. */
static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams)
{
DEBUGLOG(5, "ZSTD_blockSplitterEnabled(splitBlocks=%d)", cctxParams->splitBlocks);
return (cctxParams->splitBlocks != 0);
}
/* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types
* and size of the sequences statistics
*/
typedef struct {
U32 LLtype;
U32 Offtype;
U32 MLtype;
size_t size;
size_t lastCountSize; /* Accounts for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
} ZSTD_symbolEncodingTypeStats_t;
/* ZSTD_buildSequencesStatistics():
* Returns a ZSTD_symbolEncodingTypeStats_t, or a zstd error code in the `size` field.
* Modifies `nextEntropy` to have the appropriate values as a side effect.
* nbSeq must be greater than 0.
*
* entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32)
*/
static ZSTD_symbolEncodingTypeStats_t
ZSTD_buildSequencesStatistics(seqStore_t* seqStorePtr, size_t nbSeq,
const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy,
BYTE* dst, const BYTE* const dstEnd,
ZSTD_strategy strategy, unsigned* countWorkspace,
void* entropyWorkspace, size_t entropyWkspSize) {
BYTE* const ostart = dst;
const BYTE* const oend = dstEnd;
BYTE* op = ostart;
FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
const BYTE* const llCodeTable = seqStorePtr->llCode;
const BYTE* const mlCodeTable = seqStorePtr->mlCode;
ZSTD_symbolEncodingTypeStats_t stats;
stats.lastCountSize = 0;
/* convert length/distances into codes */
ZSTD_seqToCodes(seqStorePtr);
assert(op <= oend);
assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */
/* build CTable for Literal Lengths */
{ unsigned max = MaxLL;
size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
DEBUGLOG(5, "Building LL table");
nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
stats.LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
countWorkspace, max, mostFrequent, nbSeq,
LLFSELog, prevEntropy->litlengthCTable,
LL_defaultNorm, LL_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(set_basic < set_compressed && set_rle < set_compressed);
assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(
op, (size_t)(oend - op),
CTable_LitLength, LLFSELog, (symbolEncodingType_e)stats.LLtype,
countWorkspace, max, llCodeTable, nbSeq,
LL_defaultNorm, LL_defaultNormLog, MaxLL,
prevEntropy->litlengthCTable,
sizeof(prevEntropy->litlengthCTable),
entropyWorkspace, entropyWkspSize);
if (ZSTD_isError(countSize)) {
DEBUGLOG(3, "ZSTD_buildCTable for LitLens failed");
stats.size = countSize;
return stats;
}
if (stats.LLtype == set_compressed)
stats.lastCountSize = countSize;
op += countSize;
assert(op <= oend);
} }
/* build CTable for Offsets */
{ unsigned max = MaxOff;
size_t const mostFrequent = HIST_countFast_wksp(
countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
DEBUGLOG(5, "Building OF table");
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
countWorkspace, max, mostFrequent, nbSeq,
OffFSELog, prevEntropy->offcodeCTable,
OF_defaultNorm, OF_defaultNormLog,
defaultPolicy, strategy);
assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(
op, (size_t)(oend - op),
CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)stats.Offtype,
countWorkspace, max, ofCodeTable, nbSeq,
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
prevEntropy->offcodeCTable,
sizeof(prevEntropy->offcodeCTable),
entropyWorkspace, entropyWkspSize);
if (ZSTD_isError(countSize)) {
DEBUGLOG(3, "ZSTD_buildCTable for Offsets failed");
stats.size = countSize;
return stats;
}
if (stats.Offtype == set_compressed)
stats.lastCountSize = countSize;
op += countSize;
assert(op <= oend);
} }
/* build CTable for MatchLengths */
{ unsigned max = MaxML;
size_t const mostFrequent = HIST_countFast_wksp(
countWorkspace, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
stats.MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode,
countWorkspace, max, mostFrequent, nbSeq,
MLFSELog, prevEntropy->matchlengthCTable,
ML_defaultNorm, ML_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(
op, (size_t)(oend - op),
CTable_MatchLength, MLFSELog, (symbolEncodingType_e)stats.MLtype,
countWorkspace, max, mlCodeTable, nbSeq,
ML_defaultNorm, ML_defaultNormLog, MaxML,
prevEntropy->matchlengthCTable,
sizeof(prevEntropy->matchlengthCTable),
entropyWorkspace, entropyWkspSize);
if (ZSTD_isError(countSize)) {
DEBUGLOG(3, "ZSTD_buildCTable for MatchLengths failed");
stats.size = countSize;
return stats;
}
if (stats.MLtype == set_compressed)
stats.lastCountSize = countSize;
op += countSize;
assert(op <= oend);
} }
stats.size = (size_t)(op-ostart);
return stats;
}
/* ZSTD_entropyCompressSeqStore_internal():
* compresses both literals and sequences
* Returns compressed size of block, or a zstd error.
*/
MEM_STATIC size_t MEM_STATIC size_t
ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr, ZSTD_entropyCompressSequences_internal(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy, const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy, ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams, const ZSTD_CCtx_params* cctxParams,
@@ -2561,20 +2201,22 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable; FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
const seqDef* const sequences = seqStorePtr->sequencesStart; const seqDef* const sequences = seqStorePtr->sequencesStart;
const size_t nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
const BYTE* const ofCodeTable = seqStorePtr->ofCode; const BYTE* const ofCodeTable = seqStorePtr->ofCode;
const BYTE* const llCodeTable = seqStorePtr->llCode; const BYTE* const llCodeTable = seqStorePtr->llCode;
const BYTE* const mlCodeTable = seqStorePtr->mlCode; const BYTE* const mlCodeTable = seqStorePtr->mlCode;
BYTE* const ostart = (BYTE*)dst; BYTE* const ostart = (BYTE*)dst;
BYTE* const oend = ostart + dstCapacity; BYTE* const oend = ostart + dstCapacity;
BYTE* op = ostart; BYTE* op = ostart;
size_t lastCountSize; size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
BYTE* seqHead;
BYTE* lastNCount = NULL;
entropyWorkspace = count + (MaxSeq + 1); entropyWorkspace = count + (MaxSeq + 1);
entropyWkspSize -= (MaxSeq + 1) * sizeof(*count); entropyWkspSize -= (MaxSeq + 1) * sizeof(*count);
DEBUGLOG(4, "ZSTD_entropyCompressSeqStore_internal (nbSeq=%zu)", nbSeq); DEBUGLOG(4, "ZSTD_entropyCompressSequences_internal (nbSeq=%zu)", nbSeq);
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
assert(entropyWkspSize >= HUF_WORKSPACE_SIZE); assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
@@ -2614,20 +2256,95 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
return (size_t)(op - ostart); return (size_t)(op - ostart);
} }
{
ZSTD_symbolEncodingTypeStats_t stats; /* seqHead : flags for FSE encoding type */
BYTE* seqHead = op++; seqHead = op++;
/* build stats for sequences */ assert(op <= oend);
stats = ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq,
&prevEntropy->fse, &nextEntropy->fse, /* convert length/distances into codes */
op, oend, ZSTD_seqToCodes(seqStorePtr);
strategy, count, /* build CTable for Literal Lengths */
entropyWorkspace, entropyWkspSize); { unsigned max = MaxLL;
FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
*seqHead = (BYTE)((stats.LLtype<<6) + (stats.Offtype<<4) + (stats.MLtype<<2)); DEBUGLOG(5, "Building LL table");
lastCountSize = stats.lastCountSize; nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
op += stats.size; LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode,
} count, max, mostFrequent, nbSeq,
LLFSELog, prevEntropy->fse.litlengthCTable,
LL_defaultNorm, LL_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(set_basic < set_compressed && set_rle < set_compressed);
assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(
op, (size_t)(oend - op),
CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
count, max, llCodeTable, nbSeq,
LL_defaultNorm, LL_defaultNormLog, MaxLL,
prevEntropy->fse.litlengthCTable,
sizeof(prevEntropy->fse.litlengthCTable),
entropyWorkspace, entropyWkspSize);
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
if (LLtype == set_compressed)
lastNCount = op;
op += countSize;
assert(op <= oend);
} }
/* build CTable for Offsets */
{ unsigned max = MaxOff;
size_t const mostFrequent = HIST_countFast_wksp(
count, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
DEBUGLOG(5, "Building OF table");
nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;
Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode,
count, max, mostFrequent, nbSeq,
OffFSELog, prevEntropy->fse.offcodeCTable,
OF_defaultNorm, OF_defaultNormLog,
defaultPolicy, strategy);
assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(
op, (size_t)(oend - op),
CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
count, max, ofCodeTable, nbSeq,
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
prevEntropy->fse.offcodeCTable,
sizeof(prevEntropy->fse.offcodeCTable),
entropyWorkspace, entropyWkspSize);
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
if (Offtype == set_compressed)
lastNCount = op;
op += countSize;
assert(op <= oend);
} }
/* build CTable for MatchLengths */
{ unsigned max = MaxML;
size_t const mostFrequent = HIST_countFast_wksp(
count, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode,
count, max, mostFrequent, nbSeq,
MLFSELog, prevEntropy->fse.matchlengthCTable,
ML_defaultNorm, ML_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(
op, (size_t)(oend - op),
CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
count, max, mlCodeTable, nbSeq,
ML_defaultNorm, ML_defaultNormLog, MaxML,
prevEntropy->fse.matchlengthCTable,
sizeof(prevEntropy->fse.matchlengthCTable),
entropyWorkspace, entropyWkspSize);
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
if (MLtype == set_compressed)
lastNCount = op;
op += countSize;
assert(op <= oend);
} }
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
{ size_t const bitstreamSize = ZSTD_encodeSequences( { size_t const bitstreamSize = ZSTD_encodeSequences(
op, (size_t)(oend - op), op, (size_t)(oend - op),
@@ -2647,9 +2364,9 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
* In this exceedingly rare case, we will simply emit an uncompressed * In this exceedingly rare case, we will simply emit an uncompressed
* block, since it isn't worth optimizing. * block, since it isn't worth optimizing.
*/ */
if (lastCountSize && (lastCountSize + bitstreamSize) < 4) { if (lastNCount && (op - lastNCount) < 4) {
/* lastCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
assert(lastCountSize + bitstreamSize == 3); assert(op - lastNCount == 3);
DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
"emitting an uncompressed block."); "emitting an uncompressed block.");
return 0; return 0;
@@ -2661,7 +2378,7 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr,
} }
MEM_STATIC size_t MEM_STATIC size_t
ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr, ZSTD_entropyCompressSequences(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy, const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy, ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams, const ZSTD_CCtx_params* cctxParams,
@@ -2670,7 +2387,7 @@ ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr,
void* entropyWorkspace, size_t entropyWkspSize, void* entropyWorkspace, size_t entropyWkspSize,
int bmi2) int bmi2)
{ {
size_t const cSize = ZSTD_entropyCompressSeqStore_internal( size_t const cSize = ZSTD_entropyCompressSequences_internal(
seqStorePtr, prevEntropy, nextEntropy, cctxParams, seqStorePtr, prevEntropy, nextEntropy, cctxParams,
dst, dstCapacity, dst, dstCapacity,
entropyWorkspace, entropyWkspSize, bmi2); entropyWorkspace, entropyWkspSize, bmi2);
@@ -2680,20 +2397,20 @@ ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr,
*/ */
if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity)) if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
return 0; /* block not compressed */ return 0; /* block not compressed */
FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed"); FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSequences_internal failed");
/* Check compressibility */ /* Check compressibility */
{ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy); { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
if (cSize >= maxCSize) return 0; /* block not compressed */ if (cSize >= maxCSize) return 0; /* block not compressed */
} }
DEBUGLOG(4, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize); DEBUGLOG(4, "ZSTD_entropyCompressSequences() cSize: %zu\n", cSize);
return cSize; return cSize;
} }
/* ZSTD_selectBlockCompressor() : /* ZSTD_selectBlockCompressor() :
* Not static, but internal use only (used by long distance matcher) * Not static, but internal use only (used by long distance matcher)
* assumption : strat is a valid strategy */ * assumption : strat is a valid strategy */
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e useRowMatchFinder, ZSTD_dictMode_e dictMode) ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
{ {
static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
{ ZSTD_compressBlock_fast /* default for 0 */, { ZSTD_compressBlock_fast /* default for 0 */,
@@ -2741,28 +2458,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRow
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat)); assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
DEBUGLOG(4, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder); selectedCompressor = blockCompressor[(int)dictMode][(int)strat];
if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) {
static const ZSTD_blockCompressor rowBasedBlockCompressors[4][3] = {
{ ZSTD_compressBlock_greedy_row,
ZSTD_compressBlock_lazy_row,
ZSTD_compressBlock_lazy2_row },
{ ZSTD_compressBlock_greedy_extDict_row,
ZSTD_compressBlock_lazy_extDict_row,
ZSTD_compressBlock_lazy2_extDict_row },
{ ZSTD_compressBlock_greedy_dictMatchState_row,
ZSTD_compressBlock_lazy_dictMatchState_row,
ZSTD_compressBlock_lazy2_dictMatchState_row },
{ ZSTD_compressBlock_greedy_dedicatedDictSearch_row,
ZSTD_compressBlock_lazy_dedicatedDictSearch_row,
ZSTD_compressBlock_lazy2_dedicatedDictSearch_row }
};
DEBUGLOG(4, "Selecting a row-based matchfinder");
assert(useRowMatchFinder != ZSTD_urm_auto);
selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy];
} else {
selectedCompressor = blockCompressor[(int)dictMode][(int)strat];
}
assert(selectedCompressor != NULL); assert(selectedCompressor != NULL);
return selectedCompressor; return selectedCompressor;
} }
@@ -2778,7 +2474,7 @@ void ZSTD_resetSeqStore(seqStore_t* ssPtr)
{ {
ssPtr->lit = ssPtr->litStart; ssPtr->lit = ssPtr->litStart;
ssPtr->sequences = ssPtr->sequencesStart; ssPtr->sequences = ssPtr->sequencesStart;
ssPtr->longLengthType = ZSTD_llt_none; ssPtr->longLengthID = 0;
} }
typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e; typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e;
@@ -2831,7 +2527,6 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
ZSTD_ldm_blockCompress(&zc->externSeqStore, ZSTD_ldm_blockCompress(&zc->externSeqStore,
ms, &zc->seqStore, ms, &zc->seqStore,
zc->blockState.nextCBlock->rep, zc->blockState.nextCBlock->rep,
zc->appliedParams.useRowMatchFinder,
src, srcSize); src, srcSize);
assert(zc->externSeqStore.pos <= zc->externSeqStore.size); assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
} else if (zc->appliedParams.ldmParams.enableLdm) { } else if (zc->appliedParams.ldmParams.enableLdm) {
@@ -2848,13 +2543,10 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
ZSTD_ldm_blockCompress(&ldmSeqStore, ZSTD_ldm_blockCompress(&ldmSeqStore,
ms, &zc->seqStore, ms, &zc->seqStore,
zc->blockState.nextCBlock->rep, zc->blockState.nextCBlock->rep,
zc->appliedParams.useRowMatchFinder,
src, srcSize); src, srcSize);
assert(ldmSeqStore.pos == ldmSeqStore.size); assert(ldmSeqStore.pos == ldmSeqStore.size);
} else { /* not long range mode */ } else { /* not long range mode */
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
zc->appliedParams.useRowMatchFinder,
dictMode);
ms->ldmSeqStore = NULL; ms->ldmSeqStore = NULL;
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
} }
@@ -2888,9 +2580,9 @@ static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
outSeqs[i].rep = 0; outSeqs[i].rep = 0;
if (i == seqStore->longLengthPos) { if (i == seqStore->longLengthPos) {
if (seqStore->longLengthType == ZSTD_llt_literalLength) { if (seqStore->longLengthID == 1) {
outSeqs[i].litLength += 0x10000; outSeqs[i].litLength += 0x10000;
} else if (seqStore->longLengthType == ZSTD_llt_matchLength) { } else if (seqStore->longLengthID == 2) {
outSeqs[i].matchLength += 0x10000; outSeqs[i].matchLength += 0x10000;
} }
} }
@@ -3001,713 +2693,11 @@ static int ZSTD_maybeRLE(seqStore_t const* seqStore)
return nbSeqs < 4 && nbLits < 10; return nbSeqs < 4 && nbLits < 10;
} }
static void ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs) static void ZSTD_confirmRepcodesAndEntropyTables(ZSTD_CCtx* zc)
{ {
ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock; ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
bs->prevCBlock = bs->nextCBlock; zc->blockState.prevCBlock = zc->blockState.nextCBlock;
bs->nextCBlock = tmp; zc->blockState.nextCBlock = tmp;
}
/* Writes the block header */
static void writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock) {
U32 const cBlockHeader = cSize == 1 ?
lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
MEM_writeLE24(op, cBlockHeader);
DEBUGLOG(3, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
}
/** ZSTD_buildBlockEntropyStats_literals() :
* Builds entropy for the literals.
* Stores literals block type (raw, rle, compressed, repeat) and
* huffman description table to hufMetadata.
* Requires ENTROPY_WORKSPACE_SIZE workspace
* @return : size of huffman description table or error code */
static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize,
const ZSTD_hufCTables_t* prevHuf,
ZSTD_hufCTables_t* nextHuf,
ZSTD_hufCTablesMetadata_t* hufMetadata,
const int disableLiteralsCompression,
void* workspace, size_t wkspSize)
{
BYTE* const wkspStart = (BYTE*)workspace;
BYTE* const wkspEnd = wkspStart + wkspSize;
BYTE* const countWkspStart = wkspStart;
unsigned* const countWksp = (unsigned*)workspace;
const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
BYTE* const nodeWksp = countWkspStart + countWkspSize;
const size_t nodeWkspSize = wkspEnd-nodeWksp;
unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX;
unsigned huffLog = HUF_TABLELOG_DEFAULT;
HUF_repeat repeat = prevHuf->repeatMode;
DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_literals (srcSize=%zu)", srcSize);
/* Prepare nextEntropy assuming reusing the existing table */
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
if (disableLiteralsCompression) {
DEBUGLOG(5, "set_basic - disabled");
hufMetadata->hType = set_basic;
return 0;
}
/* small ? don't even attempt compression (speed opt) */
#ifndef COMPRESS_LITERALS_SIZE_MIN
#define COMPRESS_LITERALS_SIZE_MIN 63
#endif
{ size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
if (srcSize <= minLitSize) {
DEBUGLOG(5, "set_basic - too small");
hufMetadata->hType = set_basic;
return 0;
}
}
/* Scan input and build symbol stats */
{ size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize);
FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
if (largest == srcSize) {
DEBUGLOG(5, "set_rle");
hufMetadata->hType = set_rle;
return 0;
}
if (largest <= (srcSize >> 7)+4) {
DEBUGLOG(5, "set_basic - no gain");
hufMetadata->hType = set_basic;
return 0;
}
}
/* Validate the previous Huffman table */
if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
repeat = HUF_repeat_none;
}
/* Build Huffman Tree */
ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
{ size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
maxSymbolValue, huffLog,
nodeWksp, nodeWkspSize);
FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
huffLog = (U32)maxBits;
{ /* Build and write the CTable */
size_t const newCSize = HUF_estimateCompressedSize(
(HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
size_t const hSize = HUF_writeCTable_wksp(
hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
(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(
(HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
DEBUGLOG(5, "set_repeat - smaller");
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_repeat;
return 0;
}
}
if (newCSize + hSize >= srcSize) {
DEBUGLOG(5, "set_basic - no gains");
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_basic;
return 0;
}
DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
hufMetadata->hType = set_compressed;
nextHuf->repeatMode = HUF_repeat_check;
return hSize;
}
}
}
/* ZSTD_buildDummySequencesStatistics():
* Returns a ZSTD_symbolEncodingTypeStats_t with all encoding types as set_basic,
* and updates nextEntropy to the appropriate repeatMode.
*/
static ZSTD_symbolEncodingTypeStats_t
ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) {
ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0};
nextEntropy->litlength_repeatMode = FSE_repeat_none;
nextEntropy->offcode_repeatMode = FSE_repeat_none;
nextEntropy->matchlength_repeatMode = FSE_repeat_none;
return stats;
}
/** ZSTD_buildBlockEntropyStats_sequences() :
* Builds entropy for the sequences.
* Stores symbol compression modes and fse table to fseMetadata.
* Requires ENTROPY_WORKSPACE_SIZE wksp.
* @return : size of fse tables or error code */
static size_t ZSTD_buildBlockEntropyStats_sequences(seqStore_t* seqStorePtr,
const ZSTD_fseCTables_t* prevEntropy,
ZSTD_fseCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
ZSTD_fseCTablesMetadata_t* fseMetadata,
void* workspace, size_t wkspSize)
{
ZSTD_strategy const strategy = cctxParams->cParams.strategy;
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
BYTE* const ostart = fseMetadata->fseTablesBuffer;
BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
BYTE* op = ostart;
unsigned* countWorkspace = (unsigned*)workspace;
unsigned* entropyWorkspace = countWorkspace + (MaxSeq + 1);
size_t entropyWorkspaceSize = wkspSize - (MaxSeq + 1) * sizeof(*countWorkspace);
ZSTD_symbolEncodingTypeStats_t stats;
DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq);
stats = nbSeq != 0 ? ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq,
prevEntropy, nextEntropy, op, oend,
strategy, countWorkspace,
entropyWorkspace, entropyWorkspaceSize)
: ZSTD_buildDummySequencesStatistics(nextEntropy);
FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
fseMetadata->llType = (symbolEncodingType_e) stats.LLtype;
fseMetadata->ofType = (symbolEncodingType_e) stats.Offtype;
fseMetadata->mlType = (symbolEncodingType_e) stats.MLtype;
fseMetadata->lastCountSize = stats.lastCountSize;
return stats.size;
}
/** ZSTD_buildBlockEntropyStats() :
* Builds entropy for the block.
* Requires workspace size ENTROPY_WORKSPACE_SIZE
*
* @return : 0 on success or error code
*/
size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
ZSTD_entropyCTablesMetadata_t* entropyMetadata,
void* workspace, size_t wkspSize)
{
size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart;
entropyMetadata->hufMetadata.hufDesSize =
ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize,
&prevEntropy->huf, &nextEntropy->huf,
&entropyMetadata->hufMetadata,
ZSTD_disableLiteralsCompression(cctxParams),
workspace, wkspSize);
FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed");
entropyMetadata->fseMetadata.fseTablesSize =
ZSTD_buildBlockEntropyStats_sequences(seqStorePtr,
&prevEntropy->fse, &nextEntropy->fse,
cctxParams,
&entropyMetadata->fseMetadata,
workspace, wkspSize);
FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildBlockEntropyStats_sequences failed");
return 0;
}
/* Returns the size estimate for the literals section (header + content) of a block */
static size_t ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize,
const ZSTD_hufCTables_t* huf,
const ZSTD_hufCTablesMetadata_t* hufMetadata,
void* workspace, size_t wkspSize,
int writeEntropy)
{
unsigned* const countWksp = (unsigned*)workspace;
unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX;
size_t literalSectionHeaderSize = 3 + (litSize >= 1 KB) + (litSize >= 16 KB);
U32 singleStream = litSize < 256;
if (hufMetadata->hType == set_basic) return litSize;
else if (hufMetadata->hType == set_rle) return 1;
else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) {
size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize);
if (ZSTD_isError(largest)) return litSize;
{ size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue);
if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize;
if (!singleStream) cLitSizeEstimate += 6; /* multi-stream huffman uses 6-byte jump table */
return cLitSizeEstimate + literalSectionHeaderSize;
} }
assert(0); /* impossible */
return 0;
}
/* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */
static size_t ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type,
const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
const FSE_CTable* fseCTable,
const U32* additionalBits,
short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
void* workspace, size_t wkspSize)
{
unsigned* const countWksp = (unsigned*)workspace;
const BYTE* ctp = codeTable;
const BYTE* const ctStart = ctp;
const BYTE* const ctEnd = ctStart + nbSeq;
size_t cSymbolTypeSizeEstimateInBits = 0;
unsigned max = maxCode;
HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
if (type == set_basic) {
/* We selected this encoding type, so it must be valid. */
assert(max <= defaultMax);
(void)defaultMax;
cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max);
} else if (type == set_rle) {
cSymbolTypeSizeEstimateInBits = 0;
} else if (type == set_compressed || type == set_repeat) {
cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max);
}
if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) {
return nbSeq * 10;
}
while (ctp < ctEnd) {
if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp];
else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */
ctp++;
}
return cSymbolTypeSizeEstimateInBits >> 3;
}
/* Returns the size estimate for the sequences section (header + content) of a block */
static size_t ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable,
const BYTE* llCodeTable,
const BYTE* mlCodeTable,
size_t nbSeq,
const ZSTD_fseCTables_t* fseTables,
const ZSTD_fseCTablesMetadata_t* fseMetadata,
void* workspace, size_t wkspSize,
int writeEntropy)
{
size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ);
size_t cSeqSizeEstimate = 0;
cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff,
fseTables->offcodeCTable, NULL,
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
workspace, wkspSize);
cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL,
fseTables->litlengthCTable, LL_bits,
LL_defaultNorm, LL_defaultNormLog, MaxLL,
workspace, wkspSize);
cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML,
fseTables->matchlengthCTable, ML_bits,
ML_defaultNorm, ML_defaultNormLog, MaxML,
workspace, wkspSize);
if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
return cSeqSizeEstimate + sequencesSectionHeaderSize;
}
/* Returns the size estimate for a given stream of literals, of, ll, ml */
static size_t ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize,
const BYTE* ofCodeTable,
const BYTE* llCodeTable,
const BYTE* mlCodeTable,
size_t nbSeq,
const ZSTD_entropyCTables_t* entropy,
const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
void* workspace, size_t wkspSize,
int writeLitEntropy, int writeSeqEntropy) {
size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize,
&entropy->huf, &entropyMetadata->hufMetadata,
workspace, wkspSize, writeLitEntropy);
size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable,
nbSeq, &entropy->fse, &entropyMetadata->fseMetadata,
workspace, wkspSize, writeSeqEntropy);
return seqSize + literalsSize + ZSTD_blockHeaderSize;
}
/* Builds entropy statistics and uses them for blocksize estimation.
*
* Returns the estimated compressed size of the seqStore, or a zstd error.
*/
static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, const ZSTD_CCtx* zc) {
ZSTD_entropyCTablesMetadata_t entropyMetadata;
FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore,
&zc->blockState.prevCBlock->entropy,
&zc->blockState.nextCBlock->entropy,
&zc->appliedParams,
&entropyMetadata,
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
return ZSTD_estimateBlockSize(seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
(size_t)(seqStore->sequences - seqStore->sequencesStart),
&zc->blockState.nextCBlock->entropy, &entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE,
(int)(entropyMetadata.hufMetadata.hType == set_compressed), 1);
}
/* Returns literals bytes represented in a seqStore */
static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore) {
size_t literalsBytes = 0;
size_t const nbSeqs = seqStore->sequences - seqStore->sequencesStart;
size_t i;
for (i = 0; i < nbSeqs; ++i) {
seqDef seq = seqStore->sequencesStart[i];
literalsBytes += seq.litLength;
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) {
literalsBytes += 0x10000;
}
}
return literalsBytes;
}
/* Returns match bytes represented in a seqStore */
static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore) {
size_t matchBytes = 0;
size_t const nbSeqs = seqStore->sequences - seqStore->sequencesStart;
size_t i;
for (i = 0; i < nbSeqs; ++i) {
seqDef seq = seqStore->sequencesStart[i];
matchBytes += seq.matchLength + MINMATCH;
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
matchBytes += 0x10000;
}
}
return matchBytes;
}
/* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx).
* Stores the result in resultSeqStore.
*/
static void ZSTD_deriveSeqStoreChunk(seqStore_t* resultSeqStore,
const seqStore_t* originalSeqStore,
size_t startIdx, size_t endIdx) {
BYTE* const litEnd = originalSeqStore->lit;
size_t literalsBytes;
size_t literalsBytesPreceding = 0;
*resultSeqStore = *originalSeqStore;
if (startIdx > 0) {
resultSeqStore->sequences = originalSeqStore->sequencesStart + startIdx;
literalsBytesPreceding = ZSTD_countSeqStoreLiteralsBytes(resultSeqStore);
}
/* Move longLengthPos into the correct position if necessary */
if (originalSeqStore->longLengthType != ZSTD_llt_none) {
if (originalSeqStore->longLengthPos < startIdx || originalSeqStore->longLengthPos > endIdx) {
resultSeqStore->longLengthType = ZSTD_llt_none;
} else {
resultSeqStore->longLengthPos -= (U32)startIdx;
}
}
resultSeqStore->sequencesStart = originalSeqStore->sequencesStart + startIdx;
resultSeqStore->sequences = originalSeqStore->sequencesStart + endIdx;
literalsBytes = ZSTD_countSeqStoreLiteralsBytes(resultSeqStore);
resultSeqStore->litStart += literalsBytesPreceding;
if (endIdx == (size_t)(originalSeqStore->sequences - originalSeqStore->sequencesStart)) {
/* This accounts for possible last literals if the derived chunk reaches the end of the block */
resultSeqStore->lit = litEnd;
} else {
resultSeqStore->lit = resultSeqStore->litStart+literalsBytes;
}
resultSeqStore->llCode += startIdx;
resultSeqStore->mlCode += startIdx;
resultSeqStore->ofCode += startIdx;
}
/**
* Returns the raw offset represented by the combination of offCode, ll0, and repcode history.
* offCode must be an offCode representing a repcode, therefore in the range of [0, 2].
*/
static U32 ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offCode, const U32 ll0) {
U32 const adjustedOffCode = offCode + ll0;
assert(offCode < ZSTD_REP_NUM);
if (adjustedOffCode == ZSTD_REP_NUM) {
/* litlength == 0 and offCode == 2 implies selection of first repcode - 1 */
assert(rep[0] > 0);
return rep[0] - 1;
}
return rep[adjustedOffCode];
}
/**
* ZSTD_seqStore_resolveOffCodes() reconciles any possible divergences in offset history that may arise
* due to emission of RLE/raw blocks that disturb the offset history, and replaces any repcodes within
* the seqStore that may be invalid.
*
* dRepcodes are updated as would be on the decompression side. cRepcodes are updated exactly in
* accordance with the seqStore.
*/
static void ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRepcodes,
seqStore_t* const seqStore, U32 const nbSeq) {
U32 idx = 0;
for (; idx < nbSeq; ++idx) {
seqDef* const seq = seqStore->sequencesStart + idx;
U32 const ll0 = (seq->litLength == 0);
U32 offCode = seq->offset - 1;
assert(seq->offset > 0);
if (offCode <= ZSTD_REP_MOVE) {
U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offCode, ll0);
U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offCode, ll0);
/* Adjust simulated decompression repcode history if we come across a mismatch. Replace
* the repcode with the offset it actually references, determined by the compression
* repcode history.
*/
if (dRawOffset != cRawOffset) {
seq->offset = cRawOffset + ZSTD_REP_NUM;
}
}
/* Compression repcode history is always updated with values directly from the unmodified seqStore.
* Decompression repcode history may use modified seq->offset value taken from compression repcode history.
*/
*dRepcodes = ZSTD_updateRep(dRepcodes->rep, seq->offset - 1, ll0);
*cRepcodes = ZSTD_updateRep(cRepcodes->rep, offCode, ll0);
}
}
/* ZSTD_compressSeqStore_singleBlock():
* Compresses a seqStore into a block with a block header, into the buffer dst.
*
* Returns the total size of that block (including header) or a ZSTD error code.
*/
static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const seqStore,
repcodes_t* const dRep, repcodes_t* const cRep,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
U32 lastBlock, U32 isPartition) {
const U32 rleMaxLength = 25;
BYTE* op = (BYTE*)dst;
const BYTE* ip = (const BYTE*)src;
size_t cSize;
size_t cSeqsSize;
/* In case of an RLE or raw block, the simulated decompression repcode history must be reset */
repcodes_t const dRepOriginal = *dRep;
if (isPartition)
ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart));
cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore,
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams,
op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize,
srcSize,
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
zc->bmi2);
FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!");
if (!zc->isFirstBlock &&
cSeqsSize < rleMaxLength &&
ZSTD_isRLE((BYTE const*)src, srcSize)) {
/* We don't want to emit our first block as a RLE even if it qualifies because
* doing so will cause the decoder (cli only) to throw a "should consume all input error."
* This is only an issue for zstd <= v1.4.3
*/
cSeqsSize = 1;
}
if (zc->seqCollector.collectSequences) {
ZSTD_copyBlockSequences(zc);
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState);
return 0;
}
if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
if (cSeqsSize == 0) {
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
FORWARD_IF_ERROR(cSize, "Nocompress block failed");
DEBUGLOG(4, "Writing out nocompress block, size: %zu", cSize);
*dRep = dRepOriginal; /* reset simulated decompression repcode history */
} else if (cSeqsSize == 1) {
cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock);
FORWARD_IF_ERROR(cSize, "RLE compress block failed");
DEBUGLOG(4, "Writing out RLE block, size: %zu", cSize);
*dRep = dRepOriginal; /* reset simulated decompression repcode history */
} else {
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState);
writeBlockHeader(op, cSeqsSize, srcSize, lastBlock);
cSize = ZSTD_blockHeaderSize + cSeqsSize;
DEBUGLOG(4, "Writing out compressed block, size: %zu", cSize);
}
return cSize;
}
/* Struct to keep track of where we are in our recursive calls. */
typedef struct {
U32* splitLocations; /* Array of split indices */
size_t idx; /* The current index within splitLocations being worked on */
} seqStoreSplits;
#define MIN_SEQUENCES_BLOCK_SPLITTING 300
#define MAX_NB_SPLITS 196
/* Helper function to perform the recursive search for block splits.
* Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half.
* If advantageous to split, then we recurse down the two sub-blocks. If not, or if an error occurred in estimation, then
* we do not recurse.
*
* Note: The recursion depth is capped by a heuristic minimum number of sequences, defined by MIN_SEQUENCES_BLOCK_SPLITTING.
* In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING).
* In practice, recursion depth usually doesn't go beyond 4.
*
* Furthermore, the number of splits is capped by MAX_NB_SPLITS. At MAX_NB_SPLITS == 196 with the current existing blockSize
* maximum of 128 KB, this value is actually impossible to reach.
*/
static void ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
const ZSTD_CCtx* zc, const seqStore_t* origSeqStore) {
seqStore_t fullSeqStoreChunk;
seqStore_t firstHalfSeqStore;
seqStore_t secondHalfSeqStore;
size_t estimatedOriginalSize;
size_t estimatedFirstHalfSize;
size_t estimatedSecondHalfSize;
size_t midIdx = (startIdx + endIdx)/2;
if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= MAX_NB_SPLITS) {
return;
}
ZSTD_deriveSeqStoreChunk(&fullSeqStoreChunk, origSeqStore, startIdx, endIdx);
ZSTD_deriveSeqStoreChunk(&firstHalfSeqStore, origSeqStore, startIdx, midIdx);
ZSTD_deriveSeqStoreChunk(&secondHalfSeqStore, origSeqStore, midIdx, endIdx);
estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&fullSeqStoreChunk, zc);
estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&firstHalfSeqStore, zc);
estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&secondHalfSeqStore, zc);
DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu",
estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize);
if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) {
return;
}
if (estimatedFirstHalfSize + estimatedSecondHalfSize < estimatedOriginalSize) {
ZSTD_deriveBlockSplitsHelper(splits, startIdx, midIdx, zc, origSeqStore);
splits->splitLocations[splits->idx] = (U32)midIdx;
splits->idx++;
ZSTD_deriveBlockSplitsHelper(splits, midIdx, endIdx, zc, origSeqStore);
}
}
/* Base recursive function. Populates a table with intra-block partition indices that can improve compression ratio.
*
* Returns the number of splits made (which equals the size of the partition table - 1).
*/
static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq) {
seqStoreSplits splits = {partitions, 0};
if (nbSeq <= 4) {
DEBUGLOG(4, "ZSTD_deriveBlockSplits: Too few sequences to split");
/* Refuse to try and split anything with less than 4 sequences */
return 0;
}
ZSTD_deriveBlockSplitsHelper(&splits, 0, nbSeq, zc, &zc->seqStore);
splits.splitLocations[splits.idx] = nbSeq;
DEBUGLOG(5, "ZSTD_deriveBlockSplits: final nb partitions: %zu", splits.idx+1);
return splits.idx;
}
/* ZSTD_compressBlock_splitBlock():
* Attempts to split a given block into multiple blocks to improve compression ratio.
*
* Returns combined size of all blocks (which includes headers), or a ZSTD error code.
*/
static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity,
const void* src, size_t blockSize, U32 lastBlock, U32 nbSeq) {
size_t cSize = 0;
const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst;
U32 partitions[MAX_NB_SPLITS];
size_t i = 0;
size_t srcBytesTotal = 0;
size_t numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
seqStore_t nextSeqStore;
seqStore_t currSeqStore;
/* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
* may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two
* separate repcode histories that simulate repcode history on compression and decompression side,
* and use the histories to determine whether we must replace a particular repcode with its raw offset.
*
* 1) cRep gets updated for each partition, regardless of whether the block was emitted as uncompressed
* or RLE. This allows us to retrieve the offset value that an invalid repcode references within
* a nocompress/RLE block.
* 2) dRep gets updated only for compressed partitions, and when a repcode gets replaced, will use
* the replacement offset value rather than the original repcode to update the repcode history.
* dRep also will be the final repcode history sent to the next block.
*
* See ZSTD_seqStore_resolveOffCodes() for more details.
*/
repcodes_t dRep;
repcodes_t cRep;
ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
(unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
(unsigned)zc->blockState.matchState.nextToUpdate);
if (numSplits == 0) {
size_t cSizeSingleBlock = ZSTD_compressSeqStore_singleBlock(zc, &zc->seqStore,
&dRep, &cRep,
op, dstCapacity,
ip, blockSize,
lastBlock, 0 /* isPartition */);
FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!");
DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits");
assert(cSizeSingleBlock <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize);
return cSizeSingleBlock;
}
ZSTD_deriveSeqStoreChunk(&currSeqStore, &zc->seqStore, 0, partitions[0]);
for (i = 0; i <= numSplits; ++i) {
size_t srcBytes;
size_t cSizeChunk;
U32 const lastPartition = (i == numSplits);
U32 lastBlockEntireSrc = 0;
srcBytes = ZSTD_countSeqStoreLiteralsBytes(&currSeqStore) + ZSTD_countSeqStoreMatchBytes(&currSeqStore);
srcBytesTotal += srcBytes;
if (lastPartition) {
/* This is the final partition, need to account for possible last literals */
srcBytes += blockSize - srcBytesTotal;
lastBlockEntireSrc = lastBlock;
} else {
ZSTD_deriveSeqStoreChunk(&nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]);
}
cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, &currSeqStore,
&dRep, &cRep,
op, dstCapacity,
ip, srcBytes,
lastBlockEntireSrc, 1 /* isPartition */);
DEBUGLOG(5, "Estimated size: %zu actual size: %zu", ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&currSeqStore, zc), cSizeChunk);
FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!");
ip += srcBytes;
op += cSizeChunk;
dstCapacity -= cSizeChunk;
cSize += cSizeChunk;
currSeqStore = nextSeqStore;
assert(cSizeChunk <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize);
}
/* cRep and dRep may have diverged during the compression. If so, we use the dRep repcodes
* for the next block.
*/
ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(repcodes_t));
return cSize;
}
static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize, U32 lastBlock) {
const BYTE* ip = (const BYTE*)src;
BYTE* op = (BYTE*)dst;
U32 nbSeq;
size_t cSize;
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock");
{ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
if (bss == ZSTDbss_noCompress) {
if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
DEBUGLOG(4, "ZSTD_compressBlock_splitBlock: Nocompress block");
return cSize;
}
nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart);
}
assert(zc->appliedParams.splitBlocks == 1);
cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq);
FORWARD_IF_ERROR(cSize, "Splitting blocks failed!");
return cSize;
} }
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
@@ -3733,12 +2723,12 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
if (zc->seqCollector.collectSequences) { if (zc->seqCollector.collectSequences) {
ZSTD_copyBlockSequences(zc); ZSTD_copyBlockSequences(zc);
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); ZSTD_confirmRepcodesAndEntropyTables(zc);
return 0; return 0;
} }
/* encode sequences and literals */ /* encode sequences and literals */
cSize = ZSTD_entropyCompressSeqStore(&zc->seqStore, cSize = ZSTD_entropyCompressSequences(&zc->seqStore,
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams, &zc->appliedParams,
dst, dstCapacity, dst, dstCapacity,
@@ -3767,7 +2757,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
out: out:
if (!ZSTD_isError(cSize) && cSize > 1) { if (!ZSTD_isError(cSize) && cSize > 1) {
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); ZSTD_confirmRepcodesAndEntropyTables(zc);
} }
/* We check that dictionaries have offset codes available for the first /* We check that dictionaries have offset codes available for the first
* block. After the first block, the offcode table might not have large * block. After the first block, the offcode table might not have large
@@ -3820,7 +2810,7 @@ static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc,
size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy); size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy);
FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed"); FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed");
if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) { if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) {
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); ZSTD_confirmRepcodesAndEntropyTables(zc);
return cSize; return cSize;
} }
} }
@@ -3860,9 +2850,9 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
void const* ip, void const* ip,
void const* iend) void const* iend)
{ {
U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy); if (ZSTD_window_needOverflowCorrection(ms->window, iend)) {
U32 const maxDist = (U32)1 << params->cParams.windowLog; U32 const maxDist = (U32)1 << params->cParams.windowLog;
if (ZSTD_window_needOverflowCorrection(ms->window, cycleLog, maxDist, ms->loadedDictEnd, ip, iend)) { U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy);
U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
@@ -3885,7 +2875,7 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
* Frame is supposed already started (header already produced) * Frame is supposed already started (header already produced)
* @return : compressed size, or an error code * @return : compressed size, or an error code
*/ */
static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
U32 lastFrameChunk) U32 lastFrameChunk)
@@ -3925,10 +2915,6 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed"); FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed");
assert(cSize > 0); assert(cSize > 0);
assert(cSize <= blockSize + ZSTD_blockHeaderSize); assert(cSize <= blockSize + ZSTD_blockHeaderSize);
} else if (ZSTD_blockSplitterEnabled(&cctx->appliedParams)) {
cSize = ZSTD_compressBlock_splitBlock(cctx, op, dstCapacity, ip, blockSize, lastBlock);
FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_splitBlock failed");
assert(cSize > 0 || cctx->seqCollector.collectSequences == 1);
} else { } else {
cSize = ZSTD_compressBlock_internal(cctx, cSize = ZSTD_compressBlock_internal(cctx,
op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
@@ -3991,7 +2977,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
if (!singleSegment) op[pos++] = windowLogByte; if (!singleSegment) op[pos++] = windowLogByte;
switch(dictIDSizeCode) switch(dictIDSizeCode)
{ {
default: assert(0); /* impossible */ default:
assert(0); /* impossible */
ZSTD_FALLTHROUGH;
case 0 : break; case 0 : break;
case 1 : op[pos] = (BYTE)(dictID); pos++; break; case 1 : op[pos] = (BYTE)(dictID); pos++; break;
case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break; case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
@@ -3999,7 +2987,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
} }
switch(fcsCode) switch(fcsCode)
{ {
default: assert(0); /* impossible */ default:
assert(0); /* impossible */
ZSTD_FALLTHROUGH;
case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break; case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break; case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break; case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
@@ -4084,12 +3074,11 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (!srcSize) return fhSize; /* do not generate an empty block if no input */ if (!srcSize) return fhSize; /* do not generate an empty block if no input */
if (!ZSTD_window_update(&ms->window, src, srcSize, ms->forceNonContiguous)) { if (!ZSTD_window_update(&ms->window, src, srcSize)) {
ms->forceNonContiguous = 0;
ms->nextToUpdate = ms->window.dictLimit; ms->nextToUpdate = ms->window.dictLimit;
} }
if (cctx->appliedParams.ldmParams.enableLdm) { if (cctx->appliedParams.ldmParams.enableLdm) {
ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0); ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
} }
if (!frame) { if (!frame) {
@@ -4157,86 +3146,63 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
{ {
const BYTE* ip = (const BYTE*) src; const BYTE* ip = (const BYTE*) src;
const BYTE* const iend = ip + srcSize; const BYTE* const iend = ip + srcSize;
int const loadLdmDict = params->ldmParams.enableLdm && ls != NULL;
ZSTD_window_update(&ms->window, src, srcSize);
ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
if (params->ldmParams.enableLdm && ls != NULL) {
ZSTD_window_update(&ls->window, src, srcSize);
ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
}
/* Assert that we the ms params match the params we're being given */ /* Assert that we the ms params match the params we're being given */
ZSTD_assertEqualCParams(params->cParams, ms->cParams); ZSTD_assertEqualCParams(params->cParams, ms->cParams);
if (srcSize > ZSTD_CHUNKSIZE_MAX) {
/* Allow the dictionary to set indices up to exactly ZSTD_CURRENT_MAX.
* Dictionaries right at the edge will immediately trigger overflow
* correction, but I don't want to insert extra constraints here.
*/
U32 const maxDictSize = ZSTD_CURRENT_MAX - 1;
/* We must have cleared our windows when our source is this large. */
assert(ZSTD_window_isEmpty(ms->window));
if (loadLdmDict)
assert(ZSTD_window_isEmpty(ls->window));
/* If the dictionary is too large, only load the suffix of the dictionary. */
if (srcSize > maxDictSize) {
ip = iend - maxDictSize;
src = ip;
srcSize = maxDictSize;
}
}
DEBUGLOG(4, "ZSTD_loadDictionaryContent(): useRowMatchFinder=%d", (int)params->useRowMatchFinder);
ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0);
ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
ms->forceNonContiguous = params->deterministicRefPrefix;
if (loadLdmDict) {
ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0);
ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
}
if (srcSize <= HASH_READ_SIZE) return 0; if (srcSize <= HASH_READ_SIZE) return 0;
ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, iend); while (iend - ip > HASH_READ_SIZE) {
size_t const remaining = (size_t)(iend - ip);
size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);
const BYTE* const ichunk = ip + chunk;
if (loadLdmDict) ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, ichunk);
ZSTD_ldm_fillHashTable(ls, ip, iend, &params->ldmParams);
switch(params->cParams.strategy) if (params->ldmParams.enableLdm && ls != NULL)
{ ZSTD_ldm_fillHashTable(ls, (const BYTE*)src, (const BYTE*)src + srcSize, &params->ldmParams);
case ZSTD_fast:
ZSTD_fillHashTable(ms, iend, dtlm);
break;
case ZSTD_dfast:
ZSTD_fillDoubleHashTable(ms, iend, dtlm);
break;
case ZSTD_greedy: switch(params->cParams.strategy)
case ZSTD_lazy: {
case ZSTD_lazy2: case ZSTD_fast:
assert(srcSize >= HASH_READ_SIZE); ZSTD_fillHashTable(ms, ichunk, dtlm);
if (ms->dedicatedDictSearch) { break;
assert(ms->chainTable != NULL); case ZSTD_dfast:
ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, iend-HASH_READ_SIZE); ZSTD_fillDoubleHashTable(ms, ichunk, dtlm);
} else { break;
assert(params->useRowMatchFinder != ZSTD_urm_auto);
if (params->useRowMatchFinder == ZSTD_urm_enableRowMatchFinder) { case ZSTD_greedy:
size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog) * sizeof(U16); case ZSTD_lazy:
ZSTD_memset(ms->tagTable, 0, tagTableSize); case ZSTD_lazy2:
ZSTD_row_update(ms, iend-HASH_READ_SIZE); if (chunk >= HASH_READ_SIZE && ms->dedicatedDictSearch) {
DEBUGLOG(4, "Using row-based hash table for lazy dict"); assert(chunk == remaining); /* must load everything in one go */
} else { ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, ichunk-HASH_READ_SIZE);
ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE); } else if (chunk >= HASH_READ_SIZE) {
DEBUGLOG(4, "Using chain-based hash table for lazy dict"); ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE);
} }
break;
case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
case ZSTD_btopt:
case ZSTD_btultra:
case ZSTD_btultra2:
if (chunk >= HASH_READ_SIZE)
ZSTD_updateTree(ms, ichunk-HASH_READ_SIZE, ichunk);
break;
default:
assert(0); /* not possible : not a valid strategy id */
} }
break;
case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ ip = ichunk;
case ZSTD_btopt:
case ZSTD_btultra:
case ZSTD_btultra2:
assert(srcSize >= HASH_READ_SIZE);
ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
break;
default:
assert(0); /* not possible : not a valid strategy id */
} }
ms->nextToUpdate = (U32)(iend - ms->window.base); ms->nextToUpdate = (U32)(iend - ms->window.base);
@@ -4375,6 +3341,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
const BYTE* const dictEnd = dictPtr + dictSize; const BYTE* const dictEnd = dictPtr + dictSize;
size_t dictID; size_t dictID;
size_t eSize; size_t eSize;
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
assert(dictSize >= 8); assert(dictSize >= 8);
assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY); assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
@@ -4445,9 +3412,8 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
const ZSTD_CCtx_params* params, U64 pledgedSrcSize, const ZSTD_CCtx_params* params, U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff) ZSTD_buffered_policy_e zbuff)
{ {
size_t const dictContentSize = cdict ? cdict->dictContentSize : dictSize;
#if ZSTD_TRACE #if ZSTD_TRACE
cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; cctx->traceCtx = ZSTD_trace_compress_begin(cctx);
#endif #endif
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog); DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog);
/* params are supposed to be fully validated at this point */ /* params are supposed to be fully validated at this point */
@@ -4463,8 +3429,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff); return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
} }
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,
dictContentSize,
ZSTDcrp_makeClean, zbuff) , ""); ZSTDcrp_makeClean, zbuff) , "");
{ size_t const dictID = cdict ? { size_t const dictID = cdict ?
ZSTD_compress_insertDictionary( ZSTD_compress_insertDictionary(
@@ -4479,7 +3444,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
assert(dictID <= UINT_MAX); assert(dictID <= UINT_MAX);
cctx->dictID = (U32)dictID; cctx->dictID = (U32)dictID;
cctx->dictContentSize = dictContentSize; cctx->dictContentSize = cdict ? cdict->dictContentSize : dictSize;
} }
return 0; return 0;
} }
@@ -4579,7 +3544,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize) void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
{ {
#if ZSTD_TRACE #if ZSTD_TRACE
if (cctx->traceCtx && ZSTD_trace_compress_end != NULL) { if (cctx->traceCtx) {
int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0; int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0;
ZSTD_Trace trace; ZSTD_Trace trace;
ZSTD_memset(&trace, 0, sizeof(trace)); ZSTD_memset(&trace, 0, sizeof(trace));
@@ -4632,14 +3597,15 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
const void* dict,size_t dictSize, const void* dict,size_t dictSize,
ZSTD_parameters params) ZSTD_parameters params)
{ {
ZSTD_CCtx_params cctxParams;
DEBUGLOG(4, "ZSTD_compress_advanced"); DEBUGLOG(4, "ZSTD_compress_advanced");
FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), "");
ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, &params, ZSTD_NO_CLEVEL); ZSTD_CCtxParams_init_internal(&cctxParams, &params, ZSTD_NO_CLEVEL);
return ZSTD_compress_advanced_internal(cctx, return ZSTD_compress_advanced_internal(cctx,
dst, dstCapacity, dst, dstCapacity,
src, srcSize, src, srcSize,
dict, dictSize, dict, dictSize,
&cctx->simpleApiParams); &cctxParams);
} }
/* Internal */ /* Internal */
@@ -4663,13 +3629,14 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize, const void* dict, size_t dictSize,
int compressionLevel) int compressionLevel)
{ {
ZSTD_CCtx_params cctxParams;
{ {
ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict); ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict);
assert(params.fParams.contentSizeFlag == 1); assert(params.fParams.contentSizeFlag == 1);
ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, &params, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT: compressionLevel); ZSTD_CCtxParams_init_internal(&cctxParams, &params, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT: compressionLevel);
} }
DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize); DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctx->simpleApiParams); return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);
} }
size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
@@ -4713,10 +3680,7 @@ size_t ZSTD_estimateCDictSize_advanced(
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict)); DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict));
return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
+ ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)
/* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)
* in case we are using DDS with row-hash. */
+ ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_urm_auto, &cParams),
/* enableDedicatedDictSearch */ 1, /* forCCtx */ 0)
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0 + (dictLoadMethod == ZSTD_dlm_byRef ? 0
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *)))); : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *))));
} }
@@ -4747,6 +3711,9 @@ static size_t ZSTD_initCDict_internal(
assert(!ZSTD_checkCParams(params.cParams)); assert(!ZSTD_checkCParams(params.cParams));
cdict->matchState.cParams = params.cParams; cdict->matchState.cParams = params.cParams;
cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch; cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch;
if (cdict->matchState.dedicatedDictSearch && dictSize > ZSTD_CHUNKSIZE_MAX) {
cdict->matchState.dedicatedDictSearch = 0;
}
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
cdict->dictContent = dictBuffer; cdict->dictContent = dictBuffer;
} else { } else {
@@ -4767,7 +3734,6 @@ static size_t ZSTD_initCDict_internal(
&cdict->matchState, &cdict->matchState,
&cdict->workspace, &cdict->workspace,
&params.cParams, &params.cParams,
params.useRowMatchFinder,
ZSTDcrp_makeClean, ZSTDcrp_makeClean,
ZSTDirp_reset, ZSTDirp_reset,
ZSTD_resetTarget_CDict), ""); ZSTD_resetTarget_CDict), "");
@@ -4791,17 +3757,14 @@ static size_t ZSTD_initCDict_internal(
static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize, static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_compressionParameters cParams, ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
U32 enableDedicatedDictSearch,
ZSTD_customMem customMem)
{ {
if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
{ size_t const workspaceSize = { size_t const workspaceSize =
ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) +
ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, enableDedicatedDictSearch, /* forCCtx */ 0) + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) +
(dictLoadMethod == ZSTD_dlm_byRef ? 0 (dictLoadMethod == ZSTD_dlm_byRef ? 0
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))); : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))));
void* const workspace = ZSTD_customMalloc(workspaceSize, customMem); void* const workspace = ZSTD_customMalloc(workspaceSize, customMem);
@@ -4820,7 +3783,7 @@ static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
ZSTD_cwksp_move(&cdict->workspace, &ws); ZSTD_cwksp_move(&cdict->workspace, &ws);
cdict->customMem = customMem; cdict->customMem = customMem;
cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */ cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */
cdict->useRowMatchFinder = useRowMatchFinder;
return cdict; return cdict;
} }
} }
@@ -4872,13 +3835,10 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2(
&cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
} }
DEBUGLOG(3, "ZSTD_createCDict_advanced2: DDS: %u", cctxParams.enableDedicatedDictSearch);
cctxParams.cParams = cParams; cctxParams.cParams = cParams;
cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
cdict = ZSTD_createCDict_advanced_internal(dictSize, cdict = ZSTD_createCDict_advanced_internal(dictSize,
dictLoadMethod, cctxParams.cParams, dictLoadMethod, cctxParams.cParams,
cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch,
customMem); customMem);
if (ZSTD_isError( ZSTD_initCDict_internal(cdict, if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
@@ -4947,9 +3907,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
ZSTD_dictContentType_e dictContentType, ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams) ZSTD_compressionParameters cParams)
{ {
ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_urm_auto, &cParams); size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
/* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0);
size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0 + (dictLoadMethod == ZSTD_dlm_byRef ? 0
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))) : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))))
@@ -4974,8 +3932,6 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
ZSTD_CCtxParams_init(&params, 0); ZSTD_CCtxParams_init(&params, 0);
params.cParams = cParams; params.cParams = cParams;
params.useRowMatchFinder = useRowMatchFinder;
cdict->useRowMatchFinder = useRowMatchFinder;
if (ZSTD_isError( ZSTD_initCDict_internal(cdict, if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dict, dictSize, dict, dictSize,
@@ -5002,15 +3958,15 @@ unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict)
return cdict->dictID; return cdict->dictID;
} }
/* ZSTD_compressBegin_usingCDict_internal() :
* Implementation of various ZSTD_compressBegin_usingCDict* functions. /* ZSTD_compressBegin_usingCDict_advanced() :
*/ * cdict must be != NULL */
static size_t ZSTD_compressBegin_usingCDict_internal( size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{ {
ZSTD_CCtx_params cctxParams; ZSTD_CCtx_params cctxParams;
DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_internal"); DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!"); RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!");
/* Initialize the cctxParams from the cdict */ /* Initialize the cctxParams from the cdict */
{ {
@@ -5042,46 +3998,23 @@ static size_t ZSTD_compressBegin_usingCDict_internal(
ZSTDb_not_buffered); ZSTDb_not_buffered);
} }
/* ZSTD_compressBegin_usingCDict_advanced() :
* This function is DEPRECATED.
* cdict must be != NULL */
size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, pledgedSrcSize);
}
/* ZSTD_compressBegin_usingCDict() : /* ZSTD_compressBegin_usingCDict() :
* cdict must be != NULL */ * pledgedSrcSize=0 means "unknown"
* if pledgedSrcSize>0, it will enable contentSizeFlag */
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
{ {
ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN);
} }
/*! ZSTD_compress_usingCDict_internal():
* Implementation of various ZSTD_compress_usingCDict* functions.
*/
static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
{
FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
/*! ZSTD_compress_usingCDict_advanced():
* This function is DEPRECATED.
*/
size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
{ {
return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
} }
/*! ZSTD_compress_usingCDict() : /*! ZSTD_compress_usingCDict() :
@@ -5095,7 +4028,7 @@ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
const ZSTD_CDict* cdict) const ZSTD_CDict* cdict)
{ {
ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, fParams);
} }
@@ -5403,7 +4336,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
zcs->outBuffFlushedSize = 0; zcs->outBuffFlushedSize = 0;
zcs->streamStage = zcss_flush; /* pass-through to flush stage */ zcs->streamStage = zcss_flush; /* pass-through to flush stage */
} }
/* fall-through */ ZSTD_FALLTHROUGH;
case zcss_flush: case zcss_flush:
DEBUGLOG(5, "flush stage"); DEBUGLOG(5, "flush stage");
assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered); assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
@@ -5505,13 +4438,8 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */ FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */ ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */ assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
if (cctx->cdict && !cctx->localDict.cdict) { if (cctx->cdict)
/* Let the cdict's compression level take priority over the requested params. params.compressionLevel = cctx->cdict->compressionLevel; /* let cdict take priority in terms of compression level */
* But do not take the cdict's compression level if the "cdict" is actually a localDict
* generated from ZSTD_initLocalDict().
*/
params.compressionLevel = cctx->cdict->compressionLevel;
}
DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage"); DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-fix pledgedSrcSize */ if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-fix pledgedSrcSize */
{ {
@@ -5530,20 +4458,13 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
params.ldmParams.enableLdm = 1; params.ldmParams.enableLdm = 1;
} }
if (ZSTD_CParams_useBlockSplitter(&params.cParams)) {
DEBUGLOG(4, "Block splitter enabled by default (window size >= 128K, strategy >= btopt)");
params.splitBlocks = 1;
}
params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, &params.cParams);
#ifdef ZSTD_MULTITHREAD #ifdef ZSTD_MULTITHREAD
if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */ params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
} }
if (params.nbWorkers > 0) { if (params.nbWorkers > 0) {
#if ZSTD_TRACE #if ZSTD_TRACE
cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; cctx->traceCtx = ZSTD_trace_compress_begin(cctx);
#endif #endif
/* mt context creation */ /* mt context creation */
if (cctx->mtctx == NULL) { if (cctx->mtctx == NULL) {
@@ -6011,7 +4932,7 @@ static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
continue; continue;
} }
compressedSeqsSize = ZSTD_entropyCompressSeqStore(&cctx->seqStore, compressedSeqsSize = ZSTD_entropyCompressSequences(&cctx->seqStore,
&cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy, &cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy,
&cctx->appliedParams, &cctx->appliedParams,
op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize, op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
@@ -6043,7 +4964,7 @@ static size_t ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
} else { } else {
U32 cBlockHeader; U32 cBlockHeader;
/* Error checking and repcodes update */ /* Error checking and repcodes update */
ZSTD_blockState_confirmRepcodesAndEntropyTables(&cctx->blockState); ZSTD_confirmRepcodesAndEntropyTables(cctx);
if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
@@ -6144,7 +5065,6 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
#define ZSTD_MAX_CLEVEL 22 #define ZSTD_MAX_CLEVEL 22
int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; }
static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
{ /* "default" - for any srcSize > 256 KB */ { /* "default" - for any srcSize > 256 KB */
@@ -6279,7 +5199,7 @@ static int ZSTD_dedicatedDictSearch_isSupported(
{ {
return (cParams->strategy >= ZSTD_greedy) return (cParams->strategy >= ZSTD_greedy)
&& (cParams->strategy <= ZSTD_lazy2) && (cParams->strategy <= ZSTD_lazy2)
&& (cParams->hashLog > cParams->chainLog) && (cParams->hashLog >= cParams->chainLog)
&& (cParams->chainLog <= 24); && (cParams->chainLog <= 24);
} }
@@ -6298,9 +5218,6 @@ static void ZSTD_dedicatedDictSearch_revertCParams(
case ZSTD_lazy: case ZSTD_lazy:
case ZSTD_lazy2: case ZSTD_lazy2:
cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG; cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG;
if (cParams->hashLog < ZSTD_HASHLOG_MIN) {
cParams->hashLog = ZSTD_HASHLOG_MIN;
}
break; break;
case ZSTD_btlazy2: case ZSTD_btlazy2:
case ZSTD_btopt: case ZSTD_btopt:
@@ -6349,7 +5266,6 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel,
else row = compressionLevel; else row = compressionLevel;
{ ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
DEBUGLOG(5, "ZSTD_getCParams_internal selected tableID: %u row: %u strat: %u", tableID, row, (U32)cp.strategy);
/* acceleration factor */ /* acceleration factor */
if (compressionLevel < 0) { if (compressionLevel < 0) {
int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel); int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel);
+20 -164
View File
@@ -81,53 +81,6 @@ typedef struct {
ZSTD_fseCTables_t fse; ZSTD_fseCTables_t fse;
} ZSTD_entropyCTables_t; } ZSTD_entropyCTables_t;
/***********************************************
* Entropy buffer statistics structs and funcs *
***********************************************/
/** ZSTD_hufCTablesMetadata_t :
* Stores Literals Block Type for a super-block in hType, and
* huffman tree description in hufDesBuffer.
* hufDesSize refers to the size of huffman tree description in bytes.
* This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */
typedef struct {
symbolEncodingType_e hType;
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
size_t hufDesSize;
} ZSTD_hufCTablesMetadata_t;
/** ZSTD_fseCTablesMetadata_t :
* Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
* fse tables in fseTablesBuffer.
* fseTablesSize refers to the size of fse tables in bytes.
* This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */
typedef struct {
symbolEncodingType_e llType;
symbolEncodingType_e ofType;
symbolEncodingType_e mlType;
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
size_t fseTablesSize;
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
} ZSTD_fseCTablesMetadata_t;
typedef struct {
ZSTD_hufCTablesMetadata_t hufMetadata;
ZSTD_fseCTablesMetadata_t fseMetadata;
} ZSTD_entropyCTablesMetadata_t;
/** ZSTD_buildBlockEntropyStats() :
* Builds entropy for the block.
* @return : 0 on success or error code */
size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
ZSTD_entropyCTablesMetadata_t* entropyMetadata,
void* workspace, size_t wkspSize);
/*********************************
* Compression internals structs *
*********************************/
typedef struct { typedef struct {
U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */ U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
U32 len; /* Raw length of match */ U32 len; /* Raw length of match */
@@ -188,21 +141,14 @@ typedef struct {
} ZSTD_compressedBlockState_t; } ZSTD_compressedBlockState_t;
typedef struct { typedef struct {
BYTE const* nextSrc; /* next block here to continue on current prefix */ BYTE const* nextSrc; /* next block here to continue on current prefix */
BYTE const* base; /* All regular indexes relative to this position */ BYTE const* base; /* All regular indexes relative to this position */
BYTE const* dictBase; /* extDict indexes relative to this position */ BYTE const* dictBase; /* extDict indexes relative to this position */
U32 dictLimit; /* below that point, need extDict */ U32 dictLimit; /* below that point, need extDict */
U32 lowLimit; /* below that point, no more valid data */ U32 lowLimit; /* below that point, no more valid data */
U32 nbOverflowCorrections; /* Number of times overflow correction has run since
* ZSTD_window_init(). Useful for debugging coredumps
* and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY.
*/
} ZSTD_window_t; } ZSTD_window_t;
typedef struct ZSTD_matchState_t ZSTD_matchState_t; typedef struct ZSTD_matchState_t ZSTD_matchState_t;
#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
struct ZSTD_matchState_t { struct ZSTD_matchState_t {
ZSTD_window_t window; /* State for window round buffer management */ ZSTD_window_t window; /* State for window round buffer management */
U32 loadedDictEnd; /* index of end of dictionary, within context's referential. U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
@@ -214,17 +160,9 @@ struct ZSTD_matchState_t {
*/ */
U32 nextToUpdate; /* index from which to continue table update */ U32 nextToUpdate; /* index from which to continue table update */
U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */ U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */
U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/
U16* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */
U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */
U32* hashTable; U32* hashTable;
U32* hashTable3; U32* hashTable3;
U32* chainTable; U32* chainTable;
U32 forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */
int dedicatedDictSearch; /* Indicates whether this matchState is using the int dedicatedDictSearch; /* Indicates whether this matchState is using the
* dedicated dictionary search structure. * dedicated dictionary search structure.
*/ */
@@ -317,15 +255,6 @@ struct ZSTD_CCtx_params_s {
ZSTD_sequenceFormat_e blockDelimiters; ZSTD_sequenceFormat_e blockDelimiters;
int validateSequences; int validateSequences;
/* Block splitting */
int splitBlocks;
/* Param for deciding whether to use row-based matchfinder */
ZSTD_useRowMatchFinderMode_e useRowMatchFinder;
/* Always load a dictionary in ext-dict mode (not prefix mode)? */
int deterministicRefPrefix;
/* Internal use, for createCCtxParams() and freeCCtxParams() only */ /* Internal use, for createCCtxParams() and freeCCtxParams() only */
ZSTD_customMem customMem; ZSTD_customMem customMem;
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */ }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
@@ -349,7 +278,6 @@ struct ZSTD_CCtx_s {
int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
ZSTD_CCtx_params requestedParams; ZSTD_CCtx_params requestedParams;
ZSTD_CCtx_params appliedParams; ZSTD_CCtx_params appliedParams;
ZSTD_CCtx_params simpleApiParams; /* Param storage used by the simple API - not sticky. Must only be used in top-level simple API functions for storage. */
U32 dictID; U32 dictID;
size_t dictContentSize; size_t dictContentSize;
@@ -442,7 +370,7 @@ typedef enum {
typedef size_t (*ZSTD_blockCompressor) ( typedef size_t (*ZSTD_blockCompressor) (
ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e rowMatchfinderMode, ZSTD_dictMode_e dictMode); ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode);
MEM_STATIC U32 ZSTD_LLcode(U32 litLength) MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
@@ -558,7 +486,7 @@ MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParam
return 1; return 1;
default: default:
assert(0 /* impossible: pre-validated */); assert(0 /* impossible: pre-validated */);
/* fall-through */ ZSTD_FALLTHROUGH;
case ZSTD_lcm_auto: case ZSTD_lcm_auto:
return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
} }
@@ -619,8 +547,8 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
/* literal Length */ /* literal Length */
if (litLength>0xFFFF) { if (litLength>0xFFFF) {
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
seqStorePtr->longLengthType = ZSTD_llt_literalLength; seqStorePtr->longLengthID = 1;
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
} }
seqStorePtr->sequences[0].litLength = (U16)litLength; seqStorePtr->sequences[0].litLength = (U16)litLength;
@@ -630,8 +558,8 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
/* match Length */ /* match Length */
if (mlBase>0xFFFF) { if (mlBase>0xFFFF) {
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */
seqStorePtr->longLengthType = ZSTD_llt_matchLength; seqStorePtr->longLengthID = 2;
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
} }
seqStorePtr->sequences[0].matchLength = (U16)mlBase; seqStorePtr->sequences[0].matchLength = (U16)mlBase;
@@ -882,13 +810,6 @@ MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)
window->dictLimit = end; window->dictLimit = end;
} }
MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window)
{
return window.dictLimit == 1 &&
window.lowLimit == 1 &&
(window.nextSrc - window.base) == 1;
}
/** /**
* ZSTD_window_hasExtDict(): * ZSTD_window_hasExtDict():
* Returns non-zero if the window has a non-empty extDict. * Returns non-zero if the window has a non-empty extDict.
@@ -912,69 +833,15 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
ZSTD_noDict; ZSTD_noDict;
} }
/* Defining this macro to non-zero tells zstd to run the overflow correction
* code much more frequently. This is very inefficient, and should only be
* used for tests and fuzzers.
*/
#ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY
# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1
# else
# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0
# endif
#endif
/**
* ZSTD_window_canOverflowCorrect():
* Returns non-zero if the indices are large enough for overflow correction
* to work correctly without impacting compression ratio.
*/
MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window,
U32 cycleLog,
U32 maxDist,
U32 loadedDictEnd,
void const* src)
{
U32 const cycleSize = 1u << cycleLog;
U32 const curr = (U32)((BYTE const*)src - window.base);
U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize);
/* Adjust the min index to backoff the overflow correction frequency,
* so we don't waste too much CPU in overflow correction. If this
* computation overflows we don't really care, we just need to make
* sure it is at least minIndexToOverflowCorrect.
*/
U32 const adjustment = window.nbOverflowCorrections + 1;
U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment,
minIndexToOverflowCorrect);
U32 const indexLargeEnough = curr > adjustedIndex;
/* Only overflow correct early if the dictionary is invalidated already,
* so we don't hurt compression ratio.
*/
U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd;
return indexLargeEnough && dictionaryInvalidated;
}
/** /**
* ZSTD_window_needOverflowCorrection(): * ZSTD_window_needOverflowCorrection():
* Returns non-zero if the indices are getting too large and need overflow * Returns non-zero if the indices are getting too large and need overflow
* protection. * protection.
*/ */
MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
U32 cycleLog,
U32 maxDist,
U32 loadedDictEnd,
void const* src,
void const* srcEnd) void const* srcEnd)
{ {
U32 const curr = (U32)((BYTE const*)srcEnd - window.base); U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
if (ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) {
if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) {
return 1;
}
}
return curr > ZSTD_CURRENT_MAX; return curr > ZSTD_CURRENT_MAX;
} }
@@ -986,6 +853,7 @@ MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
* *
* The least significant cycleLog bits of the indices must remain the same, * The least significant cycleLog bits of the indices must remain the same,
* which may be 0. Every index up to maxDist in the past must be valid. * which may be 0. Every index up to maxDist in the past must be valid.
* NOTE: (maxDist & cycleMask) must be zero.
*/ */
MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
U32 maxDist, void const* src) U32 maxDist, void const* src)
@@ -1009,25 +877,17 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
* 3. (cctx->lowLimit + 1<<windowLog) < 1<<32: * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:
* windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32. * windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
*/ */
U32 const cycleSize = 1u << cycleLog; U32 const cycleMask = (1U << cycleLog) - 1;
U32 const cycleMask = cycleSize - 1;
U32 const curr = (U32)((BYTE const*)src - window->base); U32 const curr = (U32)((BYTE const*)src - window->base);
U32 const currentCycle0 = curr & cycleMask; U32 const currentCycle0 = curr & cycleMask;
/* Exclude zero so that newCurrent - maxDist >= 1. */ /* Exclude zero so that newCurrent - maxDist >= 1. */
U32 const currentCycle1 = currentCycle0 == 0 ? cycleSize : currentCycle0; U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
U32 const newCurrent = currentCycle1 + MAX(maxDist, cycleSize); U32 const newCurrent = currentCycle1 + maxDist;
U32 const correction = curr - newCurrent; U32 const correction = curr - newCurrent;
/* maxDist must be a power of two so that: assert((maxDist & cycleMask) == 0);
* (newCurrent & cycleMask) == (curr & cycleMask)
* This is required to not corrupt the chains / binary tree.
*/
assert((maxDist & (maxDist - 1)) == 0);
assert((curr & cycleMask) == (newCurrent & cycleMask));
assert(curr > newCurrent); assert(curr > newCurrent);
if (!ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { /* Loose bound, should be around 1<<29 (see above) */
/* Loose bound, should be around 1<<29 (see above) */ assert(correction > 1<<28);
assert(correction > 1<<28);
}
window->base += correction; window->base += correction;
window->dictBase += correction; window->dictBase += correction;
@@ -1043,8 +903,6 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
assert(window->lowLimit <= newCurrent); assert(window->lowLimit <= newCurrent);
assert(window->dictLimit <= newCurrent); assert(window->dictLimit <= newCurrent);
++window->nbOverflowCorrections;
DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
window->lowLimit); window->lowLimit);
return correction; return correction;
@@ -1154,7 +1012,6 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
window->dictLimit = 1; /* start from 1, so that 1st position is valid */ window->dictLimit = 1; /* start from 1, so that 1st position is valid */
window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */ window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
window->nextSrc = window->base + 1; /* see issue #1241 */ window->nextSrc = window->base + 1; /* see issue #1241 */
window->nbOverflowCorrections = 0;
} }
/** /**
@@ -1165,8 +1022,7 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
* Returns non-zero if the segment is contiguous. * Returns non-zero if the segment is contiguous.
*/ */
MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window, MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
void const* src, size_t srcSize, void const* src, size_t srcSize)
int forceNonContiguous)
{ {
BYTE const* const ip = (BYTE const*)src; BYTE const* const ip = (BYTE const*)src;
U32 contiguous = 1; U32 contiguous = 1;
@@ -1176,7 +1032,7 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
assert(window->base != NULL); assert(window->base != NULL);
assert(window->dictBase != NULL); assert(window->dictBase != NULL);
/* Check if blocks follow each other */ /* Check if blocks follow each other */
if (src != window->nextSrc || forceNonContiguous) { if (src != window->nextSrc) {
/* not contiguous */ /* not contiguous */
size_t const distanceFromBase = (size_t)(window->nextSrc - window->base); size_t const distanceFromBase = (size_t)(window->nextSrc - window->base);
DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit); DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit);
+1 -1
View File
@@ -117,7 +117,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
} }
} }
if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) { if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
} }
-2
View File
@@ -85,8 +85,6 @@ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t
{ {
unsigned cost = 0; unsigned cost = 0;
unsigned s; unsigned s;
assert(total > 0);
for (s = 0; s <= max; ++s) { for (s = 0; s <= max; ++s) {
unsigned norm = (unsigned)((256 * count[s]) / total); unsigned norm = (unsigned)((256 * count[s]) / total);
if (count[s] != 0 && norm == 0) if (count[s] != 0 && norm == 0)
+284 -4
View File
@@ -15,10 +15,289 @@
#include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */ #include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */
#include "hist.h" /* HIST_countFast_wksp */ #include "hist.h" /* HIST_countFast_wksp */
#include "zstd_compress_internal.h" /* ZSTD_[huf|fse|entropy]CTablesMetadata_t */ #include "zstd_compress_internal.h"
#include "zstd_compress_sequences.h" #include "zstd_compress_sequences.h"
#include "zstd_compress_literals.h" #include "zstd_compress_literals.h"
/*-*************************************
* Superblock entropy buffer structs
***************************************/
/** ZSTD_hufCTablesMetadata_t :
* Stores Literals Block Type for a super-block in hType, and
* huffman tree description in hufDesBuffer.
* hufDesSize refers to the size of huffman tree description in bytes.
* This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
typedef struct {
symbolEncodingType_e hType;
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
size_t hufDesSize;
} ZSTD_hufCTablesMetadata_t;
/** ZSTD_fseCTablesMetadata_t :
* Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
* fse tables in fseTablesBuffer.
* fseTablesSize refers to the size of fse tables in bytes.
* This metadata is populated in ZSTD_buildSuperBlockEntropy_sequences() */
typedef struct {
symbolEncodingType_e llType;
symbolEncodingType_e ofType;
symbolEncodingType_e mlType;
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
size_t fseTablesSize;
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
} ZSTD_fseCTablesMetadata_t;
typedef struct {
ZSTD_hufCTablesMetadata_t hufMetadata;
ZSTD_fseCTablesMetadata_t fseMetadata;
} ZSTD_entropyCTablesMetadata_t;
/** ZSTD_buildSuperBlockEntropy_literal() :
* Builds entropy for the super-block literals.
* Stores literals block type (raw, rle, compressed, repeat) and
* huffman description table to hufMetadata.
* @return : size of huffman description table or error code */
static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSize,
const ZSTD_hufCTables_t* prevHuf,
ZSTD_hufCTables_t* nextHuf,
ZSTD_hufCTablesMetadata_t* hufMetadata,
const int disableLiteralsCompression,
void* workspace, size_t wkspSize)
{
BYTE* const wkspStart = (BYTE*)workspace;
BYTE* const wkspEnd = wkspStart + wkspSize;
BYTE* const countWkspStart = wkspStart;
unsigned* const countWksp = (unsigned*)workspace;
const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
BYTE* const nodeWksp = countWkspStart + countWkspSize;
const size_t nodeWkspSize = wkspEnd-nodeWksp;
unsigned maxSymbolValue = 255;
unsigned huffLog = HUF_TABLELOG_DEFAULT;
HUF_repeat repeat = prevHuf->repeatMode;
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
/* Prepare nextEntropy assuming reusing the existing table */
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
if (disableLiteralsCompression) {
DEBUGLOG(5, "set_basic - disabled");
hufMetadata->hType = set_basic;
return 0;
}
/* small ? don't even attempt compression (speed opt) */
# define COMPRESS_LITERALS_SIZE_MIN 63
{ size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
if (srcSize <= minLitSize) {
DEBUGLOG(5, "set_basic - too small");
hufMetadata->hType = set_basic;
return 0;
}
}
/* Scan input and build symbol stats */
{ size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize);
FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
if (largest == srcSize) {
DEBUGLOG(5, "set_rle");
hufMetadata->hType = set_rle;
return 0;
}
if (largest <= (srcSize >> 7)+4) {
DEBUGLOG(5, "set_basic - no gain");
hufMetadata->hType = set_basic;
return 0;
}
}
/* Validate the previous Huffman table */
if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
repeat = HUF_repeat_none;
}
/* Build Huffman Tree */
ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
{ size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
maxSymbolValue, huffLog,
nodeWksp, nodeWkspSize);
FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
huffLog = (U32)maxBits;
{ /* Build and write the CTable */
size_t const newCSize = HUF_estimateCompressedSize(
(HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
size_t const hSize = HUF_writeCTable_wksp(
hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
(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(
(HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
DEBUGLOG(5, "set_repeat - smaller");
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_repeat;
return 0;
}
}
if (newCSize + hSize >= srcSize) {
DEBUGLOG(5, "set_basic - no gains");
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
hufMetadata->hType = set_basic;
return 0;
}
DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
hufMetadata->hType = set_compressed;
nextHuf->repeatMode = HUF_repeat_check;
return hSize;
}
}
}
/** ZSTD_buildSuperBlockEntropy_sequences() :
* Builds entropy for the super-block sequences.
* Stores symbol compression modes and fse table to fseMetadata.
* @return : size of fse tables or error code */
static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
const ZSTD_fseCTables_t* prevEntropy,
ZSTD_fseCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
ZSTD_fseCTablesMetadata_t* fseMetadata,
void* workspace, size_t wkspSize)
{
BYTE* const wkspStart = (BYTE*)workspace;
BYTE* const wkspEnd = wkspStart + wkspSize;
BYTE* const countWkspStart = wkspStart;
unsigned* const countWksp = (unsigned*)workspace;
const size_t countWkspSize = (MaxSeq + 1) * sizeof(unsigned);
BYTE* const cTableWksp = countWkspStart + countWkspSize;
const size_t cTableWkspSize = wkspEnd-cTableWksp;
ZSTD_strategy const strategy = cctxParams->cParams.strategy;
FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
const BYTE* const llCodeTable = seqStorePtr->llCode;
const BYTE* const mlCodeTable = seqStorePtr->mlCode;
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
BYTE* const ostart = fseMetadata->fseTablesBuffer;
BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
BYTE* op = ostart;
assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
ZSTD_memset(workspace, 0, wkspSize);
fseMetadata->lastCountSize = 0;
/* convert length/distances into codes */
ZSTD_seqToCodes(seqStorePtr);
/* build CTable for Literal Lengths */
{ U32 LLtype;
unsigned max = MaxLL;
size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
DEBUGLOG(5, "Building LL table");
nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
countWksp, max, mostFrequent, nbSeq,
LLFSELog, prevEntropy->litlengthCTable,
LL_defaultNorm, LL_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(set_basic < set_compressed && set_rle < set_compressed);
assert(!(LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
countWksp, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
cTableWksp, cTableWkspSize);
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
if (LLtype == set_compressed)
fseMetadata->lastCountSize = countSize;
op += countSize;
fseMetadata->llType = (symbolEncodingType_e) LLtype;
} }
/* build CTable for Offsets */
{ U32 Offtype;
unsigned max = MaxOff;
size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
DEBUGLOG(5, "Building OF table");
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
countWksp, max, mostFrequent, nbSeq,
OffFSELog, prevEntropy->offcodeCTable,
OF_defaultNorm, OF_defaultNormLog,
defaultPolicy, strategy);
assert(!(Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
countWksp, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
cTableWksp, cTableWkspSize);
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
if (Offtype == set_compressed)
fseMetadata->lastCountSize = countSize;
op += countSize;
fseMetadata->ofType = (symbolEncodingType_e) Offtype;
} }
/* build CTable for MatchLengths */
{ U32 MLtype;
unsigned max = MaxML;
size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode,
countWksp, max, mostFrequent, nbSeq,
MLFSELog, prevEntropy->matchlengthCTable,
ML_defaultNorm, ML_defaultNormLog,
ZSTD_defaultAllowed, strategy);
assert(!(MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
countWksp, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
cTableWksp, cTableWkspSize);
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
if (MLtype == set_compressed)
fseMetadata->lastCountSize = countSize;
op += countSize;
fseMetadata->mlType = (symbolEncodingType_e) MLtype;
} }
assert((size_t) (op-ostart) <= sizeof(fseMetadata->fseTablesBuffer));
return op-ostart;
}
/** ZSTD_buildSuperBlockEntropy() :
* Builds entropy for the super-block.
* @return : 0 on success or error code */
static size_t
ZSTD_buildSuperBlockEntropy(seqStore_t* seqStorePtr,
const ZSTD_entropyCTables_t* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy,
const ZSTD_CCtx_params* cctxParams,
ZSTD_entropyCTablesMetadata_t* entropyMetadata,
void* workspace, size_t wkspSize)
{
size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart;
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy");
entropyMetadata->hufMetadata.hufDesSize =
ZSTD_buildSuperBlockEntropy_literal(seqStorePtr->litStart, litSize,
&prevEntropy->huf, &nextEntropy->huf,
&entropyMetadata->hufMetadata,
ZSTD_disableLiteralsCompression(cctxParams),
workspace, wkspSize);
FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildSuperBlockEntropy_literal failed");
entropyMetadata->fseMetadata.fseTablesSize =
ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr,
&prevEntropy->fse, &nextEntropy->fse,
cctxParams,
&entropyMetadata->fseMetadata,
workspace, wkspSize);
FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildSuperBlockEntropy_sequences failed");
return 0;
}
/** ZSTD_compressSubBlock_literal() : /** ZSTD_compressSubBlock_literal() :
* Compresses literals section for a sub-block. * Compresses literals section for a sub-block.
* When we have to write the Huffman table we will sometimes choose a header * When we have to write the Huffman table we will sometimes choose a header
@@ -132,6 +411,8 @@ static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef*
const seqDef* sp = sstart; const seqDef* sp = sstart;
size_t matchLengthSum = 0; size_t matchLengthSum = 0;
size_t litLengthSum = 0; size_t litLengthSum = 0;
/* Only used by assert(), suppress unused variable warnings in production. */
(void)litLengthSum;
while (send-sp > 0) { while (send-sp > 0) {
ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp); ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
litLengthSum += seqLen.litLength; litLengthSum += seqLen.litLength;
@@ -365,9 +646,8 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
void* workspace, size_t wkspSize, void* workspace, size_t wkspSize,
int writeEntropy) int writeEntropy)
{ {
size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ size_t sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
size_t cSeqSizeEstimate = 0; size_t cSeqSizeEstimate = 0;
if (nbSeq == 0) return sequencesSectionHeaderSize;
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
nbSeq, fseTables->offcodeCTable, NULL, nbSeq, fseTables->offcodeCTable, NULL,
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
@@ -553,7 +833,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
unsigned lastBlock) { unsigned lastBlock) {
ZSTD_entropyCTablesMetadata_t entropyMetadata; ZSTD_entropyCTablesMetadata_t entropyMetadata;
FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore, FORWARD_IF_ERROR(ZSTD_buildSuperBlockEntropy(&zc->seqStore,
&zc->blockState.prevCBlock->entropy, &zc->blockState.prevCBlock->entropy,
&zc->blockState.nextCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams, &zc->appliedParams,
+45 -146
View File
@@ -35,10 +35,6 @@ extern "C" {
#define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128 #define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128
#endif #endif
/* Set our tables and aligneds to align by 64 bytes */
#define ZSTD_CWKSP_ALIGNMENT_BYTES 64
/*-************************************* /*-*************************************
* Structures * Structures
***************************************/ ***************************************/
@@ -121,11 +117,10 @@ typedef enum {
* - Tables: these are any of several different datastructures (hash tables, * - Tables: these are any of several different datastructures (hash tables,
* chain tables, binary trees) that all respect a common format: they are * chain tables, binary trees) that all respect a common format: they are
* uint32_t arrays, all of whose values are between 0 and (nextSrc - base). * uint32_t arrays, all of whose values are between 0 and (nextSrc - base).
* Their sizes depend on the cparams. These tables are 64-byte aligned. * Their sizes depend on the cparams.
* *
* - Aligned: these buffers are used for various purposes that require 4 byte * - Aligned: these buffers are used for various purposes that require 4 byte
* alignment, but don't require any initialization before they're used. These * alignment, but don't require any initialization before they're used.
* buffers are each aligned to 64 bytes.
* *
* - Buffers: these buffers are used for various purposes that don't require * - Buffers: these buffers are used for various purposes that don't require
* any alignment or initialization before they're used. This means they can * any alignment or initialization before they're used. This means they can
@@ -138,7 +133,8 @@ typedef enum {
* *
* 1. Objects * 1. Objects
* 2. Buffers * 2. Buffers
* 3. Aligned/Tables * 3. Aligned
* 4. Tables
* *
* Attempts to reserve objects of different types out of order will fail. * Attempts to reserve objects of different types out of order will fail.
*/ */
@@ -191,8 +187,6 @@ MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) {
* Since tables aren't currently redzoned, you don't need to call through this * Since tables aren't currently redzoned, you don't need to call through this
* to figure out how much space you need for the matchState tables. Everything * to figure out how much space you need for the matchState tables. Everything
* else is though. * else is though.
*
* Do not use for sizing aligned buffers. Instead, use ZSTD_cwksp_aligned_alloc_size().
*/ */
MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) { MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) {
if (size == 0) if (size == 0)
@@ -204,110 +198,30 @@ MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) {
#endif #endif
} }
/** MEM_STATIC void ZSTD_cwksp_internal_advance_phase(
* Returns an adjusted alloc size that is the nearest larger multiple of 64 bytes.
* Used to determine the number of bytes required for a given "aligned".
*/
MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size) {
return ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(size, ZSTD_CWKSP_ALIGNMENT_BYTES));
}
/**
* Returns the amount of additional space the cwksp must allocate
* for internal purposes (currently only alignment).
*/
MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) {
/* For alignment, the wksp will always allocate an additional n_1=[1, 64] bytes
* to align the beginning of tables section, as well as another n_2=[0, 63] bytes
* to align the beginning of the aligned secion.
*
* n_1 + n_2 == 64 bytes if the cwksp is freshly allocated, due to tables and
* aligneds being sized in multiples of 64 bytes.
*/
size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES;
return slackSpace;
}
/**
* Return the number of additional bytes required to align a pointer to the given number of bytes.
* alignBytes must be a power of two.
*/
MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignBytes) {
size_t const alignBytesMask = alignBytes - 1;
size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask;
assert((alignBytes & alignBytesMask) == 0);
assert(bytes != ZSTD_CWKSP_ALIGNMENT_BYTES);
return bytes;
}
/**
* Internal function. Do not use directly.
* Reserves the given number of bytes within the aligned/buffer segment of the wksp, which
* counts from the end of the wksp. (as opposed to the object/table segment)
*
* Returns a pointer to the beginning of that space.
*/
MEM_STATIC void* ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes) {
void* const alloc = (BYTE*)ws->allocStart - bytes;
void* const bottom = ws->tableEnd;
DEBUGLOG(5, "cwksp: reserving %p %zd bytes, %zd bytes remaining",
alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);
ZSTD_cwksp_assert_internal_consistency(ws);
assert(alloc >= bottom);
if (alloc < bottom) {
DEBUGLOG(4, "cwksp: alloc failed!");
ws->allocFailed = 1;
return NULL;
}
if (alloc < ws->tableValidEnd) {
ws->tableValidEnd = alloc;
}
ws->allocStart = alloc;
return alloc;
}
/**
* Moves the cwksp to the next phase, and does any necessary allocations.
* Returns a 0 on success, or zstd error
*/
MEM_STATIC size_t ZSTD_cwksp_internal_advance_phase(
ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) { ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) {
assert(phase >= ws->phase); assert(phase >= ws->phase);
if (phase > ws->phase) { if (phase > ws->phase) {
/* Going from allocating objects to allocating buffers */
if (ws->phase < ZSTD_cwksp_alloc_buffers && if (ws->phase < ZSTD_cwksp_alloc_buffers &&
phase >= ZSTD_cwksp_alloc_buffers) { phase >= ZSTD_cwksp_alloc_buffers) {
ws->tableValidEnd = ws->objectEnd; ws->tableValidEnd = ws->objectEnd;
} }
/* Going from allocating buffers to allocating aligneds/tables */
if (ws->phase < ZSTD_cwksp_alloc_aligned && if (ws->phase < ZSTD_cwksp_alloc_aligned &&
phase >= ZSTD_cwksp_alloc_aligned) { phase >= ZSTD_cwksp_alloc_aligned) {
{ /* Align the start of the "aligned" to 64 bytes. Use [1, 64] bytes. */ /* If unaligned allocations down from a too-large top have left us
size_t const bytesToAlign = * unaligned, we need to realign our alloc ptr. Technically, this
ZSTD_CWKSP_ALIGNMENT_BYTES - ZSTD_cwksp_bytes_to_align_ptr(ws->allocStart, ZSTD_CWKSP_ALIGNMENT_BYTES); * can consume space that is unaccounted for in the neededSpace
DEBUGLOG(5, "reserving aligned alignment addtl space: %zu", bytesToAlign); * calculation. However, I believe this can only happen when the
ZSTD_STATIC_ASSERT((ZSTD_CWKSP_ALIGNMENT_BYTES & (ZSTD_CWKSP_ALIGNMENT_BYTES - 1)) == 0); /* power of 2 */ * workspace is too large, and specifically when it is too large
RETURN_ERROR_IF(!ZSTD_cwksp_reserve_internal_buffer_space(ws, bytesToAlign), * by a larger margin than the space that will be consumed. */
memory_allocation, "aligned phase - alignment initial allocation failed!"); /* TODO: cleaner, compiler warning friendly way to do this??? */
} ws->allocStart = (BYTE*)ws->allocStart - ((size_t)ws->allocStart & (sizeof(U32)-1));
{ /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */ if (ws->allocStart < ws->tableValidEnd) {
void* const alloc = ws->objectEnd; ws->tableValidEnd = ws->allocStart;
size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES);
void* const end = (BYTE*)alloc + bytesToAlign;
DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign);
RETURN_ERROR_IF(end > ws->workspaceEnd, memory_allocation,
"table phase - alignment initial allocation failed!");
ws->objectEnd = end;
ws->tableEnd = end;
ws->tableValidEnd = end;
} }
} }
ws->phase = phase; ws->phase = phase;
ZSTD_cwksp_assert_internal_consistency(ws);
} }
return 0;
} }
/** /**
@@ -323,25 +237,38 @@ MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) {
MEM_STATIC void* ZSTD_cwksp_reserve_internal( MEM_STATIC void* ZSTD_cwksp_reserve_internal(
ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) { ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) {
void* alloc; void* alloc;
if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) { void* bottom = ws->tableEnd;
ZSTD_cwksp_internal_advance_phase(ws, phase);
alloc = (BYTE *)ws->allocStart - bytes;
if (bytes == 0)
return NULL; return NULL;
}
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* over-reserve space */ /* over-reserve space */
bytes += 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; alloc = (BYTE *)alloc - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
#endif #endif
alloc = ZSTD_cwksp_reserve_internal_buffer_space(ws, bytes); DEBUGLOG(5, "cwksp: reserving %p %zd bytes, %zd bytes remaining",
alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);
ZSTD_cwksp_assert_internal_consistency(ws);
assert(alloc >= bottom);
if (alloc < bottom) {
DEBUGLOG(4, "cwksp: alloc failed!");
ws->allocFailed = 1;
return NULL;
}
if (alloc < ws->tableValidEnd) {
ws->tableValidEnd = alloc;
}
ws->allocStart = alloc;
#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
/* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
* either size. */ * either size. */
if (alloc) { alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { __asan_unpoison_memory_region(alloc, bytes);
__asan_unpoison_memory_region(alloc, bytes);
}
} }
#endif #endif
@@ -356,36 +283,28 @@ MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) {
} }
/** /**
* Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). * Reserves and returns memory sized on and aligned on sizeof(unsigned).
*/ */
MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) { MEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) {
void* ptr = ZSTD_cwksp_reserve_internal(ws, ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES), assert((bytes & (sizeof(U32)-1)) == 0);
ZSTD_cwksp_alloc_aligned); return ZSTD_cwksp_reserve_internal(ws, ZSTD_cwksp_align(bytes, sizeof(U32)), ZSTD_cwksp_alloc_aligned);
assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
return ptr;
} }
/** /**
* Aligned on 64 bytes. These buffers have the special property that * Aligned on sizeof(unsigned). These buffers have the special property that
* their values remain constrained, allowing us to re-use them without * their values remain constrained, allowing us to re-use them without
* memset()-ing them. * memset()-ing them.
*/ */
MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) { MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {
const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned; const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned;
void* alloc; void* alloc = ws->tableEnd;
void* end; void* end = (BYTE *)alloc + bytes;
void* top; void* top = ws->allocStart;
if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) {
return NULL;
}
alloc = ws->tableEnd;
end = (BYTE *)alloc + bytes;
top = ws->allocStart;
DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining", DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining",
alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);
assert((bytes & (sizeof(U32)-1)) == 0); assert((bytes & (sizeof(U32)-1)) == 0);
ZSTD_cwksp_internal_advance_phase(ws, phase);
ZSTD_cwksp_assert_internal_consistency(ws); ZSTD_cwksp_assert_internal_consistency(ws);
assert(end <= top); assert(end <= top);
if (end > top) { if (end > top) {
@@ -401,8 +320,6 @@ MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {
} }
#endif #endif
assert((bytes & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0);
assert(((size_t)alloc & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
return alloc; return alloc;
} }
@@ -610,24 +527,6 @@ MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) {
* Functions Checking Free Space * Functions Checking Free Space
***************************************/ ***************************************/
/* ZSTD_alignmentSpaceWithinBounds() :
* Returns if the estimated space needed for a wksp is within an acceptable limit of the
* actual amount of space used.
*/
MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp* const ws,
size_t const estimatedSpace, int resizedWorkspace) {
if (resizedWorkspace) {
/* Resized/newly allocated wksp should have exact bounds */
return ZSTD_cwksp_used(ws) == estimatedSpace;
} else {
/* Due to alignment, when reusing a workspace, we can actually consume 63 fewer or more bytes
* than estimatedSpace. See the comments in zstd_cwksp.h for details.
*/
return (ZSTD_cwksp_used(ws) >= estimatedSpace - 63) && (ZSTD_cwksp_used(ws) <= estimatedSpace + 63);
}
}
MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) { MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) {
return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd); return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd);
} }
+2 -4
View File
@@ -244,8 +244,6 @@ _search_next_long:
while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
} }
/* fall-through */
_match_found: _match_found:
offset_2 = offset_1; offset_2 = offset_1;
offset_1 = offset; offset_1 = offset;
@@ -409,7 +407,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */ if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
& (offset_1 < curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */ & (repIndex > dictStartIndex))
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4; mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
@@ -477,7 +475,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
U32 const repIndex2 = current2 - offset_2; U32 const repIndex2 = current2 - offset_2;
const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */ if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */
& (offset_2 < current2 - dictStartIndex)) & (repIndex2 > dictStartIndex))
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) { && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
+3 -3
View File
@@ -416,9 +416,9 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
const BYTE* const repMatch = repBase + repIndex; const BYTE* const repMatch = repBase + repIndex;
hashTable[h] = curr; /* update hash table */ hashTable[h] = curr; /* update hash table */
DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr); DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr);
assert(offset_1 <= curr +1); /* check repIndex */
if ( ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))
& (offset_1 < curr+1 - dictStartIndex) ) /* note: we are searching at curr+1 */
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4; size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4;
@@ -453,7 +453,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
U32 const current2 = (U32)(ip-base); U32 const current2 = (U32)(ip-base);
U32 const repIndex2 = current2 - offset_2; U32 const repIndex2 = current2 - offset_2;
const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 < curr - dictStartIndex)) /* intentional overflow */ if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (repIndex2 > dictStartIndex)) /* intentional overflow */
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) { && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
+147 -917
View File
@@ -93,7 +93,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
assert(curr >= btLow); assert(curr >= btLow);
assert(ip < iend); /* condition for ZSTD_count */ assert(ip < iend); /* condition for ZSTD_count */
while (nbCompares-- && (matchIndex > windowLow)) { for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask); U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
assert(matchIndex < curr); assert(matchIndex < curr);
@@ -185,7 +185,7 @@ ZSTD_DUBT_findBetterDictMatch (
(void)dictMode; (void)dictMode;
assert(dictMode == ZSTD_dictMatchState); assert(dictMode == ZSTD_dictMatchState);
while (nbCompares-- && (dictMatchIndex > dictLowLimit)) { for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) {
U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask); U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match = dictBase + dictMatchIndex; const BYTE* match = dictBase + dictMatchIndex;
@@ -309,7 +309,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
matchIndex = hashTable[h]; matchIndex = hashTable[h];
hashTable[h] = curr; /* Update Hash Table */ hashTable[h] = curr; /* Update Hash Table */
while (nbCompares-- && (matchIndex > windowLow)) { for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask); U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match; const BYTE* match;
@@ -357,6 +357,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
*smallerPtr = *largerPtr = 0; *smallerPtr = *largerPtr = 0;
assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dictMatchState && nbCompares) { if (dictMode == ZSTD_dictMatchState && nbCompares) {
bestLength = ZSTD_DUBT_findBetterDictMatch( bestLength = ZSTD_DUBT_findBetterDictMatch(
ms, ip, iend, ms, ip, iend,
@@ -438,9 +439,43 @@ static size_t ZSTD_BtFindBestMatch_extDict_selectMLS (
} }
} }
/***********************************
* Dedicated dict search
/* *********************************
* Hash Chain
***********************************/ ***********************************/
#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)]
/* Update chains up to ip (excluded)
Assumption : always within prefix (i.e. not within extDict) */
FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal(
ZSTD_matchState_t* ms,
const ZSTD_compressionParameters* const cParams,
const BYTE* ip, U32 const mls)
{
U32* const hashTable = ms->hashTable;
const U32 hashLog = cParams->hashLog;
U32* const chainTable = ms->chainTable;
const U32 chainMask = (1 << cParams->chainLog) - 1;
const BYTE* const base = ms->window.base;
const U32 target = (U32)(ip - base);
U32 idx = ms->nextToUpdate;
while(idx < target) { /* catch up */
size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
hashTable[h] = idx;
idx++;
}
ms->nextToUpdate = target;
return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
}
U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {
const ZSTD_compressionParameters* const cParams = &ms->cParams;
return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);
}
void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip) void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip)
{ {
@@ -466,10 +501,11 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B
U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog); U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog);
U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx; U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx;
U32 hashIdx; U32 hashIdx;
assert(ms->cParams.chainLog <= 24); assert(ms->cParams.chainLog <= 24);
assert(ms->cParams.hashLog > ms->cParams.chainLog); assert(ms->cParams.hashLog >= ms->cParams.chainLog);
assert(idx != 0); assert(idx != 0);
assert(tmpMinChain <= minChain); assert(tmpMinChain <= minChain);
@@ -500,7 +536,7 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B
if (count == cacheSize) { if (count == cacheSize) {
for (count = 0; count < chainLimit;) { for (count = 0; count < chainLimit;) {
if (i < minChain) { if (i < minChain) {
if (!i || ++countBeyondMinChain > cacheSize) { if (!i || countBeyondMinChain++ > cacheSize) {
/* only allow pulling `cacheSize` number of entries /* only allow pulling `cacheSize` number of entries
* into the cache or chainTable beyond `minChain`, * into the cache or chainTable beyond `minChain`,
* to replace the entries pulled out of the * to replace the entries pulled out of the
@@ -556,139 +592,6 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B
ms->nextToUpdate = target; ms->nextToUpdate = target;
} }
/* Returns the longest match length found in the dedicated dict search structure.
* If none are longer than the argument ml, then ml will be returned.
*/
FORCE_INLINE_TEMPLATE
size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nbAttempts,
const ZSTD_matchState_t* const dms,
const BYTE* const ip, const BYTE* const iLimit,
const BYTE* const prefixStart, const U32 curr,
const U32 dictLimit, const size_t ddsIdx) {
const U32 ddsLowestIndex = dms->window.dictLimit;
const BYTE* const ddsBase = dms->window.base;
const BYTE* const ddsEnd = dms->window.nextSrc;
const U32 ddsSize = (U32)(ddsEnd - ddsBase);
const U32 ddsIndexDelta = dictLimit - ddsSize;
const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG);
const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1;
U32 ddsAttempt;
U32 matchIndex;
for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) {
PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]);
}
{
U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
U32 const chainIndex = chainPackedPointer >> 8;
PREFETCH_L1(&dms->chainTable[chainIndex]);
}
for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) {
size_t currentMl=0;
const BYTE* match;
matchIndex = dms->hashTable[ddsIdx + ddsAttempt];
match = ddsBase + matchIndex;
if (!matchIndex) {
return ml;
}
/* guaranteed by table construction */
(void)ddsLowestIndex;
assert(matchIndex >= ddsLowestIndex);
assert(match+4 <= ddsEnd);
if (MEM_read32(match) == MEM_read32(ip)) {
/* assumption : matchIndex <= dictLimit-4 (by table construction) */
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
}
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) {
/* best possible, avoids read overflow on next attempt */
return ml;
}
}
}
{
U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
U32 chainIndex = chainPackedPointer >> 8;
U32 const chainLength = chainPackedPointer & 0xFF;
U32 const chainAttempts = nbAttempts - ddsAttempt;
U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts;
U32 chainAttempt;
for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) {
PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]);
}
for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) {
size_t currentMl=0;
const BYTE* match;
matchIndex = dms->chainTable[chainIndex];
match = ddsBase + matchIndex;
/* guaranteed by table construction */
assert(matchIndex >= ddsLowestIndex);
assert(match+4 <= ddsEnd);
if (MEM_read32(match) == MEM_read32(ip)) {
/* assumption : matchIndex <= dictLimit-4 (by table construction) */
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
}
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
}
}
return ml;
}
/* *********************************
* Hash Chain
***********************************/
#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)]
/* Update chains up to ip (excluded)
Assumption : always within prefix (i.e. not within extDict) */
FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal(
ZSTD_matchState_t* ms,
const ZSTD_compressionParameters* const cParams,
const BYTE* ip, U32 const mls)
{
U32* const hashTable = ms->hashTable;
const U32 hashLog = cParams->hashLog;
U32* const chainTable = ms->chainTable;
const U32 chainMask = (1 << cParams->chainLog) - 1;
const BYTE* const base = ms->window.base;
const U32 target = (U32)(ip - base);
U32 idx = ms->nextToUpdate;
while(idx < target) { /* catch up */
size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
hashTable[h] = idx;
idx++;
}
ms->nextToUpdate = target;
return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
}
U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {
const ZSTD_compressionParameters* const cParams = &ms->cParams;
return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);
}
/* inlining is important to hardwire a hot branch (template emulation) */ /* inlining is important to hardwire a hot branch (template emulation) */
FORCE_INLINE_TEMPLATE FORCE_INLINE_TEMPLATE
@@ -758,9 +661,92 @@ size_t ZSTD_HcFindBestMatch_generic (
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
} }
assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dedicatedDictSearch) { if (dictMode == ZSTD_dedicatedDictSearch) {
ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms, const U32 ddsLowestIndex = dms->window.dictLimit;
ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); const BYTE* const ddsBase = dms->window.base;
const BYTE* const ddsEnd = dms->window.nextSrc;
const U32 ddsSize = (U32)(ddsEnd - ddsBase);
const U32 ddsIndexDelta = dictLimit - ddsSize;
const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG);
const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1;
U32 ddsAttempt;
for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) {
PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]);
}
{
U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
U32 const chainIndex = chainPackedPointer >> 8;
PREFETCH_L1(&dms->chainTable[chainIndex]);
}
for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) {
size_t currentMl=0;
const BYTE* match;
matchIndex = dms->hashTable[ddsIdx + ddsAttempt];
match = ddsBase + matchIndex;
if (!matchIndex) {
return ml;
}
/* guaranteed by table construction */
(void)ddsLowestIndex;
assert(matchIndex >= ddsLowestIndex);
assert(match+4 <= ddsEnd);
if (MEM_read32(match) == MEM_read32(ip)) {
/* assumption : matchIndex <= dictLimit-4 (by table construction) */
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
}
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) {
/* best possible, avoids read overflow on next attempt */
return ml;
}
}
}
{
U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
U32 chainIndex = chainPackedPointer >> 8;
U32 const chainLength = chainPackedPointer & 0xFF;
U32 const chainAttempts = nbAttempts - ddsAttempt;
U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts;
U32 chainAttempt;
for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) {
PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]);
}
for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) {
size_t currentMl=0;
const BYTE* match;
matchIndex = dms->chainTable[chainIndex];
match = ddsBase + matchIndex;
/* guaranteed by table construction */
assert(matchIndex >= ddsLowestIndex);
assert(match+4 <= ddsEnd);
if (MEM_read32(match) == MEM_read32(ip)) {
/* assumption : matchIndex <= dictLimit-4 (by table construction) */
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
}
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
}
}
} else if (dictMode == ZSTD_dictMatchState) { } else if (dictMode == ZSTD_dictMatchState) {
const U32* const dmsChainTable = dms->chainTable; const U32* const dmsChainTable = dms->chainTable;
const U32 dmsChainSize = (1 << dms->cParams.chainLog); const U32 dmsChainSize = (1 << dms->cParams.chainLog);
@@ -861,657 +847,11 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
} }
} }
/* *********************************
* (SIMD) Row-based matchfinder
***********************************/
/* Constants for row-based hash */
#define ZSTD_ROW_HASH_TAG_OFFSET 1 /* byte offset of hashes in the match state's tagTable from the beginning of a row */
#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */
#define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1)
#define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1)
typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */
#if !defined(ZSTD_NO_INTRINSICS) && defined(__SSE2__) /* SIMD SSE version */
#include <emmintrin.h>
typedef __m128i ZSTD_Vec128;
/* Returns a 128-bit container with 128-bits from src */
static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) {
return _mm_loadu_si128((ZSTD_Vec128 const*)src);
}
/* Returns a ZSTD_Vec128 with the byte "val" packed 16 times */
static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) {
return _mm_set1_epi8((char)val);
}
/* Do byte-by-byte comparison result of x and y. Then collapse 128-bit resultant mask
* into a 32-bit mask that is the MSB of each byte.
* */
static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) {
return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y));
}
typedef struct {
__m128i fst;
__m128i snd;
} ZSTD_Vec256;
static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) {
ZSTD_Vec256 v;
v.fst = ZSTD_Vec128_read(ptr);
v.snd = ZSTD_Vec128_read((ZSTD_Vec128 const*)ptr + 1);
return v;
}
static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) {
ZSTD_Vec256 v;
v.fst = ZSTD_Vec128_set8(val);
v.snd = ZSTD_Vec128_set8(val);
return v;
}
static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) {
ZSTD_VecMask fstMask;
ZSTD_VecMask sndMask;
fstMask = ZSTD_Vec128_cmpMask8(x.fst, y.fst);
sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd);
return fstMask | (sndMask << 16);
}
#elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */
#include <arm_neon.h>
typedef uint8x16_t ZSTD_Vec128;
static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) {
return vld1q_u8((const BYTE* const)src);
}
static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) {
return vdupq_n_u8(val);
}
/* Mimics '_mm_movemask_epi8()' from SSE */
static U32 ZSTD_vmovmaskq_u8(ZSTD_Vec128 val) {
/* Shift out everything but the MSB bits in each byte */
uint16x8_t highBits = vreinterpretq_u16_u8(vshrq_n_u8(val, 7));
/* Merge the even lanes together with vsra (right shift and add) */
uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(highBits, highBits, 7));
uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14));
uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28));
/* Extract the low 8 bits from each lane, merge */
return vgetq_lane_u8(paired64, 0) | ((U32)vgetq_lane_u8(paired64, 8) << 8);
}
static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) {
return (ZSTD_VecMask)ZSTD_vmovmaskq_u8(vceqq_u8(x, y));
}
typedef struct {
uint8x16_t fst;
uint8x16_t snd;
} ZSTD_Vec256;
static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) {
ZSTD_Vec256 v;
v.fst = ZSTD_Vec128_read(ptr);
v.snd = ZSTD_Vec128_read((ZSTD_Vec128 const*)ptr + 1);
return v;
}
static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) {
ZSTD_Vec256 v;
v.fst = ZSTD_Vec128_set8(val);
v.snd = ZSTD_Vec128_set8(val);
return v;
}
static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) {
ZSTD_VecMask fstMask;
ZSTD_VecMask sndMask;
fstMask = ZSTD_Vec128_cmpMask8(x.fst, y.fst);
sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd);
return fstMask | (sndMask << 16);
}
#else /* Scalar fallback version */
#define VEC128_NB_SIZE_T (16 / sizeof(size_t))
typedef struct {
size_t vec[VEC128_NB_SIZE_T];
} ZSTD_Vec128;
static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) {
ZSTD_Vec128 ret;
ZSTD_memcpy(ret.vec, src, VEC128_NB_SIZE_T*sizeof(size_t));
return ret;
}
static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) {
ZSTD_Vec128 ret = { {0} };
int startBit = sizeof(size_t) * 8 - 8;
for (;startBit >= 0; startBit -= 8) {
unsigned j = 0;
for (;j < VEC128_NB_SIZE_T; ++j) {
ret.vec[j] |= ((size_t)val << startBit);
}
}
return ret;
}
/* Compare x to y, byte by byte, generating a "matches" bitfield */
static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) {
ZSTD_VecMask res = 0;
unsigned i = 0;
unsigned l = 0;
for (; i < VEC128_NB_SIZE_T; ++i) {
const size_t cmp1 = x.vec[i];
const size_t cmp2 = y.vec[i];
unsigned j = 0;
for (; j < sizeof(size_t); ++j, ++l) {
if (((cmp1 >> j*8) & 0xFF) == ((cmp2 >> j*8) & 0xFF)) {
res |= ((U32)1 << (j+i*sizeof(size_t)));
}
}
}
return res;
}
#define VEC256_NB_SIZE_T 2*VEC128_NB_SIZE_T
typedef struct {
size_t vec[VEC256_NB_SIZE_T];
} ZSTD_Vec256;
static ZSTD_Vec256 ZSTD_Vec256_read(const void* const src) {
ZSTD_Vec256 ret;
ZSTD_memcpy(ret.vec, src, VEC256_NB_SIZE_T*sizeof(size_t));
return ret;
}
static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) {
ZSTD_Vec256 ret = { {0} };
int startBit = sizeof(size_t) * 8 - 8;
for (;startBit >= 0; startBit -= 8) {
unsigned j = 0;
for (;j < VEC256_NB_SIZE_T; ++j) {
ret.vec[j] |= ((size_t)val << startBit);
}
}
return ret;
}
/* Compare x to y, byte by byte, generating a "matches" bitfield */
static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) {
ZSTD_VecMask res = 0;
unsigned i = 0;
unsigned l = 0;
for (; i < VEC256_NB_SIZE_T; ++i) {
const size_t cmp1 = x.vec[i];
const size_t cmp2 = y.vec[i];
unsigned j = 0;
for (; j < sizeof(size_t); ++j, ++l) {
if (((cmp1 >> j*8) & 0xFF) == ((cmp2 >> j*8) & 0xFF)) {
res |= ((U32)1 << (j+i*sizeof(size_t)));
}
}
}
return res;
}
#endif /* !defined(ZSTD_NO_INTRINSICS) && defined(__SSE2__) */
/* ZSTD_VecMask_next():
* Starting from the LSB, returns the idx of the next non-zero bit.
* Basically counting the nb of trailing zeroes.
*/
static U32 ZSTD_VecMask_next(ZSTD_VecMask val) {
# if defined(_MSC_VER) /* Visual */
unsigned long r=0;
return _BitScanForward(&r, val) ? (U32)r : 0;
# elif defined(__GNUC__) && (__GNUC__ >= 3)
return (U32)__builtin_ctz(val);
# else
/* Software ctz version: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
static const U32 multiplyDeBruijnBitPosition[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return multiplyDeBruijnBitPosition[((U32)((v & -(int)v) * 0x077CB531U)) >> 27];
# endif
}
/* ZSTD_VecMask_rotateRight():
* Rotates a bitfield to the right by "rotation" bits.
* If the rotation is greater than totalBits, the returned mask is 0.
*/
FORCE_INLINE_TEMPLATE ZSTD_VecMask
ZSTD_VecMask_rotateRight(ZSTD_VecMask mask, U32 const rotation, U32 const totalBits) {
if (rotation == 0)
return mask;
switch (totalBits) {
default:
assert(0);
case 16:
return (mask >> rotation) | (U16)(mask << (16 - rotation));
case 32:
return (mask >> rotation) | (U32)(mask << (32 - rotation));
}
}
/* ZSTD_row_nextIndex():
* Returns the next index to insert at within a tagTable row, and updates the "head"
* value to reflect the update. Essentially cycles backwards from [0, {entries per row})
*/
FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE* const tagRow, U32 const rowMask) {
U32 const next = (*tagRow - 1) & rowMask;
*tagRow = (BYTE)next;
return next;
}
/* ZSTD_isAligned():
* Checks that a pointer is aligned to "align" bytes which must be a power of 2.
*/
MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) {
assert((align & (align - 1)) == 0);
return (((size_t)ptr) & (align - 1)) == 0;
}
/* ZSTD_row_prefetch():
* Performs prefetching for the hashTable and tagTable at a given row.
*/
FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, U16 const* tagTable, U32 const relRow, U32 const rowLog) {
PREFETCH_L1(hashTable + relRow);
if (rowLog == 5) {
PREFETCH_L1(hashTable + relRow + 16);
}
PREFETCH_L1(tagTable + relRow);
assert(rowLog == 4 || rowLog == 5);
assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */
assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on a multiple of 32 or 64 bytes */
}
/* ZSTD_row_fillHashCache():
* Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries,
* but not beyond iLimit.
*/
static void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base,
U32 const rowLog, U32 const mls,
U32 idx, const BYTE* const iLimit)
{
U32 const* const hashTable = ms->hashTable;
U16 const* const tagTable = ms->tagTable;
U32 const hashLog = ms->rowHashLog;
U32 const maxElemsToPrefetch = (base + idx) > iLimit ? 0 : (U32)(iLimit - (base + idx) + 1);
U32 const lim = idx + MIN(ZSTD_ROW_HASH_CACHE_SIZE, maxElemsToPrefetch);
for (; idx < lim; ++idx) {
U32 const hash = (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
U32 const row = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
ZSTD_row_prefetch(hashTable, tagTable, row, rowLog);
ms->hashCache[idx & ZSTD_ROW_HASH_CACHE_MASK] = hash;
}
DEBUGLOG(6, "ZSTD_row_fillHashCache(): [%u %u %u %u %u %u %u %u]", ms->hashCache[0], ms->hashCache[1],
ms->hashCache[2], ms->hashCache[3], ms->hashCache[4],
ms->hashCache[5], ms->hashCache[6], ms->hashCache[7]);
}
/* ZSTD_row_nextCachedHash():
* Returns the hash of base + idx, and replaces the hash in the hash cache with the byte at
* base + idx + ZSTD_ROW_HASH_CACHE_SIZE. Also prefetches the appropriate rows from hashTable and tagTable.
*/
FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable,
U16 const* tagTable, BYTE const* base,
U32 idx, U32 const hashLog,
U32 const rowLog, U32 const mls)
{
U32 const newHash = (U32)ZSTD_hashPtr(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
U32 const row = (newHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
ZSTD_row_prefetch(hashTable, tagTable, row, rowLog);
{ U32 const hash = cache[idx & ZSTD_ROW_HASH_CACHE_MASK];
cache[idx & ZSTD_ROW_HASH_CACHE_MASK] = newHash;
return hash;
}
}
/* ZSTD_row_update_internal():
* Inserts the byte at ip into the appropriate position in the hash table.
* Determines the relative row, and the position within the {16, 32} entry row to insert at.
*/
FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip,
U32 const mls, U32 const rowLog,
U32 const rowMask, U32 const useCache)
{
U32* const hashTable = ms->hashTable;
U16* const tagTable = ms->tagTable;
U32 const hashLog = ms->rowHashLog;
const BYTE* const base = ms->window.base;
const U32 target = (U32)(ip - base);
U32 idx = ms->nextToUpdate;
DEBUGLOG(6, "ZSTD_row_update_internal(): nextToUpdate=%u, current=%u", idx, target);
for (; idx < target; ++idx) {
U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, idx, hashLog, rowLog, mls)
: (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
U32* const row = hashTable + relRow;
BYTE* tagRow = (BYTE*)(tagTable + relRow); /* Though tagTable is laid out as a table of U16, each tag is only 1 byte.
Explicit cast allows us to get exact desired position within each row */
U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask);
assert(hash == ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls));
((BYTE*)tagRow)[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK;
row[pos] = idx;
}
ms->nextToUpdate = target;
}
/* ZSTD_row_update():
* External wrapper for ZSTD_row_update_internal(). Used for filling the hashtable during dictionary
* processing.
*/
void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) {
const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
const U32 rowMask = (1u << rowLog) - 1;
const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */);
DEBUGLOG(5, "ZSTD_row_update(), rowLog=%u", rowLog);
ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* dont use cache */);
}
/* Returns a ZSTD_VecMask (U32) that has the nth bit set to 1 if the newly-computed "tag" matches
* the hash at the nth position in a row of the tagTable.
*/
FORCE_INLINE_TEMPLATE
ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 head, const U32 rowEntries) {
ZSTD_VecMask matches = 0;
if (rowEntries == 16) {
ZSTD_Vec128 hashes = ZSTD_Vec128_read(tagRow + ZSTD_ROW_HASH_TAG_OFFSET);
ZSTD_Vec128 expandedTags = ZSTD_Vec128_set8(tag);
matches = ZSTD_Vec128_cmpMask8(hashes, expandedTags);
} else if (rowEntries == 32) {
ZSTD_Vec256 hashes = ZSTD_Vec256_read(tagRow + ZSTD_ROW_HASH_TAG_OFFSET);
ZSTD_Vec256 expandedTags = ZSTD_Vec256_set8(tag);
matches = ZSTD_Vec256_cmpMask8(hashes, expandedTags);
} else {
assert(0);
}
/* Each row is a circular buffer beginning at the value of "head". So we must rotate the "matches" bitfield
to match up with the actual layout of the entries within the hashTable */
return ZSTD_VecMask_rotateRight(matches, head, rowEntries);
}
/* The high-level approach of the SIMD row based match finder is as follows:
* - Figure out where to insert the new entry:
* - Generate a hash from a byte along with an additional 1-byte "short hash". The additional byte is our "tag"
* - The hashTable is effectively split into groups or "rows" of 16 or 32 entries of U32, and the hash determines
* which row to insert into.
* - Determine the correct position within the row to insert the entry into. Each row of 16 or 32 can
* be considered as a circular buffer with a "head" index that resides in the tagTable.
* - Also insert the "tag" into the equivalent row and position in the tagTable.
* - Note: The tagTable has 17 or 33 1-byte entries per row, due to 16 or 32 tags, and 1 "head" entry.
* The 17 or 33 entry rows are spaced out to occur every 32 or 64 bytes, respectively,
* for alignment/performance reasons, leaving some bytes unused.
* - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte "short hash" and
* generate a bitfield that we can cycle through to check the collisions in the hash table.
* - Pick the longest match.
*/
FORCE_INLINE_TEMPLATE
size_t ZSTD_RowFindBestMatch_generic (
ZSTD_matchState_t* ms,
const BYTE* const ip, const BYTE* const iLimit,
size_t* offsetPtr,
const U32 mls, const ZSTD_dictMode_e dictMode,
const U32 rowLog)
{
U32* const hashTable = ms->hashTable;
U16* const tagTable = ms->tagTable;
U32* const hashCache = ms->hashCache;
const U32 hashLog = ms->rowHashLog;
const ZSTD_compressionParameters* const cParams = &ms->cParams;
const BYTE* const base = ms->window.base;
const BYTE* const dictBase = ms->window.dictBase;
const U32 dictLimit = ms->window.dictLimit;
const BYTE* const prefixStart = base + dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
const U32 curr = (U32)(ip-base);
const U32 maxDistance = 1U << cParams->windowLog;
const U32 lowestValid = ms->window.lowLimit;
const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
const U32 isDictionary = (ms->loadedDictEnd != 0);
const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
const U32 rowEntries = (1U << rowLog);
const U32 rowMask = rowEntries - 1;
const U32 cappedSearchLog = MIN(cParams->searchLog, rowLog); /* nb of searches is capped at nb entries per row */
U32 nbAttempts = 1U << cappedSearchLog;
size_t ml=4-1;
/* DMS/DDS variables that may be referenced laster */
const ZSTD_matchState_t* const dms = ms->dictMatchState;
size_t ddsIdx;
U32 ddsExtraAttempts; /* cctx hash tables are limited in searches, but allow extra searches into DDS */
U32 dmsTag;
U32* dmsRow;
BYTE* dmsTagRow;
if (dictMode == ZSTD_dedicatedDictSearch) {
const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
{ /* Prefetch DDS hashtable entry */
ddsIdx = ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG;
PREFETCH_L1(&dms->hashTable[ddsIdx]);
}
ddsExtraAttempts = cParams->searchLog > rowLog ? 1U << (cParams->searchLog - rowLog) : 0;
}
if (dictMode == ZSTD_dictMatchState) {
/* Prefetch DMS rows */
U32* const dmsHashTable = dms->hashTable;
U16* const dmsTagTable = dms->tagTable;
U32 const dmsHash = (U32)ZSTD_hashPtr(ip, dms->rowHashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
U32 const dmsRelRow = (dmsHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
dmsTag = dmsHash & ZSTD_ROW_HASH_TAG_MASK;
dmsTagRow = (BYTE*)(dmsTagTable + dmsRelRow);
dmsRow = dmsHashTable + dmsRelRow;
ZSTD_row_prefetch(dmsHashTable, dmsTagTable, dmsRelRow, rowLog);
}
/* Update the hashTable and tagTable up to (but not including) ip */
ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */);
{ /* Get the hash for ip, compute the appropriate row */
U32 const hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls);
U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
U32 const tag = hash & ZSTD_ROW_HASH_TAG_MASK;
U32* const row = hashTable + relRow;
BYTE* tagRow = (BYTE*)(tagTable + relRow);
U32 const head = *tagRow & rowMask;
U32 matchBuffer[32 /* maximum nb entries per row */];
size_t numMatches = 0;
size_t currMatch = 0;
ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, head, rowEntries);
/* Cycle through the matches and prefetch */
for (; (matches > 0) && (nbAttempts > 0); --nbAttempts, matches &= (matches - 1)) {
U32 const matchPos = (head + ZSTD_VecMask_next(matches)) & rowMask;
U32 const matchIndex = row[matchPos];
assert(numMatches < rowEntries);
if (matchIndex < lowLimit)
break;
if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
PREFETCH_L1(base + matchIndex);
} else {
PREFETCH_L1(dictBase + matchIndex);
}
matchBuffer[numMatches++] = matchIndex;
}
/* Speed opt: insert current byte into hashtable too. This allows us to avoid one iteration of the loop
in ZSTD_row_update_internal() at the next search. */
{
U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask);
tagRow[pos + ZSTD_ROW_HASH_TAG_OFFSET] = (BYTE)tag;
row[pos] = ms->nextToUpdate++;
}
/* Return the longest match */
for (; currMatch < numMatches; ++currMatch) {
U32 const matchIndex = matchBuffer[currMatch];
size_t currentMl=0;
assert(matchIndex < curr);
assert(matchIndex >= lowLimit);
if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
const BYTE* const match = base + matchIndex;
assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */
if (match[ml] == ip[ml]) /* potentially better */
currentMl = ZSTD_count(ip, match, iLimit);
} else {
const BYTE* const match = dictBase + matchIndex;
assert(match+4 <= dictEnd);
if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
}
/* Save best solution */
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
}
}
if (dictMode == ZSTD_dedicatedDictSearch) {
ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms,
ip, iLimit, prefixStart, curr, dictLimit, ddsIdx);
} else if (dictMode == ZSTD_dictMatchState) {
/* TODO: Measure and potentially add prefetching to DMS */
const U32 dmsLowestIndex = dms->window.dictLimit;
const BYTE* const dmsBase = dms->window.base;
const BYTE* const dmsEnd = dms->window.nextSrc;
const U32 dmsSize = (U32)(dmsEnd - dmsBase);
const U32 dmsIndexDelta = dictLimit - dmsSize;
{ U32 const head = *dmsTagRow & rowMask;
U32 matchBuffer[32 /* maximum nb row entries */];
size_t numMatches = 0;
size_t currMatch = 0;
ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, head, rowEntries);
for (; (matches > 0) && (nbAttempts > 0); --nbAttempts, matches &= (matches - 1)) {
U32 const matchPos = (head + ZSTD_VecMask_next(matches)) & rowMask;
U32 const matchIndex = dmsRow[matchPos];
if (matchIndex < dmsLowestIndex)
break;
PREFETCH_L1(dmsBase + matchIndex);
matchBuffer[numMatches++] = matchIndex;
}
/* Return the longest match */
for (; currMatch < numMatches; ++currMatch) {
U32 const matchIndex = matchBuffer[currMatch];
size_t currentMl=0;
assert(matchIndex >= dmsLowestIndex);
assert(matchIndex < curr);
{ const BYTE* const match = dmsBase + matchIndex;
assert(match+4 <= dmsEnd);
if (MEM_read32(match) == MEM_read32(ip))
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4;
}
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break;
}
}
}
}
return ml;
}
/* Inlining is important to hardwire a hot branch (template emulation) */
FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectMLS (
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* const iLimit,
const ZSTD_dictMode_e dictMode, size_t* offsetPtr, const U32 rowLog)
{
switch(ms->cParams.minMatch)
{
default : /* includes case 3 */
case 4 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, dictMode, rowLog);
case 5 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, dictMode, rowLog);
case 7 :
case 6 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, dictMode, rowLog);
}
}
FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectRowLog (
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr)
{
const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
switch(cappedSearchLog)
{
default :
case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 4);
case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 5);
}
}
FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dictMatchState_selectRowLog(
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr)
{
const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
switch(cappedSearchLog)
{
default :
case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 4);
case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 5);
}
}
FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRowLog(
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr)
{
const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
switch(cappedSearchLog)
{
default :
case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 4);
case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 5);
}
}
FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_extDict_selectRowLog (
ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr)
{
const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5);
switch(cappedSearchLog)
{
default :
case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 4);
case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 5);
}
}
/* ******************************* /* *******************************
* Common parser - lazy strategy * Common parser - lazy strategy
*********************************/ *********************************/
typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e; typedef enum { search_hashChain, search_binaryTree } searchMethod_e;
FORCE_INLINE_TEMPLATE size_t FORCE_INLINE_TEMPLATE size_t
ZSTD_compressBlock_lazy_generic( ZSTD_compressBlock_lazy_generic(
@@ -1525,11 +865,10 @@ ZSTD_compressBlock_lazy_generic(
const BYTE* ip = istart; const BYTE* ip = istart;
const BYTE* anchor = istart; const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize; const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; const BYTE* const ilimit = iend - 8;
const BYTE* const base = ms->window.base; const BYTE* const base = ms->window.base;
const U32 prefixLowestIndex = ms->window.dictLimit; const U32 prefixLowestIndex = ms->window.dictLimit;
const BYTE* const prefixLowest = base + prefixLowestIndex; const BYTE* const prefixLowest = base + prefixLowestIndex;
const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
typedef size_t (*searchMax_f)( typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms, ZSTD_matchState_t* ms,
@@ -1541,30 +880,26 @@ ZSTD_compressBlock_lazy_generic(
* that should never occur (extDict modes go to the other implementation * that should never occur (extDict modes go to the other implementation
* below and there is no DDSS for binary tree search yet). * below and there is no DDSS for binary tree search yet).
*/ */
const searchMax_f searchFuncs[4][3] = { const searchMax_f searchFuncs[4][2] = {
{ {
ZSTD_HcFindBestMatch_selectMLS, ZSTD_HcFindBestMatch_selectMLS,
ZSTD_BtFindBestMatch_selectMLS, ZSTD_BtFindBestMatch_selectMLS
ZSTD_RowFindBestMatch_selectRowLog
}, },
{ {
NULL,
NULL, NULL,
NULL NULL
}, },
{ {
ZSTD_HcFindBestMatch_dictMatchState_selectMLS, ZSTD_HcFindBestMatch_dictMatchState_selectMLS,
ZSTD_BtFindBestMatch_dictMatchState_selectMLS, ZSTD_BtFindBestMatch_dictMatchState_selectMLS
ZSTD_RowFindBestMatch_dictMatchState_selectRowLog
}, },
{ {
ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS, ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS,
NULL, NULL
ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRowLog
} }
}; };
searchMax_f const searchMax = searchFuncs[dictMode][(int)searchMethod]; searchMax_f const searchMax = searchFuncs[dictMode][searchMethod == search_binaryTree];
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0; U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
const int isDMS = dictMode == ZSTD_dictMatchState; const int isDMS = dictMode == ZSTD_dictMatchState;
@@ -1582,7 +917,9 @@ ZSTD_compressBlock_lazy_generic(
assert(searchMax != NULL); assert(searchMax != NULL);
DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod); DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u)", (U32)dictMode);
/* init */
ip += (dictAndPrefixLength == 0); ip += (dictAndPrefixLength == 0);
if (dictMode == ZSTD_noDict) { if (dictMode == ZSTD_noDict) {
U32 const curr = (U32)(ip - base); U32 const curr = (U32)(ip - base);
@@ -1598,12 +935,6 @@ ZSTD_compressBlock_lazy_generic(
assert(offset_2 <= dictAndPrefixLength); assert(offset_2 <= dictAndPrefixLength);
} }
if (searchMethod == search_rowHash) {
ZSTD_row_fillHashCache(ms, base, rowLog,
MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */),
ms->nextToUpdate, ilimit);
}
/* Match Loop */ /* Match Loop */
#if defined(__GNUC__) && defined(__x86_64__) #if defined(__GNUC__) && defined(__x86_64__)
/* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the
@@ -1869,70 +1200,6 @@ size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch); return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch);
} }
/* Row-based matchfinder */
size_t ZSTD_compressBlock_lazy2_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict);
}
size_t ZSTD_compressBlock_lazy_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict);
}
size_t ZSTD_compressBlock_greedy_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_noDict);
}
size_t ZSTD_compressBlock_lazy2_dictMatchState_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_lazy_dictMatchState_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_greedy_dictMatchState_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dedicatedDictSearch);
}
size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dedicatedDictSearch);
}
size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dedicatedDictSearch);
}
FORCE_INLINE_TEMPLATE FORCE_INLINE_TEMPLATE
size_t ZSTD_compressBlock_lazy_extDict_generic( size_t ZSTD_compressBlock_lazy_extDict_generic(
@@ -1945,7 +1212,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const BYTE* ip = istart; const BYTE* ip = istart;
const BYTE* anchor = istart; const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize; const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; const BYTE* const ilimit = iend - 8;
const BYTE* const base = ms->window.base; const BYTE* const base = ms->window.base;
const U32 dictLimit = ms->window.dictLimit; const U32 dictLimit = ms->window.dictLimit;
const BYTE* const prefixStart = base + dictLimit; const BYTE* const prefixStart = base + dictLimit;
@@ -1953,28 +1220,18 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const dictStart = dictBase + ms->window.lowLimit; const BYTE* const dictStart = dictBase + ms->window.lowLimit;
const U32 windowLog = ms->cParams.windowLog; const U32 windowLog = ms->cParams.windowLog;
const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
typedef size_t (*searchMax_f)( typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms, ZSTD_matchState_t* ms,
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
const searchMax_f searchFuncs[3] = { searchMax_f searchMax = searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
ZSTD_HcFindBestMatch_extDict_selectMLS,
ZSTD_BtFindBestMatch_extDict_selectMLS,
ZSTD_RowFindBestMatch_extDict_selectRowLog
};
searchMax_f searchMax = searchFuncs[(int)searchMethod];
U32 offset_1 = rep[0], offset_2 = rep[1]; U32 offset_1 = rep[0], offset_2 = rep[1];
DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod); DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic");
/* init */ /* init */
ip += (ip == prefixStart); ip += (ip == prefixStart);
if (searchMethod == search_rowHash) {
ZSTD_row_fillHashCache(ms, base, rowLog,
MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */),
ms->nextToUpdate, ilimit);
}
/* Match Loop */ /* Match Loop */
#if defined(__GNUC__) && defined(__x86_64__) #if defined(__GNUC__) && defined(__x86_64__)
@@ -1994,8 +1251,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const U32 repIndex = (U32)(curr+1 - offset_1); const U32 repIndex = (U32)(curr+1 - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex; const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
& (offset_1 < curr+1 - windowLow) ) /* note: we are searching at curr+1 */
if (MEM_read32(ip+1) == MEM_read32(repMatch)) { if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
/* repcode detected we should take it */ /* repcode detected we should take it */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -2010,7 +1266,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
matchLength = ml2, start = ip, offset=offsetFound; matchLength = ml2, start = ip, offset=offsetFound;
} }
if (matchLength < 4) { if (matchLength < 4) {
ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */ ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */
continue; continue;
} }
@@ -2026,8 +1282,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const U32 repIndex = (U32)(curr - offset_1); const U32 repIndex = (U32)(curr - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex; const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
& (offset_1 < curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
if (MEM_read32(ip) == MEM_read32(repMatch)) { if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected */ /* repcode detected */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -2058,8 +1313,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
const U32 repIndex = (U32)(curr - offset_1); const U32 repIndex = (U32)(curr - offset_1);
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex; const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
& (offset_1 < curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
if (MEM_read32(ip) == MEM_read32(repMatch)) { if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected */ /* repcode detected */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -2105,8 +1359,7 @@ _storeSequence:
const U32 repIndex = repCurrent - offset_2; const U32 repIndex = repCurrent - offset_2;
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
const BYTE* const repMatch = repBase + repIndex; const BYTE* const repMatch = repBase + repIndex;
if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
& (offset_2 < repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
if (MEM_read32(ip) == MEM_read32(repMatch)) { if (MEM_read32(ip) == MEM_read32(repMatch)) {
/* repcode detected we should take it */ /* repcode detected we should take it */
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
@@ -2159,26 +1412,3 @@ size_t ZSTD_compressBlock_btlazy2_extDict(
{ {
return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2); return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2);
} }
size_t ZSTD_compressBlock_greedy_extDict_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0);
}
size_t ZSTD_compressBlock_lazy_extDict_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1);
}
size_t ZSTD_compressBlock_lazy2_extDict_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2);
}
-38
View File
@@ -26,7 +26,6 @@ extern "C" {
#define ZSTD_LAZY_DDSS_BUCKET_LOG 2 #define ZSTD_LAZY_DDSS_BUCKET_LOG 2
U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip); U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip);
void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip);
void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip); void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip);
@@ -44,15 +43,6 @@ size_t ZSTD_compressBlock_lazy(
size_t ZSTD_compressBlock_greedy( size_t ZSTD_compressBlock_greedy(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy2_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_btlazy2_dictMatchState( size_t ZSTD_compressBlock_btlazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -66,15 +56,6 @@ size_t ZSTD_compressBlock_lazy_dictMatchState(
size_t ZSTD_compressBlock_greedy_dictMatchState( size_t ZSTD_compressBlock_greedy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy2_dictMatchState_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy_dictMatchState_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_dictMatchState_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -85,15 +66,6 @@ size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_extDict( size_t ZSTD_compressBlock_greedy_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
@@ -104,19 +76,9 @@ size_t ZSTD_compressBlock_lazy_extDict(
size_t ZSTD_compressBlock_lazy2_extDict( size_t ZSTD_compressBlock_lazy2_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_extDict_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy_extDict_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy2_extDict_row(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize);
size_t ZSTD_compressBlock_btlazy2_extDict( size_t ZSTD_compressBlock_btlazy2_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
void const* src, size_t srcSize); void const* src, size_t srcSize);
#if defined (__cplusplus) #if defined (__cplusplus)
} }
+14 -50
View File
@@ -57,33 +57,6 @@ static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const*
} }
} }
/** ZSTD_ldm_gear_reset()
* Feeds [data, data + minMatchLength) into the hash without registering any
* splits. This effectively resets the hash state. This is used when skipping
* over data, either at the beginning of a block, or skipping sections.
*/
static void ZSTD_ldm_gear_reset(ldmRollingHashState_t* state,
BYTE const* data, size_t minMatchLength)
{
U64 hash = state->rolling;
size_t n = 0;
#define GEAR_ITER_ONCE() do { \
hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \
n += 1; \
} while (0)
while (n + 3 < minMatchLength) {
GEAR_ITER_ONCE();
GEAR_ITER_ONCE();
GEAR_ITER_ONCE();
GEAR_ITER_ONCE();
}
while (n < minMatchLength) {
GEAR_ITER_ONCE();
}
#undef GEAR_ITER_ONCE
}
/** ZSTD_ldm_gear_feed(): /** ZSTD_ldm_gear_feed():
* *
* Registers in the splits array all the split points found in the first * Registers in the splits array all the split points found in the first
@@ -282,7 +255,7 @@ void ZSTD_ldm_fillHashTable(
while (ip < iend) { while (ip < iend) {
size_t hashed; size_t hashed;
unsigned n; unsigned n;
numSplits = 0; numSplits = 0;
hashed = ZSTD_ldm_gear_feed(&hashState, ip, iend - ip, splits, &numSplits); hashed = ZSTD_ldm_gear_feed(&hashState, ip, iend - ip, splits, &numSplits);
@@ -354,8 +327,16 @@ static size_t ZSTD_ldm_generateSequences_internal(
/* Initialize the rolling hash state with the first minMatchLength bytes */ /* Initialize the rolling hash state with the first minMatchLength bytes */
ZSTD_ldm_gear_init(&hashState, params); ZSTD_ldm_gear_init(&hashState, params);
ZSTD_ldm_gear_reset(&hashState, ip, minMatchLength); {
ip += minMatchLength; size_t n = 0;
while (n < minMatchLength) {
numSplits = 0;
n += ZSTD_ldm_gear_feed(&hashState, ip + n, minMatchLength - n,
splits, &numSplits);
}
ip += minMatchLength;
}
while (ip < ilimit) { while (ip < ilimit) {
size_t hashed; size_t hashed;
@@ -380,7 +361,6 @@ static size_t ZSTD_ldm_generateSequences_internal(
for (n = 0; n < numSplits; n++) { for (n = 0; n < numSplits; n++) {
size_t forwardMatchLength = 0, backwardMatchLength = 0, size_t forwardMatchLength = 0, backwardMatchLength = 0,
bestMatchLength = 0, mLength; bestMatchLength = 0, mLength;
U32 offset;
BYTE const* const split = candidates[n].split; BYTE const* const split = candidates[n].split;
U32 const checksum = candidates[n].checksum; U32 const checksum = candidates[n].checksum;
U32 const hash = candidates[n].hash; U32 const hash = candidates[n].hash;
@@ -448,9 +428,9 @@ static size_t ZSTD_ldm_generateSequences_internal(
} }
/* Match found */ /* Match found */
offset = (U32)(split - base) - bestEntry->offset;
mLength = forwardMatchLength + backwardMatchLength; mLength = forwardMatchLength + backwardMatchLength;
{ {
U32 const offset = (U32)(split - base) - bestEntry->offset;
rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size; rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
/* Out of sequence storage */ /* Out of sequence storage */
@@ -467,21 +447,6 @@ static size_t ZSTD_ldm_generateSequences_internal(
ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params); ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
anchor = split + forwardMatchLength; anchor = split + forwardMatchLength;
/* If we find a match that ends after the data that we've hashed
* then we have a repeating, overlapping, pattern. E.g. all zeros.
* If one repetition of the pattern matches our `stopMask` then all
* repetitions will. We don't need to insert them all into out table,
* only the first one. So skip over overlapping matches.
* This is a major speed boost (20x) for compressing a single byte
* repeated, when that byte ends up in the table.
*/
if (anchor > ip + hashed) {
ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength);
/* Continue the outter loop at anchor (ip + hashed == anchor). */
ip = anchor - hashed;
break;
}
} }
ip += hashed; ip += hashed;
@@ -535,7 +500,7 @@ size_t ZSTD_ldm_generateSequences(
assert(chunkStart < iend); assert(chunkStart < iend);
/* 1. Perform overflow correction if necessary. */ /* 1. Perform overflow correction if necessary. */
if (ZSTD_window_needOverflowCorrection(ldmState->window, 0, maxDist, ldmState->loadedDictEnd, chunkStart, chunkEnd)) { if (ZSTD_window_needOverflowCorrection(ldmState->window, chunkEnd)) {
U32 const ldmHSize = 1U << params->hashLog; U32 const ldmHSize = 1U << params->hashLog;
U32 const correction = ZSTD_window_correctOverflow( U32 const correction = ZSTD_window_correctOverflow(
&ldmState->window, /* cycleLog */ 0, maxDist, chunkStart); &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart);
@@ -657,13 +622,12 @@ void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
void const* src, size_t srcSize) void const* src, size_t srcSize)
{ {
const ZSTD_compressionParameters* const cParams = &ms->cParams; const ZSTD_compressionParameters* const cParams = &ms->cParams;
unsigned const minMatch = cParams->minMatch; unsigned const minMatch = cParams->minMatch;
ZSTD_blockCompressor const blockCompressor = ZSTD_blockCompressor const blockCompressor =
ZSTD_selectBlockCompressor(cParams->strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms)); ZSTD_selectBlockCompressor(cParams->strategy, ZSTD_matchState_dictMode(ms));
/* Input bounds */ /* Input bounds */
BYTE const* const istart = (BYTE const*)src; BYTE const* const istart = (BYTE const*)src;
BYTE const* const iend = istart + srcSize; BYTE const* const iend = istart + srcSize;
-1
View File
@@ -66,7 +66,6 @@ size_t ZSTD_ldm_generateSequences(
*/ */
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_useRowMatchFinderMode_e useRowMatchFinder,
void const* src, size_t srcSize); void const* src, size_t srcSize);
/** /**
+18 -3
View File
@@ -8,6 +8,20 @@
* You may select, at your option, one of the above-listed licenses. * 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 "zstd_compress_internal.h"
#include "hist.h" #include "hist.h"
#include "zstd_opt.h" #include "zstd_opt.h"
@@ -408,7 +422,7 @@ static U32 ZSTD_insertBt1(
hashTable[h] = curr; /* Update Hash Table */ hashTable[h] = curr; /* Update Hash Table */
assert(windowLow > 0); assert(windowLow > 0);
while (nbCompares-- && (matchIndex >= windowLow)) { for (; nbCompares && (matchIndex >= windowLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask); U32* const nextPtr = bt + 2*(matchIndex & btMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
assert(matchIndex < curr); assert(matchIndex < curr);
@@ -639,7 +653,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
hashTable[h] = curr; /* Update Hash Table */ hashTable[h] = curr; /* Update Hash Table */
while (nbCompares-- && (matchIndex >= matchLow)) { for (; nbCompares && (matchIndex >= matchLow); --nbCompares) {
U32* const nextPtr = bt + 2*(matchIndex & btMask); U32* const nextPtr = bt + 2*(matchIndex & btMask);
const BYTE* match; const BYTE* match;
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
@@ -692,12 +706,13 @@ U32 ZSTD_insertBtAndGetAllMatches (
*smallerPtr = *largerPtr = 0; *smallerPtr = *largerPtr = 0;
assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
if (dictMode == ZSTD_dictMatchState && nbCompares) { if (dictMode == ZSTD_dictMatchState && nbCompares) {
size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls); size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);
U32 dictMatchIndex = dms->hashTable[dmsH]; U32 dictMatchIndex = dms->hashTable[dmsH];
const U32* const dmsBt = dms->chainTable; const U32* const dmsBt = dms->chainTable;
commonLengthSmaller = commonLengthLarger = 0; commonLengthSmaller = commonLengthLarger = 0;
while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) { for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) {
const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask); const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match = dmsBase + dictMatchIndex; const BYTE* match = dmsBase + dictMatchIndex;
+5 -14
View File
@@ -512,7 +512,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState,
if (dictSize > 0) { if (dictSize > 0) {
if (dictContentType == ZSTD_dct_rawContent) { if (dictContentType == ZSTD_dct_rawContent) {
BYTE const* const dictEnd = (const BYTE*)dict + dictSize; BYTE const* const dictEnd = (const BYTE*)dict + dictSize;
ZSTD_window_update(&serialState->ldmState.window, dict, dictSize, /* forceNonContiguous */ 0); ZSTD_window_update(&serialState->ldmState.window, dict, dictSize);
ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, &params.ldmParams); ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, &params.ldmParams);
serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base); serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base);
} else { } else {
@@ -569,7 +569,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
assert(seqStore.seq != NULL && seqStore.pos == 0 && assert(seqStore.seq != NULL && seqStore.pos == 0 &&
seqStore.size == 0 && seqStore.capacity > 0); seqStore.size == 0 && seqStore.capacity > 0);
assert(src.size <= serialState->params.jobSize); assert(src.size <= serialState->params.jobSize);
ZSTD_window_update(&serialState->ldmState.window, src.start, src.size, /* forceNonContiguous */ 0); ZSTD_window_update(&serialState->ldmState.window, src.start, src.size);
error = ZSTD_ldm_generateSequences( error = ZSTD_ldm_generateSequences(
&serialState->ldmState, &seqStore, &serialState->ldmState, &seqStore,
&serialState->params.ldmParams, src.start, src.size); &serialState->params.ldmParams, src.start, src.size);
@@ -695,10 +695,6 @@ static void ZSTDMT_compressionJob(void* jobDescription)
{ size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob); { size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);
if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError); if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
} }
if (!job->firstJob) {
size_t const err = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_deterministicRefPrefix, 0);
if (ZSTD_isError(err)) JOB_ERROR(err);
}
{ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, { size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */ job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
ZSTD_dtlm_fast, ZSTD_dtlm_fast,
@@ -754,12 +750,6 @@ static void ZSTDMT_compressionJob(void* jobDescription)
if (ZSTD_isError(cSize)) JOB_ERROR(cSize); if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
lastCBlockSize = cSize; lastCBlockSize = cSize;
} } } }
if (!job->firstJob) {
/* Double check that we don't have an ext-dict, because then our
* repcode invalidation doesn't work.
*/
assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));
}
ZSTD_CCtx_trace(cctx, 0); ZSTD_CCtx_trace(cctx, 0);
_endJob: _endJob:
@@ -1250,8 +1240,9 @@ size_t ZSTDMT_initCStream_internal(
if (params.rsyncable) { if (params.rsyncable) {
/* Aim for the targetsectionSize as the average job size. */ /* Aim for the targetsectionSize as the average job size. */
U32 const jobSizeKB = (U32)(mtctx->targetSectionSize >> 10); U32 const jobSizeMB = (U32)(mtctx->targetSectionSize >> 20);
U32 const rsyncBits = (assert(jobSizeKB >= 1), ZSTD_highbit32(jobSizeKB) + 10); U32 const rsyncBits = ZSTD_highbit32(jobSizeMB) + 20;
assert(jobSizeMB >= 1);
DEBUGLOG(4, "rsyncLog = %u", rsyncBits); DEBUGLOG(4, "rsyncLog = %u", rsyncBits);
mtctx->rsync.hash = 0; mtctx->rsync.hash = 0;
mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1; mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1;
+4 -4
View File
@@ -32,11 +32,11 @@
/* === Constants === */ /* === Constants === */
#ifndef ZSTDMT_NBWORKERS_MAX /* a different value can be selected at compile time */ #ifndef ZSTDMT_NBWORKERS_MAX
# define ZSTDMT_NBWORKERS_MAX ((sizeof(void*)==4) /*32-bit*/ ? 64 : 256) # define ZSTDMT_NBWORKERS_MAX 200
#endif #endif
#ifndef ZSTDMT_JOBSIZE_MIN /* a different value can be selected at compile time */ #ifndef ZSTDMT_JOBSIZE_MIN
# define ZSTDMT_JOBSIZE_MIN (512 KB) # define ZSTDMT_JOBSIZE_MIN (1 MB)
#endif #endif
#define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30) #define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30)
#define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB)) #define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB))
+1 -1
View File
@@ -886,7 +886,7 @@ HUF_decompress4X2_usingDTable_internal_body(
HUF_DECODE_SYMBOLX2_0(op2, &bitD2); HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
HUF_DECODE_SYMBOLX2_0(op3, &bitD3); HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
HUF_DECODE_SYMBOLX2_0(op4, &bitD4); HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
endSignal = (U32)LIKELY( endSignal = (U32)LIKELY((U32)
(BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
& (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
& (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
+21 -11
View File
@@ -177,12 +177,15 @@ static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet,
static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) { static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem); ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem);
DEBUGLOG(4, "Allocating new hash set"); 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); ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE; if (!ret->ddictPtrTable) {
ret->ddictPtrCount = 0; ZSTD_customFree(ret, customMem);
if (!ret || !ret->ddictPtrTable) {
return NULL; return NULL;
} }
ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
ret->ddictPtrCount = 0;
return ret; return ret;
} }
@@ -466,7 +469,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
} }
switch(dictIDSizeCode) switch(dictIDSizeCode)
{ {
default: assert(0); /* impossible */ default:
assert(0); /* impossible */
ZSTD_FALLTHROUGH;
case 0 : break; case 0 : break;
case 1 : dictID = ip[pos]; pos++; break; case 1 : dictID = ip[pos]; pos++; break;
case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
@@ -474,7 +479,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
} }
switch(fcsID) switch(fcsID)
{ {
default: assert(0); /* impossible */ default:
assert(0); /* impossible */
ZSTD_FALLTHROUGH;
case 0 : if (singleSegment) frameContentSize = ip[pos]; break; case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
case 2 : frameContentSize = MEM_readLE32(ip+pos); break; case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
@@ -788,7 +795,7 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming) static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
{ {
#if ZSTD_TRACE #if ZSTD_TRACE
if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) { if (dctx->traceCtx) {
ZSTD_Trace trace; ZSTD_Trace trace;
ZSTD_memset(&trace, 0, sizeof(trace)); ZSTD_memset(&trace, 0, sizeof(trace));
trace.version = ZSTD_VERSION_NUMBER; trace.version = ZSTD_VERSION_NUMBER;
@@ -1009,7 +1016,7 @@ static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
switch (dctx->dictUses) { switch (dctx->dictUses) {
default: default:
assert(0 /* Impossible */); assert(0 /* Impossible */);
/* fall-through */ ZSTD_FALLTHROUGH;
case ZSTD_dont_use: case ZSTD_dont_use:
ZSTD_clearDict(dctx); ZSTD_clearDict(dctx);
return NULL; return NULL;
@@ -1073,7 +1080,9 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
{ {
default: /* should not happen */ default: /* should not happen */
assert(0); assert(0);
ZSTD_FALLTHROUGH;
case ZSTDds_getFrameHeaderSize: case ZSTDds_getFrameHeaderSize:
ZSTD_FALLTHROUGH;
case ZSTDds_decodeFrameHeader: case ZSTDds_decodeFrameHeader:
return ZSTDnit_frameHeader; return ZSTDnit_frameHeader;
case ZSTDds_decodeBlockHeader: case ZSTDds_decodeBlockHeader:
@@ -1085,6 +1094,7 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
case ZSTDds_checkChecksum: case ZSTDds_checkChecksum:
return ZSTDnit_checksum; return ZSTDnit_checksum;
case ZSTDds_decodeSkippableHeader: case ZSTDds_decodeSkippableHeader:
ZSTD_FALLTHROUGH;
case ZSTDds_skipFrame: case ZSTDds_skipFrame:
return ZSTDnit_skippableFrame; return ZSTDnit_skippableFrame;
} }
@@ -1383,7 +1393,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
{ {
assert(dctx != NULL); assert(dctx != NULL);
#if ZSTD_TRACE #if ZSTD_TRACE
dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0; dctx->traceCtx = ZSTD_trace_decompress_begin(dctx);
#endif #endif
dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */
dctx->stage = ZSTDds_getFrameHeaderSize; dctx->stage = ZSTDds_getFrameHeaderSize;
@@ -1900,7 +1910,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
zds->legacyVersion = 0; zds->legacyVersion = 0;
zds->hostageByte = 0; zds->hostageByte = 0;
zds->expectedOutBuffer = *output; zds->expectedOutBuffer = *output;
/* fall-through */ ZSTD_FALLTHROUGH;
case zdss_loadHeader : case zdss_loadHeader :
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip)); DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
@@ -2038,7 +2048,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
zds->outBuffSize = neededOutBuffSize; zds->outBuffSize = neededOutBuffSize;
} } } } } }
zds->streamStage = zdss_read; zds->streamStage = zdss_read;
/* fall-through */ ZSTD_FALLTHROUGH;
case zdss_read: case zdss_read:
DEBUGLOG(5, "stage zdss_read"); DEBUGLOG(5, "stage zdss_read");
@@ -2057,7 +2067,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
} } } }
if (ip==iend) { someMoreWork = 0; break; } /* no more input */ if (ip==iend) { someMoreWork = 0; break; } /* no more input */
zds->streamStage = zdss_load; zds->streamStage = zdss_load;
/* fall-through */ ZSTD_FALLTHROUGH;
case zdss_load: case zdss_load:
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
+37 -45
View File
@@ -90,7 +90,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
case set_repeat: case set_repeat:
DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block"); DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, ""); RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
/* fall-through */ ZSTD_FALLTHROUGH;
case set_compressed: case set_compressed:
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3"); RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
@@ -658,6 +658,7 @@ typedef struct {
size_t litLength; size_t litLength;
size_t matchLength; size_t matchLength;
size_t offset; size_t offset;
const BYTE* match;
} seq_t; } seq_t;
typedef struct { typedef struct {
@@ -671,6 +672,9 @@ typedef struct {
ZSTD_fseState stateOffb; ZSTD_fseState stateOffb;
ZSTD_fseState stateML; ZSTD_fseState stateML;
size_t prevOffset[ZSTD_REP_NUM]; size_t prevOffset[ZSTD_REP_NUM];
const BYTE* prefixStart;
const BYTE* dictEnd;
size_t pos;
} seqState_t; } seqState_t;
/*! ZSTD_overlapCopy8() : /*! ZSTD_overlapCopy8() :
@@ -932,9 +936,10 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, ZSTD
: 0) : 0)
typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
typedef enum { ZSTD_p_noPrefetch=0, ZSTD_p_prefetch=1 } ZSTD_prefetch_e;
FORCE_INLINE_TEMPLATE seq_t FORCE_INLINE_TEMPLATE seq_t
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const ZSTD_prefetch_e prefetch)
{ {
seq_t seq; seq_t seq;
ZSTD_seqSymbol const llDInfo = seqState->stateLL.table[seqState->stateLL.state]; ZSTD_seqSymbol const llDInfo = seqState->stateLL.table[seqState->stateLL.state];
@@ -1009,6 +1014,14 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
if (prefetch == ZSTD_p_prefetch) {
size_t const pos = seqState->pos + seq.litLength;
const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;
seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
* No consequence though : no memory access will occur, offset is only used for prefetching */
seqState->pos = pos + seq.matchLength;
}
/* ANS state update /* ANS state update
* gcc-9.0.0 does 2.5% worse with ZSTD_updateFseStateWithDInfo(). * gcc-9.0.0 does 2.5% worse with ZSTD_updateFseStateWithDInfo().
* clang-9.2.0 does 7% worse with ZSTD_updateFseState(). * clang-9.2.0 does 7% worse with ZSTD_updateFseState().
@@ -1109,6 +1122,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
/* Regen sequences */ /* Regen sequences */
if (nbSeq) { if (nbSeq) {
seqState_t seqState; seqState_t seqState;
size_t error = 0;
dctx->fseEntropy = 1; dctx->fseEntropy = 1;
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
RETURN_ERROR_IF( RETURN_ERROR_IF(
@@ -1142,14 +1156,13 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
* If you see most cycles served out of the DSB you've hit the good case. * If you see most cycles served out of the DSB you've hit the good case.
* If it is pretty even then you may be in an okay case. * If it is pretty even then you may be in an okay case.
* *
* This issue has been reproduced on the following CPUs: * I've been able to reproduce this issue on the following CPUs:
* - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9 * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9
* Use Instruments->Counters to get DSB/MITE cycles. * Use Instruments->Counters to get DSB/MITE cycles.
* I never got performance swings, but I was able to * I never got performance swings, but I was able to
* go from the good case of mostly DSB to half of the * go from the good case of mostly DSB to half of the
* cycles served from MITE. * cycles served from MITE.
* - Coffeelake: Intel i9-9900k * - Coffeelake: Intel i9-9900k
* - Coffeelake: Intel i7-9700k
* *
* I haven't been able to reproduce the instability or DSB misses on any * I haven't been able to reproduce the instability or DSB misses on any
* of the following CPUS: * of the following CPUS:
@@ -1162,35 +1175,33 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
* *
* https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4 * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4
*/ */
__asm__(".p2align 6");
__asm__("nop");
__asm__(".p2align 5"); __asm__(".p2align 5");
__asm__("nop"); __asm__("nop");
# if __GNUC__ >= 9
/* better for gcc-9 and gcc-10, worse for clang and gcc-8 */
__asm__(".p2align 3");
# else
__asm__(".p2align 4"); __asm__(".p2align 4");
# endif
#endif #endif
for ( ; ; ) { for ( ; ; ) {
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_noPrefetch);
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
assert(!ZSTD_isError(oneSeqSize)); assert(!ZSTD_isError(oneSeqSize));
if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
#endif #endif
if (UNLIKELY(ZSTD_isError(oneSeqSize)))
return oneSeqSize;
DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
op += oneSeqSize;
if (UNLIKELY(!--nbSeq))
break;
BIT_reloadDStream(&(seqState.DStream)); BIT_reloadDStream(&(seqState.DStream));
op += oneSeqSize;
/* gcc and clang both don't like early returns in this loop.
* Instead break and check for an error at the end of the loop.
*/
if (UNLIKELY(ZSTD_isError(oneSeqSize))) {
error = oneSeqSize;
break;
}
if (UNLIKELY(!--nbSeq)) break;
} }
/* check if reached exact end */ /* check if reached exact end */
DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq); DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
if (ZSTD_isError(error)) return error;
RETURN_ERROR_IF(nbSeq, corruption_detected, ""); RETURN_ERROR_IF(nbSeq, corruption_detected, "");
RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, ""); RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
/* save reps for next block */ /* save reps for next block */
@@ -1221,24 +1232,6 @@ ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
FORCE_INLINE_TEMPLATE size_t
ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
const BYTE* const prefixStart, const BYTE* const dictEnd)
{
prefetchPos += sequence.litLength;
{ const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
const BYTE* const match = matchBase + prefetchPos - sequence.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
* No consequence though : memory address is only used for prefetching, not for dereferencing */
PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
}
return prefetchPos + sequence.matchLength;
}
/* This decoding function employs prefetching
* to reduce latency impact of cache misses.
* It's generally employed when block contains a significant portion of long-distance matches
* or when coupled with a "cold" dictionary */
FORCE_INLINE_TEMPLATE size_t FORCE_INLINE_TEMPLATE size_t
ZSTD_decompressSequencesLong_body( ZSTD_decompressSequencesLong_body(
ZSTD_DCtx* dctx, ZSTD_DCtx* dctx,
@@ -1261,17 +1254,18 @@ ZSTD_decompressSequencesLong_body(
/* Regen sequences */ /* Regen sequences */
if (nbSeq) { if (nbSeq) {
#define STORED_SEQS 8 #define STORED_SEQS 4
#define STORED_SEQS_MASK (STORED_SEQS-1) #define STORED_SEQS_MASK (STORED_SEQS-1)
#define ADVANCED_SEQS STORED_SEQS #define ADVANCED_SEQS 4
seq_t sequences[STORED_SEQS]; seq_t sequences[STORED_SEQS];
int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
seqState_t seqState; seqState_t seqState;
int seqNb; int seqNb;
size_t prefetchPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */
dctx->fseEntropy = 1; dctx->fseEntropy = 1;
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } { int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
seqState.prefixStart = prefixStart;
seqState.pos = (size_t)(op-prefixStart);
seqState.dictEnd = dictEnd;
assert(dst != NULL); assert(dst != NULL);
assert(iend >= ip); assert(iend >= ip);
RETURN_ERROR_IF( RETURN_ERROR_IF(
@@ -1283,23 +1277,21 @@ ZSTD_decompressSequencesLong_body(
/* prepare in advance */ /* prepare in advance */
for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) { for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); sequences[seqNb] = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_prefetch);
prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); PREFETCH_L1(sequences[seqNb].match); PREFETCH_L1(sequences[seqNb].match + sequences[seqNb].matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
sequences[seqNb] = sequence;
} }
RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, ""); RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
/* decode and decompress */ /* decode and decompress */
for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb<nbSeq) ; seqNb++) { for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb<nbSeq) ; seqNb++) {
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, ZSTD_p_prefetch);
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd); size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
assert(!ZSTD_isError(oneSeqSize)); assert(!ZSTD_isError(oneSeqSize));
if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
#endif #endif
if (ZSTD_isError(oneSeqSize)) return oneSeqSize; if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
PREFETCH_L1(sequence.match); PREFETCH_L1(sequence.match + sequence.matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
sequences[seqNb & STORED_SEQS_MASK] = sequence; sequences[seqNb & STORED_SEQS_MASK] = sequence;
op += oneSeqSize; op += oneSeqSize;
} }
+5 -6
View File
@@ -26,16 +26,15 @@
#include <string.h> /* memset */ #include <string.h> /* memset */
#include <time.h> /* clock */ #include <time.h> /* clock */
#ifndef ZDICT_STATIC_LINKING_ONLY
# define ZDICT_STATIC_LINKING_ONLY
#endif
#include "../common/mem.h" /* read */ #include "../common/mem.h" /* read */
#include "../common/pool.h" #include "../common/pool.h"
#include "../common/threading.h" #include "../common/threading.h"
#include "../common/zstd_internal.h" /* includes zstd.h */
#include "../zdict.h"
#include "cover.h" #include "cover.h"
#include "../common/zstd_internal.h" /* includes zstd.h */
#ifndef ZDICT_STATIC_LINKING_ONLY
#define ZDICT_STATIC_LINKING_ONLY
#endif
#include "zdict.h"
/*-************************************* /*-*************************************
* Constants * Constants
+4 -5
View File
@@ -8,10 +8,6 @@
* You may select, at your option, one of the above-listed licenses. * You may select, at your option, one of the above-listed licenses.
*/ */
#ifndef ZDICT_STATIC_LINKING_ONLY
# define ZDICT_STATIC_LINKING_ONLY
#endif
#include <stdio.h> /* fprintf */ #include <stdio.h> /* fprintf */
#include <stdlib.h> /* malloc, free, qsort */ #include <stdlib.h> /* malloc, free, qsort */
#include <string.h> /* memset */ #include <string.h> /* memset */
@@ -20,7 +16,10 @@
#include "../common/pool.h" #include "../common/pool.h"
#include "../common/threading.h" #include "../common/threading.h"
#include "../common/zstd_internal.h" /* includes zstd.h */ #include "../common/zstd_internal.h" /* includes zstd.h */
#include "../zdict.h" #ifndef ZDICT_STATIC_LINKING_ONLY
#define ZDICT_STATIC_LINKING_ONLY
#endif
#include "zdict.h"
/** /**
* COVER_best_t is used for two purposes: * COVER_best_t is used for two purposes:
+5 -6
View File
@@ -16,17 +16,16 @@
#include <string.h> /* memset */ #include <string.h> /* memset */
#include <time.h> /* clock */ #include <time.h> /* clock */
#ifndef ZDICT_STATIC_LINKING_ONLY
# define ZDICT_STATIC_LINKING_ONLY
#endif
#include "../common/mem.h" /* read */ #include "../common/mem.h" /* read */
#include "../common/pool.h" #include "../common/pool.h"
#include "../common/threading.h" #include "../common/threading.h"
#include "cover.h"
#include "../common/zstd_internal.h" /* includes zstd.h */ #include "../common/zstd_internal.h" /* includes zstd.h */
#include "../compress/zstd_compress_internal.h" /* ZSTD_hash*() */ #include "../compress/zstd_compress_internal.h" /* ZSTD_hash*() */
#include "../zdict.h" #ifndef ZDICT_STATIC_LINKING_ONLY
#include "cover.h" #define ZDICT_STATIC_LINKING_ONLY
#endif
#include "zdict.h"
/*-************************************* /*-*************************************
+6 -7
View File
@@ -41,19 +41,18 @@
#include <stdio.h> /* fprintf, fopen, ftello64 */ #include <stdio.h> /* fprintf, fopen, ftello64 */
#include <time.h> /* clock */ #include <time.h> /* clock */
#ifndef ZDICT_STATIC_LINKING_ONLY
# define ZDICT_STATIC_LINKING_ONLY
#endif
#define HUF_STATIC_LINKING_ONLY
#include "../common/mem.h" /* read */ #include "../common/mem.h" /* read */
#include "../common/fse.h" /* FSE_normalizeCount, FSE_writeNCount */ #include "../common/fse.h" /* FSE_normalizeCount, FSE_writeNCount */
#define HUF_STATIC_LINKING_ONLY
#include "../common/huf.h" /* HUF_buildCTable, HUF_writeCTable */ #include "../common/huf.h" /* HUF_buildCTable, HUF_writeCTable */
#include "../common/zstd_internal.h" /* includes zstd.h */ #include "../common/zstd_internal.h" /* includes zstd.h */
#include "../common/xxhash.h" /* XXH64 */ #include "../common/xxhash.h" /* XXH64 */
#include "../compress/zstd_compress_internal.h" /* ZSTD_loadCEntropy() */
#include "../zdict.h"
#include "divsufsort.h" #include "divsufsort.h"
#ifndef ZDICT_STATIC_LINKING_ONLY
# define ZDICT_STATIC_LINKING_ONLY
#endif
#include "zdict.h"
#include "../compress/zstd_compress_internal.h" /* ZSTD_loadCEntropy() */
/*-************************************* /*-*************************************
+1 -147
View File
@@ -36,145 +36,6 @@ extern "C" {
# define ZDICTLIB_API ZDICTLIB_VISIBILITY # define ZDICTLIB_API ZDICTLIB_VISIBILITY
#endif #endif
/*******************************************************************************
* Zstd dictionary builder
*
* FAQ
* ===
* Why should I use a dictionary?
* ------------------------------
*
* Zstd can use dictionaries to improve compression ratio of small data.
* Traditionally small files don't compress well because there is very little
* repetion in a single sample, since it is small. But, if you are compressing
* many similar files, like a bunch of JSON records that share the same
* structure, you can train a dictionary on ahead of time on some samples of
* these files. Then, zstd can use the dictionary to find repetitions that are
* present across samples. This can vastly improve compression ratio.
*
* When is a dictionary useful?
* ----------------------------
*
* Dictionaries are useful when compressing many small files that are similar.
* The larger a file is, the less benefit a dictionary will have. Generally,
* we don't expect dictionary compression to be effective past 100KB. And the
* smaller a file is, the more we would expect the dictionary to help.
*
* How do I use a dictionary?
* --------------------------
*
* Simply pass the dictionary to the zstd compressor with
* `ZSTD_CCtx_loadDictionary()`. The same dictionary must then be passed to
* the decompressor, using `ZSTD_DCtx_loadDictionary()`. There are other
* more advanced functions that allow selecting some options, see zstd.h for
* complete documentation.
*
* What is a zstd dictionary?
* --------------------------
*
* A zstd dictionary has two pieces: Its header, and its content. The header
* contains a magic number, the dictionary ID, and entropy tables. These
* entropy tables allow zstd to save on header costs in the compressed file,
* which really matters for small data. The content is just bytes, which are
* repeated content that is common across many samples.
*
* What is a raw content dictionary?
* ---------------------------------
*
* A raw content dictionary is just bytes. It doesn't have a zstd dictionary
* header, a dictionary ID, or entropy tables. Any buffer is a valid raw
* content dictionary.
*
* How do I train a dictionary?
* ----------------------------
*
* Gather samples from your use case. These samples should be similar to each
* other. If you have several use cases, you could try to train one dictionary
* per use case.
*
* Pass those samples to `ZDICT_trainFromBuffer()` and that will train your
* dictionary. There are a few advanced versions of this function, but this
* is a great starting point. If you want to further tune your dictionary
* you could try `ZDICT_optimizeTrainFromBuffer_cover()`. If that is too slow
* you can try `ZDICT_optimizeTrainFromBuffer_fastCover()`.
*
* If the dictionary training function fails, that is likely because you
* either passed too few samples, or a dictionary would not be effective
* for your data. Look at the messages that the dictionary trainer printed,
* if it doesn't say too few samples, then a dictionary would not be effective.
*
* How large should my dictionary be?
* ----------------------------------
*
* A reasonable dictionary size, the `dictBufferCapacity`, is about 100KB.
* The zstd CLI defaults to a 110KB dictionary. You likely don't need a
* dictionary larger than that. But, most use cases can get away with a
* smaller dictionary. The advanced dictionary builders can automatically
* shrink the dictionary for you, and select a the smallest size that
* doesn't hurt compression ratio too much. See the `shrinkDict` parameter.
* A smaller dictionary can save memory, and potentially speed up
* compression.
*
* How many samples should I provide to the dictionary builder?
* ------------------------------------------------------------
*
* We generally recommend passing ~100x the size of the dictionary
* in samples. A few thousand should suffice. Having too few samples
* can hurt the dictionaries effectiveness. Having more samples will
* only improve the dictionaries effectiveness. But having too many
* samples can slow down the dictionary builder.
*
* How do I determine if a dictionary will be effective?
* -----------------------------------------------------
*
* Simply train a dictionary and try it out. You can use zstd's built in
* benchmarking tool to test the dictionary effectiveness.
*
* # Benchmark levels 1-3 without a dictionary
* zstd -b1e3 -r /path/to/my/files
* # Benchmark levels 1-3 with a dictioanry
* zstd -b1e3 -r /path/to/my/files -D /path/to/my/dictionary
*
* When should I retrain a dictionary?
* -----------------------------------
*
* You should retrain a dictionary when its effectiveness drops. Dictionary
* effectiveness drops as the data you are compressing changes. Generally, we do
* expect dictionaries to "decay" over time, as your data changes, but the rate
* at which they decay depends on your use case. Internally, we regularly
* retrain dictionaries, and if the new dictionary performs significantly
* better than the old dictionary, we will ship the new dictionary.
*
* I have a raw content dictionary, how do I turn it into a zstd dictionary?
* -------------------------------------------------------------------------
*
* If you have a raw content dictionary, e.g. by manually constructing it, or
* using a third-party dictionary builder, you can turn it into a zstd
* dictionary by using `ZDICT_finalizeDictionary()`. You'll also have to
* provide some samples of the data. It will add the zstd header to the
* raw content, which contains a dictionary ID and entropy tables, which
* will improve compression ratio, and allow zstd to write the dictionary ID
* into the frame, if you so choose.
*
* Do I have to use zstd's dictionary builder?
* -------------------------------------------
*
* No! You can construct dictionary content however you please, it is just
* bytes. It will always be valid as a raw content dictionary. If you want
* a zstd dictionary, which can improve compression ratio, use
* `ZDICT_finalizeDictionary()`.
*
* What is the attack surface of a zstd dictionary?
* ------------------------------------------------
*
* Zstd is heavily fuzz tested, including loading fuzzed dictionaries, so
* zstd should never crash, or access out-of-bounds memory no matter what
* the dictionary is. However, if an attacker can control the dictionary
* during decompression, they can cause zstd to generate arbitrary bytes,
* just like if they controlled the compressed data.
*
******************************************************************************/
/*! ZDICT_trainFromBuffer(): /*! ZDICT_trainFromBuffer():
* Train a dictionary from an array of samples. * Train a dictionary from an array of samples.
@@ -203,14 +64,7 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCap
typedef struct { typedef struct {
int compressionLevel; /*< optimize for a specific zstd compression level; 0 means default */ int compressionLevel; /*< optimize for a specific zstd compression level; 0 means default */
unsigned notificationLevel; /*< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */ unsigned notificationLevel; /*< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
unsigned dictID; /*< force dictID value; 0 means auto mode (32-bits random value) unsigned dictID; /*< force dictID value; 0 means auto mode (32-bits random value) */
* NOTE: The zstd format reserves some dictionary IDs for future use.
* You may use them in private settings, but be warned that they
* may be used by zstd in a public dictionary registry in the future.
* These dictionary IDs are:
* - low range : <= 32767
* - high range : >= (2^31)
*/
} ZDICT_params_t; } ZDICT_params_t;
/*! ZDICT_finalizeDictionary(): /*! ZDICT_finalizeDictionary():
+72 -152
View File
@@ -71,8 +71,8 @@ extern "C" {
/*------ Version ------*/ /*------ Version ------*/
#define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MAJOR 1
#define ZSTD_VERSION_MINOR 5 #define ZSTD_VERSION_MINOR 4
#define ZSTD_VERSION_RELEASE 0 #define ZSTD_VERSION_RELEASE 10
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
/*! ZSTD_versionNumber() : /*! ZSTD_versionNumber() :
@@ -109,6 +109,7 @@ ZSTDLIB_API const char* ZSTD_versionString(void);
#define ZSTD_BLOCKSIZE_MAX (1<<ZSTD_BLOCKSIZELOG_MAX) #define ZSTD_BLOCKSIZE_MAX (1<<ZSTD_BLOCKSIZELOG_MAX)
/*************************************** /***************************************
* Simple API * Simple API
***************************************/ ***************************************/
@@ -165,7 +166,7 @@ ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t
* @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */ * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */
ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
/*! ZSTD_findFrameCompressedSize() : Requires v1.4.0+ /*! ZSTD_findFrameCompressedSize() :
* `src` should point to the start of a ZSTD frame or skippable frame. * `src` should point to the start of a ZSTD frame or skippable frame.
* `srcSize` must be >= first frame size * `srcSize` must be >= first frame size
* @return : the compressed size of the first frame starting at `src`, * @return : the compressed size of the first frame starting at `src`,
@@ -179,9 +180,8 @@ ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize)
ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */
ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */ ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */ ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */
ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed, requires v1.4.0+ */ ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed */
ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */ ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
ZSTDLIB_API int ZSTD_defaultCLevel(void); /*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */
/*************************************** /***************************************
@@ -234,9 +234,9 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx,
const void* src, size_t srcSize); const void* src, size_t srcSize);
/********************************************* /***************************************
* Advanced compression API (Requires v1.4.0+) * Advanced compression API
**********************************************/ ***************************************/
/* API design : /* API design :
* Parameters are pushed one by one into an existing context, * Parameters are pushed one by one into an existing context,
@@ -266,6 +266,7 @@ typedef enum { ZSTD_fast=1,
Only the order (from fast to strong) is guaranteed */ Only the order (from fast to strong) is guaranteed */
} ZSTD_strategy; } ZSTD_strategy;
typedef enum { typedef enum {
/* compression parameters /* compression parameters
@@ -331,6 +332,7 @@ typedef enum {
* The higher the value of selected strategy, the more complex it is, * The higher the value of selected strategy, the more complex it is,
* resulting in stronger and slower compression. * resulting in stronger and slower compression.
* Special: value 0 means "use default strategy". */ * Special: value 0 means "use default strategy". */
/* LDM mode parameters */ /* LDM mode parameters */
ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching. ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching.
* This parameter is designed to improve compression ratio * This parameter is designed to improve compression ratio
@@ -387,7 +389,7 @@ typedef enum {
ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1. ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1.
* Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads. * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads.
* 0 means default, which is dynamically determined based on compression parameters. * 0 means default, which is dynamically determined based on compression parameters.
* Job size must be a minimum of overlap size, or ZSTDMT_JOBSIZE_MIN (= 512 KB), whichever is largest. * Job size must be a minimum of overlap size, or 1 MB, whichever is largest.
* The minimum size is automatically and transparently enforced. */ * The minimum size is automatically and transparently enforced. */
ZSTD_c_overlapLog=402, /* Control the overlap size, as a fraction of window size. ZSTD_c_overlapLog=402, /* Control the overlap size, as a fraction of window size.
* The overlap size is an amount of data reloaded from previous job at the beginning of a new job. * The overlap size is an amount of data reloaded from previous job at the beginning of a new job.
@@ -417,8 +419,6 @@ typedef enum {
* ZSTD_c_stableOutBuffer * ZSTD_c_stableOutBuffer
* ZSTD_c_blockDelimiters * ZSTD_c_blockDelimiters
* ZSTD_c_validateSequences * ZSTD_c_validateSequences
* ZSTD_c_splitBlocks
* ZSTD_c_useRowMatchFinder
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
* note : never ever use experimentalParam? names directly; * note : never ever use experimentalParam? names directly;
* also, the enums values themselves are unstable and can still change. * also, the enums values themselves are unstable and can still change.
@@ -434,10 +434,7 @@ typedef enum {
ZSTD_c_experimentalParam9=1006, ZSTD_c_experimentalParam9=1006,
ZSTD_c_experimentalParam10=1007, ZSTD_c_experimentalParam10=1007,
ZSTD_c_experimentalParam11=1008, ZSTD_c_experimentalParam11=1008,
ZSTD_c_experimentalParam12=1009, ZSTD_c_experimentalParam12=1009
ZSTD_c_experimentalParam13=1010,
ZSTD_c_experimentalParam14=1011,
ZSTD_c_experimentalParam15=1012
} ZSTD_cParameter; } ZSTD_cParameter;
typedef struct { typedef struct {
@@ -522,9 +519,9 @@ ZSTDLIB_API size_t ZSTD_compress2( ZSTD_CCtx* cctx,
const void* src, size_t srcSize); const void* src, size_t srcSize);
/*********************************************** /***************************************
* Advanced decompression API (Requires v1.4.0+) * Advanced decompression API
************************************************/ ***************************************/
/* The advanced API pushes parameters one by one into an existing DCtx context. /* The advanced API pushes parameters one by one into an existing DCtx context.
* Parameters are sticky, and remain valid for all following frames * Parameters are sticky, and remain valid for all following frames
@@ -686,7 +683,7 @@ typedef enum {
: note : multithreaded compression will block to flush as much output as possible. */ : note : multithreaded compression will block to flush as much output as possible. */
} ZSTD_EndDirective; } ZSTD_EndDirective;
/*! ZSTD_compressStream2() : Requires v1.4.0+ /*! ZSTD_compressStream2() :
* Behaves about the same as ZSTD_compressStream, with additional control on end directive. * Behaves about the same as ZSTD_compressStream, with additional control on end directive.
* - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*() * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*()
* - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode) * - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode)
@@ -732,11 +729,11 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output
/* ***************************************************************************** /* *****************************************************************************
* This following is a legacy streaming API, available since v1.0+ . * This following is a legacy streaming API.
* It can be replaced by ZSTD_CCtx_reset() and ZSTD_compressStream2(). * It can be replaced by ZSTD_CCtx_reset() and ZSTD_compressStream2().
* It is redundant, but remains fully supported. * It is redundant, but remains fully supported.
* Streaming in combination with advanced parameters and dictionary compression * Advanced parameters and dictionary compression can only be used through the
* can only be used through the new API. * new API.
******************************************************************************/ ******************************************************************************/
/*! /*!
@@ -814,7 +811,7 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output
/*! ZSTD_compress_usingDict() : /*! ZSTD_compress_usingDict() :
* Compression at an explicit compression level using a Dictionary. * Compression at an explicit compression level using a Dictionary.
* A dictionary can be any arbitrary data segment (also called a prefix), * A dictionary can be any arbitrary data segment (also called a prefix),
* or a buffer with specified information (see zdict.h). * or a buffer with specified information (see dictBuilder/zdict.h).
* Note : This function loads the dictionary, resulting in significant startup delay. * Note : This function loads the dictionary, resulting in significant startup delay.
* It's intended for a dictionary used only once. * It's intended for a dictionary used only once.
* Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. */ * Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. */
@@ -897,25 +894,19 @@ ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
* Dictionary helper functions * Dictionary helper functions
*******************************/ *******************************/
/*! ZSTD_getDictID_fromDict() : Requires v1.4.0+ /*! ZSTD_getDictID_fromDict() :
* Provides the dictID stored within dictionary. * Provides the dictID stored within dictionary.
* if @return == 0, the dictionary is not conformant with Zstandard specification. * if @return == 0, the dictionary is not conformant with Zstandard specification.
* It can still be loaded, but as a content-only dictionary. */ * It can still be loaded, but as a content-only dictionary. */
ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize); ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
/*! ZSTD_getDictID_fromCDict() : Requires v1.5.0+ /*! ZSTD_getDictID_fromDDict() :
* Provides the dictID of the dictionary loaded into `cdict`.
* If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
* Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
/*! ZSTD_getDictID_fromDDict() : Requires v1.4.0+
* Provides the dictID of the dictionary loaded into `ddict`. * Provides the dictID of the dictionary loaded into `ddict`.
* If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
* Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
/*! ZSTD_getDictID_fromFrame() : Requires v1.4.0+ /*! ZSTD_getDictID_fromFrame() :
* Provides the dictID required to decompressed the frame stored within `src`. * Provides the dictID required to decompressed the frame stored within `src`.
* If @return == 0, the dictID could not be decoded. * If @return == 0, the dictID could not be decoded.
* This could for one of the following reasons : * This could for one of the following reasons :
@@ -929,7 +920,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
/******************************************************************************* /*******************************************************************************
* Advanced dictionary and prefix API (Requires v1.4.0+) * Advanced dictionary and prefix API
* *
* This API allows dictionaries to be used with ZSTD_compress2(), * This API allows dictionaries to be used with ZSTD_compress2(),
* ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and * ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and
@@ -938,7 +929,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
******************************************************************************/ ******************************************************************************/
/*! ZSTD_CCtx_loadDictionary() : Requires v1.4.0+ /*! ZSTD_CCtx_loadDictionary() :
* Create an internal CDict from `dict` buffer. * Create an internal CDict from `dict` buffer.
* Decompression will have to use same dictionary. * Decompression will have to use same dictionary.
* @result : 0, or an error code (which can be tested with ZSTD_isError()). * @result : 0, or an error code (which can be tested with ZSTD_isError()).
@@ -957,7 +948,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
* to precisely select how dictionary content must be interpreted. */ * to precisely select how dictionary content must be interpreted. */
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
/*! ZSTD_CCtx_refCDict() : Requires v1.4.0+ /*! ZSTD_CCtx_refCDict() :
* Reference a prepared dictionary, to be used for all next compressed frames. * Reference a prepared dictionary, to be used for all next compressed frames.
* Note that compression parameters are enforced from within CDict, * Note that compression parameters are enforced from within CDict,
* and supersede any compression parameter previously set within CCtx. * and supersede any compression parameter previously set within CCtx.
@@ -971,7 +962,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
* Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. */ * Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. */
ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
/*! ZSTD_CCtx_refPrefix() : Requires v1.4.0+ /*! ZSTD_CCtx_refPrefix() :
* Reference a prefix (single-usage dictionary) for next compressed frame. * Reference a prefix (single-usage dictionary) for next compressed frame.
* A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end). * A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end).
* Decompression will need same prefix to properly regenerate data. * Decompression will need same prefix to properly regenerate data.
@@ -992,7 +983,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx,
const void* prefix, size_t prefixSize); const void* prefix, size_t prefixSize);
/*! ZSTD_DCtx_loadDictionary() : Requires v1.4.0+ /*! ZSTD_DCtx_loadDictionary() :
* Create an internal DDict from dict buffer, * Create an internal DDict from dict buffer,
* to be used to decompress next frames. * to be used to decompress next frames.
* The dictionary remains valid for all future frames, until explicitly invalidated. * The dictionary remains valid for all future frames, until explicitly invalidated.
@@ -1009,7 +1000,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx,
*/ */
ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
/*! ZSTD_DCtx_refDDict() : Requires v1.4.0+ /*! ZSTD_DCtx_refDDict() :
* Reference a prepared dictionary, to be used to decompress next frames. * Reference a prepared dictionary, to be used to decompress next frames.
* The dictionary remains active for decompression of future frames using same DCtx. * The dictionary remains active for decompression of future frames using same DCtx.
* *
@@ -1027,7 +1018,7 @@ ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, s
*/ */
ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
/*! ZSTD_DCtx_refPrefix() : Requires v1.4.0+ /*! ZSTD_DCtx_refPrefix() :
* Reference a prefix (single-usage dictionary) to decompress next frame. * Reference a prefix (single-usage dictionary) to decompress next frame.
* This is the reverse operation of ZSTD_CCtx_refPrefix(), * This is the reverse operation of ZSTD_CCtx_refPrefix(),
* and must use the same prefix as the one used during compression. * and must use the same prefix as the one used during compression.
@@ -1048,7 +1039,7 @@ ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx,
/* === Memory management === */ /* === Memory management === */
/*! ZSTD_sizeof_*() : Requires v1.4.0+ /*! ZSTD_sizeof_*() :
* These functions give the _current_ memory usage of selected object. * These functions give the _current_ memory usage of selected object.
* Note that object memory usage can evolve (increase or decrease) over time. */ * Note that object memory usage can evolve (increase or decrease) over time. */
ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
@@ -1073,28 +1064,6 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) #if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY)
#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY #define ZSTD_H_ZSTD_STATIC_LINKING_ONLY
/* Deprecation warnings :
* Should these warnings be a problem, it is generally possible to disable them,
* typically with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual.
* Otherwise, it's also possible to define ZSTD_DISABLE_DEPRECATE_WARNINGS.
*/
#ifdef ZSTD_DISABLE_DEPRECATE_WARNINGS
# define ZSTD_DEPRECATED(message) ZSTDLIB_API /* disable deprecation warnings */
#else
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
# define ZSTD_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_API
# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__)
# define ZSTD_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated(message)))
# elif defined(__GNUC__) && (__GNUC__ >= 3)
# define ZSTD_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated))
# elif defined(_MSC_VER)
# define ZSTD_DEPRECATED(message) ZSTDLIB_API __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement ZSTD_DEPRECATED for this compiler")
# define ZSTD_DEPRECATED(message) ZSTDLIB_API
# endif
#endif /* ZSTD_DISABLE_DEPRECATE_WARNINGS */
/**************************************************************************************** /****************************************************************************************
* experimental API (static linking only) * experimental API (static linking only)
**************************************************************************************** ****************************************************************************************
@@ -1301,11 +1270,6 @@ typedef enum {
ZSTD_lcm_uncompressed = 2 /**< Always emit uncompressed literals. */ ZSTD_lcm_uncompressed = 2 /**< Always emit uncompressed literals. */
} ZSTD_literalCompressionMode_e; } ZSTD_literalCompressionMode_e;
typedef enum {
ZSTD_urm_auto = 0, /* Automatically determine whether or not we use row matchfinder */
ZSTD_urm_disableRowMatchFinder = 1, /* Never use row matchfinder */
ZSTD_urm_enableRowMatchFinder = 2 /* Always use row matchfinder when applicable */
} ZSTD_useRowMatchFinderMode_e;
/*************************************** /***************************************
* Frame size functions * Frame size functions
@@ -1613,6 +1577,12 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(
* note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */ * note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
/*! ZSTD_getDictID_fromCDict() :
* Provides the dictID of the dictionary loaded into `cdict`.
* If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
* Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
/*! ZSTD_getCParams() : /*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */ * `estimatedSrcSize` value is optional, select 0 if not known */
@@ -1639,20 +1609,18 @@ ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParame
/*! ZSTD_compress_advanced() : /*! ZSTD_compress_advanced() :
* Note : this function is now DEPRECATED. * Note : this function is now DEPRECATED.
* It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters.
* This prototype will generate compilation warnings. */ * This prototype will be marked as deprecated and generate compilation warning on reaching v1.5.x */
ZSTD_DEPRECATED("use ZSTD_compress2") ZSTDLIB_API size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const void* dict,size_t dictSize, const void* dict,size_t dictSize,
ZSTD_parameters params); ZSTD_parameters params);
/*! ZSTD_compress_usingCDict_advanced() : /*! ZSTD_compress_usingCDict_advanced() :
* Note : this function is now DEPRECATED. * Note : this function is now REDUNDANT.
* It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters. * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters.
* This prototype will generate compilation warnings. */ * This prototype will be marked as deprecated and generate compilation warning in some future version */
ZSTD_DEPRECATED("use ZSTD_compress2 with ZSTD_CCtx_loadDictionary") ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const ZSTD_CDict* cdict, const ZSTD_CDict* cdict,
@@ -1714,7 +1682,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
/* Controls how the literals are compressed (default is auto). /* Controls how the literals are compressed (default is auto).
* The value must be of type ZSTD_literalCompressionMode_e. * The value must be of type ZSTD_literalCompressionMode_e.
* See ZSTD_literalCompressionMode_e enum definition for details. * See ZSTD_literalCompressionMode_t enum definition for details.
*/ */
#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5 #define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5
@@ -1866,46 +1834,6 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
*/ */
#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12 #define ZSTD_c_validateSequences ZSTD_c_experimentalParam12
/* ZSTD_c_splitBlocks
* Default is 0 == disabled. Set to 1 to enable block splitting.
*
* Will attempt to split blocks in order to improve compression ratio at the cost of speed.
*/
#define ZSTD_c_splitBlocks ZSTD_c_experimentalParam13
/* ZSTD_c_useRowMatchFinder
* Default is ZSTD_urm_auto.
* Controlled with ZSTD_useRowMatchFinderMode_e enum.
*
* By default, in ZSTD_urm_auto, when finalizing the compression parameters, the library
* will decide at runtime whether to use the row-based matchfinder based on support for SIMD
* instructions as well as the windowLog.
*
* Set to ZSTD_urm_disableRowMatchFinder to never use row-based matchfinder.
* Set to ZSTD_urm_enableRowMatchFinder to force usage of row-based matchfinder.
*/
#define ZSTD_c_useRowMatchFinder ZSTD_c_experimentalParam14
/* ZSTD_c_deterministicRefPrefix
* Default is 0 == disabled. Set to 1 to enable.
*
* Zstd produces different results for prefix compression when the prefix is
* directly adjacent to the data about to be compressed vs. when it isn't.
* This is because zstd detects that the two buffers are contiguous and it can
* use a more efficient match finding algorithm. However, this produces different
* results than when the two buffers are non-contiguous. This flag forces zstd
* to always load the prefix in non-contiguous mode, even if it happens to be
* adjacent to the data, to guarantee determinism.
*
* If you really care about determinism when using a dictionary or prefix,
* like when doing delta compression, you should select this option. It comes
* at a speed penalty of about ~2.5% if the dictionary and data happened to be
* contiguous, and is free if they weren't contiguous. We don't expect that
* intentionally making the dictionary and data contiguous will be worth the
* cost to memcpy() the data.
*/
#define ZSTD_c_deterministicRefPrefix ZSTD_c_experimentalParam15
/*! ZSTD_CCtx_getParameter() : /*! ZSTD_CCtx_getParameter() :
* Get the requested compression parameter value, selected by enum ZSTD_cParameter, * Get the requested compression parameter value, selected by enum ZSTD_cParameter,
* and store it into int* value. * and store it into int* value.
@@ -1951,7 +1879,7 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compre
*/ */
ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
/*! ZSTD_CCtxParams_setParameter() : Requires v1.4.0+ /*! ZSTD_CCtxParams_setParameter() :
* Similar to ZSTD_CCtx_setParameter. * Similar to ZSTD_CCtx_setParameter.
* Set one compression parameter, selected by enum ZSTD_cParameter. * Set one compression parameter, selected by enum ZSTD_cParameter.
* Parameters must be applied to a ZSTD_CCtx using * Parameters must be applied to a ZSTD_CCtx using
@@ -2117,13 +2045,11 @@ ZSTDLIB_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param
/*! ZSTD_DCtx_setFormat() : /*! ZSTD_DCtx_setFormat() :
* This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter().
* Instruct the decoder context about what kind of data to decode next. * Instruct the decoder context about what kind of data to decode next.
* This instruction is mandatory to decode data without a fully-formed header, * This instruction is mandatory to decode data without a fully-formed header,
* such ZSTD_f_zstd1_magicless for example. * such ZSTD_f_zstd1_magicless for example.
* @return : 0, or an error code (which can be tested using ZSTD_isError()). */ * @return : 0, or an error code (which can be tested using ZSTD_isError()). */
ZSTD_DEPRECATED("use ZSTD_DCtx_setParameter() instead") ZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
/*! ZSTD_decompressStream_simpleArgs() : /*! ZSTD_decompressStream_simpleArgs() :
* Same as ZSTD_decompressStream(), * Same as ZSTD_decompressStream(),
@@ -2147,7 +2073,7 @@ ZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs (
/*===== Advanced Streaming compression functions =====*/ /*===== Advanced Streaming compression functions =====*/
/*! ZSTD_initCStream_srcSize() : /*! ZSTD_initCStream_srcSize() :
* This function is DEPRECATED, and equivalent to: * This function is deprecated, and equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any) * ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)
* ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); * ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
@@ -2156,15 +2082,15 @@ ZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs (
* pledgedSrcSize must be correct. If it is not known at init time, use * pledgedSrcSize must be correct. If it is not known at init time, use
* ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, * ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs,
* "0" also disables frame content size field. It may be enabled in the future. * "0" also disables frame content size field. It may be enabled in the future.
* This prototype will generate compilation warnings. * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/ */
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") ZSTDLIB_API size_t
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
int compressionLevel, int compressionLevel,
unsigned long long pledgedSrcSize); unsigned long long pledgedSrcSize);
/*! ZSTD_initCStream_usingDict() : /*! ZSTD_initCStream_usingDict() :
* This function is DEPRECATED, and is equivalent to: * This function is deprecated, and is equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel); * ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
* ZSTD_CCtx_loadDictionary(zcs, dict, dictSize); * ZSTD_CCtx_loadDictionary(zcs, dict, dictSize);
@@ -2173,15 +2099,15 @@ size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
* dict == NULL or dictSize < 8, in which case no dict is used. * dict == NULL or dictSize < 8, in which case no dict is used.
* Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if * Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if
* it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy. * it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.
* This prototype will generate compilation warnings. * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/ */
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") ZSTDLIB_API size_t
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
const void* dict, size_t dictSize, const void* dict, size_t dictSize,
int compressionLevel); int compressionLevel);
/*! ZSTD_initCStream_advanced() : /*! ZSTD_initCStream_advanced() :
* This function is DEPRECATED, and is approximately equivalent to: * This function is deprecated, and is approximately equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* // Pseudocode: Set each zstd parameter and leave the rest as-is. * // Pseudocode: Set each zstd parameter and leave the rest as-is.
* for ((param, value) : params) { * for ((param, value) : params) {
@@ -2193,24 +2119,23 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
* dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy. * dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy.
* pledgedSrcSize must be correct. * pledgedSrcSize must be correct.
* If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. * If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
* This prototype will generate compilation warnings. * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/ */
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") ZSTDLIB_API size_t
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
const void* dict, size_t dictSize, const void* dict, size_t dictSize,
ZSTD_parameters params, ZSTD_parameters params,
unsigned long long pledgedSrcSize); unsigned long long pledgedSrcSize);
/*! ZSTD_initCStream_usingCDict() : /*! ZSTD_initCStream_usingCDict() :
* This function is DEPRECATED, and equivalent to: * This function is deprecated, and equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_refCDict(zcs, cdict); * ZSTD_CCtx_refCDict(zcs, cdict);
* *
* note : cdict will just be referenced, and must outlive compression session * note : cdict will just be referenced, and must outlive compression session
* This prototype will generate compilation warnings. * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/ */
ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions") ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
/*! ZSTD_initCStream_usingCDict_advanced() : /*! ZSTD_initCStream_usingCDict_advanced() :
* This function is DEPRECATED, and is approximately equivalent to: * This function is DEPRECATED, and is approximately equivalent to:
@@ -2225,21 +2150,18 @@ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
* same as ZSTD_initCStream_usingCDict(), with control over frame parameters. * same as ZSTD_initCStream_usingCDict(), with control over frame parameters.
* pledgedSrcSize must be correct. If srcSize is not known at init time, use * pledgedSrcSize must be correct. If srcSize is not known at init time, use
* value ZSTD_CONTENTSIZE_UNKNOWN. * value ZSTD_CONTENTSIZE_UNKNOWN.
* This prototype will generate compilation warnings. * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/ */
ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions") ZSTDLIB_API size_t
size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
const ZSTD_CDict* cdict, const ZSTD_CDict* cdict,
ZSTD_frameParameters fParams, ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize); unsigned long long pledgedSrcSize);
/*! ZSTD_resetCStream() : /*! ZSTD_resetCStream() :
* This function is DEPRECATED, and is equivalent to: * This function is deprecated, and is equivalent to:
* ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
* ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize); * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);
* Note: ZSTD_resetCStream() interprets pledgedSrcSize == 0 as ZSTD_CONTENTSIZE_UNKNOWN, but
* ZSTD_CCtx_setPledgedSrcSize() does not do the same, so ZSTD_CONTENTSIZE_UNKNOWN must be
* explicitly specified.
* *
* start a new frame, using same parameters from previous frame. * start a new frame, using same parameters from previous frame.
* This is typically useful to skip dictionary loading stage, since it will re-use it in-place. * This is typically useful to skip dictionary loading stage, since it will re-use it in-place.
@@ -2249,10 +2171,9 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
* For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs, * For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs,
* but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead. * but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead.
* @return : 0, or an error code (which can be tested using ZSTD_isError()) * @return : 0, or an error code (which can be tested using ZSTD_isError())
* This prototype will generate compilation warnings. * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
*/ */
ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions") ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
typedef struct { typedef struct {
@@ -2339,7 +2260,8 @@ ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
ZSTD_CCtx object can be re-used multiple times within successive compression operations. ZSTD_CCtx object can be re-used multiple times within successive compression operations.
Start by initializing a context. Start by initializing a context.
Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression. Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
or ZSTD_compressBegin_advanced(), for finer parameter control.
It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx() It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
Then, consume your input using ZSTD_compressContinue(). Then, consume your input using ZSTD_compressContinue().
@@ -2364,17 +2286,15 @@ ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
/*===== Buffer-less streaming compression functions =====*/ /*===== Buffer-less streaming compression functions =====*/
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */
ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */
ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */
ZSTD_DEPRECATED("use advanced API to access custom parameters")
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */
ZSTD_DEPRECATED("use advanced API to access custom parameters")
size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */
/** /**
Buffer-less streaming decompression (synchronous mode) Buffer-less streaming decompression (synchronous mode)
+2 -9
View File
@@ -100,12 +100,8 @@ ZSTD_ALL_SRC = $(ZSTDLIB_LOCAL_SRC) $(ZSTD_CLI_SRC)
ZSTD_ALL_OBJ := $(ZSTD_ALL_SRC:.c=.o) ZSTD_ALL_OBJ := $(ZSTD_ALL_SRC:.c=.o)
UNAME := $(shell uname) UNAME := $(shell uname)
ifndef BUILD_DIR
ifeq ($(UNAME), Darwin) ifeq ($(UNAME), Darwin)
ifeq ($(shell md5 < /dev/null > /dev/null; echo $$?), 0) HASH ?= md5
HASH ?= md5
endif
else ifeq ($(UNAME), FreeBSD) else ifeq ($(UNAME), FreeBSD)
HASH ?= gmd5sum HASH ?= gmd5sum
else ifeq ($(UNAME), NetBSD) else ifeq ($(UNAME), NetBSD)
@@ -116,6 +112,7 @@ endif
HASH ?= md5sum HASH ?= md5sum
HAVE_HASH :=$(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0) HAVE_HASH :=$(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0)
ifndef BUILD_DIR
HASH_DIR = conf_$(shell echo $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(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) ifeq ($(HAVE_HASH),0)
$(info warning : could not find HASH ($(HASH)), needed to differentiate builds using different flags) $(info warning : could not find HASH ($(HASH)), needed to differentiate builds using different flags)
@@ -279,19 +276,16 @@ zstd-nolegacy : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAG
zstd-nolegacy : $(ZSTDLIB_CORE_SRC) $(ZDICT_SRC) $(ZSTD_CLI_OBJ) zstd-nolegacy : $(ZSTDLIB_CORE_SRC) $(ZDICT_SRC) $(ZSTD_CLI_OBJ)
$(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS) $(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS)
.PHONY: zstd-nomt
zstd-nomt : THREAD_CPP := zstd-nomt : THREAD_CPP :=
zstd-nomt : THREAD_LD := zstd-nomt : THREAD_LD :=
zstd-nomt : THREAD_MSG := - multi-threading disabled zstd-nomt : THREAD_MSG := - multi-threading disabled
zstd-nomt : zstd zstd-nomt : zstd
.PHONY: zstd-nogz
zstd-nogz : ZLIBCPP := zstd-nogz : ZLIBCPP :=
zstd-nogz : ZLIBLD := zstd-nogz : ZLIBLD :=
zstd-nogz : ZLIB_MSG := - gzip support is disabled zstd-nogz : ZLIB_MSG := - gzip support is disabled
zstd-nogz : zstd zstd-nogz : zstd
.PHONY: zstd-noxz
zstd-noxz : LZMACPP := zstd-noxz : LZMACPP :=
zstd-noxz : LZMALD := zstd-noxz : LZMALD :=
zstd-noxz : LZMA_MSG := - xz/lzma support is disabled zstd-noxz : LZMA_MSG := - xz/lzma support is disabled
@@ -306,7 +300,6 @@ zstd-dll : zstd
## zstd-pgo: zstd executable optimized with PGO. ## zstd-pgo: zstd executable optimized with PGO.
.PHONY: zstd-pgo
zstd-pgo : zstd-pgo :
$(MAKE) clean $(MAKE) clean
$(MAKE) zstd MOREFLAGS=-fprofile-generate $(MAKE) zstd MOREFLAGS=-fprofile-generate
+1 -2
View File
@@ -224,8 +224,7 @@ Therefore, this avenue is intentionally restricted and only supports `ZSTD_CLEVE
that `zstd` will use for compression, which by default is `1`. that `zstd` will use for compression, which by default is `1`.
This functionality only exists when `zstd` is compiled with multithread support. This functionality only exists when `zstd` is compiled with multithread support.
`0` means "use as many threads as detected cpu cores on local system". `0` means "use as many threads as detected cpu cores on local system".
The max # of threads is capped at `ZSTDMT_NBWORKERS_MAX`, The max # of threads is capped at: `ZSTDMT_NBWORKERS_MAX==200`.
which is either 64 in 32-bit mode, or 256 for 64-bit environments.
This functionality can be useful when `zstd` CLI is invoked in a way that doesn't allow passing arguments. This functionality can be useful when `zstd` CLI is invoked in a way that doesn't allow passing arguments.
One such scenario is `tar --zstd`. One such scenario is `tar --zstd`.
+12 -6
View File
@@ -36,7 +36,7 @@
#include "datagen.h" /* RDG_genBuffer */ #include "datagen.h" /* RDG_genBuffer */
#include "../lib/common/xxhash.h" #include "../lib/common/xxhash.h"
#include "benchzstd.h" #include "benchzstd.h"
#include "../lib/zstd_errors.h" #include "../lib/common/zstd_errors.h"
/* ************************************* /* *************************************
@@ -67,10 +67,18 @@ static const size_t maxMemory = (sizeof(size_t)==4) ?
/* ************************************* /* *************************************
* console display * console display
***************************************/ ***************************************/
#define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush(NULL); } #define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
#define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } #define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); }
/* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */ /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */
static const U64 g_refreshRate = SEC_TO_MICRO / 6;
static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER;
#define DISPLAYUPDATE(l, ...) { if (displayLevel>=l) { \
if ((UTIL_clockSpanMicro(g_displayClock) > g_refreshRate) || (displayLevel>=4)) \
{ g_displayClock = UTIL_getTime(); DISPLAY(__VA_ARGS__); \
if (displayLevel>=4) fflush(stderr); } } }
/* ************************************* /* *************************************
* Exceptions * Exceptions
@@ -129,8 +137,7 @@ BMK_advancedParams_t BMK_initAdvancedParams(void) {
0, /* ldmHashLog */ 0, /* ldmHashLog */
0, /* ldmBuckSizeLog */ 0, /* ldmBuckSizeLog */
0, /* ldmHashRateLog */ 0, /* ldmHashRateLog */
ZSTD_lcm_auto, /* literalCompressionMode */ ZSTD_lcm_auto /* literalCompressionMode */
0 /* useRowMatchFinder */
}; };
return res; return res;
} }
@@ -168,7 +175,6 @@ BMK_initCCtx(ZSTD_CCtx* ctx,
CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, adv->nbWorkers)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_nbWorkers, adv->nbWorkers));
} }
CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, cLevel)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, cLevel));
CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_useRowMatchFinder, adv->useRowMatchFinder));
CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_enableLongDistanceMatching, adv->ldmFlag)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_enableLongDistanceMatching, adv->ldmFlag));
CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmMinMatch, adv->ldmMinMatch)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmMinMatch, adv->ldmMinMatch));
CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmHashLog, adv->ldmHashLog)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_ldmHashLog, adv->ldmHashLog));
@@ -760,7 +766,7 @@ static int BMK_loadFiles(void* buffer, size_t bufferSize,
} }
{ FILE* const f = fopen(fileNamesTable[n], "rb"); { FILE* const f = fopen(fileNamesTable[n], "rb");
if (f==NULL) RETURN_ERROR_INT(10, "impossible to open file %s", fileNamesTable[n]); if (f==NULL) RETURN_ERROR_INT(10, "impossible to open file %s", fileNamesTable[n]);
DISPLAYLEVEL(2, "Loading %s... \r", fileNamesTable[n]); DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[n]);
if (fileSize > bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */ if (fileSize > bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */
{ size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f); { size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f);
if (readSize != (size_t)fileSize) RETURN_ERROR_INT(11, "could not read %s", fileNamesTable[n]); if (readSize != (size_t)fileSize) RETURN_ERROR_INT(11, "could not read %s", fileNamesTable[n]);
-1
View File
@@ -117,7 +117,6 @@ typedef struct {
int ldmBucketSizeLog; int ldmBucketSizeLog;
int ldmHashRateLog; int ldmHashRateLog;
ZSTD_literalCompressionMode_e literalCompressionMode; ZSTD_literalCompressionMode_e literalCompressionMode;
int useRowMatchFinder; /* use row-based matchfinder if possible */
} BMK_advancedParams_t; } BMK_advancedParams_t;
/* returns default parameters used by nonAdvanced functions */ /* returns default parameters used by nonAdvanced functions */
+1 -1
View File
@@ -19,7 +19,7 @@
* Dependencies * Dependencies
***************************************/ ***************************************/
#define ZDICT_STATIC_LINKING_ONLY #define ZDICT_STATIC_LINKING_ONLY
#include "../lib/zdict.h" /* ZDICT_params_t */ #include "../lib/dictBuilder/zdict.h" /* ZDICT_params_t */
/*-************************************* /*-*************************************
+65 -95
View File
@@ -25,10 +25,9 @@
***************************************/ ***************************************/
#include "platform.h" /* Large Files support, SET_BINARY_MODE */ #include "platform.h" /* Large Files support, SET_BINARY_MODE */
#include "util.h" /* UTIL_getFileSize, UTIL_isRegularFile, UTIL_isSameFile */ #include "util.h" /* UTIL_getFileSize, UTIL_isRegularFile, UTIL_isSameFile */
#include <stdio.h> /* fprintf, open, fdopen, fread, _fileno, stdin, stdout */ #include <stdio.h> /* fprintf, fopen, fread, _fileno, stdin, stdout */
#include <stdlib.h> /* malloc, free */ #include <stdlib.h> /* malloc, free */
#include <string.h> /* strcmp, strlen */ #include <string.h> /* strcmp, strlen */
#include <fcntl.h> /* O_WRONLY */
#include <assert.h> #include <assert.h>
#include <errno.h> /* errno */ #include <errno.h> /* errno */
#include <limits.h> /* INT_MAX */ #include <limits.h> /* INT_MAX */
@@ -45,7 +44,7 @@
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */
#include "../lib/zstd.h" #include "../lib/zstd.h"
#include "../lib/zstd_errors.h" /* ZSTD_error_frameParameter_windowTooLarge */ #include "../lib/common/zstd_errors.h" /* ZSTD_error_frameParameter_windowTooLarge */
#if defined(ZSTD_GZCOMPRESS) || defined(ZSTD_GZDECOMPRESS) #if defined(ZSTD_GZCOMPRESS) || defined(ZSTD_GZDECOMPRESS)
# include <zlib.h> # include <zlib.h>
@@ -74,14 +73,6 @@
#define FNSPACE 30 #define FNSPACE 30
/* Default file permissions 0666 (modulated by umask) */
#if !defined(_WIN32)
/* These macros aren't defined on windows. */
#define DEFAULT_FILE_PERMISSIONS (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
#else
#define DEFAULT_FILE_PERMISSIONS (0666)
#endif
/*-************************************* /*-*************************************
* Macros * Macros
***************************************/ ***************************************/
@@ -93,10 +84,10 @@
struct FIO_display_prefs_s { struct FIO_display_prefs_s {
int displayLevel; /* 0 : no display; 1: errors; 2: + result + interaction + warnings; 3: + progression; 4: + information */ int displayLevel; /* 0 : no display; 1: errors; 2: + result + interaction + warnings; 3: + progression; 4: + information */
FIO_progressSetting_e progressSetting; U32 noProgress;
}; };
static FIO_display_prefs_t g_display_prefs = {2, FIO_ps_auto}; static FIO_display_prefs_t g_display_prefs = {2, 0};
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
#define DISPLAYOUT(...) fprintf(stdout, __VA_ARGS__) #define DISPLAYOUT(...) fprintf(stdout, __VA_ARGS__)
@@ -105,10 +96,10 @@ static FIO_display_prefs_t g_display_prefs = {2, FIO_ps_auto};
static const U64 g_refreshRate = SEC_TO_MICRO / 6; static const U64 g_refreshRate = SEC_TO_MICRO / 6;
static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER; static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER;
#define READY_FOR_UPDATE() ((g_display_prefs.progressSetting != FIO_ps_never) && UTIL_clockSpanMicro(g_displayClock) > g_refreshRate) #define READY_FOR_UPDATE() (!g_display_prefs.noProgress && UTIL_clockSpanMicro(g_displayClock) > g_refreshRate)
#define DELAY_NEXT_UPDATE() { g_displayClock = UTIL_getTime(); } #define DELAY_NEXT_UPDATE() { g_displayClock = UTIL_getTime(); }
#define DISPLAYUPDATE(l, ...) { \ #define DISPLAYUPDATE(l, ...) { \
if (g_display_prefs.displayLevel>=l && (g_display_prefs.progressSetting != FIO_ps_never)) { \ if (g_display_prefs.displayLevel>=l && !g_display_prefs.noProgress) { \
if (READY_FOR_UPDATE() || (g_display_prefs.displayLevel>=4)) { \ if (READY_FOR_UPDATE() || (g_display_prefs.displayLevel>=4)) { \
DELAY_NEXT_UPDATE(); \ DELAY_NEXT_UPDATE(); \
DISPLAY(__VA_ARGS__); \ DISPLAY(__VA_ARGS__); \
@@ -307,7 +298,6 @@ struct FIO_prefs_s {
int blockSize; int blockSize;
int overlapLog; int overlapLog;
U32 adaptiveMode; U32 adaptiveMode;
U32 useRowMatchFinder;
int rsyncable; int rsyncable;
int minAdaptLevel; int minAdaptLevel;
int maxAdaptLevel; int maxAdaptLevel;
@@ -333,7 +323,6 @@ struct FIO_prefs_s {
int excludeCompressedFiles; int excludeCompressedFiles;
int patchFromMode; int patchFromMode;
int contentSize; int contentSize;
int allowBlockDevices;
}; };
/*-************************************* /*-*************************************
@@ -394,7 +383,6 @@ FIO_prefs_t* FIO_createPreferences(void)
ret->testMode = 0; ret->testMode = 0;
ret->literalCompressionMode = ZSTD_lcm_auto; ret->literalCompressionMode = ZSTD_lcm_auto;
ret->excludeCompressedFiles = 0; ret->excludeCompressedFiles = 0;
ret->allowBlockDevices = 0;
return ret; return ret;
} }
@@ -430,7 +418,7 @@ void FIO_freeContext(FIO_ctx_t* const fCtx)
void FIO_setNotificationLevel(int level) { g_display_prefs.displayLevel=level; } void FIO_setNotificationLevel(int level) { g_display_prefs.displayLevel=level; }
void FIO_setProgressSetting(FIO_progressSetting_e setting) { g_display_prefs.progressSetting = setting; } void FIO_setNoProgress(unsigned noProgress) { g_display_prefs.noProgress = noProgress; }
/*-************************************* /*-*************************************
@@ -462,8 +450,6 @@ void FIO_setNbWorkers(FIO_prefs_t* const prefs, int nbWorkers) {
void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles) { prefs->excludeCompressedFiles = excludeCompressedFiles; } void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles) { prefs->excludeCompressedFiles = excludeCompressedFiles; }
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices) { prefs->allowBlockDevices = allowBlockDevices; }
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) { void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) {
if (blockSize && prefs->nbWorkers==0) if (blockSize && prefs->nbWorkers==0)
DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n"); DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n");
@@ -482,10 +468,6 @@ void FIO_setAdaptiveMode(FIO_prefs_t* const prefs, unsigned adapt) {
prefs->adaptiveMode = adapt; prefs->adaptiveMode = adapt;
} }
void FIO_setUseRowMatchFinder(FIO_prefs_t* const prefs, int useRowMatchFinder) {
prefs->useRowMatchFinder = useRowMatchFinder;
}
void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable) { void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable) {
if ((rsyncable>0) && (prefs->nbWorkers==0)) if ((rsyncable>0) && (prefs->nbWorkers==0))
EXM_THROW(1, "Rsyncable mode is not compatible with single thread mode \n"); EXM_THROW(1, "Rsyncable mode is not compatible with single thread mode \n");
@@ -606,12 +588,11 @@ static int FIO_removeFile(const char* path)
} }
/** FIO_openSrcFile() : /** FIO_openSrcFile() :
* condition : `srcFileName` must be non-NULL. `prefs` may be NULL. * condition : `srcFileName` must be non-NULL.
* @result : FILE* to `srcFileName`, or NULL if it fails */ * @result : FILE* to `srcFileName`, or NULL if it fails */
static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFileName) static FILE* FIO_openSrcFile(const char* srcFileName)
{ {
stat_t statbuf; stat_t statbuf;
int allowBlockDevices = prefs != NULL ? prefs->allowBlockDevices : 0;
assert(srcFileName != NULL); assert(srcFileName != NULL);
if (!strcmp (srcFileName, stdinmark)) { if (!strcmp (srcFileName, stdinmark)) {
DISPLAYLEVEL(4,"Using stdin for input \n"); DISPLAYLEVEL(4,"Using stdin for input \n");
@@ -627,7 +608,6 @@ static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFile
if (!UTIL_isRegularFileStat(&statbuf) if (!UTIL_isRegularFileStat(&statbuf)
&& !UTIL_isFIFOStat(&statbuf) && !UTIL_isFIFOStat(&statbuf)
&& !(allowBlockDevices && UTIL_isBlockDevStat(&statbuf))
) { ) {
DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n", DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
srcFileName); srcFileName);
@@ -646,8 +626,7 @@ static FILE* FIO_openSrcFile(const FIO_prefs_t* const prefs, const char* srcFile
* @result : FILE* to `dstFileName`, or NULL if it fails */ * @result : FILE* to `dstFileName`, or NULL if it fails */
static FILE* static FILE*
FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs, FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
const char* srcFileName, const char* dstFileName, const char* srcFileName, const char* dstFileName)
const int mode)
{ {
if (prefs->testMode) return NULL; /* do not open file in test mode */ if (prefs->testMode) return NULL; /* do not open file in test mode */
@@ -674,6 +653,7 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
if (UTIL_isRegularFile(dstFileName)) { if (UTIL_isRegularFile(dstFileName)) {
/* Check if destination file already exists */ /* Check if destination file already exists */
FILE* const fCheck = fopen( dstFileName, "rb" );
#if !defined(_WIN32) #if !defined(_WIN32)
/* this test does not work on Windows : /* this test does not work on Windows :
* `NUL` and `nul` are detected as regular files */ * `NUL` and `nul` are detected as regular files */
@@ -682,39 +662,26 @@ FIO_openDstFile(FIO_ctx_t* fCtx, FIO_prefs_t* const prefs,
dstFileName); dstFileName);
} }
#endif #endif
if (!prefs->overwrite) { if (fCheck != NULL) { /* dst file exists, authorization prompt */
if (g_display_prefs.displayLevel <= 1) { fclose(fCheck);
/* No interaction possible */ if (!prefs->overwrite) {
DISPLAY("zstd: %s already exists; not overwritten \n", if (g_display_prefs.displayLevel <= 1) {
dstFileName); /* No interaction possible */
return NULL; DISPLAY("zstd: %s already exists; not overwritten \n",
dstFileName);
return NULL;
}
DISPLAY("zstd: %s already exists; ", dstFileName);
if (UTIL_requireUserConfirmation("overwrite (y/n) ? ", "Not overwritten \n", "yY", fCtx->hasStdinInput))
return NULL;
} }
DISPLAY("zstd: %s already exists; ", dstFileName); /* need to unlink */
if (UTIL_requireUserConfirmation("overwrite (y/n) ? ", "Not overwritten \n", "yY", fCtx->hasStdinInput)) FIO_removeFile(dstFileName);
return NULL; } }
}
/* need to unlink */
FIO_removeFile(dstFileName);
}
{ { const int old_umask = UTIL_umask(0177); /* u-x,go-rwx */
#if defined(_WIN32) FILE* const f = fopen( dstFileName, "wb" );
/* Windows requires opening the file as a "binary" file to avoid UTIL_umask(old_umask);
* mangling. This macro doesn't exist on unix. */
const int openflags = O_WRONLY|O_CREAT|O_TRUNC|O_BINARY;
const int fd = _open(dstFileName, openflags, mode);
FILE* f = NULL;
if (fd != -1) {
f = _fdopen(fd, "wb");
}
#else
const int openflags = O_WRONLY|O_CREAT|O_TRUNC;
const int fd = open(dstFileName, openflags, mode);
FILE* f = NULL;
if (fd != -1) {
f = fdopen(fd, "wb");
}
#endif
if (f == NULL) { if (f == NULL) {
DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno)); DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno));
} }
@@ -951,7 +918,7 @@ static void FIO_adjustParamsForPatchFromMode(FIO_prefs_t* const prefs,
FIO_adjustMemLimitForPatchFromMode(prefs, dictSize, maxSrcFileSize); FIO_adjustMemLimitForPatchFromMode(prefs, dictSize, maxSrcFileSize);
if (fileWindowLog > ZSTD_WINDOWLOG_MAX) if (fileWindowLog > ZSTD_WINDOWLOG_MAX)
DISPLAYLEVEL(1, "Max window log exceeded by file (compression ratio will suffer)\n"); DISPLAYLEVEL(1, "Max window log exceeded by file (compression ratio will suffer)\n");
comprParams->windowLog = MAX(ZSTD_WINDOWLOG_MIN, MIN(ZSTD_WINDOWLOG_MAX, fileWindowLog)); comprParams->windowLog = MIN(ZSTD_WINDOWLOG_MAX, fileWindowLog);
if (fileWindowLog > ZSTD_cycleLog(cParams.chainLog, cParams.strategy)) { if (fileWindowLog > ZSTD_cycleLog(cParams.chainLog, cParams.strategy)) {
if (!prefs->ldmFlag) if (!prefs->ldmFlag)
DISPLAYLEVEL(1, "long mode automatically triggered\n"); DISPLAYLEVEL(1, "long mode automatically triggered\n");
@@ -1019,7 +986,6 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
if (prefs->ldmHashRateLog != FIO_LDM_PARAM_NOTSET) { if (prefs->ldmHashRateLog != FIO_LDM_PARAM_NOTSET) {
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_ldmHashRateLog, prefs->ldmHashRateLog) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_ldmHashRateLog, prefs->ldmHashRateLog) );
} }
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_useRowMatchFinder, prefs->useRowMatchFinder));
/* compression parameters */ /* compression parameters */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_windowLog, (int)comprParams.windowLog) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_windowLog, (int)comprParams.windowLog) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_chainLog, (int)comprParams.chainLog) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_chainLog, (int)comprParams.chainLog) );
@@ -1404,25 +1370,24 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx,
(unsigned)(zfp.consumed >> 20), (unsigned)(zfp.consumed >> 20),
(unsigned)(zfp.produced >> 20), (unsigned)(zfp.produced >> 20),
cShare ); cShare );
} else if (g_display_prefs.displayLevel >= 2 || g_display_prefs.progressSetting == FIO_ps_always) { } else { /* summarized notifications if == 2 */
/* Require level 2 or forcibly displayed progress counter for summarized updates */ DISPLAYLEVEL(2, "\r%79s\r", ""); /* Clear out the current displayed line */
DISPLAYLEVEL(1, "\r%79s\r", ""); /* Clear out the current displayed line */
if (fCtx->nbFilesTotal > 1) { if (fCtx->nbFilesTotal > 1) {
size_t srcFileNameSize = strlen(srcFileName); size_t srcFileNameSize = strlen(srcFileName);
/* Ensure that the string we print is roughly the same size each time */ /* Ensure that the string we print is roughly the same size each time */
if (srcFileNameSize > 18) { if (srcFileNameSize > 18) {
const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15; const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15;
DISPLAYLEVEL(1, "Compress: %u/%u files. Current: ...%s ", DISPLAYLEVEL(2, "Compress: %u/%u files. Current: ...%s ",
fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName); fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName);
} else { } else {
DISPLAYLEVEL(1, "Compress: %u/%u files. Current: %*s ", DISPLAYLEVEL(2, "Compress: %u/%u files. Current: %*s ",
fCtx->currFileIdx+1, fCtx->nbFilesTotal, (int)(18-srcFileNameSize), srcFileName); fCtx->currFileIdx+1, fCtx->nbFilesTotal, (int)(18-srcFileNameSize), srcFileName);
} }
} }
DISPLAYLEVEL(1, "Read : %2u ", (unsigned)(zfp.consumed >> 20)); DISPLAYLEVEL(2, "Read : %2u ", (unsigned)(zfp.consumed >> 20));
if (fileSize != UTIL_FILESIZE_UNKNOWN) if (fileSize != UTIL_FILESIZE_UNKNOWN)
DISPLAYLEVEL(2, "/ %2u ", (unsigned)(fileSize >> 20)); DISPLAYLEVEL(2, "/ %2u ", (unsigned)(fileSize >> 20));
DISPLAYLEVEL(1, "MB ==> %2.f%%", cShare); DISPLAYLEVEL(2, "MB ==> %2.f%%", cShare);
DELAY_NEXT_UPDATE(); DELAY_NEXT_UPDATE();
} }
@@ -1638,24 +1603,23 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
int closeDstFile = 0; int closeDstFile = 0;
int result; int result;
stat_t statbuf; stat_t statbuf;
int transfer_permissions = 0;
assert(ress.srcFile != NULL); assert(ress.srcFile != NULL);
if (ress.dstFile == NULL) { if (ress.dstFile == NULL) {
int dstFilePermissions = DEFAULT_FILE_PERMISSIONS;
if ( strcmp (srcFileName, stdinmark)
&& UTIL_stat(srcFileName, &statbuf)
&& UTIL_isRegularFileStat(&statbuf) ) {
dstFilePermissions = statbuf.st_mode;
}
closeDstFile = 1; closeDstFile = 1;
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s \n", dstFileName); DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: opening dst: %s \n", dstFileName);
ress.dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFilePermissions); ress.dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName);
if (ress.dstFile==NULL) return 1; /* could not open dstFileName */ if (ress.dstFile==NULL) return 1; /* could not open dstFileName */
/* Must only be added after FIO_openDstFile() succeeds. /* Must only be added after FIO_openDstFile() succeeds.
* Otherwise we may delete the destination file if it already exists, * Otherwise we may delete the destination file if it already exists,
* and the user presses Ctrl-C when asked if they wish to overwrite. * and the user presses Ctrl-C when asked if they wish to overwrite.
*/ */
addHandler(dstFileName); addHandler(dstFileName);
if ( strcmp (srcFileName, stdinmark)
&& UTIL_stat(srcFileName, &statbuf)
&& UTIL_isRegularFileStat(&statbuf) )
transfer_permissions = 1;
} }
result = FIO_compressFilename_internal(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel); result = FIO_compressFilename_internal(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel);
@@ -1675,6 +1639,11 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx,
&& strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */ && strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */
) { ) {
FIO_removeFile(dstFileName); /* remove compression artefact; note don't do anything special if remove() fails */ FIO_removeFile(dstFileName); /* remove compression artefact; note don't do anything special if remove() fails */
} else if (transfer_permissions) {
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: transferring permissions into dst: %s \n", dstFileName);
UTIL_setFileStat(dstFileName, &statbuf);
} else {
DISPLAYLEVEL(6, "FIO_compressFilename_dstFile: do not transfer permissions into dst: %s \n", dstFileName);
} }
} }
@@ -1733,7 +1702,7 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx,
return 0; return 0;
} }
ress.srcFile = FIO_openSrcFile(prefs, srcFileName); ress.srcFile = FIO_openSrcFile(srcFileName);
if (ress.srcFile == NULL) return 1; /* srcFile could not be opened */ if (ress.srcFile == NULL) return 1; /* srcFile could not be opened */
result = FIO_compressFilename_dstFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel); result = FIO_compressFilename_dstFile(fCtx, prefs, ress, dstFileName, srcFileName, compressionLevel);
@@ -1846,7 +1815,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
FIO_freeCResources(&ress); FIO_freeCResources(&ress);
return 1; return 1;
} }
ress.dstFile = FIO_openDstFile(fCtx, prefs, NULL, outFileName, DEFAULT_FILE_PERMISSIONS); ress.dstFile = FIO_openDstFile(fCtx, prefs, NULL, outFileName);
if (ress.dstFile == NULL) { /* could not open outFileName */ if (ress.dstFile == NULL) { /* could not open outFileName */
error = 1; error = 1;
} else { } else {
@@ -2165,7 +2134,7 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput,
/* Write block */ /* Write block */
storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, prefs, storedSkips); storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, prefs, storedSkips);
frameSize += outBuff.pos; frameSize += outBuff.pos;
if (!fCtx->hasStdoutOutput || g_display_prefs.progressSetting == FIO_ps_always) { if (!fCtx->hasStdoutOutput) {
if (fCtx->nbFilesTotal > 1) { if (fCtx->nbFilesTotal > 1) {
size_t srcFileNameSize = strlen(srcFileName); size_t srcFileNameSize = strlen(srcFileName);
if (srcFileNameSize > 18) { if (srcFileNameSize > 18) {
@@ -2536,19 +2505,13 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
{ {
int result; int result;
stat_t statbuf; stat_t statbuf;
int transfer_permissions = 0;
int releaseDstFile = 0; int releaseDstFile = 0;
if ((ress.dstFile == NULL) && (prefs->testMode==0)) { if ((ress.dstFile == NULL) && (prefs->testMode==0)) {
int dstFilePermissions = DEFAULT_FILE_PERMISSIONS;
if ( strcmp(srcFileName, stdinmark) /* special case : don't transfer permissions from stdin */
&& UTIL_stat(srcFileName, &statbuf)
&& UTIL_isRegularFileStat(&statbuf) ) {
dstFilePermissions = statbuf.st_mode;
}
releaseDstFile = 1; releaseDstFile = 1;
ress.dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName, dstFilePermissions); ress.dstFile = FIO_openDstFile(fCtx, prefs, srcFileName, dstFileName);
if (ress.dstFile==NULL) return 1; if (ress.dstFile==NULL) return 1;
/* Must only be added after FIO_openDstFile() succeeds. /* Must only be added after FIO_openDstFile() succeeds.
@@ -2556,6 +2519,11 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
* and the user presses Ctrl-C when asked if they wish to overwrite. * and the user presses Ctrl-C when asked if they wish to overwrite.
*/ */
addHandler(dstFileName); addHandler(dstFileName);
if ( strcmp(srcFileName, stdinmark) /* special case : don't transfer permissions from stdin */
&& UTIL_stat(srcFileName, &statbuf)
&& UTIL_isRegularFileStat(&statbuf) )
transfer_permissions = 1;
} }
result = FIO_decompressFrames(fCtx, ress, srcFile, prefs, dstFileName, srcFileName); result = FIO_decompressFrames(fCtx, ress, srcFile, prefs, dstFileName, srcFileName);
@@ -2573,6 +2541,8 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx,
&& strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */ && strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */
) { ) {
FIO_removeFile(dstFileName); /* remove decompression artefact; note: don't do anything special if remove() fails */ FIO_removeFile(dstFileName); /* remove decompression artefact; note: don't do anything special if remove() fails */
} else if ( transfer_permissions /* file permissions correctly extracted from src */ ) {
UTIL_setFileStat(dstFileName, &statbuf); /* transfer file permissions from src into dst */
} }
} }
@@ -2595,7 +2565,7 @@ static int FIO_decompressSrcFile(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs
return 1; return 1;
} }
srcFile = FIO_openSrcFile(prefs, srcFileName); srcFile = FIO_openSrcFile(srcFileName);
if (srcFile==NULL) return 1; if (srcFile==NULL) return 1;
ress.srcBufferLoaded = 0; ress.srcBufferLoaded = 0;
@@ -2774,7 +2744,7 @@ FIO_decompressMultipleFilenames(FIO_ctx_t* const fCtx,
return 1; return 1;
} }
if (!prefs->testMode) { if (!prefs->testMode) {
ress.dstFile = FIO_openDstFile(fCtx, prefs, NULL, outFileName, DEFAULT_FILE_PERMISSIONS); ress.dstFile = FIO_openDstFile(fCtx, prefs, NULL, outFileName);
if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName); if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName);
} }
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; fCtx->currFileIdx++) { for (; fCtx->currFileIdx < fCtx->nbFilesTotal; fCtx->currFileIdx++) {
@@ -2945,7 +2915,7 @@ static InfoError
getFileInfo_fileConfirmed(fileInfo_t* info, const char* inFileName) getFileInfo_fileConfirmed(fileInfo_t* info, const char* inFileName)
{ {
InfoError status; InfoError status;
FILE* const srcFile = FIO_openSrcFile(NULL, inFileName); FILE* const srcFile = FIO_openSrcFile(inFileName);
ERROR_IF(srcFile == NULL, info_file_error, "Error: could not open source file %s", inFileName); ERROR_IF(srcFile == NULL, info_file_error, "Error: could not open source file %s", inFileName);
info->compressedSize = UTIL_getFileSize(inFileName); info->compressedSize = UTIL_getFileSize(inFileName);
+1 -5
View File
@@ -68,8 +68,6 @@ void FIO_freeContext(FIO_ctx_t* const fCtx);
typedef struct FIO_display_prefs_s FIO_display_prefs_t; typedef struct FIO_display_prefs_s FIO_display_prefs_t;
typedef enum { FIO_ps_auto, FIO_ps_never, FIO_ps_always } FIO_progressSetting_e;
/*-************************************* /*-*************************************
* Parameters * Parameters
***************************************/ ***************************************/
@@ -79,7 +77,6 @@ void FIO_overwriteMode(FIO_prefs_t* const prefs);
void FIO_setAdaptiveMode(FIO_prefs_t* const prefs, unsigned adapt); void FIO_setAdaptiveMode(FIO_prefs_t* const prefs, unsigned adapt);
void FIO_setAdaptMin(FIO_prefs_t* const prefs, int minCLevel); void FIO_setAdaptMin(FIO_prefs_t* const prefs, int minCLevel);
void FIO_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel); void FIO_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel);
void FIO_setUseRowMatchFinder(FIO_prefs_t* const prefs, int useRowMatchFinder);
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize); void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize);
void FIO_setChecksumFlag(FIO_prefs_t* const prefs, int checksumFlag); void FIO_setChecksumFlag(FIO_prefs_t* const prefs, int checksumFlag);
void FIO_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag); void FIO_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag);
@@ -102,10 +99,9 @@ void FIO_setLiteralCompressionMode(
FIO_prefs_t* const prefs, FIO_prefs_t* const prefs,
ZSTD_literalCompressionMode_e mode); ZSTD_literalCompressionMode_e mode);
void FIO_setProgressSetting(FIO_progressSetting_e progressSetting); void FIO_setNoProgress(unsigned noProgress);
void FIO_setNotificationLevel(int level); void FIO_setNotificationLevel(int level);
void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles); void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles);
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices);
void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value); void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value);
void FIO_setContentSize(FIO_prefs_t* const prefs, int value); void FIO_setContentSize(FIO_prefs_t* const prefs, int value);
-1
View File
@@ -22,7 +22,6 @@ extern "C" {
****************************************/ ****************************************/
#if defined(_MSC_VER) #if defined(_MSC_VER)
# define _CRT_SECURE_NO_WARNINGS /* Disable Visual Studio warning messages for fopen, strncpy, strerror */ # define _CRT_SECURE_NO_WARNINGS /* Disable Visual Studio warning messages for fopen, strncpy, strerror */
# define _CRT_NONSTDC_NO_WARNINGS /* Disable C4996 complaining about posix function names */
# if (_MSC_VER <= 1800) /* 1800 == Visual Studio 2013 */ # if (_MSC_VER <= 1800) /* 1800 == Visual Studio 2013 */
# define _CRT_SECURE_NO_DEPRECATE /* VS2005 - must be declared before <io.h> and <windows.h> */ # define _CRT_SECURE_NO_DEPRECATE /* VS2005 - must be declared before <io.h> and <windows.h> */
# define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */ # define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */
+13 -13
View File
@@ -159,6 +159,15 @@ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions)
return chmod(filename, 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 UTIL_setFileStat(const char *filename, const stat_t *statbuf)
{ {
int res = 0; int res = 0;
@@ -260,17 +269,6 @@ int UTIL_isFIFOStat(const stat_t* statbuf)
return 0; return 0;
} }
/* UTIL_isBlockDevStat : distinguish named pipes */
int UTIL_isBlockDevStat(const stat_t* statbuf)
{
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */
#if PLATFORM_POSIX_VERSION >= 200112L
if (S_ISBLK(statbuf->st_mode)) return 1;
#endif
(void)statbuf;
return 0;
}
int UTIL_isLink(const char* infilename) int UTIL_isLink(const char* infilename)
{ {
/* macro guards, as defined in : https://linux.die.net/man/2/lstat */ /* macro guards, as defined in : https://linux.die.net/man/2/lstat */
@@ -323,7 +321,9 @@ U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles)
static size_t readLineFromFile(char* buf, size_t len, FILE* file) static size_t readLineFromFile(char* buf, size_t len, FILE* file)
{ {
assert(!feof(file)); assert(!feof(file));
if ( fgets(buf, (int) len, file) == NULL ) return 0; /* Work around Cygwin problem when len == 1 it returns NULL. */
if (len <= 1) return 0;
CONTROL( fgets(buf, (int) len, file) );
{ size_t linelen = strlen(buf); { size_t linelen = strlen(buf);
if (strlen(buf)==0) return 0; if (strlen(buf)==0) return 0;
if (buf[linelen-1] == '\n') linelen--; if (buf[linelen-1] == '\n') linelen--;
@@ -983,7 +983,7 @@ void UTIL_mirrorSourceFilesDirectories(const char** inFileNames, unsigned int nb
} }
FileNamesTable* FileNamesTable*
UTIL_createExpandedFNT(const char* const* inputNames, size_t nbIfns, int followLinks) UTIL_createExpandedFNT(const char** inputNames, size_t nbIfns, int followLinks)
{ {
unsigned nbFiles; unsigned nbFiles;
char* buf = (char*)malloc(LIST_SIZE_INCREASE); char* buf = (char*)malloc(LIST_SIZE_INCREASE);
+7 -3
View File
@@ -22,7 +22,7 @@ extern "C" {
#include "platform.h" /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */ #include "platform.h" /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */
#include <stddef.h> /* size_t, ptrdiff_t */ #include <stddef.h> /* size_t, ptrdiff_t */
#include <sys/types.h> /* stat, utime */ #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 */ #include "../lib/common/mem.h" /* U64 */
@@ -143,7 +143,6 @@ int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
int UTIL_isRegularFileStat(const stat_t* statbuf); int UTIL_isRegularFileStat(const stat_t* statbuf);
int UTIL_isDirectoryStat(const stat_t* statbuf); int UTIL_isDirectoryStat(const stat_t* statbuf);
int UTIL_isFIFOStat(const stat_t* statbuf); int UTIL_isFIFOStat(const stat_t* statbuf);
int UTIL_isBlockDevStat(const stat_t* statbuf);
U64 UTIL_getFileSizeStat(const stat_t* statbuf); U64 UTIL_getFileSizeStat(const stat_t* statbuf);
/** /**
@@ -153,6 +152,11 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf);
*/ */
int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions); int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions);
/**
* 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 * 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 * functions will do a stat() call internally and then use that result to
@@ -273,7 +277,7 @@ void UTIL_refFilename(FileNamesTable* fnt, const char* filename);
* or NULL in case of error * or NULL in case of error
*/ */
FileNamesTable* FileNamesTable*
UTIL_createExpandedFNT(const char* const* filenames, size_t nbFilenames, int followLinks); UTIL_createExpandedFNT(const char** filenames, size_t nbFilenames, int followLinks);
/*-**************************************** /*-****************************************
+7 -7
View File
@@ -1,5 +1,5 @@
. .
.TH "ZSTD" "1" "May 2021" "zstd 1.5.0" "User Commands" .TH "ZSTD" "1" "December 2020" "zstd 1.4.8" "User Commands"
. .
.SH "NAME" .SH "NAME"
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files \fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
@@ -105,7 +105,7 @@ Display information related to a zstd compressed file, such as size, ratio, and
\fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\. \fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\. \fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to ZSTDMT_NBWORKERS_MAX==200\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-\-single\-thread\fR: Does not spawn a thread for compression, use a single thread for both I/O and compression\. In this mode, compression is serialized with I/O, which is slightly slower\. (This is different from \fB\-T1\fR, which spawns 1 compression thread in parallel of I/O)\. This mode is the only one available when multithread support is disabled\. Single\-thread mode features lower memory usage\. Final compressed result is slightly different from \fB\-T1\fR\. \fB\-\-single\-thread\fR: Does not spawn a thread for compression, use a single thread for both I/O and compression\. In this mode, compression is serialized with I/O, which is slightly slower\. (This is different from \fB\-T1\fR, which spawns 1 compression thread in parallel of I/O)\. This mode is the only one available when multithread support is disabled\. Single\-thread mode features lower memory usage\. Final compressed result is slightly different from \fB\-T1\fR\.
@@ -156,7 +156,7 @@ This is also used during compression when using with \-\-patch\-from=\. In this
\fB\-o FILE\fR: save result into \fBFILE\fR \fB\-o FILE\fR: save result into \fBFILE\fR
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. \fB\-f\fR, \fB\-\-force\fR: overwrite output without prompting, and (de)compress symbolic links
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console \fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console
@@ -218,7 +218,7 @@ Using environment variables to set parameters has security implications\. Theref
\fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\. \fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\.
. .
.P .P
\fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of (\fB1\fR), and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this to have any effect\. \fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \'ZSTD_NBTHREADS\fBhas a default value of (\fR1\fB), and is capped at ZSTDMT_NBWORKERS_MAX==200\.\fRzstd` must be compiled with multithread support for this to have any effect\.
. .
.P .P
They can both be overridden by corresponding command line arguments: \fB\-#\fR for compression level and \fB\-T#\fR for number of compression threads\. They can both be overridden by corresponding command line arguments: \fB\-#\fR for compression level and \fB\-T#\fR for number of compression threads\.
@@ -343,9 +343,6 @@ set process priority to real\-time
. .
.SH "ADVANCED COMPRESSION OPTIONS" .SH "ADVANCED COMPRESSION OPTIONS"
. .
.SS "\-B#:"
Select the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to (slightly) different compressed frames\.
.
.SS "\-\-zstd[=options]:" .SS "\-\-zstd[=options]:"
\fBzstd\fR provides 22 predefined compression levels\. The selected or default predefined compression level can be changed with advanced compression options\. The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR: \fBzstd\fR provides 22 predefined compression levels\. The selected or default predefined compression level can be changed with advanced compression options\. The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR:
. .
@@ -484,6 +481,9 @@ The following parameters sets advanced compression options to something similar
.P .P
\fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 \fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
. .
.SS "\-B#:"
Select the size of each compression job\. This parameter is available only when multi\-threading is enabled\. Default value is \fB4 * windowSize\fR, which means it varies depending on compression level\. \fB\-B#\fR makes it possible to select a custom value\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 1 MB, or \fBoverlapSize\fR, whichever is largest\.
.
.SH "BUGS" .SH "BUGS"
Report bugs at: https://github\.com/facebook/zstd/issues Report bugs at: https://github\.com/facebook/zstd/issues
. .
+12 -16
View File
@@ -115,8 +115,7 @@ the last one takes effect.
* `-T#`, `--threads=#`: * `-T#`, `--threads=#`:
Compress using `#` working threads (default: 1). Compress using `#` working threads (default: 1).
If `#` is 0, attempt to detect and use the number of physical CPU cores. If `#` is 0, attempt to detect and use the number of physical CPU cores.
In all cases, the nb of threads is capped to `ZSTDMT_NBWORKERS_MAX`, In all cases, the nb of threads is capped to ZSTDMT_NBWORKERS_MAX==200.
which is either 64 in 32-bit mode, or 256 for 64-bit environments.
This modifier does nothing if `zstd` is compiled without multithread support. This modifier does nothing if `zstd` is compiled without multithread support.
* `--single-thread`: * `--single-thread`:
Does not spawn a thread for compression, use a single thread for both I/O and compression. Does not spawn a thread for compression, use a single thread for both I/O and compression.
@@ -203,7 +202,7 @@ the last one takes effect.
save result into `FILE` save result into `FILE`
* `-f`, `--force`: * `-f`, `--force`:
disable input and output checks. Allows overwriting existing files, input disable input and output checks. Allows overwriting existing files, input
from console, output to stdout, operating on links, block devices, etc. from console, output to stdout, operating on links, etc.
* `-c`, `--stdout`: * `-c`, `--stdout`:
force write to standard output, even if it is the console force write to standard output, even if it is the console
* `--[no-]sparse`: * `--[no-]sparse`:
@@ -216,7 +215,7 @@ the last one takes effect.
This setting overrides default and can force sparse mode over stdout. This setting overrides default and can force sparse mode over stdout.
* `--rm`: * `--rm`:
remove source file(s) after successful compression or decompression. If used in combination with remove source file(s) after successful compression or decompression. If used in combination with
-o, will trigger a confirmation prompt (which can be silenced with -f), as this is a destructive operation. -o, will trigger a confirmation prompt (which can be silenced with -f), as this is a destructive operation.
* `-k`, `--keep`: * `-k`, `--keep`:
keep source file(s) after successful compression or decompression. keep source file(s) after successful compression or decompression.
This is the default behavior. This is the default behavior.
@@ -282,11 +281,11 @@ If the value of `ZSTD_CLEVEL` is not a valid integer, it will be ignored with a
`ZSTD_NBTHREADS` can be used to set the number of threads `zstd` will attempt to use during compression. `ZSTD_NBTHREADS` can be used to set the number of threads `zstd` will attempt to use during compression.
If the value of `ZSTD_NBTHREADS` is not a valid unsigned integer, it will be ignored with a warning message. If the value of `ZSTD_NBTHREADS` is not a valid unsigned integer, it will be ignored with a warning message.
`ZSTD_NBTHREADS` has a default value of (`1`), and is capped at ZSTDMT_NBWORKERS_MAX==200. `zstd` must be 'ZSTD_NBTHREADS` has a default value of (`1`), and is capped at ZSTDMT_NBWORKERS_MAX==200. `zstd` must be
compiled with multithread support for this to have any effect. compiled with multithread support for this to have any effect.
They can both be overridden by corresponding command line arguments: They can both be overridden by corresponding command line arguments:
`-#` for compression level and `-T#` for number of compression threads. `-#` for compression level and `-T#` for number of compression threads.
DICTIONARY BUILDER DICTIONARY BUILDER
@@ -424,16 +423,6 @@ BENCHMARK
ADVANCED COMPRESSION OPTIONS ADVANCED COMPRESSION OPTIONS
---------------------------- ----------------------------
### -B#:
Select the size of each compression job.
This parameter is only available when multi-threading is enabled.
Each compression job is run in parallel, so this value indirectly impacts the nb of active threads.
Default job size varies depending on compression level (generally `4 * windowSize`).
`-B#` makes it possible to manually select a custom size.
Note that job size must respect a minimum value which is enforced transparently.
This minimum is either 512 KB, or `overlapSize`, whichever is largest.
Different job sizes will lead to (slightly) different compressed frames.
### --zstd[=options]: ### --zstd[=options]:
`zstd` provides 22 predefined compression levels. `zstd` provides 22 predefined compression levels.
The selected or default predefined compression level can be changed with The selected or default predefined compression level can be changed with
@@ -577,6 +566,13 @@ similar to predefined level 19 for files bigger than 256 KB:
`--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 `--zstd`=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
### -B#:
Select the size of each compression job.
This parameter is available only when multi-threading is enabled.
Default value is `4 * windowSize`, which means it varies depending on compression level.
`-B#` makes it possible to select a custom value.
Note that job size must respect a minimum value which is enforced transparently.
This minimum is either 1 MB, or `overlapSize`, whichever is largest.
BUGS BUGS
---- ----
+6 -17
View File
@@ -148,8 +148,7 @@ static void usage(FILE* f, const char* programName)
DISPLAY_F(f, " -D DICT: use DICT as Dictionary for compression or decompression \n"); 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, " -o file: result stored into `file` (only 1 output file) \n");
DISPLAY_F(f, " -f : disable input and output checks. Allows overwriting existing files,\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,\n"); DISPLAY_F(f, " input from console, output to stdout, operating on links, etc.\n");
DISPLAY_F(f, " block devices, etc.\n");
DISPLAY_F(f, "--rm : remove source file(s) after successful de/compression \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, " -k : preserve source file(s) (default) \n");
DISPLAY_F(f, " -h/-H : display help/long help and exit \n"); DISPLAY_F(f, " -h/-H : display help/long help and exit \n");
@@ -167,8 +166,7 @@ static void usage_advanced(const char* programName)
DISPLAYOUT( " -v : verbose mode; specify multiple times to increase verbosity \n"); DISPLAYOUT( " -v : verbose mode; specify multiple times to increase verbosity \n");
DISPLAYOUT( " -q : suppress warnings; specify twice to suppress errors too \n"); DISPLAYOUT( " -q : suppress warnings; specify twice to suppress errors too \n");
DISPLAYOUT( "--[no-]progress : forcibly display, or never display the progress counter.\n"); DISPLAYOUT( "--no-progress : do not display the progress counter \n");
DISPLAYOUT( " note: any (de)compressed output to terminal will mix with progress counter text. \n");
#ifdef UTIL_HAS_CREATEFILELIST #ifdef UTIL_HAS_CREATEFILELIST
DISPLAYOUT( " -r : operate recursively on directories \n"); DISPLAYOUT( " -r : operate recursively on directories \n");
@@ -207,7 +205,6 @@ static void usage_advanced(const char* programName)
DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog); DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog);
DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1); DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1);
DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n"); DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n");
DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n");
# ifdef ZSTD_MULTITHREAD # ifdef ZSTD_MULTITHREAD
DISPLAYOUT( " -T# : spawns # compression threads (default: 1, 0==# cores) \n"); DISPLAYOUT( " -T# : spawns # compression threads (default: 1, 0==# cores) \n");
DISPLAYOUT( " -B# : select size of each job (default: 0==automatic) \n"); DISPLAYOUT( " -B# : select size of each job (default: 0==automatic) \n");
@@ -726,7 +723,6 @@ int main(int const argCount, const char* argv[])
{ {
int argNb, int argNb,
followLinks = 0, followLinks = 0,
allowBlockDevices = 0,
forceStdin = 0, forceStdin = 0,
forceStdout = 0, forceStdout = 0,
hasStdout = 0, hasStdout = 0,
@@ -734,7 +730,6 @@ int main(int const argCount, const char* argv[])
main_pause = 0, main_pause = 0,
nbWorkers = 0, nbWorkers = 0,
adapt = 0, adapt = 0,
useRowMatchFinder = 0,
adaptMin = MINCLEVEL, adaptMin = MINCLEVEL,
adaptMax = MAXCLEVEL, adaptMax = MAXCLEVEL,
rsyncable = 0, rsyncable = 0,
@@ -841,7 +836,7 @@ int main(int const argCount, const char* argv[])
if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; } if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; }
if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; } if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; }
if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; } if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; }
if (!strcmp(argument, "--force")) { FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; allowBlockDevices=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, "--version")) { printVersion(); CLEAN_RETURN(0); }
if (!strcmp(argument, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); } if (!strcmp(argument, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); }
if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; } if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; }
@@ -862,8 +857,6 @@ int main(int const argCount, const char* argv[])
if (!strcmp(argument, "--content-size")) { contentSize = 1; continue; } if (!strcmp(argument, "--content-size")) { contentSize = 1; continue; }
if (!strcmp(argument, "--no-content-size")) { contentSize = 0; continue; } if (!strcmp(argument, "--no-content-size")) { contentSize = 0; continue; }
if (!strcmp(argument, "--adapt")) { adapt = 1; continue; } if (!strcmp(argument, "--adapt")) { adapt = 1; continue; }
if (!strcmp(argument, "--no-row-match-finder")) { useRowMatchFinder = 1; continue; }
if (!strcmp(argument, "--row-match-finder")) { useRowMatchFinder = 2; continue; }
if (longCommandWArg(&argument, "--adapt=")) { adapt = 1; if (!parseAdaptParameters(argument, &adaptMin, &adaptMax)) { badusage(programName); CLEAN_RETURN(1); } continue; } if (longCommandWArg(&argument, "--adapt=")) { adapt = 1; if (!parseAdaptParameters(argument, &adaptMin, &adaptMax)) { badusage(programName); CLEAN_RETURN(1); } continue; }
if (!strcmp(argument, "--single-thread")) { nbWorkers = 0; singleThread = 1; continue; } if (!strcmp(argument, "--single-thread")) { nbWorkers = 0; singleThread = 1; continue; }
if (!strcmp(argument, "--format=zstd")) { suffix = ZSTD_EXTENSION; FIO_setCompressionType(prefs, FIO_zstdCompression); continue; } if (!strcmp(argument, "--format=zstd")) { suffix = ZSTD_EXTENSION; FIO_setCompressionType(prefs, FIO_zstdCompression); continue; }
@@ -880,8 +873,7 @@ int main(int const argCount, const char* argv[])
if (!strcmp(argument, "--rsyncable")) { rsyncable = 1; continue; } if (!strcmp(argument, "--rsyncable")) { rsyncable = 1; continue; }
if (!strcmp(argument, "--compress-literals")) { literalCompressionMode = ZSTD_lcm_huffman; continue; } if (!strcmp(argument, "--compress-literals")) { literalCompressionMode = ZSTD_lcm_huffman; continue; }
if (!strcmp(argument, "--no-compress-literals")) { literalCompressionMode = ZSTD_lcm_uncompressed; continue; } if (!strcmp(argument, "--no-compress-literals")) { literalCompressionMode = ZSTD_lcm_uncompressed; continue; }
if (!strcmp(argument, "--no-progress")) { FIO_setProgressSetting(FIO_ps_never); continue; } if (!strcmp(argument, "--no-progress")) { FIO_setNoProgress(1); continue; }
if (!strcmp(argument, "--progress")) { FIO_setProgressSetting(FIO_ps_always); continue; }
if (!strcmp(argument, "--exclude-compressed")) { FIO_setExcludeCompressedFile(prefs, 1); continue; } if (!strcmp(argument, "--exclude-compressed")) { FIO_setExcludeCompressedFile(prefs, 1); continue; }
/* long commands with arguments */ /* long commands with arguments */
@@ -1028,7 +1020,7 @@ int main(int const argCount, const char* argv[])
case 'D': argument++; NEXT_FIELD(dictFileName); break; case 'D': argument++; NEXT_FIELD(dictFileName); break;
/* Overwrite */ /* Overwrite */
case 'f': FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; allowBlockDevices=1; argument++; break; case 'f': FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; argument++; break;
/* Verbose mode */ /* Verbose mode */
case 'v': g_displayLevel++; argument++; break; case 'v': g_displayLevel++; argument++; break;
@@ -1204,7 +1196,6 @@ int main(int const argCount, const char* argv[])
benchParams.ldmFlag = ldmFlag; benchParams.ldmFlag = ldmFlag;
benchParams.ldmMinMatch = (int)g_ldmMinMatch; benchParams.ldmMinMatch = (int)g_ldmMinMatch;
benchParams.ldmHashLog = (int)g_ldmHashLog; benchParams.ldmHashLog = (int)g_ldmHashLog;
benchParams.useRowMatchFinder = useRowMatchFinder;
if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) { if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) {
benchParams.ldmBucketSizeLog = (int)g_ldmBucketSizeLog; benchParams.ldmBucketSizeLog = (int)g_ldmBucketSizeLog;
} }
@@ -1335,7 +1326,6 @@ int main(int const argCount, const char* argv[])
FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize); FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize);
FIO_determineHasStdinInput(fCtx, filenames); FIO_determineHasStdinInput(fCtx, filenames);
FIO_setNotificationLevel(g_displayLevel); FIO_setNotificationLevel(g_displayLevel);
FIO_setAllowBlockDevices(prefs, allowBlockDevices);
FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL); FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL);
if (memLimit == 0) { if (memLimit == 0) {
if (compressionParams.windowLog == 0) { if (compressionParams.windowLog == 0) {
@@ -1358,7 +1348,6 @@ int main(int const argCount, const char* argv[])
if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) FIO_setLdmBucketSizeLog(prefs, (int)g_ldmBucketSizeLog); if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) FIO_setLdmBucketSizeLog(prefs, (int)g_ldmBucketSizeLog);
if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) FIO_setLdmHashRateLog(prefs, (int)g_ldmHashRateLog); if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) FIO_setLdmHashRateLog(prefs, (int)g_ldmHashRateLog);
FIO_setAdaptiveMode(prefs, (unsigned)adapt); FIO_setAdaptiveMode(prefs, (unsigned)adapt);
FIO_setUseRowMatchFinder(prefs, useRowMatchFinder);
FIO_setAdaptMin(prefs, adaptMin); FIO_setAdaptMin(prefs, adaptMin);
FIO_setAdaptMax(prefs, adaptMax); FIO_setAdaptMax(prefs, adaptMax);
FIO_setRsyncable(prefs, rsyncable); FIO_setRsyncable(prefs, rsyncable);
@@ -1398,7 +1387,7 @@ int main(int const argCount, const char* argv[])
else else
operationResult = FIO_compressMultipleFilenames(fCtx, prefs, filenames->fileNames, outMirroredDirName, outDirName, outFileName, suffix, dictFileName, cLevel, compressionParams); operationResult = FIO_compressMultipleFilenames(fCtx, prefs, filenames->fileNames, outMirroredDirName, outDirName, outFileName, suffix, dictFileName, cLevel, compressionParams);
#else #else
(void)contentSize; (void)suffix; (void)adapt; (void)rsyncable; (void)ultra; (void)cLevel; (void)ldmFlag; (void)literalCompressionMode; (void)targetCBlockSize; (void)streamSrcSize; (void)srcSizeHint; (void)ZSTD_strategyMap; (void)useRowMatchFinder; /* not used when ZSTD_NOCOMPRESS set */ (void)contentSize; (void)suffix; (void)adapt; (void)rsyncable; (void)ultra; (void)cLevel; (void)ldmFlag; (void)literalCompressionMode; (void)targetCBlockSize; (void)streamSrcSize; (void)srcSizeHint; (void)ZSTD_strategyMap; /* not used when ZSTD_NOCOMPRESS set */
DISPLAY("Compression not supported \n"); DISPLAY("Compression not supported \n");
#endif #endif
} else { /* decompression or test */ } else { /* decompression or test */
+1 -1
View File
@@ -1,5 +1,5 @@
. .
.TH "ZSTDGREP" "1" "May 2021" "zstd 1.5.0" "User Commands" .TH "ZSTDGREP" "1" "December 2020" "zstd 1.4.8" "User Commands"
. .
.SH "NAME" .SH "NAME"
\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files \fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files
+1 -1
View File
@@ -1,5 +1,5 @@
. .
.TH "ZSTDLESS" "1" "May 2021" "zstd 1.5.0" "User Commands" .TH "ZSTDLESS" "1" "December 2020" "zstd 1.4.8" "User Commands"
. .
.SH "NAME" .SH "NAME"
\fBzstdless\fR \- view zstandard\-compressed files \fBzstdless\fR \- view zstandard\-compressed files
+23 -8
View File
@@ -24,12 +24,11 @@ PRGDIR = ../programs
PYTHON ?= python3 PYTHON ?= python3
TESTARTEFACT := versionsTest TESTARTEFACT := versionsTest
DEBUGLEVEL ?= 2 DEBUGLEVEL ?= 1
export DEBUGLEVEL # transmit value to sub-makefiles export DEBUGLEVEL # transmit value to sub-makefiles
DEBUGFLAGS = -g -DDEBUGLEVEL=$(DEBUGLEVEL) DEBUGFLAGS = -g -DDEBUGLEVEL=$(DEBUGLEVEL)
CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
-I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR)
-DZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY=1
ifeq ($(OS),Windows_NT) # MinGW assumed ifeq ($(OS),Windows_NT) # MinGW assumed
CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting
endif endif
@@ -38,7 +37,7 @@ CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
-Wstrict-prototypes -Wundef \ -Wstrict-prototypes -Wundef \
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
-Wredundant-decls -Wmissing-prototypes -Wno-deprecated-declarations -Wredundant-decls -Wmissing-prototypes
CFLAGS += $(DEBUGFLAGS) CFLAGS += $(DEBUGFLAGS)
CPPFLAGS += $(MOREFLAGS) CPPFLAGS += $(MOREFLAGS)
@@ -47,6 +46,7 @@ ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c
ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c
ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c
ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
ZBUFF_FILES := $(ZSTDDIR)/deprecated/*.c
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
ZSTD_F1 := $(wildcard $(ZSTD_FILES)) ZSTD_F1 := $(wildcard $(ZSTD_FILES))
@@ -131,7 +131,7 @@ zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
fullbench32: CPPFLAGS += -m32 fullbench32: CPPFLAGS += -m32
fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP) -Wno-deprecated-declarations fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP)
fullbench fullbench32 : LDFLAGS += $(MULTITHREAD_LD) fullbench fullbench32 : LDFLAGS += $(MULTITHREAD_LD)
fullbench fullbench32 : DEBUGFLAGS = -DNDEBUG # turn off assert() for speed measurements fullbench fullbench32 : DEBUGFLAGS = -DNDEBUG # turn off assert() for speed measurements
fullbench fullbench32 : $(ZSTD_FILES) fullbench fullbench32 : $(ZSTD_FILES)
@@ -147,7 +147,7 @@ fullbench-dll: $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/benchfn.c $(PRGDIR
# $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll # $(CC) $(FLAGS) $(filter %.c,$^) -o $@$(EXT) -DZSTD_DLL_IMPORT=1 $(ZSTDDIR)/dll/libzstd.dll
$(LINK.c) $^ $(LDLIBS) -o $@$(EXT) $(LINK.c) $^ $(LDLIBS) -o $@$(EXT)
fuzzer : CPPFLAGS += $(MULTITHREAD_CPP) -Wno-deprecated-declarations fuzzer : CPPFLAGS += $(MULTITHREAD_CPP)
fuzzer : LDFLAGS += $(MULTITHREAD_LD) fuzzer : LDFLAGS += $(MULTITHREAD_LD)
fuzzer : $(ZSTDMT_OBJECTS) fuzzer : $(ZSTDMT_OBJECTS)
fuzzer fuzzer32 : $(ZDICT_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c fuzzer fuzzer32 : $(ZDICT_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c
@@ -160,6 +160,15 @@ fuzzer32 : $(ZSTD_FILES)
fuzzer-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c fuzzer-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c $(PRGDIR)/datagen.c fuzzer.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT) $(CC) $(CPPFLAGS) $(CFLAGS) $(filter %.c,$^) $(LDFLAGS) -o $@$(EXT)
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
$(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)
ZSTREAM_LOCAL_FILES := $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c seqgen.c zstreamtest.c ZSTREAM_LOCAL_FILES := $(PRGDIR)/datagen.c $(PRGDIR)/util.c $(PRGDIR)/timefn.c seqgen.c zstreamtest.c
ZSTREAM_PROPER_FILES := $(ZDICT_FILES) $(ZSTREAM_LOCAL_FILES) ZSTREAM_PROPER_FILES := $(ZDICT_FILES) $(ZSTREAM_LOCAL_FILES)
ZSTREAMFILES := $(ZSTD_FILES) $(ZSTREAM_PROPER_FILES) ZSTREAMFILES := $(ZSTD_FILES) $(ZSTREAM_PROPER_FILES)
@@ -231,8 +240,8 @@ clean:
$(PRGDIR)/zstd$(EXT) $(PRGDIR)/zstd32$(EXT) \ $(PRGDIR)/zstd$(EXT) $(PRGDIR)/zstd32$(EXT) \
fullbench$(EXT) fullbench32$(EXT) \ fullbench$(EXT) fullbench32$(EXT) \
fullbench-lib$(EXT) fullbench-dll$(EXT) \ fullbench-lib$(EXT) fullbench-dll$(EXT) \
fuzzer$(EXT) fuzzer32$(EXT) \ fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
fuzzer-dll$(EXT) zstreamtest-dll$(EXT) \ fuzzer-dll$(EXT) zstreamtest-dll$(EXT) zbufftest-dll$(EXT) \
zstreamtest$(EXT) zstreamtest32$(EXT) \ zstreamtest$(EXT) zstreamtest32$(EXT) \
datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \ datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \
symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) poolTests$(EXT) \ symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) poolTests$(EXT) \
@@ -336,6 +345,12 @@ test-fuzzer-stackmode: test-fuzzer
test-fuzzer32: fuzzer32 test-fuzzer32: fuzzer32
$(QEMU_SYS) ./fuzzer32 -v $(FUZZERTEST) $(FUZZER_FLAGS) $(QEMU_SYS) ./fuzzer32 -v $(FUZZERTEST) $(FUZZER_FLAGS)
test-zbuff: zbufftest
$(QEMU_SYS) ./zbufftest $(ZSTREAM_TESTTIME)
test-zbuff32: zbufftest32
$(QEMU_SYS) ./zbufftest32 $(ZSTREAM_TESTTIME)
test-zstream: zstreamtest test-zstream: zstreamtest
$(QEMU_SYS) ./zstreamtest -v $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) $(QEMU_SYS) ./zstreamtest -v $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
$(QEMU_SYS) ./zstreamtest --newapi -t1 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) $(QEMU_SYS) ./zstreamtest --newapi -t1 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
+1
View File
@@ -8,6 +8,7 @@ This directory contains the following programs and scripts:
- `paramgrill` : parameter tester for zstd - `paramgrill` : parameter tester for zstd
- `test-zstd-speed.py` : script for testing zstd speed difference between commits - `test-zstd-speed.py` : script for testing zstd speed difference between commits
- `test-zstd-versions.py` : compatibility test between zstd versions stored on Github (v0.1+) - `test-zstd-versions.py` : compatibility test between zstd versions stored on Github (v0.1+)
- `zbufftest` : Test tool to check ZBUFF (a buffered streaming API) integrity
- `zstreamtest` : Fuzzer test tool for zstd streaming API - `zstreamtest` : Fuzzer test tool for zstd streaming API
- `legacy` : Test tool to test decoding of legacy zstd frames - `legacy` : Test tool to test decoding of legacy zstd frames
- `decodecorpus` : Tool to generate valid Zstandard frames, for verifying decoder implementations - `decodecorpus` : Tool to generate valid Zstandard frames, for verifying decoder implementations
-1
View File
@@ -12,7 +12,6 @@
/*_************************************ /*_************************************
* Includes * Includes
**************************************/ **************************************/
#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, we still bench some deprecated functions */
#include "util.h" /* Compiler options, UTIL_GetFileSize */ #include "util.h" /* Compiler options, UTIL_GetFileSize */
#include <stdlib.h> /* malloc */ #include <stdlib.h> /* malloc */
#include <stdio.h> /* fprintf, fopen, ftello64 */ #include <stdio.h> /* fprintf, fopen, ftello64 */
-2
View File
@@ -16,11 +16,9 @@ zstd_frame_info
decompress_dstSize_tooSmall decompress_dstSize_tooSmall
fse_read_ncount fse_read_ncount
sequence_compression_api sequence_compression_api
seekable_roundtrip
fuzz-*.log fuzz-*.log
rt_lib_* rt_lib_*
d_lib_* d_lib_*
crash-*
# misc # misc
trace trace
+2 -10
View File
@@ -25,11 +25,10 @@ CORPORA_URL_PREFIX:=https://github.com/facebook/zstd/releases/download/fuzz-corp
ZSTDDIR = ../../lib ZSTDDIR = ../../lib
PRGDIR = ../../programs PRGDIR = ../../programs
CONTRIBDIR = ../../contrib
FUZZ_CPPFLAGS := -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ FUZZ_CPPFLAGS := -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
-I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(ZSTDDIR)/legacy \ -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(ZSTDDIR)/legacy \
-I$(CONTRIBDIR)/seekable_format -I$(PRGDIR) -DZSTD_MULTITHREAD -DZSTD_LEGACY_SUPPORT=1 $(CPPFLAGS) -I$(PRGDIR) -DZSTD_MULTITHREAD -DZSTD_LEGACY_SUPPORT=1 $(CPPFLAGS)
FUZZ_EXTRA_FLAGS := -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ FUZZ_EXTRA_FLAGS := -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
-Wstrict-prototypes -Wundef \ -Wstrict-prototypes -Wundef \
@@ -47,9 +46,6 @@ FUZZ_ROUND_TRIP_FLAGS := -DFUZZING_ASSERT_VALID_SEQUENCE
FUZZ_HEADERS := fuzz_helpers.h fuzz.h zstd_helpers.h fuzz_data_producer.h FUZZ_HEADERS := fuzz_helpers.h fuzz.h zstd_helpers.h fuzz_data_producer.h
FUZZ_SRC := $(PRGDIR)/util.c ./fuzz_helpers.c ./zstd_helpers.c ./fuzz_data_producer.c FUZZ_SRC := $(PRGDIR)/util.c ./fuzz_helpers.c ./zstd_helpers.c ./fuzz_data_producer.c
SEEKABLE_HEADERS = $(CONTRIBDIR)/seekable_format/zstd_seekable.h
SEEKABLE_OBJS = $(CONTRIBDIR)/seekable_format/zstdseek_compress.c $(CONTRIBDIR)/seekable_format/zstdseek_decompress.c
ZSTDCOMMON_SRC := $(ZSTDDIR)/common/*.c ZSTDCOMMON_SRC := $(ZSTDDIR)/common/*.c
ZSTDCOMP_SRC := $(ZSTDDIR)/compress/*.c ZSTDCOMP_SRC := $(ZSTDDIR)/compress/*.c
ZSTDDECOMP_SRC := $(ZSTDDIR)/decompress/*.c ZSTDDECOMP_SRC := $(ZSTDDIR)/decompress/*.c
@@ -102,8 +98,7 @@ FUZZ_TARGETS := \
dictionary_stream_round_trip \ dictionary_stream_round_trip \
decompress_dstSize_tooSmall \ decompress_dstSize_tooSmall \
fse_read_ncount \ fse_read_ncount \
sequence_compression_api \ sequence_compression_api
seekable_roundtrip
all: libregression.a $(FUZZ_TARGETS) all: libregression.a $(FUZZ_TARGETS)
@@ -197,9 +192,6 @@ fse_read_ncount: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_fse_read_ncount.
sequence_compression_api: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_sequence_compression_api.o sequence_compression_api: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_sequence_compression_api.o
$(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_sequence_compression_api.o $(LIB_FUZZING_ENGINE) -o $@ $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_sequence_compression_api.o $(LIB_FUZZING_ENGINE) -o $@
seekable_roundtrip: $(FUZZ_HEADERS) $(SEEKABLE_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) $(SEEKABLE_OBJS) rt_fuzz_seekable_roundtrip.o
$(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) $(SEEKABLE_OBJS) rt_fuzz_seekable_roundtrip.o $(LIB_FUZZING_ENGINE) -o $@
libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h $(PRGDIR)/util.c d_fuzz_regression_driver.o libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h $(PRGDIR)/util.c d_fuzz_regression_driver.o
$(AR) $(FUZZ_ARFLAGS) $@ d_fuzz_regression_driver.o $(AR) $(FUZZ_ARFLAGS) $@ d_fuzz_regression_driver.o
-1
View File
@@ -62,7 +62,6 @@ TARGET_INFO = {
'decompress_dstSize_tooSmall': TargetInfo(InputType.RAW_DATA), 'decompress_dstSize_tooSmall': TargetInfo(InputType.RAW_DATA),
'fse_read_ncount': TargetInfo(InputType.RAW_DATA), 'fse_read_ncount': TargetInfo(InputType.RAW_DATA),
'sequence_compression_api': TargetInfo(InputType.RAW_DATA), 'sequence_compression_api': TargetInfo(InputType.RAW_DATA),
'seekable_roundtrip': TargetInfo(InputType.RAW_DATA),
} }
TARGETS = list(TARGET_INFO.keys()) TARGETS = list(TARGET_INFO.keys())
ALL_TARGETS = TARGETS + ['all'] ALL_TARGETS = TARGETS + ['all']
-88
View File
@@ -1,88 +0,0 @@
/*
* 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.h"
#include "zstd_seekable.h"
#include "fuzz_helpers.h"
#include "fuzz_data_producer.h"
static ZSTD_seekable *stream = NULL;
static ZSTD_seekable_CStream *zscs = NULL;
static const size_t kSeekableOverheadSize = ZSTD_seekTableFooterSize;
int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
{
/* Give a random portion of src data to the producer, to use for
parameter generation. The rest will be used for (de)compression */
FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
size = FUZZ_dataProducer_reserveDataPrefix(producer);
size_t const compressedBufferSize = ZSTD_compressBound(size) + kSeekableOverheadSize;
uint8_t* compressedBuffer = (uint8_t*)malloc(compressedBufferSize);
uint8_t* decompressedBuffer = (uint8_t*)malloc(size);
int const cLevel = FUZZ_dataProducer_int32Range(producer, ZSTD_minCLevel(), ZSTD_maxCLevel());
unsigned const checksumFlag = FUZZ_dataProducer_int32Range(producer, 0, 1);
size_t const uncompressedSize = FUZZ_dataProducer_uint32Range(producer, 0, size);
size_t const offset = FUZZ_dataProducer_uint32Range(producer, 0, size - uncompressedSize);
size_t seekSize;
if (!zscs) {
zscs = ZSTD_seekable_createCStream();
FUZZ_ASSERT(zscs);
}
if (!stream) {
stream = ZSTD_seekable_create();
FUZZ_ASSERT(stream);
}
{ /* Perform a compression */
size_t const initStatus = ZSTD_seekable_initCStream(zscs, cLevel, checksumFlag, size);
size_t endStatus;
ZSTD_outBuffer out = { .dst=compressedBuffer, .pos=0, .size=compressedBufferSize };
ZSTD_inBuffer in = { .src=src, .pos=0, .size=size };
FUZZ_ASSERT(!ZSTD_isError(initStatus));
do {
size_t cSize = ZSTD_seekable_compressStream(zscs, &out, &in);
FUZZ_ASSERT(!ZSTD_isError(cSize));
} while (in.pos != in.size);
FUZZ_ASSERT(in.pos == in.size);
endStatus = ZSTD_seekable_endStream(zscs, &out);
FUZZ_ASSERT(!ZSTD_isError(endStatus));
seekSize = out.pos;
}
{ /* Decompress at an offset */
size_t const initStatus = ZSTD_seekable_initBuff(stream, compressedBuffer, seekSize);
size_t decompressedBytesTotal = 0;
size_t dSize;
FUZZ_ZASSERT(initStatus);
do {
dSize = ZSTD_seekable_decompress(stream, decompressedBuffer, uncompressedSize, offset);
FUZZ_ASSERT(!ZSTD_isError(dSize));
decompressedBytesTotal += dSize;
} while (decompressedBytesTotal < uncompressedSize && dSize > 0);
FUZZ_ASSERT(decompressedBytesTotal == uncompressedSize);
}
FUZZ_ASSERT_MSG(!FUZZ_memcmp(src+offset, decompressedBuffer, uncompressedSize), "Corruption!");
free(decompressedBuffer);
free(compressedBuffer);
FUZZ_dataProducer_free(producer);
#ifndef STATEFUL_FUZZING
ZSTD_seekable_free(stream); stream = NULL;
ZSTD_seekable_freeCStream(zscs); zscs = NULL;
#endif
return 0;
}
-4
View File
@@ -91,13 +91,9 @@ void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, size_t srcSize, FUZZ_dataProducer
/* Set misc parameters */ /* Set misc parameters */
setRand(cctx, ZSTD_c_nbWorkers, 0, 2, producer); setRand(cctx, ZSTD_c_nbWorkers, 0, 2, producer);
setRand(cctx, ZSTD_c_rsyncable, 0, 1, producer); setRand(cctx, ZSTD_c_rsyncable, 0, 1, producer);
setRand(cctx, ZSTD_c_useRowMatchFinder, 0, 2, producer);
setRand(cctx, ZSTD_c_enableDedicatedDictSearch, 0, 1, producer);
setRand(cctx, ZSTD_c_forceMaxWindow, 0, 1, producer); setRand(cctx, ZSTD_c_forceMaxWindow, 0, 1, producer);
setRand(cctx, ZSTD_c_literalCompressionMode, 0, 2, producer); setRand(cctx, ZSTD_c_literalCompressionMode, 0, 2, producer);
setRand(cctx, ZSTD_c_forceAttachDict, 0, 2, producer); setRand(cctx, ZSTD_c_forceAttachDict, 0, 2, producer);
setRand(cctx, ZSTD_c_splitBlocks, 0, 1, producer);
setRand(cctx, ZSTD_c_deterministicRefPrefix, 0, 1, producer);
if (FUZZ_dataProducer_uint32Range(producer, 0, 1) == 0) { if (FUZZ_dataProducer_uint32Range(producer, 0, 1) == 0) {
setRand(cctx, ZSTD_c_srcSizeHint, ZSTD_SRCSIZEHINT_MIN, 2 * srcSize, producer); setRand(cctx, ZSTD_c_srcSizeHint, ZSTD_SRCSIZEHINT_MIN, 2 * srcSize, producer);
} }
+16 -216
View File
@@ -30,7 +30,6 @@
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressContinue, ZSTD_compressBlock */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressContinue, ZSTD_compressBlock */
#include "debug.h" /* DEBUG_STATIC_ASSERT */ #include "debug.h" /* DEBUG_STATIC_ASSERT */
#include "fse.h" #include "fse.h"
#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, we still test some deprecated functions */
#include "zstd.h" /* ZSTD_VERSION_STRING */ #include "zstd.h" /* ZSTD_VERSION_STRING */
#include "zstd_errors.h" /* ZSTD_getErrorCode */ #include "zstd_errors.h" /* ZSTD_getErrorCode */
#define ZDICT_STATIC_LINKING_ONLY #define ZDICT_STATIC_LINKING_ONLY
@@ -43,7 +42,6 @@
#include "timefn.h" /* SEC_TO_MICRO, UTIL_time_t, UTIL_TIME_INITIALIZER, UTIL_clockSpanMicro, UTIL_getTime */ #include "timefn.h" /* SEC_TO_MICRO, UTIL_time_t, UTIL_TIME_INITIALIZER, UTIL_clockSpanMicro, UTIL_getTime */
/* must be included after util.h, due to ERROR macro redefinition issue on Visual Studio */ /* must be included after util.h, due to ERROR macro redefinition issue on Visual Studio */
#include "zstd_internal.h" /* ZSTD_WORKSPACETOOLARGE_MAXDURATION, ZSTD_WORKSPACETOOLARGE_FACTOR, KB, MB */ #include "zstd_internal.h" /* ZSTD_WORKSPACETOOLARGE_MAXDURATION, ZSTD_WORKSPACETOOLARGE_FACTOR, KB, MB */
#include "threading.h" /* ZSTD_pthread_create, ZSTD_pthread_join */
/*-************************************ /*-************************************
@@ -337,126 +335,6 @@ static void FUZ_decodeSequences(BYTE* dst, ZSTD_Sequence* seqs, size_t seqsSize,
} }
} }
#ifdef ZSTD_MULTITHREAD
typedef struct {
ZSTD_CCtx* cctx;
ZSTD_threadPool* pool;
void* CNBuffer;
size_t CNBuffSize;
void* compressedBuffer;
size_t compressedBufferSize;
void* decodedBuffer;
int err;
} threadPoolTests_compressionJob_payload;
static void* threadPoolTests_compressionJob(void* payload) {
threadPoolTests_compressionJob_payload* args = (threadPoolTests_compressionJob_payload*)payload;
size_t cSize;
if (ZSTD_isError(ZSTD_CCtx_refThreadPool(args->cctx, args->pool))) args->err = 1;
cSize = ZSTD_compress2(args->cctx, args->compressedBuffer, args->compressedBufferSize, args->CNBuffer, args->CNBuffSize);
if (ZSTD_isError(cSize)) args->err = 1;
if (ZSTD_isError(ZSTD_decompress(args->decodedBuffer, args->CNBuffSize, args->compressedBuffer, cSize))) args->err = 1;
return payload;
}
static int threadPoolTests(void) {
int testResult = 0;
size_t err;
size_t const CNBuffSize = 5 MB;
void* const CNBuffer = malloc(CNBuffSize);
size_t const compressedBufferSize = ZSTD_compressBound(CNBuffSize);
void* const compressedBuffer = malloc(compressedBufferSize);
void* const decodedBuffer = malloc(CNBuffSize);
size_t const kPoolNumThreads = 8;
RDG_genBuffer(CNBuffer, CNBuffSize, 0.5, 0.5, 0);
DISPLAYLEVEL(3, "thread pool test : threadPool re-use roundtrips: ");
{
ZSTD_CCtx* cctx = ZSTD_createCCtx();
ZSTD_threadPool* pool = ZSTD_createThreadPool(kPoolNumThreads);
size_t nbThreads = 1;
for (; nbThreads <= kPoolNumThreads; ++nbThreads) {
ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, (int)nbThreads);
err = ZSTD_CCtx_refThreadPool(cctx, pool);
if (ZSTD_isError(err)) {
DISPLAYLEVEL(3, "refThreadPool error!\n");
ZSTD_freeCCtx(cctx);
goto _output_error;
}
err = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize);
if (ZSTD_isError(err)) {
DISPLAYLEVEL(3, "Compression error!\n");
ZSTD_freeCCtx(cctx);
goto _output_error;
}
err = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, err);
if (ZSTD_isError(err)) {
DISPLAYLEVEL(3, "Decompression error!\n");
ZSTD_freeCCtx(cctx);
goto _output_error;
}
}
ZSTD_freeCCtx(cctx);
ZSTD_freeThreadPool(pool);
}
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "thread pool test : threadPool simultaneous usage: ");
{
void* const decodedBuffer2 = malloc(CNBuffSize);
void* const compressedBuffer2 = malloc(compressedBufferSize);
ZSTD_threadPool* pool = ZSTD_createThreadPool(kPoolNumThreads);
ZSTD_CCtx* cctx1 = ZSTD_createCCtx();
ZSTD_CCtx* cctx2 = ZSTD_createCCtx();
ZSTD_pthread_t t1;
ZSTD_pthread_t t2;
threadPoolTests_compressionJob_payload p1 = {cctx1, pool, CNBuffer, CNBuffSize,
compressedBuffer, compressedBufferSize, decodedBuffer, 0 /* err */};
threadPoolTests_compressionJob_payload p2 = {cctx2, pool, CNBuffer, CNBuffSize,
compressedBuffer2, compressedBufferSize, decodedBuffer2, 0 /* err */};
ZSTD_CCtx_setParameter(cctx1, ZSTD_c_nbWorkers, 2);
ZSTD_CCtx_setParameter(cctx2, ZSTD_c_nbWorkers, 2);
ZSTD_CCtx_refThreadPool(cctx1, pool);
ZSTD_CCtx_refThreadPool(cctx2, pool);
ZSTD_pthread_create(&t1, NULL, threadPoolTests_compressionJob, &p1);
ZSTD_pthread_create(&t2, NULL, threadPoolTests_compressionJob, &p2);
ZSTD_pthread_join(t1, NULL);
ZSTD_pthread_join(t2, NULL);
assert(!memcmp(decodedBuffer, decodedBuffer2, CNBuffSize));
free(decodedBuffer2);
free(compressedBuffer2);
ZSTD_freeThreadPool(pool);
ZSTD_freeCCtx(cctx1);
ZSTD_freeCCtx(cctx2);
if (p1.err || p2.err) goto _output_error;
}
DISPLAYLEVEL(3, "OK \n");
_end:
free(CNBuffer);
free(compressedBuffer);
free(decodedBuffer);
return testResult;
_output_error:
testResult = 1;
DISPLAY("Error detected in Unit tests ! \n");
goto _end;
}
#endif /* ZSTD_MULTITHREAD */
/*============================================= /*=============================================
* Unit tests * Unit tests
=============================================*/ =============================================*/
@@ -496,12 +374,6 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "%i (OK) \n", mcl); DISPLAYLEVEL(3, "%i (OK) \n", mcl);
} }
DISPLAYLEVEL(3, "test%3u : default compression level : ", testNb++);
{ int const defaultCLevel = ZSTD_defaultCLevel();
if (defaultCLevel != ZSTD_CLEVEL_DEFAULT) goto _output_error;
DISPLAYLEVEL(3, "%i (OK) \n", defaultCLevel);
}
DISPLAYLEVEL(3, "test%3u : ZSTD_versionNumber : ", testNb++); DISPLAYLEVEL(3, "test%3u : ZSTD_versionNumber : ", testNb++);
{ unsigned const vn = ZSTD_versionNumber(); { unsigned const vn = ZSTD_versionNumber();
DISPLAYLEVEL(3, "%u (OK) \n", vn); DISPLAYLEVEL(3, "%u (OK) \n", vn);
@@ -888,50 +760,6 @@ static int basicUnitTests(U32 const seed, double compressibility)
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : testing dict compression for determinism : ", testNb++);
{
size_t const testSize = 1024;
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
char* dict = (char*)malloc(2 * testSize);
int ldmEnabled, level;
RDG_genBuffer(dict, testSize, 0.5, 0.5, seed);
RDG_genBuffer(CNBuffer, testSize, 0.6, 0.6, seed);
memcpy(dict + testSize, CNBuffer, testSize);
for (level = 1; level <= 5; ++level) {
for (ldmEnabled = 0; ldmEnabled <= 1; ++ldmEnabled) {
size_t cSize0;
XXH64_hash_t compressedChecksum0;
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1));
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, level));
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, ldmEnabled));
CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_deterministicRefPrefix, 1));
CHECK_Z(ZSTD_CCtx_refPrefix(cctx, dict, testSize));
cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, testSize);
CHECK_Z(cSize);
CHECK_Z(ZSTD_decompress_usingDict(dctx, decodedBuffer, testSize, compressedBuffer, cSize, dict, testSize));
cSize0 = cSize;
compressedChecksum0 = XXH64(compressedBuffer, cSize, 0);
CHECK_Z(ZSTD_CCtx_refPrefix(cctx, dict, testSize));
cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, dict + testSize, testSize);
CHECK_Z(cSize);
if (cSize != cSize0) goto _output_error;
if (XXH64(compressedBuffer, cSize, 0) != compressedChecksum0) goto _output_error;
}
}
ZSTD_freeCCtx(cctx);
ZSTD_freeDCtx(dctx);
free(dict);
}
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : LDM + opt parser with small uncompressible block ", testNb++); DISPLAYLEVEL(3, "test%3i : LDM + opt parser with small uncompressible block ", testNb++);
{ ZSTD_CCtx* cctx = ZSTD_createCCtx(); { ZSTD_CCtx* cctx = ZSTD_createCCtx();
ZSTD_DCtx* dctx = ZSTD_createDCtx(); ZSTD_DCtx* dctx = ZSTD_createDCtx();
@@ -1716,15 +1544,6 @@ static int basicUnitTests(U32 const seed, double compressibility)
ZSTD_freeCCtx(cctx); ZSTD_freeCCtx(cctx);
} }
DISPLAYLEVEL(3, "test%3i : compress with block splitting : ", testNb++)
{ ZSTD_CCtx* cctx = ZSTD_createCCtx();
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_splitBlocks, 1) );
cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize);
CHECK(cSize);
ZSTD_freeCCtx(cctx);
}
DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : compress -T2 with/without literals compression : ", testNb++) DISPLAYLEVEL(3, "test%3i : compress -T2 with/without literals compression : ", testNb++)
{ ZSTD_CCtx* cctx = ZSTD_createCCtx(); { ZSTD_CCtx* cctx = ZSTD_createCCtx();
size_t cSize1, cSize2; size_t cSize1, cSize2;
@@ -1755,7 +1574,6 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : setting multithreaded parameters : ", testNb++) DISPLAYLEVEL(3, "test%3i : setting multithreaded parameters : ", testNb++)
{ ZSTD_CCtx_params* params = ZSTD_createCCtxParams(); { ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
int const jobSize = 512 KB;
int value; int value;
/* Check that the overlap log and job size are unset. */ /* Check that the overlap log and job size are unset. */
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) ); CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) );
@@ -1764,18 +1582,19 @@ static int basicUnitTests(U32 const seed, double compressibility)
CHECK_EQ(value, 0); CHECK_EQ(value, 0);
/* Set and check the overlap log and job size. */ /* Set and check the overlap log and job size. */
CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, 5) ); CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, 5) );
CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, jobSize) ); CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, 2 MB) );
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) ); CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) );
CHECK_EQ(value, 5); CHECK_EQ(value, 5);
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) ); CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) );
CHECK_EQ(value, jobSize); CHECK_EQ(value, 2 MB);
/* Set the number of workers and check the overlap log and job size. */ /* Set the number of workers and check the overlap log and job size. */
CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, 2) ); CHECK( ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, 2) );
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) ); CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_overlapLog, &value) );
CHECK_EQ(value, 5); CHECK_EQ(value, 5);
CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) ); CHECK( ZSTD_CCtxParams_getParameter(params, ZSTD_c_jobSize, &value) );
CHECK_EQ(value, jobSize); CHECK_EQ(value, 2 MB);
ZSTD_freeCCtxParams(params); ZSTD_freeCCtxParams(params);
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
@@ -1904,7 +1723,10 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(3, "test%3i : check content size on duplicated context : ", testNb++); DISPLAYLEVEL(3, "test%3i : check content size on duplicated context : ", testNb++);
{ size_t const testSize = CNBuffSize / 3; { size_t const testSize = CNBuffSize / 3;
CHECK( ZSTD_compressBegin(ctxOrig, ZSTD_defaultCLevel()) ); { ZSTD_parameters p = ZSTD_getParams(2, testSize, dictSize);
p.fParams.contentSizeFlag = 1;
CHECK( ZSTD_compressBegin_advanced(ctxOrig, CNBuffer, dictSize, p, testSize-1) );
}
CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) ); CHECK( ZSTD_copyCCtx(ctxDuplicated, ctxOrig, testSize) );
CHECK_VAR(cSize, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize), CHECK_VAR(cSize, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
@@ -1920,14 +1742,13 @@ static int basicUnitTests(U32 const seed, double compressibility)
size_t const contentSize = 9 KB; size_t const contentSize = 9 KB;
const void* const dict = (const char*)CNBuffer; const void* const dict = (const char*)CNBuffer;
const void* const contentStart = (const char*)dict + flatdictSize; const void* const contentStart = (const char*)dict + flatdictSize;
/* These upper bounds are generally within a few bytes of the compressed size */
size_t const target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770, size_t const target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770,
3770, 3770, 3770, 3750, 3750, 3770, 3770, 3770, 3750, 3750,
3742, 3670, 3670, 3660, 3660, 3742, 3670, 3670, 3660, 3660,
3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660,
3660, 3660, 3660 }; 3660, 3660, 3660 };
size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940, size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940,
2950, 2950, 2925, 2900, 2891, 2950, 2950, 2921, 2900, 2891,
2910, 2910, 2910, 2770, 2760, 2910, 2910, 2910, 2770, 2760,
2750, 2750, 2750, 2750, 2750, 2750, 2750, 2750, 2750, 2750,
2750, 2750, 2750 }; 2750, 2750, 2750 };
@@ -1964,22 +1785,6 @@ static int basicUnitTests(U32 const seed, double compressibility)
DISPLAYLEVEL(4, "level %i with dictionary : max expected %u >= reached %u \n", DISPLAYLEVEL(4, "level %i with dictionary : max expected %u >= reached %u \n",
l, (unsigned)target_wdict_cSize[l], (unsigned)wdict_cSize); l, (unsigned)target_wdict_cSize[l], (unsigned)wdict_cSize);
} }
/* Dict compression with DMS */
for ( l=1 ; l <= maxLevel; l++) {
size_t wdict_cSize;
CHECK_Z( ZSTD_CCtx_loadDictionary(ctxOrig, dict, flatdictSize) );
CHECK_Z( ZSTD_CCtx_setParameter(ctxOrig, ZSTD_c_compressionLevel, l) );
CHECK_Z( ZSTD_CCtx_setParameter(ctxOrig, ZSTD_c_enableDedicatedDictSearch, 0) );
CHECK_Z( ZSTD_CCtx_setParameter(ctxOrig, ZSTD_c_forceAttachDict, ZSTD_dictForceAttach) );
wdict_cSize = ZSTD_compress2(ctxOrig, compressedBuffer, compressedBufferSize, contentStart, contentSize);
if (wdict_cSize > target_wdict_cSize[l]) {
DISPLAYLEVEL(1, "error : compression with dictionary and compress2 at level %i worse than expected (%u > %u) \n",
l, (unsigned)wdict_cSize, (unsigned)target_wdict_cSize[l]);
goto _output_error;
}
DISPLAYLEVEL(4, "level %i with dictionary and compress2 : max expected %u >= reached %u \n",
l, (unsigned)target_wdict_cSize[l], (unsigned)wdict_cSize);
}
DISPLAYLEVEL(4, "compression efficiency tests OK \n"); DISPLAYLEVEL(4, "compression efficiency tests OK \n");
} }
@@ -2725,8 +2530,12 @@ static int basicUnitTests(U32 const seed, double compressibility)
int const compressionLevel = -1; int const compressionLevel = -1;
assert(cctx != NULL); assert(cctx != NULL);
{ size_t const cSize_1pass = ZSTD_compress(compressedBuffer, compressedBufferSize, { ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize, 0);
CNBuffer, srcSize, compressionLevel); size_t const cSize_1pass = ZSTD_compress_advanced(cctx,
compressedBuffer, compressedBufferSize,
CNBuffer, srcSize,
NULL, 0,
params);
if (ZSTD_isError(cSize_1pass)) goto _output_error; if (ZSTD_isError(cSize_1pass)) goto _output_error;
CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionLevel) ); CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compressionLevel) );
@@ -3414,16 +3223,7 @@ static int basicUnitTests(U32 const seed, double compressibility)
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : thread pool API tests : \n", testNb++) #endif
{
int const threadPoolTestResult = threadPoolTests();
if (threadPoolTestResult) {
goto _output_error;
}
}
DISPLAYLEVEL(3, "thread pool tests OK \n");
#endif /* ZSTD_MULTITHREAD */
_end: _end:
free(CNBuffer); free(CNBuffer);
+5 -16
View File
@@ -21,7 +21,7 @@ mustBeAbsent() {
$ECHO "$@ correctly not present" # for some reason, this $ECHO must exist, otherwise mustBeAbsent() always fails (??) $ECHO "$@ correctly not present" # for some reason, this $ECHO must exist, otherwise mustBeAbsent() always fails (??)
} }
# default compilation : all features enabled - no zbuff # default compilation : all features enabled
$ECHO "testing default library compilation" $ECHO "testing default library compilation"
CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
@@ -29,10 +29,10 @@ isPresent "zstd_compress.o"
isPresent "zstd_decompress.o" isPresent "zstd_decompress.o"
isPresent "zdict.o" isPresent "zdict.o"
isPresent "zstd_v07.o" isPresent "zstd_v07.o"
mustBeAbsent "zbuff_compress.o" isPresent "zbuff_compress.o"
$RM $DIR/../lib/libzstd.a tmplog $RM $DIR/../lib/libzstd.a tmplog
# compression disabled => also disable zdict # compression disabled => also disable zdict and zbuff
$ECHO "testing with compression disabled" $ECHO "testing with compression disabled"
ZSTD_LIB_COMPRESSION=0 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID ZSTD_LIB_COMPRESSION=0 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
@@ -43,7 +43,7 @@ isPresent "zstd_v07.o"
mustBeAbsent "zbuff_compress.o" mustBeAbsent "zbuff_compress.o"
$RM $DIR/../lib/libzstd.a tmplog $RM $DIR/../lib/libzstd.a tmplog
# decompression disabled => also disable legacy # decompression disabled => also disable legacy and zbuff
$ECHO "testing with decompression disabled" $ECHO "testing with decompression disabled"
ZSTD_LIB_DECOMPRESSION=0 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID ZSTD_LIB_DECOMPRESSION=0 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
@@ -65,17 +65,6 @@ isPresent "zstd_v07.o"
mustBeAbsent "zbuff_compress.o" mustBeAbsent "zbuff_compress.o"
$RM $DIR/../lib/libzstd.a tmplog $RM $DIR/../lib/libzstd.a tmplog
# deprecated function enabled => zbuff present
$ECHO "testing with deprecated functions enabled"
ZSTD_LIB_DEPRECATED=1 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID
nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog
isPresent "zstd_compress.o"
isPresent "zstd_decompress.o"
isPresent "zdict.o"
isPresent "zstd_v07.o"
isPresent "zbuff_compress.o"
$RM $DIR/../lib/libzstd.a tmplog
# dictionary builder disabled => only remove zdict # dictionary builder disabled => only remove zdict
$ECHO "testing with dictionary builder disabled" $ECHO "testing with dictionary builder disabled"
ZSTD_LIB_DICTBUILDER=0 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID ZSTD_LIB_DICTBUILDER=0 CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID
@@ -84,7 +73,7 @@ isPresent "zstd_compress.o"
isPresent "zstd_decompress.o" isPresent "zstd_decompress.o"
mustBeAbsent "zdict.o" mustBeAbsent "zdict.o"
isPresent "zstd_v07.o" isPresent "zstd_v07.o"
mustBeAbsent "zbuff_compress.o" isPresent "zbuff_compress.o"
$RM $DIR/../lib/libzstd.a tmplog $RM $DIR/../lib/libzstd.a tmplog
# both decompression and dictionary builder disabled => only compression remains # both decompression and dictionary builder disabled => only compression remains
+30 -161
View File
@@ -124,23 +124,6 @@ case "$UNAME" in
Darwin | FreeBSD | OpenBSD | NetBSD) MTIME="stat -f %m" ;; Darwin | FreeBSD | OpenBSD | NetBSD) MTIME="stat -f %m" ;;
esac esac
GET_PERMS="stat -c %a"
case "$UNAME" in
Darwin | FreeBSD | OpenBSD | NetBSD) GET_PERMS="stat -f %Lp" ;;
esac
assertFilePermissions() {
STAT1=$($GET_PERMS "$1")
STAT2=$2
[ "$STAT1" = "$STAT2" ] || die "permissions on $1 don't match expected ($STAT1 != $STAT2)"
}
assertSamePermissions() {
STAT1=$($GET_PERMS "$1")
STAT2=$($GET_PERMS "$2")
[ "$STAT1" = "$STAT2" ] || die "permissions on $1 don't match those on $2 ($STAT1 != $STAT2)"
}
DIFF="diff" DIFF="diff"
case "$UNAME" in case "$UNAME" in
SunOS) DIFF="gdiff" ;; SunOS) DIFF="gdiff" ;;
@@ -209,7 +192,7 @@ println "test : compress to stdout"
zstd tmp -c > tmpCompressed zstd tmp -c > tmpCompressed
zstd tmp --stdout > tmpCompressed # long command format zstd tmp --stdout > tmpCompressed # long command format
println "test : compress to named file" println "test : compress to named file"
rm -f tmpCompressed rm tmpCompressed
zstd tmp -o tmpCompressed zstd tmp -o tmpCompressed
test -f tmpCompressed # file must be created test -f tmpCompressed # file must be created
println "test : force write, correct order" println "test : force write, correct order"
@@ -363,7 +346,7 @@ rm -f tmplog
zstd tmp -f -o "$INTOVOID" 2>&1 | grep -v "Refusing to remove non-regular file" zstd tmp -f -o "$INTOVOID" 2>&1 | grep -v "Refusing to remove non-regular file"
println "test : --rm on stdin" println "test : --rm on stdin"
println a | zstd --rm > $INTOVOID # --rm should remain silent println a | zstd --rm > $INTOVOID # --rm should remain silent
rm -f tmp rm tmp
zstd -f tmp && die "tmp not present : should have failed" zstd -f tmp && die "tmp not present : should have failed"
test ! -f tmp.zst # tmp.zst should not be created test ! -f tmp.zst # tmp.zst should not be created
println "test : -d -f do not delete destination when source is not present" println "test : -d -f do not delete destination when source is not present"
@@ -371,7 +354,7 @@ touch tmp # create destination file
zstd -d -f tmp.zst && die "attempt to decompress a non existing file" zstd -d -f tmp.zst && die "attempt to decompress a non existing file"
test -f tmp # destination file should still be present test -f tmp # destination file should still be present
println "test : -f do not delete destination when source is not present" println "test : -f do not delete destination when source is not present"
rm -f tmp # erase source file rm tmp # erase source file
touch tmp.zst # create destination file touch tmp.zst # create destination file
zstd -f tmp && die "attempt to compress a non existing file" zstd -f tmp && die "attempt to compress a non existing file"
test -f tmp.zst # destination file should still be present test -f tmp.zst # destination file should still be present
@@ -385,7 +368,7 @@ println "\n===> decompression only tests "
dd bs=1048576 count=1 if=/dev/zero of=tmp dd bs=1048576 count=1 if=/dev/zero of=tmp
zstd -d -o tmp1 "$TESTDIR/golden-decompression/rle-first-block.zst" zstd -d -o tmp1 "$TESTDIR/golden-decompression/rle-first-block.zst"
$DIFF -s tmp1 tmp $DIFF -s tmp1 tmp
rm -f tmp* rm tmp*
println "\n===> compress multiple files" println "\n===> compress multiple files"
@@ -432,7 +415,7 @@ zstd -f tmp*
test -f tmp1.zst test -f tmp1.zst
test -f tmp2.zst test -f tmp2.zst
test -f tmp3.zst test -f tmp3.zst
rm -f tmp1 tmp2 tmp3 rm tmp1 tmp2 tmp3
println "decompress tmp* : " println "decompress tmp* : "
zstd -df ./*.zst zstd -df ./*.zst
test -f tmp1 test -f tmp1
@@ -447,7 +430,7 @@ zstd -dc tmpall* > tmpdec
test -f tmpdec # should check size of tmpdec (should be 2*(tmp1 + tmp2 + tmp3)) test -f tmpdec # should check size of tmpdec (should be 2*(tmp1 + tmp2 + tmp3))
println "compress multiple files including a missing one (notHere) : " println "compress multiple files including a missing one (notHere) : "
zstd -f tmp1 notHere tmp2 && die "missing file not detected!" zstd -f tmp1 notHere tmp2 && die "missing file not detected!"
rm -f tmp* rm tmp*
if [ "$isWindows" = false ] ; then if [ "$isWindows" = false ] ; then
@@ -462,96 +445,6 @@ if [ "$isWindows" = false ] ; then
rm -rf tmp* rm -rf tmp*
fi fi
println "\n===> zstd created file permissions tests"
if [ "$isWindows" = false ] ; then
rm -f tmp1 tmp2 tmp1.zst tmp2.zst tmp1.out tmp2.out # todo: remove
ORIGINAL_UMASK=$(umask)
umask 0000
datagen > tmp1
datagen > tmp2
assertFilePermissions tmp1 666
assertFilePermissions tmp2 666
println "test : copy 666 permissions in file -> file compression "
zstd -f tmp1 -o tmp1.zst
assertSamePermissions tmp1 tmp1.zst
println "test : copy 666 permissions in file -> file decompression "
zstd -f -d tmp1.zst -o tmp1.out
assertSamePermissions tmp1.zst tmp1.out
rm -f tmp1.zst tmp1.out
println "test : copy 400 permissions in file -> file compression (write to a read-only file) "
chmod 0400 tmp1
assertFilePermissions tmp1 400
zstd -f tmp1 -o tmp1.zst
assertSamePermissions tmp1 tmp1.zst
println "test : copy 400 permissions in file -> file decompression (write to a read-only file) "
zstd -f -d tmp1.zst -o tmp1
assertSamePermissions tmp1.zst tmp1
rm -f tmp1.zst tmp1.out
println "test : check created permissions from stdin input in compression "
zstd -f -o tmp1.zst < tmp1
assertFilePermissions tmp1.zst 666
println "test : check created permissions from stdin input in decompression "
zstd -f -d -o tmp1.out < tmp1.zst
assertFilePermissions tmp1.out 666
rm -f tmp1.zst tmp1.out
println "test : check created permissions from multiple inputs in compression "
zstd -f tmp1 tmp2 -o tmp1.zst
assertFilePermissions tmp1.zst 666
println "test : check created permissions from multiple inputs in decompression "
cp tmp1.zst tmp2.zst
zstd -f -d tmp1.zst tmp2.zst -o tmp1.out
assertFilePermissions tmp1.out 666
rm -f tmp1.zst tmp2.zst tmp1.out tmp2.out
println "test : check permissions on pre-existing output file in compression "
chmod 0600 tmp1
touch tmp1.zst
chmod 0400 tmp1.zst
zstd -f tmp1 -o tmp1.zst
assertFilePermissions tmp1.zst 600
println "test : check permissions on pre-existing output file in decompression "
chmod 0400 tmp1.zst
touch tmp1.out
chmod 0200 tmp1.out
zstd -f -d tmp1.zst -o tmp1.out
assertFilePermissions tmp1.out 400
rm -f tmp1.zst tmp1.out
umask 0666
chmod 0666 tmp1 tmp2
println "test : respect umask when copying permissions in file -> file compression "
zstd -f tmp1 -o tmp1.zst
assertFilePermissions tmp1.zst 0
println "test : respect umask when copying permissions in file -> file decompression "
chmod 0666 tmp1.zst
zstd -f -d tmp1.zst -o tmp1.out
assertFilePermissions tmp1.out 0
rm -f tmp1.zst tmp1.out
println "test : respect umask when compressing from stdin input "
zstd -f -o tmp1.zst < tmp1
assertFilePermissions tmp1.zst 0
println "test : respect umask when decompressing from stdin input "
chmod 0666 tmp1.zst
zstd -f -d -o tmp1.out < tmp1.zst
assertFilePermissions tmp1.out 0
rm -f tmp1 tmp2 tmp1.zst tmp2.zst tmp1.out tmp2.out
umask $ORIGINAL_UMASK
fi
if [ -n "$DEVNULLRIGHTS" ] ; then if [ -n "$DEVNULLRIGHTS" ] ; then
# these tests requires sudo rights, which is uncommon. # these tests requires sudo rights, which is uncommon.
@@ -566,22 +459,6 @@ if [ -n "$DEVNULLRIGHTS" ] ; then
ls -las $INTOVOID | grep "rw-rw-rw-" ls -las $INTOVOID | grep "rw-rw-rw-"
fi fi
if [ -n "$READFROMBLOCKDEVICE" ] ; then
# This creates a temporary block device, which is only possible on unix-y
# systems, is somewhat invasive, and requires sudo. For these reasons, you
# have to specifically ask for this test.
println "\n===> checking that zstd can read from a block device"
datagen -g65536 > tmp.img
sudo losetup -fP tmp.img
LOOP_DEV=$(losetup -a | grep 'tmp\.img' | cut -f1 -d:)
[ -z "$LOOP_DEV" ] && die "failed to get loopback device"
sudoZstd $LOOP_DEV -c > tmp.img.zst && die "should fail without -f"
sudoZstd -f $LOOP_DEV -c > tmp.img.zst
zstd -d tmp.img.zst -o tmp.img.copy
sudo losetup -d $LOOP_DEV
$DIFF -s tmp.img tmp.img.copy || die "round trip failed"
rm -f tmp.img tmp.img.zst tmp.img.copy
fi
println "\n===> compress multiple files into an output directory, --output-dir-flat" println "\n===> compress multiple files into an output directory, --output-dir-flat"
println henlo > tmp1 println henlo > tmp1
@@ -774,16 +651,16 @@ $DIFF helloworld.tmp result.tmp
ln -s helloworld.zst helloworld.link.zst ln -s helloworld.zst helloworld.link.zst
$EXE_PREFIX ./zstdcat helloworld.link.zst > result.tmp $EXE_PREFIX ./zstdcat helloworld.link.zst > result.tmp
$DIFF helloworld.tmp result.tmp $DIFF helloworld.tmp result.tmp
rm -f zstdcat rm zstdcat
rm -f result.tmp rm result.tmp
println "testing zcat symlink" println "testing zcat symlink"
ln -sf "$ZSTD_BIN" zcat ln -sf "$ZSTD_BIN" zcat
$EXE_PREFIX ./zcat helloworld.zst > result.tmp $EXE_PREFIX ./zcat helloworld.zst > result.tmp
$DIFF helloworld.tmp result.tmp $DIFF helloworld.tmp result.tmp
$EXE_PREFIX ./zcat helloworld.link.zst > result.tmp $EXE_PREFIX ./zcat helloworld.link.zst > result.tmp
$DIFF helloworld.tmp result.tmp $DIFF helloworld.tmp result.tmp
rm -f zcat rm zcat
rm -f ./*.tmp ./*.zstd rm ./*.tmp ./*.zstd
println "frame concatenation tests completed" println "frame concatenation tests completed"
@@ -845,7 +722,7 @@ zstd -d -v -f tmpSparseCompressed -o tmpSparseRegenerated
zstd -d -v -f tmpSparseCompressed -c >> tmpSparseRegenerated zstd -d -v -f tmpSparseCompressed -c >> tmpSparseRegenerated
ls -ls tmpSparse* # look at file size and block size on disk ls -ls tmpSparse* # look at file size and block size on disk
$DIFF tmpSparse2M tmpSparseRegenerated $DIFF tmpSparse2M tmpSparseRegenerated
rm -f tmpSparse* rm tmpSparse*
println "\n===> stream-size mode" println "\n===> stream-size mode"
@@ -991,7 +868,7 @@ then
println "- Create dictionary with multithreading enabled" println "- Create dictionary with multithreading enabled"
zstd --train -T0 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict zstd --train -T0 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict
fi fi
rm -f tmp* dictionary rm tmp* dictionary
println "\n===> fastCover dictionary builder : advanced options " println "\n===> fastCover dictionary builder : advanced options "
@@ -1033,7 +910,7 @@ zstd -o tmpDict --train-fastcover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c
test -f tmpDict test -f tmpDict
zstd --train-fastcover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c zstd --train-fastcover=k=56,d=8 "$TESTDIR"/*.c "$PRGDIR"/*.c
test -f dictionary test -f dictionary
rm -f tmp* dictionary rm tmp* dictionary
println "\n===> legacy dictionary builder " println "\n===> legacy dictionary builder "
@@ -1061,7 +938,7 @@ zstd -o tmpDict --train-legacy "$TESTDIR"/*.c "$PRGDIR"/*.c
test -f tmpDict test -f tmpDict
zstd --train-legacy "$TESTDIR"/*.c "$PRGDIR"/*.c zstd --train-legacy "$TESTDIR"/*.c "$PRGDIR"/*.c
test -f dictionary test -f dictionary
rm -f tmp* dictionary rm tmp* dictionary
println "\n===> integrity tests " println "\n===> integrity tests "
@@ -1133,7 +1010,7 @@ if [ $GZIPMODE -eq 1 ]; then
gzip -t -v tmp.gz gzip -t -v tmp.gz
gzip -f tmp gzip -f tmp
zstd -d -f -v tmp.gz zstd -d -f -v tmp.gz
rm -f tmp* rm tmp*
else else
println "gzip binary not detected" println "gzip binary not detected"
fi fi
@@ -1150,7 +1027,7 @@ if [ $GZIPMODE -eq 1 ]; then
zstd -f tmp zstd -f tmp
cat tmp.gz tmp.zst tmp.gz tmp.zst | zstd -d -f -o tmp cat tmp.gz tmp.zst tmp.gz tmp.zst | zstd -d -f -o tmp
truncateLastByte tmp.gz | zstd -t > $INTOVOID && die "incomplete frame not detected !" truncateLastByte tmp.gz | zstd -t > $INTOVOID && die "incomplete frame not detected !"
rm -f tmp* rm tmp*
else else
println "gzip mode not supported" println "gzip mode not supported"
fi fi
@@ -1181,7 +1058,7 @@ if [ $LZMAMODE -eq 1 ]; then
lzma -Q -f -k --lzma1 tmp lzma -Q -f -k --lzma1 tmp
zstd -d -f -v tmp.xz zstd -d -f -v tmp.xz
zstd -d -f -v tmp.lzma zstd -d -f -v tmp.lzma
rm -f tmp* rm tmp*
println "Creating symlinks" println "Creating symlinks"
ln -s "$ZSTD_BIN" ./xz ln -s "$ZSTD_BIN" ./xz
ln -s "$ZSTD_BIN" ./unxz ln -s "$ZSTD_BIN" ./unxz
@@ -1198,8 +1075,8 @@ if [ $LZMAMODE -eq 1 ]; then
./xz -d tmp.xz ./xz -d tmp.xz
lzma -Q tmp lzma -Q tmp
./lzma -d tmp.lzma ./lzma -d tmp.lzma
rm -f xz unxz lzma unlzma rm xz unxz lzma unlzma
rm -f tmp* rm tmp*
else else
println "xz binary not detected" println "xz binary not detected"
fi fi
@@ -1218,7 +1095,7 @@ if [ $LZMAMODE -eq 1 ]; then
cat tmp.xz tmp.lzma tmp.zst tmp.lzma tmp.xz tmp.zst | zstd -d -f -o tmp cat tmp.xz tmp.lzma tmp.zst tmp.lzma tmp.xz tmp.zst | zstd -d -f -o tmp
truncateLastByte tmp.xz | zstd -t > $INTOVOID && die "incomplete frame not detected !" truncateLastByte tmp.xz | zstd -t > $INTOVOID && die "incomplete frame not detected !"
truncateLastByte tmp.lzma | zstd -t > $INTOVOID && die "incomplete frame not detected !" truncateLastByte tmp.lzma | zstd -t > $INTOVOID && die "incomplete frame not detected !"
rm -f tmp* rm tmp*
else else
println "xz mode not supported" println "xz mode not supported"
fi fi
@@ -1237,7 +1114,7 @@ if [ $LZ4MODE -eq 1 ]; then
lz4 -t -v tmp.lz4 lz4 -t -v tmp.lz4
lz4 -f -m tmp # ensure result is sent into tmp.lz4, not stdout lz4 -f -m tmp # ensure result is sent into tmp.lz4, not stdout
zstd -d -f -v tmp.lz4 zstd -d -f -v tmp.lz4
rm -f tmp* rm tmp*
else else
println "lz4 binary not detected" println "lz4 binary not detected"
fi fi
@@ -1253,7 +1130,7 @@ if [ $LZ4MODE -eq 1 ]; then
zstd -f tmp zstd -f tmp
cat tmp.lz4 tmp.zst tmp.lz4 tmp.zst | zstd -d -f -o tmp cat tmp.lz4 tmp.zst tmp.lz4 tmp.zst | zstd -d -f -o tmp
truncateLastByte tmp.lz4 | zstd -t > $INTOVOID && die "incomplete frame not detected !" truncateLastByte tmp.lz4 | zstd -t > $INTOVOID && die "incomplete frame not detected !"
rm -f tmp* rm tmp*
else else
println "\nlz4 mode not supported" println "\nlz4 mode not supported"
fi fi
@@ -1287,7 +1164,7 @@ rm -f tmp tmp.tar tmp.tzst tmp.tgz tmp.txz tmp.tlz4 tmp1.zstd
datagen > tmp datagen > tmp
tar cf tmp.tar tmp tar cf tmp.tar tmp
zstd tmp.tar -o tmp.tzst zstd tmp.tar -o tmp.tzst
rm -f tmp.tar rm tmp.tar
zstd -d tmp.tzst zstd -d tmp.tzst
[ -e tmp.tar ] || die ".tzst failed to decompress to .tar!" [ -e tmp.tar ] || die ".tzst failed to decompress to .tar!"
rm -f tmp.tar tmp.tzst rm -f tmp.tar tmp.tzst
@@ -1348,7 +1225,7 @@ then
println "\n===> zstdmt round-trip tests " println "\n===> zstdmt round-trip tests "
roundTripTest -g4M "1 -T0" roundTripTest -g4M "1 -T0"
roundTripTest -g8M "3 -T2" roundTripTest -g8M "3 -T2"
roundTripTest -g8M "19 --long" roundTripTest -g8M "19 -T0 --long"
roundTripTest -g8000K "2 --threads=2" roundTripTest -g8000K "2 --threads=2"
fileRoundTripTest -g4M "19 -T2 -B1M" fileRoundTripTest -g4M "19 -T2 -B1M"
@@ -1366,7 +1243,7 @@ then
ZSTD_NBTHREADS=50000000000 zstd -f mt_tmp # numeric value too large, warn and revert to default setting= ZSTD_NBTHREADS=50000000000 zstd -f mt_tmp # numeric value too large, warn and revert to default setting=
ZSTD_NBTHREADS=2 zstd -f mt_tmp # correct usage ZSTD_NBTHREADS=2 zstd -f mt_tmp # correct usage
ZSTD_NBTHREADS=1 zstd -f mt_tmp # correct usage: single thread ZSTD_NBTHREADS=1 zstd -f mt_tmp # correct usage: single thread
rm -f mt_tmp* rm mt_tmp*
println "\n===> ovLog tests " println "\n===> ovLog tests "
datagen -g2MB > tmp datagen -g2MB > tmp
@@ -1390,7 +1267,7 @@ else
println "\n===> no multithreading, skipping zstdmt tests " println "\n===> no multithreading, skipping zstdmt tests "
fi fi
rm -f tmp* rm tmp*
println "\n===> zstd --list/-l single frame tests " println "\n===> zstd --list/-l single frame tests "
datagen > tmp1 datagen > tmp1
@@ -1423,9 +1300,9 @@ zstd -f $TEST_DATA_FILE -o $FULL_COMPRESSED_FILE
dd bs=1 count=100 if=$FULL_COMPRESSED_FILE of=$TRUNCATED_COMPRESSED_FILE dd bs=1 count=100 if=$FULL_COMPRESSED_FILE of=$TRUNCATED_COMPRESSED_FILE
zstd --list $TRUNCATED_COMPRESSED_FILE && die "-l must fail on truncated file" zstd --list $TRUNCATED_COMPRESSED_FILE && die "-l must fail on truncated file"
rm -f $TEST_DATA_FILE rm $TEST_DATA_FILE
rm -f $FULL_COMPRESSED_FILE rm $FULL_COMPRESSED_FILE
rm -f $TRUNCATED_COMPRESSED_FILE rm $TRUNCATED_COMPRESSED_FILE
println "\n===> zstd --list/-l errors when presented with stdin / no files" println "\n===> zstd --list/-l errors when presented with stdin / no files"
zstd -l && die "-l must fail on empty list of files" zstd -l && die "-l must fail on empty list of files"
@@ -1469,7 +1346,7 @@ zstd -D tmp1 tmp2 -c | zstd --trace tmp.trace -t -D tmp1
zstd -b1e10i0 --trace tmp.trace tmp1 zstd -b1e10i0 --trace tmp.trace tmp1
zstd -b1e10i0 --trace tmp.trace tmp1 tmp2 tmp3 zstd -b1e10i0 --trace tmp.trace tmp1 tmp2 tmp3
rm -f tmp* rm tmp*
println "\n===> zstd long distance matching tests " println "\n===> zstd long distance matching tests "
@@ -1553,14 +1430,6 @@ datagen -g5000000 > tmp_patch
zstd -15 --patch-from=tmp_dict tmp_patch 2>&1 | grep "long mode automatically triggered" zstd -15 --patch-from=tmp_dict tmp_patch 2>&1 | grep "long mode automatically triggered"
rm -rf tmp* rm -rf tmp*
println "\n===> patch-from very large dictionary and file test"
datagen -g550000000 -P0 > tmp_dict
datagen -g100000000 -P1 > tmp_patch
zstd --long=30 -1f --patch-from tmp_dict tmp_patch
zstd --long=30 -df --patch-from tmp_dict tmp_patch.zst -o tmp_patch_recon
$DIFF -s tmp_patch_recon tmp_patch
rm -rf tmp*
println "\n===> patch-from --stream-size test" println "\n===> patch-from --stream-size test"
datagen -g1000 -P50 > tmp_dict datagen -g1000 -P50 > tmp_dict
datagen -g1000 -P10 > tmp_patch datagen -g1000 -P10 > tmp_patch
+15 -132
View File
@@ -28,134 +28,20 @@
}; };
/* Define a config for each level we want to test with. */ /* Define a config for each level we want to test with. */
#define LEVEL(x) \ #define LEVEL(x) \
param_value_t const level_##x##_param_values[] = { \ param_value_t const level_##x##_param_values[] = { \
{.param = ZSTD_c_compressionLevel, .value = x}, \ {.param = ZSTD_c_compressionLevel, .value = x}, \
}; \ }; \
param_value_t const level_##x##_param_values_dms[] = { \ config_t const level_##x = { \
{.param = ZSTD_c_compressionLevel, .value = x}, \ .name = "level " #x, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \ .cli_args = "-" #x, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \ .param_values = PARAM_VALUES(level_##x##_param_values), \
}; \ }; \
param_value_t const level_##x##_param_values_dds[] = { \ config_t const level_##x##_dict = { \
{.param = ZSTD_c_compressionLevel, .value = x}, \ .name = "level " #x " with dict", \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 1}, \ .cli_args = "-" #x, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \ .param_values = PARAM_VALUES(level_##x##_param_values), \
}; \ .use_dictionary = 1, \
param_value_t const level_##x##_param_values_dictcopy[] = { \
{.param = ZSTD_c_compressionLevel, .value = x}, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceCopy}, \
}; \
param_value_t const level_##x##_param_values_dictload[] = { \
{.param = ZSTD_c_compressionLevel, .value = x}, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceLoad}, \
}; \
config_t const level_##x = { \
.name = "level " #x, \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(level_##x##_param_values), \
}; \
config_t const level_##x##_dict = { \
.name = "level " #x " with dict", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(level_##x##_param_values), \
.use_dictionary = 1, \
}; \
config_t const level_##x##_dict_dms = { \
.name = "level " #x " with dict dms", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(level_##x##_param_values_dms), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; \
config_t const level_##x##_dict_dds = { \
.name = "level " #x " with dict dds", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(level_##x##_param_values_dds), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; \
config_t const level_##x##_dict_copy = { \
.name = "level " #x " with dict copy", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(level_##x##_param_values_dictcopy), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; \
config_t const level_##x##_dict_load = { \
.name = "level " #x " with dict load", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(level_##x##_param_values_dictload), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
};
/* Define a config specifically to test row hash based levels and settings.
*/
#define ROW_LEVEL(x, y) \
param_value_t const row_##y##_level_##x##_param_values[] = { \
{.param = ZSTD_c_useRowMatchFinder, .value = y}, \
{.param = ZSTD_c_compressionLevel, .value = x}, \
}; \
param_value_t const row_##y##_level_##x##_param_values_dms[] = { \
{.param = ZSTD_c_useRowMatchFinder, .value = y}, \
{.param = ZSTD_c_compressionLevel, .value = x}, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \
}; \
param_value_t const row_##y##_level_##x##_param_values_dds[] = { \
{.param = ZSTD_c_useRowMatchFinder, .value = y}, \
{.param = ZSTD_c_compressionLevel, .value = x}, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 1}, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceAttach}, \
}; \
param_value_t const row_##y##_level_##x##_param_values_dictcopy[] = { \
{.param = ZSTD_c_useRowMatchFinder, .value = y}, \
{.param = ZSTD_c_compressionLevel, .value = x}, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceCopy}, \
}; \
param_value_t const row_##y##_level_##x##_param_values_dictload[] = { \
{.param = ZSTD_c_useRowMatchFinder, .value = y}, \
{.param = ZSTD_c_compressionLevel, .value = x}, \
{.param = ZSTD_c_enableDedicatedDictSearch, .value = 0}, \
{.param = ZSTD_c_forceAttachDict, .value = ZSTD_dictForceLoad}, \
}; \
config_t const row_##y##_level_##x = { \
.name = "level " #x " row " #y, \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(row_##y##_level_##x##_param_values), \
.advanced_api_only = 1, \
}; \
config_t const row_##y##_level_##x##_dict_dms = { \
.name = "level " #x " row " #y " with dict dms", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dms), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; \
config_t const row_##y##_level_##x##_dict_dds = { \
.name = "level " #x " row " #y " with dict dds", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dds), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; \
config_t const row_##y##_level_##x##_dict_copy = { \
.name = "level " #x " row " #y" with dict copy", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dictcopy), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; \
config_t const row_##y##_level_##x##_dict_load = { \
.name = "level " #x " row " #y " with dict load", \
.cli_args = "-" #x, \
.param_values = PARAM_VALUES(row_##y##_level_##x##_param_values_dictload), \
.use_dictionary = 1, \
.advanced_api_only = 1, \
}; };
#define PARAM_VALUES(pv) \ #define PARAM_VALUES(pv) \
@@ -165,7 +51,6 @@
#undef LEVEL #undef LEVEL
#undef FAST_LEVEL #undef FAST_LEVEL
#undef ROW_LEVEL
static config_t no_pledged_src_size = { static config_t no_pledged_src_size = {
.name = "no source size", .name = "no source size",
@@ -309,10 +194,8 @@ static config_t explicit_params = {
static config_t const* g_configs[] = { static config_t const* g_configs[] = {
#define FAST_LEVEL(x) &level_fast##x, &level_fast##x##_dict, #define FAST_LEVEL(x) &level_fast##x, &level_fast##x##_dict,
#define LEVEL(x) &level_##x, &level_##x##_dict, &level_##x##_dict_dms, &level_##x##_dict_dds, &level_##x##_dict_copy, &level_##x##_dict_load, #define LEVEL(x) &level_##x, &level_##x##_dict,
#define ROW_LEVEL(x, y) &row_##y##_level_##x, &row_##y##_level_##x##_dict_dms, &row_##y##_level_##x##_dict_dds, &row_##y##_level_##x##_dict_copy, &row_##y##_level_##x##_dict_load,
#include "levels.h" #include "levels.h"
#undef ROW_LEVEL
#undef LEVEL #undef LEVEL
#undef FAST_LEVEL #undef FAST_LEVEL
-5
View File
@@ -53,11 +53,6 @@ typedef struct {
* when the method allows it. Defaults to yes. * when the method allows it. Defaults to yes.
*/ */
int no_pledged_src_size; int no_pledged_src_size;
/**
* Boolean parameter that says that this config should only be used
* for methods that use the advanced compression API
*/
int advanced_api_only;
} config_t; } config_t;
/** /**
-1
View File
@@ -14,7 +14,6 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> /* free() */
#include <sys/stat.h> #include <sys/stat.h>
-13
View File
@@ -14,9 +14,6 @@
#ifndef FAST_LEVEL #ifndef FAST_LEVEL
# error FAST_LEVEL(x) must be defined # error FAST_LEVEL(x) must be defined
#endif #endif
#ifndef ROW_LEVEL
# error ROW_LEVEL(x, y) must be defined
#endif
/** /**
* The levels are chosen to trigger every strategy in every source size, * The levels are chosen to trigger every strategy in every source size,
@@ -34,22 +31,12 @@ LEVEL(1)
LEVEL(3) LEVEL(3)
LEVEL(4) LEVEL(4)
/* ROW_LEVEL triggers the row hash (force enabled and disabled) with different
* dictionary strategies, and 16/32 row entries based on the level/searchLog.
* 1 == disabled, 2 == enabled.
*/
ROW_LEVEL(5, 1)
ROW_LEVEL(5, 2)
LEVEL(5) LEVEL(5)
LEVEL(6) LEVEL(6)
ROW_LEVEL(7, 1)
ROW_LEVEL(7, 2)
LEVEL(7) LEVEL(7)
LEVEL(9) LEVEL(9)
ROW_LEVEL(12, 1)
ROW_LEVEL(12, 2)
LEVEL(13) LEVEL(13)
LEVEL(16) LEVEL(16)
+1 -14
View File
@@ -102,9 +102,6 @@ static result_t simple_compress(method_state_t* base, config_t const* config) {
*/ */
if (base->data->type != data_type_file) if (base->data->type != data_type_file)
return result_error(result_error_skip); return result_error(result_error_skip);
if (config->advanced_api_only)
return result_error(result_error_skip);
if (config->use_dictionary || config->no_pledged_src_size) if (config->use_dictionary || config->no_pledged_src_size)
return result_error(result_error_skip); return result_error(result_error_skip);
@@ -154,9 +151,6 @@ static result_t compress_cctx_compress(
if (base->data->type != data_type_dir) if (base->data->type != data_type_dir)
return result_error(result_error_skip); return result_error(result_error_skip);
if (config->advanced_api_only)
return result_error(result_error_skip);
int const level = config_get_level(config); int const level = config_get_level(config);
@@ -260,9 +254,6 @@ static result_t cli_compress(method_state_t* state, config_t const* config) {
if (config->cli_args == NULL) if (config->cli_args == NULL)
return result_error(result_error_skip); return result_error(result_error_skip);
if (config->advanced_api_only)
return result_error(result_error_skip);
/* We don't support no pledged source size with directories. Too slow. */ /* We don't support no pledged source size with directories. Too slow. */
if (state->data->type == data_type_dir && config->no_pledged_src_size) if (state->data->type == data_type_dir && config->no_pledged_src_size)
return result_error(result_error_skip); return result_error(result_error_skip);
@@ -532,10 +523,6 @@ static result_t old_streaming_compress_internal(
result = result_error(result_error_skip); result = result_error(result_error_skip);
goto out; goto out;
} }
if (config->advanced_api_only) {
result = result_error(result_error_skip);
goto out;
}
if (init_cstream(state, zcs, config, advanced, cdict ? &cd : NULL)) { if (init_cstream(state, zcs, config, advanced, cdict ? &cd : NULL)) {
result = result_error(result_error_compression_error); result = result_error(result_error_compression_error);
goto out; goto out;
@@ -664,7 +651,7 @@ method_t const old_streaming_advanced = {
}; };
method_t const old_streaming_cdict = { method_t const old_streaming_cdict = {
.name = "old streaming cdict", .name = "old streaming cdcit",
.create = buffer_state_create, .create = buffer_state_create,
.compress = old_streaming_compress_cdict, .compress = old_streaming_compress_cdict,
.destroy = buffer_state_destroy, .destroy = buffer_state_destroy,
+307 -787
View File
@@ -6,10 +6,10 @@ silesia.tar, level 0, compress
silesia.tar, level 1, compress simple, 5334885 silesia.tar, level 1, compress simple, 5334885
silesia.tar, level 3, compress simple, 4861425 silesia.tar, level 3, compress simple, 4861425
silesia.tar, level 4, compress simple, 4799630 silesia.tar, level 4, compress simple, 4799630
silesia.tar, level 5, compress simple, 4719256 silesia.tar, level 5, compress simple, 4722324
silesia.tar, level 6, compress simple, 4677721 silesia.tar, level 6, compress simple, 4672279
silesia.tar, level 7, compress simple, 4613541 silesia.tar, level 7, compress simple, 4606715
silesia.tar, level 9, compress simple, 4555426 silesia.tar, level 9, compress simple, 4554147
silesia.tar, level 13, compress simple, 4491764 silesia.tar, level 13, compress simple, 4491764
silesia.tar, level 16, compress simple, 4381332 silesia.tar, level 16, compress simple, 4381332
silesia.tar, level 19, compress simple, 4281605 silesia.tar, level 19, compress simple, 4281605
@@ -23,10 +23,10 @@ github.tar, level 0, compress
github.tar, level 1, compress simple, 39265 github.tar, level 1, compress simple, 39265
github.tar, level 3, compress simple, 38441 github.tar, level 3, compress simple, 38441
github.tar, level 4, compress simple, 38467 github.tar, level 4, compress simple, 38467
github.tar, level 5, compress simple, 39693 github.tar, level 5, compress simple, 39788
github.tar, level 6, compress simple, 39621 github.tar, level 6, compress simple, 39603
github.tar, level 7, compress simple, 39213 github.tar, level 7, compress simple, 39206
github.tar, level 9, compress simple, 36758 github.tar, level 9, compress simple, 36717
github.tar, level 13, compress simple, 35621 github.tar, level 13, compress simple, 35621
github.tar, level 16, compress simple, 40255 github.tar, level 16, compress simple, 40255
github.tar, level 19, compress simple, 32837 github.tar, level 19, compress simple, 32837
@@ -40,10 +40,10 @@ silesia, level 0, compress
silesia, level 1, compress cctx, 5313204 silesia, level 1, compress cctx, 5313204
silesia, level 3, compress cctx, 4849552 silesia, level 3, compress cctx, 4849552
silesia, level 4, compress cctx, 4786970 silesia, level 4, compress cctx, 4786970
silesia, level 5, compress cctx, 4707794 silesia, level 5, compress cctx, 4710236
silesia, level 6, compress cctx, 4666383 silesia, level 6, compress cctx, 4660056
silesia, level 7, compress cctx, 4603381 silesia, level 7, compress cctx, 4596296
silesia, level 9, compress cctx, 4546001 silesia, level 9, compress cctx, 4543925
silesia, level 13, compress cctx, 4482135 silesia, level 13, compress cctx, 4482135
silesia, level 16, compress cctx, 4377465 silesia, level 16, compress cctx, 4377465
silesia, level 19, compress cctx, 4293330 silesia, level 19, compress cctx, 4293330
@@ -53,7 +53,7 @@ silesia, multithreaded long distance mode, compress
silesia, small window log, compress cctx, 7084179 silesia, small window log, compress cctx, 7084179
silesia, small hash log, compress cctx, 6555021 silesia, small hash log, compress cctx, 6555021
silesia, small chain log, compress cctx, 4931148 silesia, small chain log, compress cctx, 4931148
silesia, explicit params, compress cctx, 4794479 silesia, explicit params, compress cctx, 4794677
silesia, uncompressed literals, compress cctx, 4849552 silesia, uncompressed literals, compress cctx, 4849552
silesia, uncompressed literals optimal, compress cctx, 4293330 silesia, uncompressed literals optimal, compress cctx, 4293330
silesia, huffman literals, compress cctx, 6178460 silesia, huffman literals, compress cctx, 6178460
@@ -73,13 +73,13 @@ github, level 3 with dict, compress
github, level 4, compress cctx, 136199 github, level 4, compress cctx, 136199
github, level 4 with dict, compress cctx, 41725 github, level 4 with dict, compress cctx, 41725
github, level 5, compress cctx, 135121 github, level 5, compress cctx, 135121
github, level 5 with dict, compress cctx, 38759 github, level 5 with dict, compress cctx, 38934
github, level 6, compress cctx, 135122 github, level 6, compress cctx, 135122
github, level 6 with dict, compress cctx, 38669 github, level 6 with dict, compress cctx, 38628
github, level 7, compress cctx, 135122 github, level 7, compress cctx, 135122
github, level 7 with dict, compress cctx, 38755 github, level 7 with dict, compress cctx, 38745
github, level 9, compress cctx, 135122 github, level 9, compress cctx, 135122
github, level 9 with dict, compress cctx, 39398 github, level 9 with dict, compress cctx, 39341
github, level 13, compress cctx, 134064 github, level 13, compress cctx, 134064
github, level 13 with dict, compress cctx, 39948 github, level 13 with dict, compress cctx, 39948
github, level 16, compress cctx, 134064 github, level 16, compress cctx, 134064
@@ -97,30 +97,30 @@ github, uncompressed literals, compress
github, uncompressed literals optimal, compress cctx, 134064 github, uncompressed literals optimal, compress cctx, 134064
github, huffman literals, compress cctx, 175568 github, huffman literals, compress cctx, 175568
github, multithreaded with advanced params, compress cctx, 141102 github, multithreaded with advanced params, compress cctx, 141102
silesia, level -5, zstdcli, 6737655 silesia, level -5, zstdcli, 6882553
silesia, level -3, zstdcli, 6444725 silesia, level -3, zstdcli, 6568424
silesia, level -1, zstdcli, 6178508 silesia, level -1, zstdcli, 6183451
silesia, level 0, zstdcli, 4849600 silesia, level 0, zstdcli, 4849600
silesia, level 1, zstdcli, 5313252 silesia, level 1, zstdcli, 5314210
silesia, level 3, zstdcli, 4849600 silesia, level 3, zstdcli, 4849600
silesia, level 4, zstdcli, 4787018 silesia, level 4, zstdcli, 4787018
silesia, level 5, zstdcli, 4707842 silesia, level 5, zstdcli, 4710284
silesia, level 6, zstdcli, 4666431 silesia, level 6, zstdcli, 4660104
silesia, level 7, zstdcli, 4603429 silesia, level 7, zstdcli, 4596344
silesia, level 9, zstdcli, 4546049 silesia, level 9, zstdcli, 4543973
silesia, level 13, zstdcli, 4482183 silesia, level 13, zstdcli, 4482183
silesia, level 16, zstdcli, 4360299 silesia, level 16, zstdcli, 4377513
silesia, level 19, zstdcli, 4283285 silesia, level 19, zstdcli, 4293378
silesia, long distance mode, zstdcli, 4840806 silesia, long distance mode, zstdcli, 4840792
silesia, multithreaded, zstdcli, 4849600 silesia, multithreaded, zstdcli, 4849600
silesia, multithreaded long distance mode, zstdcli, 4840806 silesia, multithreaded long distance mode, zstdcli, 4840792
silesia, small window log, zstdcli, 7095967 silesia, small window log, zstdcli, 7111012
silesia, small hash log, zstdcli, 6526189 silesia, small hash log, zstdcli, 6555069
silesia, small chain log, zstdcli, 4912245 silesia, small chain log, zstdcli, 4931196
silesia, explicit params, zstdcli, 4795856 silesia, explicit params, zstdcli, 4797112
silesia, uncompressed literals, zstdcli, 5128030 silesia, uncompressed literals, zstdcli, 5128030
silesia, uncompressed literals optimal, zstdcli, 4317944 silesia, uncompressed literals optimal, zstdcli, 4325520
silesia, huffman literals, zstdcli, 5326316 silesia, huffman literals, zstdcli, 5331216
silesia, multithreaded with advanced params, zstdcli, 5128030 silesia, multithreaded with advanced params, zstdcli, 5128030
silesia.tar, level -5, zstdcli, 6738934 silesia.tar, level -5, zstdcli, 6738934
silesia.tar, level -3, zstdcli, 6448419 silesia.tar, level -3, zstdcli, 6448419
@@ -129,23 +129,23 @@ silesia.tar, level 0, zstdcli,
silesia.tar, level 1, zstdcli, 5336318 silesia.tar, level 1, zstdcli, 5336318
silesia.tar, level 3, zstdcli, 4861512 silesia.tar, level 3, zstdcli, 4861512
silesia.tar, level 4, zstdcli, 4800529 silesia.tar, level 4, zstdcli, 4800529
silesia.tar, level 5, zstdcli, 4720121 silesia.tar, level 5, zstdcli, 4723364
silesia.tar, level 6, zstdcli, 4678661 silesia.tar, level 6, zstdcli, 4673663
silesia.tar, level 7, zstdcli, 4614424 silesia.tar, level 7, zstdcli, 4608403
silesia.tar, level 9, zstdcli, 4556062 silesia.tar, level 9, zstdcli, 4554751
silesia.tar, level 13, zstdcli, 4491768 silesia.tar, level 13, zstdcli, 4491768
silesia.tar, level 16, zstdcli, 4356831 silesia.tar, level 16, zstdcli, 4381336
silesia.tar, level 19, zstdcli, 4264491 silesia.tar, level 19, zstdcli, 4281609
silesia.tar, no source size, zstdcli, 4861508 silesia.tar, no source size, zstdcli, 4861508
silesia.tar, long distance mode, zstdcli, 4853226 silesia.tar, long distance mode, zstdcli, 4853153
silesia.tar, multithreaded, zstdcli, 4861512 silesia.tar, multithreaded, zstdcli, 4861512
silesia.tar, multithreaded long distance mode, zstdcli, 4853226 silesia.tar, multithreaded long distance mode, zstdcli, 4853153
silesia.tar, small window log, zstdcli, 7101576 silesia.tar, small window log, zstdcli, 7101576
silesia.tar, small hash log, zstdcli, 6529290 silesia.tar, small hash log, zstdcli, 6587959
silesia.tar, small chain log, zstdcli, 4917022 silesia.tar, small chain log, zstdcli, 4943310
silesia.tar, explicit params, zstdcli, 4821274 silesia.tar, explicit params, zstdcli, 4822362
silesia.tar, uncompressed literals, zstdcli, 5129559 silesia.tar, uncompressed literals, zstdcli, 5129559
silesia.tar, uncompressed literals optimal, zstdcli, 4307457 silesia.tar, uncompressed literals optimal, zstdcli, 4320931
silesia.tar, huffman literals, zstdcli, 5347610 silesia.tar, huffman literals, zstdcli, 5347610
silesia.tar, multithreaded with advanced params, zstdcli, 5129559 silesia.tar, multithreaded with advanced params, zstdcli, 5129559
github, level -5, zstdcli, 207285 github, level -5, zstdcli, 207285
@@ -163,15 +163,15 @@ github, level 3 with dict, zstdcli,
github, level 4, zstdcli, 138199 github, level 4, zstdcli, 138199
github, level 4 with dict, zstdcli, 43251 github, level 4 with dict, zstdcli, 43251
github, level 5, zstdcli, 137121 github, level 5, zstdcli, 137121
github, level 5 with dict, zstdcli, 40728 github, level 5 with dict, zstdcli, 40741
github, level 6, zstdcli, 137122 github, level 6, zstdcli, 137122
github, level 6 with dict, zstdcli, 40630 github, level 6 with dict, zstdcli, 40632
github, level 7, zstdcli, 137122 github, level 7, zstdcli, 137122
github, level 7 with dict, zstdcli, 40747 github, level 7 with dict, zstdcli, 40771
github, level 9, zstdcli, 137122 github, level 9, zstdcli, 137122
github, level 9 with dict, zstdcli, 41338 github, level 9 with dict, zstdcli, 41332
github, level 13, zstdcli, 136064 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, zstdcli, 136064
github, level 16 with dict, zstdcli, 39577 github, level 16 with dict, zstdcli, 39577
github, level 19, zstdcli, 136064 github, level 19, zstdcli, 136064
@@ -187,28 +187,28 @@ github, uncompressed literals, zstdcli,
github, uncompressed literals optimal, zstdcli, 159227 github, uncompressed literals optimal, zstdcli, 159227
github, huffman literals, zstdcli, 144465 github, huffman literals, zstdcli, 144465
github, multithreaded with advanced params, zstdcli, 167915 github, multithreaded with advanced params, zstdcli, 167915
github.tar, level -5, zstdcli, 46860 github.tar, level -5, zstdcli, 46751
github.tar, level -5 with dict, zstdcli, 44575 github.tar, level -5 with dict, zstdcli, 43975
github.tar, level -3, zstdcli, 43758 github.tar, level -3, zstdcli, 43541
github.tar, level -3 with dict, zstdcli, 41451 github.tar, level -3 with dict, zstdcli, 40809
github.tar, level -1, zstdcli, 42494 github.tar, level -1, zstdcli, 42469
github.tar, level -1 with dict, zstdcli, 41135 github.tar, level -1 with dict, zstdcli, 41126
github.tar, level 0, zstdcli, 38445 github.tar, level 0, zstdcli, 38445
github.tar, level 0 with dict, zstdcli, 37999 github.tar, level 0 with dict, zstdcli, 37999
github.tar, level 1, zstdcli, 39269 github.tar, level 1, zstdcli, 39346
github.tar, level 1 with dict, zstdcli, 38284 github.tar, level 1 with dict, zstdcli, 38313
github.tar, level 3, zstdcli, 38445 github.tar, level 3, zstdcli, 38445
github.tar, level 3 with dict, zstdcli, 37999 github.tar, level 3 with dict, zstdcli, 37999
github.tar, level 4, zstdcli, 38471 github.tar, level 4, zstdcli, 38471
github.tar, level 4 with dict, zstdcli, 37952 github.tar, level 4 with dict, zstdcli, 37952
github.tar, level 5, zstdcli, 39697 github.tar, level 5, zstdcli, 39792
github.tar, level 5 with dict, zstdcli, 39032 github.tar, level 5 with dict, zstdcli, 39231
github.tar, level 6, zstdcli, 39625 github.tar, level 6, zstdcli, 39607
github.tar, level 6 with dict, zstdcli, 38614 github.tar, level 6 with dict, zstdcli, 38669
github.tar, level 7, zstdcli, 39217 github.tar, level 7, zstdcli, 39210
github.tar, level 7 with dict, zstdcli, 37871 github.tar, level 7 with dict, zstdcli, 37958
github.tar, level 9, zstdcli, 36762 github.tar, level 9, zstdcli, 36721
github.tar, level 9 with dict, zstdcli, 36641 github.tar, level 9 with dict, zstdcli, 36886
github.tar, level 13, zstdcli, 35625 github.tar, level 13, zstdcli, 35625
github.tar, level 13 with dict, zstdcli, 38730 github.tar, level 13 with dict, zstdcli, 38730
github.tar, level 16, zstdcli, 40259 github.tar, level 16, zstdcli, 40259
@@ -217,16 +217,16 @@ github.tar, level 19, zstdcli,
github.tar, level 19 with dict, zstdcli, 32899 github.tar, level 19 with dict, zstdcli, 32899
github.tar, no source size, zstdcli, 38442 github.tar, no source size, zstdcli, 38442
github.tar, no source size with dict, zstdcli, 38004 github.tar, no source size with dict, zstdcli, 38004
github.tar, long distance mode, zstdcli, 39730 github.tar, long distance mode, zstdcli, 39726
github.tar, multithreaded, zstdcli, 38445 github.tar, multithreaded, zstdcli, 38445
github.tar, multithreaded long distance mode, zstdcli, 39730 github.tar, multithreaded long distance mode, zstdcli, 39726
github.tar, small window log, zstdcli, 198544 github.tar, small window log, zstdcli, 199432
github.tar, small hash log, zstdcli, 129874 github.tar, small hash log, zstdcli, 129874
github.tar, small chain log, zstdcli, 41673 github.tar, small chain log, zstdcli, 41673
github.tar, explicit params, zstdcli, 41227 github.tar, explicit params, zstdcli, 41199
github.tar, uncompressed literals, zstdcli, 41126 github.tar, uncompressed literals, zstdcli, 41126
github.tar, uncompressed literals optimal, zstdcli, 35392 github.tar, uncompressed literals optimal, zstdcli, 35392
github.tar, huffman literals, zstdcli, 38781 github.tar, huffman literals, zstdcli, 38804
github.tar, multithreaded with advanced params, zstdcli, 41126 github.tar, multithreaded with advanced params, zstdcli, 41126
silesia, level -5, advanced one pass, 6737607 silesia, level -5, advanced one pass, 6737607
silesia, level -3, advanced one pass, 6444677 silesia, level -3, advanced one pass, 6444677
@@ -235,29 +235,23 @@ silesia, level 0, advanced
silesia, level 1, advanced one pass, 5313204 silesia, level 1, advanced one pass, 5313204
silesia, level 3, advanced one pass, 4849552 silesia, level 3, advanced one pass, 4849552
silesia, level 4, advanced one pass, 4786970 silesia, level 4, advanced one pass, 4786970
silesia, level 5 row 1, advanced one pass, 4710236 silesia, level 5, advanced one pass, 4710236
silesia, level 5 row 2, advanced one pass, 4707794 silesia, level 6, advanced one pass, 4660056
silesia, level 5, advanced one pass, 4707794 silesia, level 7, advanced one pass, 4596296
silesia, level 6, advanced one pass, 4666383 silesia, level 9, advanced one pass, 4543925
silesia, level 7 row 1, advanced one pass, 4596296
silesia, level 7 row 2, advanced one pass, 4603381
silesia, level 7, advanced one pass, 4603381
silesia, level 9, advanced one pass, 4546001
silesia, level 12 row 1, advanced one pass, 4519288
silesia, level 12 row 2, advanced one pass, 4521397
silesia, level 13, advanced one pass, 4482135 silesia, level 13, advanced one pass, 4482135
silesia, level 16, advanced one pass, 4360251 silesia, level 16, advanced one pass, 4377465
silesia, level 19, advanced one pass, 4283237 silesia, level 19, advanced one pass, 4293330
silesia, no source size, advanced one pass, 4849552 silesia, no source size, advanced one pass, 4849552
silesia, long distance mode, advanced one pass, 4840738 silesia, long distance mode, advanced one pass, 4840744
silesia, multithreaded, advanced one pass, 4849552 silesia, multithreaded, advanced one pass, 4849552
silesia, multithreaded long distance mode, advanced one pass, 4840758 silesia, multithreaded long distance mode, advanced one pass, 4840744
silesia, small window log, advanced one pass, 7095919 silesia, small window log, advanced one pass, 7095919
silesia, small hash log, advanced one pass, 6526141 silesia, small hash log, advanced one pass, 6555021
silesia, small chain log, advanced one pass, 4912197 silesia, small chain log, advanced one pass, 4931148
silesia, explicit params, advanced one pass, 4795856 silesia, explicit params, advanced one pass, 4797095
silesia, uncompressed literals, advanced one pass, 5127982 silesia, uncompressed literals, advanced one pass, 5127982
silesia, uncompressed literals optimal, advanced one pass, 4317896 silesia, uncompressed literals optimal, advanced one pass, 4325472
silesia, huffman literals, advanced one pass, 5326268 silesia, huffman literals, advanced one pass, 5326268
silesia, multithreaded with advanced params, advanced one pass, 5127982 silesia, multithreaded with advanced params, advanced one pass, 5127982
silesia.tar, level -5, advanced one pass, 6738593 silesia.tar, level -5, advanced one pass, 6738593
@@ -267,29 +261,23 @@ silesia.tar, level 0, advanced
silesia.tar, level 1, advanced one pass, 5334885 silesia.tar, level 1, advanced one pass, 5334885
silesia.tar, level 3, advanced one pass, 4861425 silesia.tar, level 3, advanced one pass, 4861425
silesia.tar, level 4, advanced one pass, 4799630 silesia.tar, level 4, advanced one pass, 4799630
silesia.tar, level 5 row 1, advanced one pass, 4722324 silesia.tar, level 5, advanced one pass, 4722324
silesia.tar, level 5 row 2, advanced one pass, 4719256 silesia.tar, level 6, advanced one pass, 4672279
silesia.tar, level 5, advanced one pass, 4719256 silesia.tar, level 7, advanced one pass, 4606715
silesia.tar, level 6, advanced one pass, 4677721 silesia.tar, level 9, advanced one pass, 4554147
silesia.tar, level 7 row 1, advanced one pass, 4606715
silesia.tar, level 7 row 2, advanced one pass, 4613541
silesia.tar, level 7, advanced one pass, 4613541
silesia.tar, level 9, advanced one pass, 4555426
silesia.tar, level 12 row 1, advanced one pass, 4529459
silesia.tar, level 12 row 2, advanced one pass, 4530256
silesia.tar, level 13, advanced one pass, 4491764 silesia.tar, level 13, advanced one pass, 4491764
silesia.tar, level 16, advanced one pass, 4356827 silesia.tar, level 16, advanced one pass, 4381332
silesia.tar, level 19, advanced one pass, 4264487 silesia.tar, level 19, advanced one pass, 4281605
silesia.tar, no source size, advanced one pass, 4861425 silesia.tar, no source size, advanced one pass, 4861425
silesia.tar, long distance mode, advanced one pass, 4847754 silesia.tar, long distance mode, advanced one pass, 4847735
silesia.tar, multithreaded, advanced one pass, 4861508 silesia.tar, multithreaded, advanced one pass, 4861508
silesia.tar, multithreaded long distance mode, advanced one pass, 4853222 silesia.tar, multithreaded long distance mode, advanced one pass, 4853149
silesia.tar, small window log, advanced one pass, 7101530 silesia.tar, small window log, advanced one pass, 7101530
silesia.tar, small hash log, advanced one pass, 6529232 silesia.tar, small hash log, advanced one pass, 6587951
silesia.tar, small chain log, advanced one pass, 4917041 silesia.tar, small chain log, advanced one pass, 4943307
silesia.tar, explicit params, advanced one pass, 4807380 silesia.tar, explicit params, advanced one pass, 4808589
silesia.tar, uncompressed literals, advanced one pass, 5129458 silesia.tar, uncompressed literals, advanced one pass, 5129458
silesia.tar, uncompressed literals optimal, advanced one pass, 4307453 silesia.tar, uncompressed literals optimal, advanced one pass, 4320927
silesia.tar, huffman literals, advanced one pass, 5347335 silesia.tar, huffman literals, advanced one pass, 5347335
silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555
github, level -5, advanced one pass, 205285 github, level -5, advanced one pass, 205285
@@ -300,100 +288,26 @@ github, level -1, advanced
github, level -1 with dict, advanced one pass, 43170 github, level -1 with dict, advanced one pass, 43170
github, level 0, advanced one pass, 136335 github, level 0, advanced one pass, 136335
github, level 0 with dict, advanced one pass, 41148 github, level 0 with dict, advanced one pass, 41148
github, level 0 with dict dms, advanced one pass, 41148
github, level 0 with dict dds, advanced one pass, 41148
github, level 0 with dict copy, advanced one pass, 41124
github, level 0 with dict load, advanced one pass, 42252
github, level 1, advanced one pass, 142465 github, level 1, advanced one pass, 142465
github, level 1 with dict, advanced one pass, 41682 github, level 1 with dict, advanced one pass, 41682
github, level 1 with dict dms, advanced one pass, 41682
github, level 1 with dict dds, advanced one pass, 41682
github, level 1 with dict copy, advanced one pass, 41674
github, level 1 with dict load, advanced one pass, 43755
github, level 3, advanced one pass, 136335 github, level 3, advanced one pass, 136335
github, level 3 with dict, advanced one pass, 41148 github, level 3 with dict, advanced one pass, 41148
github, level 3 with dict dms, advanced one pass, 41148
github, level 3 with dict dds, advanced one pass, 41148
github, level 3 with dict copy, advanced one pass, 41124
github, level 3 with dict load, advanced one pass, 42252
github, level 4, advanced one pass, 136199 github, level 4, advanced one pass, 136199
github, level 4 with dict, advanced one pass, 41251 github, level 4 with dict, advanced one pass, 41251
github, level 4 with dict dms, advanced one pass, 41251
github, level 4 with dict dds, advanced one pass, 41251
github, level 4 with dict copy, advanced one pass, 41216
github, level 4 with dict load, advanced one pass, 41159
github, level 5 row 1, advanced one pass, 135121
github, level 5 row 1 with dict dms, advanced one pass, 38938
github, level 5 row 1 with dict dds, advanced one pass, 38732
github, level 5 row 1 with dict copy, advanced one pass, 38934
github, level 5 row 1 with dict load, advanced one pass, 40725
github, level 5 row 2, advanced one pass, 134584
github, level 5 row 2 with dict dms, advanced one pass, 38758
github, level 5 row 2 with dict dds, advanced one pass, 38728
github, level 5 row 2 with dict copy, advanced one pass, 38759
github, level 5 row 2 with dict load, advanced one pass, 41518
github, level 5, advanced one pass, 135121 github, level 5, advanced one pass, 135121
github, level 5 with dict, advanced one pass, 38758 github, level 5 with dict, advanced one pass, 38938
github, level 5 with dict dms, advanced one pass, 38758
github, level 5 with dict dds, advanced one pass, 38728
github, level 5 with dict copy, advanced one pass, 38759
github, level 5 with dict load, advanced one pass, 40725
github, level 6, advanced one pass, 135122 github, level 6, advanced one pass, 135122
github, level 6 with dict, advanced one pass, 38671 github, level 6 with dict, advanced one pass, 38632
github, level 6 with dict dms, advanced one pass, 38671
github, level 6 with dict dds, advanced one pass, 38630
github, level 6 with dict copy, advanced one pass, 38669
github, level 6 with dict load, advanced one pass, 40695
github, level 7 row 1, advanced one pass, 135122
github, level 7 row 1 with dict dms, advanced one pass, 38771
github, level 7 row 1 with dict dds, advanced one pass, 38771
github, level 7 row 1 with dict copy, advanced one pass, 38745
github, level 7 row 1 with dict load, advanced one pass, 40695
github, level 7 row 2, advanced one pass, 134584
github, level 7 row 2 with dict dms, advanced one pass, 38758
github, level 7 row 2 with dict dds, advanced one pass, 38747
github, level 7 row 2 with dict copy, advanced one pass, 38755
github, level 7 row 2 with dict load, advanced one pass, 41030
github, level 7, advanced one pass, 135122 github, level 7, advanced one pass, 135122
github, level 7 with dict, advanced one pass, 38758 github, level 7 with dict, advanced one pass, 38771
github, level 7 with dict dms, advanced one pass, 38758
github, level 7 with dict dds, advanced one pass, 38747
github, level 7 with dict copy, advanced one pass, 38755
github, level 7 with dict load, advanced one pass, 40695
github, level 9, advanced one pass, 135122 github, level 9, advanced one pass, 135122
github, level 9 with dict, advanced one pass, 39437 github, level 9 with dict, advanced one pass, 39332
github, level 9 with dict dms, advanced one pass, 39437
github, level 9 with dict dds, advanced one pass, 39338
github, level 9 with dict copy, advanced one pass, 39398
github, level 9 with dict load, advanced one pass, 41710
github, level 12 row 1, advanced one pass, 134180
github, level 12 row 1 with dict dms, advanced one pass, 39677
github, level 12 row 1 with dict dds, advanced one pass, 39677
github, level 12 row 1 with dict copy, advanced one pass, 39677
github, level 12 row 1 with dict load, advanced one pass, 41166
github, level 12 row 2, advanced one pass, 134180
github, level 12 row 2 with dict dms, advanced one pass, 39677
github, level 12 row 2 with dict dds, advanced one pass, 39677
github, level 12 row 2 with dict copy, advanced one pass, 39677
github, level 12 row 2 with dict load, advanced one pass, 41166
github, level 13, advanced one pass, 134064 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 13 with dict dms, advanced one pass, 39743
github, level 13 with dict dds, advanced one pass, 39743
github, level 13 with dict copy, advanced one pass, 39948
github, level 13 with dict load, advanced one pass, 42626
github, level 16, advanced one pass, 134064 github, level 16, advanced one pass, 134064
github, level 16 with dict, advanced one pass, 37577 github, level 16 with dict, advanced one pass, 37577
github, level 16 with dict dms, advanced one pass, 37577
github, level 16 with dict dds, advanced one pass, 37577
github, level 16 with dict copy, advanced one pass, 37568
github, level 16 with dict load, advanced one pass, 42340
github, level 19, advanced one pass, 134064 github, level 19, advanced one pass, 134064
github, level 19 with dict, advanced one pass, 37576 github, level 19 with dict, advanced one pass, 37576
github, level 19 with dict dms, advanced one pass, 37576
github, level 19 with dict dds, advanced one pass, 37576
github, level 19 with dict copy, advanced one pass, 37567
github, level 19 with dict load, advanced one pass, 39613
github, no source size, advanced one pass, 136335 github, no source size, advanced one pass, 136335
github, no source size with dict, advanced one pass, 41148 github, no source size with dict, advanced one pass, 41148
github, long distance mode, advanced one pass, 136335 github, long distance mode, advanced one pass, 136335
@@ -408,116 +322,42 @@ github, uncompressed literals optimal, advanced
github, huffman literals, advanced one pass, 142465 github, huffman literals, advanced one pass, 142465
github, multithreaded with advanced params, advanced one pass, 165915 github, multithreaded with advanced params, advanced one pass, 165915
github.tar, level -5, advanced one pass, 46856 github.tar, level -5, advanced one pass, 46856
github.tar, level -5 with dict, advanced one pass, 44571 github.tar, level -5 with dict, advanced one pass, 43971
github.tar, level -3, advanced one pass, 43754 github.tar, level -3, advanced one pass, 43754
github.tar, level -3 with dict, advanced one pass, 41447 github.tar, level -3 with dict, advanced one pass, 40805
github.tar, level -1, advanced one pass, 42490 github.tar, level -1, advanced one pass, 42490
github.tar, level -1 with dict, advanced one pass, 41131 github.tar, level -1 with dict, advanced one pass, 41122
github.tar, level 0, advanced one pass, 38441 github.tar, level 0, advanced one pass, 38441
github.tar, level 0 with dict, advanced one pass, 37995 github.tar, level 0 with dict, advanced one pass, 37995
github.tar, level 0 with dict dms, advanced one pass, 38003
github.tar, level 0 with dict dds, advanced one pass, 38003
github.tar, level 0 with dict copy, advanced one pass, 37995
github.tar, level 0 with dict load, advanced one pass, 37956
github.tar, level 1, advanced one pass, 39265 github.tar, level 1, advanced one pass, 39265
github.tar, level 1 with dict, advanced one pass, 38280 github.tar, level 1 with dict, advanced one pass, 38309
github.tar, level 1 with dict dms, advanced one pass, 38290
github.tar, level 1 with dict dds, advanced one pass, 38290
github.tar, level 1 with dict copy, advanced one pass, 38280
github.tar, level 1 with dict load, advanced one pass, 38729
github.tar, level 3, advanced one pass, 38441 github.tar, level 3, advanced one pass, 38441
github.tar, level 3 with dict, advanced one pass, 37995 github.tar, level 3 with dict, advanced one pass, 37995
github.tar, level 3 with dict dms, advanced one pass, 38003
github.tar, level 3 with dict dds, advanced one pass, 38003
github.tar, level 3 with dict copy, advanced one pass, 37995
github.tar, level 3 with dict load, advanced one pass, 37956
github.tar, level 4, advanced one pass, 38467 github.tar, level 4, advanced one pass, 38467
github.tar, level 4 with dict, advanced one pass, 37948 github.tar, level 4 with dict, advanced one pass, 37948
github.tar, level 4 with dict dms, advanced one pass, 37954 github.tar, level 5, advanced one pass, 39788
github.tar, level 4 with dict dds, advanced one pass, 37954 github.tar, level 5 with dict, advanced one pass, 39715
github.tar, level 4 with dict copy, advanced one pass, 37948 github.tar, level 6, advanced one pass, 39603
github.tar, level 4 with dict load, advanced one pass, 37927 github.tar, level 6 with dict, advanced one pass, 38800
github.tar, level 5 row 1, advanced one pass, 39788 github.tar, level 7, advanced one pass, 39206
github.tar, level 5 row 1 with dict dms, advanced one pass, 39365 github.tar, level 7 with dict, advanced one pass, 38071
github.tar, level 5 row 1 with dict dds, advanced one pass, 39233 github.tar, level 9, advanced one pass, 36717
github.tar, level 5 row 1 with dict copy, advanced one pass, 39715 github.tar, level 9 with dict, advanced one pass, 36898
github.tar, level 5 row 1 with dict load, advanced one pass, 39209
github.tar, level 5 row 2, advanced one pass, 39693
github.tar, level 5 row 2 with dict dms, advanced one pass, 39024
github.tar, level 5 row 2 with dict dds, advanced one pass, 39028
github.tar, level 5 row 2 with dict copy, advanced one pass, 39040
github.tar, level 5 row 2 with dict load, advanced one pass, 39037
github.tar, level 5, advanced one pass, 39693
github.tar, level 5 with dict, advanced one pass, 39040
github.tar, level 5 with dict dms, advanced one pass, 39024
github.tar, level 5 with dict dds, advanced one pass, 39028
github.tar, level 5 with dict copy, advanced one pass, 39040
github.tar, level 5 with dict load, advanced one pass, 39037
github.tar, level 6, advanced one pass, 39621
github.tar, level 6 with dict, advanced one pass, 38622
github.tar, level 6 with dict dms, advanced one pass, 38608
github.tar, level 6 with dict dds, advanced one pass, 38610
github.tar, level 6 with dict copy, advanced one pass, 38622
github.tar, level 6 with dict load, advanced one pass, 38962
github.tar, level 7 row 1, advanced one pass, 39206
github.tar, level 7 row 1 with dict dms, advanced one pass, 37954
github.tar, level 7 row 1 with dict dds, advanced one pass, 37954
github.tar, level 7 row 1 with dict copy, advanced one pass, 38071
github.tar, level 7 row 1 with dict load, advanced one pass, 38584
github.tar, level 7 row 2, advanced one pass, 39213
github.tar, level 7 row 2 with dict dms, advanced one pass, 37848
github.tar, level 7 row 2 with dict dds, advanced one pass, 37867
github.tar, level 7 row 2 with dict copy, advanced one pass, 37848
github.tar, level 7 row 2 with dict load, advanced one pass, 38582
github.tar, level 7, advanced one pass, 39213
github.tar, level 7 with dict, advanced one pass, 37848
github.tar, level 7 with dict dms, advanced one pass, 37848
github.tar, level 7 with dict dds, advanced one pass, 37867
github.tar, level 7 with dict copy, advanced one pass, 37848
github.tar, level 7 with dict load, advanced one pass, 38582
github.tar, level 9, advanced one pass, 36758
github.tar, level 9 with dict, advanced one pass, 36457
github.tar, level 9 with dict dms, advanced one pass, 36549
github.tar, level 9 with dict dds, advanced one pass, 36637
github.tar, level 9 with dict copy, advanced one pass, 36457
github.tar, level 9 with dict load, advanced one pass, 36350
github.tar, level 12 row 1, advanced one pass, 36435
github.tar, level 12 row 1 with dict dms, advanced one pass, 36986
github.tar, level 12 row 1 with dict dds, advanced one pass, 36986
github.tar, level 12 row 1 with dict copy, advanced one pass, 36609
github.tar, level 12 row 1 with dict load, advanced one pass, 36419
github.tar, level 12 row 2, advanced one pass, 36435
github.tar, level 12 row 2 with dict dms, advanced one pass, 36986
github.tar, level 12 row 2 with dict dds, advanced one pass, 36986
github.tar, level 12 row 2 with dict copy, advanced one pass, 36609
github.tar, level 12 row 2 with dict load, advanced one pass, 36424
github.tar, level 13, advanced one pass, 35621 github.tar, level 13, advanced one pass, 35621
github.tar, level 13 with dict, advanced one pass, 38726 github.tar, level 13 with dict, advanced one pass, 38726
github.tar, level 13 with dict dms, advanced one pass, 38903
github.tar, level 13 with dict dds, advanced one pass, 38903
github.tar, level 13 with dict copy, advanced one pass, 38726
github.tar, level 13 with dict load, advanced one pass, 36372
github.tar, level 16, advanced one pass, 40255 github.tar, level 16, advanced one pass, 40255
github.tar, level 16 with dict, advanced one pass, 33639 github.tar, level 16 with dict, advanced one pass, 33639
github.tar, level 16 with dict dms, advanced one pass, 33544
github.tar, level 16 with dict dds, advanced one pass, 33544
github.tar, level 16 with dict copy, advanced one pass, 33639
github.tar, level 16 with dict load, advanced one pass, 39353
github.tar, level 19, advanced one pass, 32837 github.tar, level 19, advanced one pass, 32837
github.tar, level 19 with dict, advanced one pass, 32895 github.tar, level 19 with dict, advanced one pass, 32895
github.tar, level 19 with dict dms, advanced one pass, 32672
github.tar, level 19 with dict dds, advanced one pass, 32672
github.tar, level 19 with dict copy, advanced one pass, 32895
github.tar, level 19 with dict load, advanced one pass, 32676
github.tar, no source size, advanced one pass, 38441 github.tar, no source size, advanced one pass, 38441
github.tar, no source size with dict, advanced one pass, 37995 github.tar, no source size with dict, advanced one pass, 37995
github.tar, long distance mode, advanced one pass, 39757 github.tar, long distance mode, advanced one pass, 39722
github.tar, multithreaded, advanced one pass, 38441 github.tar, multithreaded, advanced one pass, 38441
github.tar, multithreaded long distance mode, advanced one pass, 39726 github.tar, multithreaded long distance mode, advanced one pass, 39722
github.tar, small window log, advanced one pass, 198540 github.tar, small window log, advanced one pass, 198540
github.tar, small hash log, advanced one pass, 129870 github.tar, small hash log, advanced one pass, 129870
github.tar, small chain log, advanced one pass, 41669 github.tar, small chain log, advanced one pass, 41669
github.tar, explicit params, advanced one pass, 41227 github.tar, explicit params, advanced one pass, 41199
github.tar, uncompressed literals, advanced one pass, 41122 github.tar, uncompressed literals, advanced one pass, 41122
github.tar, uncompressed literals optimal, advanced one pass, 35388 github.tar, uncompressed literals optimal, advanced one pass, 35388
github.tar, huffman literals, advanced one pass, 38777 github.tar, huffman literals, advanced one pass, 38777
@@ -529,29 +369,23 @@ silesia, level 0, advanced
silesia, level 1, advanced one pass small out, 5313204 silesia, level 1, advanced one pass small out, 5313204
silesia, level 3, advanced one pass small out, 4849552 silesia, level 3, advanced one pass small out, 4849552
silesia, level 4, advanced one pass small out, 4786970 silesia, level 4, advanced one pass small out, 4786970
silesia, level 5 row 1, advanced one pass small out, 4710236 silesia, level 5, advanced one pass small out, 4710236
silesia, level 5 row 2, advanced one pass small out, 4707794 silesia, level 6, advanced one pass small out, 4660056
silesia, level 5, advanced one pass small out, 4707794 silesia, level 7, advanced one pass small out, 4596296
silesia, level 6, advanced one pass small out, 4666383 silesia, level 9, advanced one pass small out, 4543925
silesia, level 7 row 1, advanced one pass small out, 4596296
silesia, level 7 row 2, advanced one pass small out, 4603381
silesia, level 7, advanced one pass small out, 4603381
silesia, level 9, advanced one pass small out, 4546001
silesia, level 12 row 1, advanced one pass small out, 4519288
silesia, level 12 row 2, advanced one pass small out, 4521397
silesia, level 13, advanced one pass small out, 4482135 silesia, level 13, advanced one pass small out, 4482135
silesia, level 16, advanced one pass small out, 4360251 silesia, level 16, advanced one pass small out, 4377465
silesia, level 19, advanced one pass small out, 4283237 silesia, level 19, advanced one pass small out, 4293330
silesia, no source size, advanced one pass small out, 4849552 silesia, no source size, advanced one pass small out, 4849552
silesia, long distance mode, advanced one pass small out, 4840738 silesia, long distance mode, advanced one pass small out, 4840744
silesia, multithreaded, advanced one pass small out, 4849552 silesia, multithreaded, advanced one pass small out, 4849552
silesia, multithreaded long distance mode, advanced one pass small out, 4840758 silesia, multithreaded long distance mode, advanced one pass small out, 4840744
silesia, small window log, advanced one pass small out, 7095919 silesia, small window log, advanced one pass small out, 7095919
silesia, small hash log, advanced one pass small out, 6526141 silesia, small hash log, advanced one pass small out, 6555021
silesia, small chain log, advanced one pass small out, 4912197 silesia, small chain log, advanced one pass small out, 4931148
silesia, explicit params, advanced one pass small out, 4795856 silesia, explicit params, advanced one pass small out, 4797095
silesia, uncompressed literals, advanced one pass small out, 5127982 silesia, uncompressed literals, advanced one pass small out, 5127982
silesia, uncompressed literals optimal, advanced one pass small out, 4317896 silesia, uncompressed literals optimal, advanced one pass small out, 4325472
silesia, huffman literals, advanced one pass small out, 5326268 silesia, huffman literals, advanced one pass small out, 5326268
silesia, multithreaded with advanced params, advanced one pass small out, 5127982 silesia, multithreaded with advanced params, advanced one pass small out, 5127982
silesia.tar, level -5, advanced one pass small out, 6738593 silesia.tar, level -5, advanced one pass small out, 6738593
@@ -561,29 +395,23 @@ silesia.tar, level 0, advanced
silesia.tar, level 1, advanced one pass small out, 5334885 silesia.tar, level 1, advanced one pass small out, 5334885
silesia.tar, level 3, advanced one pass small out, 4861425 silesia.tar, level 3, advanced one pass small out, 4861425
silesia.tar, level 4, advanced one pass small out, 4799630 silesia.tar, level 4, advanced one pass small out, 4799630
silesia.tar, level 5 row 1, advanced one pass small out, 4722324 silesia.tar, level 5, advanced one pass small out, 4722324
silesia.tar, level 5 row 2, advanced one pass small out, 4719256 silesia.tar, level 6, advanced one pass small out, 4672279
silesia.tar, level 5, advanced one pass small out, 4719256 silesia.tar, level 7, advanced one pass small out, 4606715
silesia.tar, level 6, advanced one pass small out, 4677721 silesia.tar, level 9, advanced one pass small out, 4554147
silesia.tar, level 7 row 1, advanced one pass small out, 4606715
silesia.tar, level 7 row 2, advanced one pass small out, 4613541
silesia.tar, level 7, advanced one pass small out, 4613541
silesia.tar, level 9, advanced one pass small out, 4555426
silesia.tar, level 12 row 1, advanced one pass small out, 4529459
silesia.tar, level 12 row 2, advanced one pass small out, 4530256
silesia.tar, level 13, advanced one pass small out, 4491764 silesia.tar, level 13, advanced one pass small out, 4491764
silesia.tar, level 16, advanced one pass small out, 4356827 silesia.tar, level 16, advanced one pass small out, 4381332
silesia.tar, level 19, advanced one pass small out, 4264487 silesia.tar, level 19, advanced one pass small out, 4281605
silesia.tar, no source size, advanced one pass small out, 4861425 silesia.tar, no source size, advanced one pass small out, 4861425
silesia.tar, long distance mode, advanced one pass small out, 4847754 silesia.tar, long distance mode, advanced one pass small out, 4847735
silesia.tar, multithreaded, advanced one pass small out, 4861508 silesia.tar, multithreaded, advanced one pass small out, 4861508
silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853222 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 window log, advanced one pass small out, 7101530
silesia.tar, small hash log, advanced one pass small out, 6529232 silesia.tar, small hash log, advanced one pass small out, 6587951
silesia.tar, small chain log, advanced one pass small out, 4917041 silesia.tar, small chain log, advanced one pass small out, 4943307
silesia.tar, explicit params, advanced one pass small out, 4807380 silesia.tar, explicit params, advanced one pass small out, 4808589
silesia.tar, uncompressed literals, advanced one pass small out, 5129458 silesia.tar, uncompressed literals, advanced one pass small out, 5129458
silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307453 silesia.tar, uncompressed literals optimal, advanced one pass small out, 4320927
silesia.tar, huffman literals, advanced one pass small out, 5347335 silesia.tar, huffman literals, advanced one pass small out, 5347335
silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555
github, level -5, advanced one pass small out, 205285 github, level -5, advanced one pass small out, 205285
@@ -594,100 +422,26 @@ github, level -1, advanced
github, level -1 with dict, advanced one pass small out, 43170 github, level -1 with dict, advanced one pass small out, 43170
github, level 0, advanced one pass small out, 136335 github, level 0, advanced one pass small out, 136335
github, level 0 with dict, advanced one pass small out, 41148 github, level 0 with dict, advanced one pass small out, 41148
github, level 0 with dict dms, advanced one pass small out, 41148
github, level 0 with dict dds, advanced one pass small out, 41148
github, level 0 with dict copy, advanced one pass small out, 41124
github, level 0 with dict load, advanced one pass small out, 42252
github, level 1, advanced one pass small out, 142465 github, level 1, advanced one pass small out, 142465
github, level 1 with dict, advanced one pass small out, 41682 github, level 1 with dict, advanced one pass small out, 41682
github, level 1 with dict dms, advanced one pass small out, 41682
github, level 1 with dict dds, advanced one pass small out, 41682
github, level 1 with dict copy, advanced one pass small out, 41674
github, level 1 with dict load, advanced one pass small out, 43755
github, level 3, advanced one pass small out, 136335 github, level 3, advanced one pass small out, 136335
github, level 3 with dict, advanced one pass small out, 41148 github, level 3 with dict, advanced one pass small out, 41148
github, level 3 with dict dms, advanced one pass small out, 41148
github, level 3 with dict dds, advanced one pass small out, 41148
github, level 3 with dict copy, advanced one pass small out, 41124
github, level 3 with dict load, advanced one pass small out, 42252
github, level 4, advanced one pass small out, 136199 github, level 4, advanced one pass small out, 136199
github, level 4 with dict, advanced one pass small out, 41251 github, level 4 with dict, advanced one pass small out, 41251
github, level 4 with dict dms, advanced one pass small out, 41251
github, level 4 with dict dds, advanced one pass small out, 41251
github, level 4 with dict copy, advanced one pass small out, 41216
github, level 4 with dict load, advanced one pass small out, 41159
github, level 5 row 1, advanced one pass small out, 135121
github, level 5 row 1 with dict dms, advanced one pass small out, 38938
github, level 5 row 1 with dict dds, advanced one pass small out, 38732
github, level 5 row 1 with dict copy, advanced one pass small out, 38934
github, level 5 row 1 with dict load, advanced one pass small out, 40725
github, level 5 row 2, advanced one pass small out, 134584
github, level 5 row 2 with dict dms, advanced one pass small out, 38758
github, level 5 row 2 with dict dds, advanced one pass small out, 38728
github, level 5 row 2 with dict copy, advanced one pass small out, 38759
github, level 5 row 2 with dict load, advanced one pass small out, 41518
github, level 5, advanced one pass small out, 135121 github, level 5, advanced one pass small out, 135121
github, level 5 with dict, advanced one pass small out, 38758 github, level 5 with dict, advanced one pass small out, 38938
github, level 5 with dict dms, advanced one pass small out, 38758
github, level 5 with dict dds, advanced one pass small out, 38728
github, level 5 with dict copy, advanced one pass small out, 38759
github, level 5 with dict load, advanced one pass small out, 40725
github, level 6, advanced one pass small out, 135122 github, level 6, advanced one pass small out, 135122
github, level 6 with dict, advanced one pass small out, 38671 github, level 6 with dict, advanced one pass small out, 38632
github, level 6 with dict dms, advanced one pass small out, 38671
github, level 6 with dict dds, advanced one pass small out, 38630
github, level 6 with dict copy, advanced one pass small out, 38669
github, level 6 with dict load, advanced one pass small out, 40695
github, level 7 row 1, advanced one pass small out, 135122
github, level 7 row 1 with dict dms, advanced one pass small out, 38771
github, level 7 row 1 with dict dds, advanced one pass small out, 38771
github, level 7 row 1 with dict copy, advanced one pass small out, 38745
github, level 7 row 1 with dict load, advanced one pass small out, 40695
github, level 7 row 2, advanced one pass small out, 134584
github, level 7 row 2 with dict dms, advanced one pass small out, 38758
github, level 7 row 2 with dict dds, advanced one pass small out, 38747
github, level 7 row 2 with dict copy, advanced one pass small out, 38755
github, level 7 row 2 with dict load, advanced one pass small out, 41030
github, level 7, advanced one pass small out, 135122 github, level 7, advanced one pass small out, 135122
github, level 7 with dict, advanced one pass small out, 38758 github, level 7 with dict, advanced one pass small out, 38771
github, level 7 with dict dms, advanced one pass small out, 38758
github, level 7 with dict dds, advanced one pass small out, 38747
github, level 7 with dict copy, advanced one pass small out, 38755
github, level 7 with dict load, advanced one pass small out, 40695
github, level 9, advanced one pass small out, 135122 github, level 9, advanced one pass small out, 135122
github, level 9 with dict, advanced one pass small out, 39437 github, level 9 with dict, advanced one pass small out, 39332
github, level 9 with dict dms, advanced one pass small out, 39437
github, level 9 with dict dds, advanced one pass small out, 39338
github, level 9 with dict copy, advanced one pass small out, 39398
github, level 9 with dict load, advanced one pass small out, 41710
github, level 12 row 1, advanced one pass small out, 134180
github, level 12 row 1 with dict dms, advanced one pass small out, 39677
github, level 12 row 1 with dict dds, advanced one pass small out, 39677
github, level 12 row 1 with dict copy, advanced one pass small out, 39677
github, level 12 row 1 with dict load, advanced one pass small out, 41166
github, level 12 row 2, advanced one pass small out, 134180
github, level 12 row 2 with dict dms, advanced one pass small out, 39677
github, level 12 row 2 with dict dds, advanced one pass small out, 39677
github, level 12 row 2 with dict copy, advanced one pass small out, 39677
github, level 12 row 2 with dict load, advanced one pass small out, 41166
github, level 13, advanced one pass small out, 134064 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 13 with dict dms, advanced one pass small out, 39743
github, level 13 with dict dds, advanced one pass small out, 39743
github, level 13 with dict copy, advanced one pass small out, 39948
github, level 13 with dict load, advanced one pass small out, 42626
github, level 16, advanced one pass small out, 134064 github, level 16, advanced one pass small out, 134064
github, level 16 with dict, advanced one pass small out, 37577 github, level 16 with dict, advanced one pass small out, 37577
github, level 16 with dict dms, advanced one pass small out, 37577
github, level 16 with dict dds, advanced one pass small out, 37577
github, level 16 with dict copy, advanced one pass small out, 37568
github, level 16 with dict load, advanced one pass small out, 42340
github, level 19, advanced one pass small out, 134064 github, level 19, advanced one pass small out, 134064
github, level 19 with dict, advanced one pass small out, 37576 github, level 19 with dict, advanced one pass small out, 37576
github, level 19 with dict dms, advanced one pass small out, 37576
github, level 19 with dict dds, advanced one pass small out, 37576
github, level 19 with dict copy, advanced one pass small out, 37567
github, level 19 with dict load, advanced one pass small out, 39613
github, no source size, advanced one pass small out, 136335 github, no source size, advanced one pass small out, 136335
github, no source size with dict, advanced one pass small out, 41148 github, no source size with dict, advanced one pass small out, 41148
github, long distance mode, advanced one pass small out, 136335 github, long distance mode, advanced one pass small out, 136335
@@ -702,116 +456,42 @@ github, uncompressed literals optimal, advanced
github, huffman literals, advanced one pass small out, 142465 github, huffman literals, advanced one pass small out, 142465
github, multithreaded with advanced params, advanced one pass small out, 165915 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, advanced one pass small out, 46856
github.tar, level -5 with dict, advanced one pass small out, 44571 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, advanced one pass small out, 43754
github.tar, level -3 with dict, advanced one pass small out, 41447 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, advanced one pass small out, 42490
github.tar, level -1 with dict, advanced one pass small out, 41131 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, advanced one pass small out, 38441
github.tar, level 0 with dict, advanced one pass small out, 37995 github.tar, level 0 with dict, advanced one pass small out, 37995
github.tar, level 0 with dict dms, advanced one pass small out, 38003
github.tar, level 0 with dict dds, advanced one pass small out, 38003
github.tar, level 0 with dict copy, advanced one pass small out, 37995
github.tar, level 0 with dict load, advanced one pass small out, 37956
github.tar, level 1, advanced one pass small out, 39265 github.tar, level 1, advanced one pass small out, 39265
github.tar, level 1 with dict, advanced one pass small out, 38280 github.tar, level 1 with dict, advanced one pass small out, 38309
github.tar, level 1 with dict dms, advanced one pass small out, 38290
github.tar, level 1 with dict dds, advanced one pass small out, 38290
github.tar, level 1 with dict copy, advanced one pass small out, 38280
github.tar, level 1 with dict load, advanced one pass small out, 38729
github.tar, level 3, advanced one pass small out, 38441 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 3 with dict, advanced one pass small out, 37995
github.tar, level 3 with dict dms, advanced one pass small out, 38003
github.tar, level 3 with dict dds, advanced one pass small out, 38003
github.tar, level 3 with dict copy, advanced one pass small out, 37995
github.tar, level 3 with dict load, advanced one pass small out, 37956
github.tar, level 4, advanced one pass small out, 38467 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 4 with dict, advanced one pass small out, 37948
github.tar, level 4 with dict dms, advanced one pass small out, 37954 github.tar, level 5, advanced one pass small out, 39788
github.tar, level 4 with dict dds, advanced one pass small out, 37954 github.tar, level 5 with dict, advanced one pass small out, 39715
github.tar, level 4 with dict copy, advanced one pass small out, 37948 github.tar, level 6, advanced one pass small out, 39603
github.tar, level 4 with dict load, advanced one pass small out, 37927 github.tar, level 6 with dict, advanced one pass small out, 38800
github.tar, level 5 row 1, advanced one pass small out, 39788 github.tar, level 7, advanced one pass small out, 39206
github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39365 github.tar, level 7 with dict, advanced one pass small out, 38071
github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39233 github.tar, level 9, advanced one pass small out, 36717
github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39715 github.tar, level 9 with dict, advanced one pass small out, 36898
github.tar, level 5 row 1 with dict load, advanced one pass small out, 39209
github.tar, level 5 row 2, advanced one pass small out, 39693
github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39024
github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39028
github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39040
github.tar, level 5 row 2 with dict load, advanced one pass small out, 39037
github.tar, level 5, advanced one pass small out, 39693
github.tar, level 5 with dict, advanced one pass small out, 39040
github.tar, level 5 with dict dms, advanced one pass small out, 39024
github.tar, level 5 with dict dds, advanced one pass small out, 39028
github.tar, level 5 with dict copy, advanced one pass small out, 39040
github.tar, level 5 with dict load, advanced one pass small out, 39037
github.tar, level 6, advanced one pass small out, 39621
github.tar, level 6 with dict, advanced one pass small out, 38622
github.tar, level 6 with dict dms, advanced one pass small out, 38608
github.tar, level 6 with dict dds, advanced one pass small out, 38610
github.tar, level 6 with dict copy, advanced one pass small out, 38622
github.tar, level 6 with dict load, advanced one pass small out, 38962
github.tar, level 7 row 1, advanced one pass small out, 39206
github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37954
github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37954
github.tar, level 7 row 1 with dict copy, advanced one pass small out, 38071
github.tar, level 7 row 1 with dict load, advanced one pass small out, 38584
github.tar, level 7 row 2, advanced one pass small out, 39213
github.tar, level 7 row 2 with dict dms, advanced one pass small out, 37848
github.tar, level 7 row 2 with dict dds, advanced one pass small out, 37867
github.tar, level 7 row 2 with dict copy, advanced one pass small out, 37848
github.tar, level 7 row 2 with dict load, advanced one pass small out, 38582
github.tar, level 7, advanced one pass small out, 39213
github.tar, level 7 with dict, advanced one pass small out, 37848
github.tar, level 7 with dict dms, advanced one pass small out, 37848
github.tar, level 7 with dict dds, advanced one pass small out, 37867
github.tar, level 7 with dict copy, advanced one pass small out, 37848
github.tar, level 7 with dict load, advanced one pass small out, 38582
github.tar, level 9, advanced one pass small out, 36758
github.tar, level 9 with dict, advanced one pass small out, 36457
github.tar, level 9 with dict dms, advanced one pass small out, 36549
github.tar, level 9 with dict dds, advanced one pass small out, 36637
github.tar, level 9 with dict copy, advanced one pass small out, 36457
github.tar, level 9 with dict load, advanced one pass small out, 36350
github.tar, level 12 row 1, advanced one pass small out, 36435
github.tar, level 12 row 1 with dict dms, advanced one pass small out, 36986
github.tar, level 12 row 1 with dict dds, advanced one pass small out, 36986
github.tar, level 12 row 1 with dict copy, advanced one pass small out, 36609
github.tar, level 12 row 1 with dict load, advanced one pass small out, 36419
github.tar, level 12 row 2, advanced one pass small out, 36435
github.tar, level 12 row 2 with dict dms, advanced one pass small out, 36986
github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986
github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609
github.tar, level 12 row 2 with dict load, advanced one pass small out, 36424
github.tar, level 13, advanced one pass small out, 35621 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 13 with dict, advanced one pass small out, 38726
github.tar, level 13 with dict dms, advanced one pass small out, 38903
github.tar, level 13 with dict dds, advanced one pass small out, 38903
github.tar, level 13 with dict copy, advanced one pass small out, 38726
github.tar, level 13 with dict load, advanced one pass small out, 36372
github.tar, level 16, advanced one pass small out, 40255 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 16 with dict, advanced one pass small out, 33639
github.tar, level 16 with dict dms, advanced one pass small out, 33544
github.tar, level 16 with dict dds, advanced one pass small out, 33544
github.tar, level 16 with dict copy, advanced one pass small out, 33639
github.tar, level 16 with dict load, advanced one pass small out, 39353
github.tar, level 19, advanced one pass small out, 32837 github.tar, level 19, advanced one pass small out, 32837
github.tar, level 19 with dict, advanced one pass small out, 32895 github.tar, level 19 with dict, advanced one pass small out, 32895
github.tar, level 19 with dict dms, advanced one pass small out, 32672
github.tar, level 19 with dict dds, advanced one pass small out, 32672
github.tar, level 19 with dict copy, advanced one pass small out, 32895
github.tar, level 19 with dict load, advanced one pass small out, 32676
github.tar, no source size, advanced one pass small out, 38441 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, no source size with dict, advanced one pass small out, 37995
github.tar, long distance mode, advanced one pass small out, 39757 github.tar, long distance mode, advanced one pass small out, 39722
github.tar, multithreaded, advanced one pass small out, 38441 github.tar, multithreaded, advanced one pass small out, 38441
github.tar, multithreaded long distance mode, advanced one pass small out, 39726 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 window log, advanced one pass small out, 198540
github.tar, small hash log, advanced one pass small out, 129870 github.tar, small hash log, advanced one pass small out, 129870
github.tar, small chain log, advanced one pass small out, 41669 github.tar, small chain log, advanced one pass small out, 41669
github.tar, explicit params, advanced one pass small out, 41227 github.tar, explicit params, advanced one pass small out, 41199
github.tar, uncompressed literals, advanced one pass small out, 41122 github.tar, uncompressed literals, advanced one pass small out, 41122
github.tar, uncompressed literals optimal, advanced one pass small out, 35388 github.tar, uncompressed literals optimal, advanced one pass small out, 35388
github.tar, huffman literals, advanced one pass small out, 38777 github.tar, huffman literals, advanced one pass small out, 38777
@@ -823,29 +503,23 @@ silesia, level 0, advanced
silesia, level 1, advanced streaming, 5314162 silesia, level 1, advanced streaming, 5314162
silesia, level 3, advanced streaming, 4849552 silesia, level 3, advanced streaming, 4849552
silesia, level 4, advanced streaming, 4786970 silesia, level 4, advanced streaming, 4786970
silesia, level 5 row 1, advanced streaming, 4710236 silesia, level 5, advanced streaming, 4710236
silesia, level 5 row 2, advanced streaming, 4707794 silesia, level 6, advanced streaming, 4660056
silesia, level 5, advanced streaming, 4707794 silesia, level 7, advanced streaming, 4596296
silesia, level 6, advanced streaming, 4666383 silesia, level 9, advanced streaming, 4543925
silesia, level 7 row 1, advanced streaming, 4596296
silesia, level 7 row 2, advanced streaming, 4603381
silesia, level 7, advanced streaming, 4603381
silesia, level 9, advanced streaming, 4546001
silesia, level 12 row 1, advanced streaming, 4519288
silesia, level 12 row 2, advanced streaming, 4521397
silesia, level 13, advanced streaming, 4482135 silesia, level 13, advanced streaming, 4482135
silesia, level 16, advanced streaming, 4360251 silesia, level 16, advanced streaming, 4377465
silesia, level 19, advanced streaming, 4283237 silesia, level 19, advanced streaming, 4293330
silesia, no source size, advanced streaming, 4849516 silesia, no source size, advanced streaming, 4849516
silesia, long distance mode, advanced streaming, 4840738 silesia, long distance mode, advanced streaming, 4840744
silesia, multithreaded, advanced streaming, 4849552 silesia, multithreaded, advanced streaming, 4849552
silesia, multithreaded long distance mode, advanced streaming, 4840758 silesia, multithreaded long distance mode, advanced streaming, 4840744
silesia, small window log, advanced streaming, 7112062 silesia, small window log, advanced streaming, 7112062
silesia, small hash log, advanced streaming, 6526141 silesia, small hash log, advanced streaming, 6555021
silesia, small chain log, advanced streaming, 4912197 silesia, small chain log, advanced streaming, 4931148
silesia, explicit params, advanced streaming, 4795887 silesia, explicit params, advanced streaming, 4797112
silesia, uncompressed literals, advanced streaming, 5127982 silesia, uncompressed literals, advanced streaming, 5127982
silesia, uncompressed literals optimal, advanced streaming, 4317896 silesia, uncompressed literals optimal, advanced streaming, 4325472
silesia, huffman literals, advanced streaming, 5331168 silesia, huffman literals, advanced streaming, 5331168
silesia, multithreaded with advanced params, advanced streaming, 5127982 silesia, multithreaded with advanced params, advanced streaming, 5127982
silesia.tar, level -5, advanced streaming, 6982759 silesia.tar, level -5, advanced streaming, 6982759
@@ -855,29 +529,23 @@ silesia.tar, level 0, advanced
silesia.tar, level 1, advanced streaming, 5336939 silesia.tar, level 1, advanced streaming, 5336939
silesia.tar, level 3, advanced streaming, 4861427 silesia.tar, level 3, advanced streaming, 4861427
silesia.tar, level 4, advanced streaming, 4799630 silesia.tar, level 4, advanced streaming, 4799630
silesia.tar, level 5 row 1, advanced streaming, 4722329 silesia.tar, level 5, advanced streaming, 4722329
silesia.tar, level 5 row 2, advanced streaming, 4719261 silesia.tar, level 6, advanced streaming, 4672288
silesia.tar, level 5, advanced streaming, 4719261 silesia.tar, level 7, advanced streaming, 4606715
silesia.tar, level 6, advanced streaming, 4677729 silesia.tar, level 9, advanced streaming, 4554154
silesia.tar, level 7 row 1, advanced streaming, 4606715
silesia.tar, level 7 row 2, advanced streaming, 4613544
silesia.tar, level 7, advanced streaming, 4613544
silesia.tar, level 9, advanced streaming, 4555432
silesia.tar, level 12 row 1, advanced streaming, 4529459
silesia.tar, level 12 row 2, advanced streaming, 4530258
silesia.tar, level 13, advanced streaming, 4491765 silesia.tar, level 13, advanced streaming, 4491765
silesia.tar, level 16, advanced streaming, 4356834 silesia.tar, level 16, advanced streaming, 4381350
silesia.tar, level 19, advanced streaming, 4264392 silesia.tar, level 19, advanced streaming, 4281562
silesia.tar, no source size, advanced streaming, 4861423 silesia.tar, no source size, advanced streaming, 4861423
silesia.tar, long distance mode, advanced streaming, 4847754 silesia.tar, long distance mode, advanced streaming, 4847735
silesia.tar, multithreaded, advanced streaming, 4861508 silesia.tar, multithreaded, advanced streaming, 4861508
silesia.tar, multithreaded long distance mode, advanced streaming, 4853222 silesia.tar, multithreaded long distance mode, advanced streaming, 4853149
silesia.tar, small window log, advanced streaming, 7118769 silesia.tar, small window log, advanced streaming, 7118769
silesia.tar, small hash log, advanced streaming, 6529235 silesia.tar, small hash log, advanced streaming, 6587952
silesia.tar, small chain log, advanced streaming, 4917021 silesia.tar, small chain log, advanced streaming, 4943312
silesia.tar, explicit params, advanced streaming, 4807401 silesia.tar, explicit params, advanced streaming, 4808618
silesia.tar, uncompressed literals, advanced streaming, 5129461 silesia.tar, uncompressed literals, advanced streaming, 5129461
silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 silesia.tar, uncompressed literals optimal, advanced streaming, 4320858
silesia.tar, huffman literals, advanced streaming, 5352360 silesia.tar, huffman literals, advanced streaming, 5352360
silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 silesia.tar, multithreaded with advanced params, advanced streaming, 5129555
github, level -5, advanced streaming, 205285 github, level -5, advanced streaming, 205285
@@ -888,100 +556,26 @@ github, level -1, advanced
github, level -1 with dict, advanced streaming, 43170 github, level -1 with dict, advanced streaming, 43170
github, level 0, advanced streaming, 136335 github, level 0, advanced streaming, 136335
github, level 0 with dict, advanced streaming, 41148 github, level 0 with dict, advanced streaming, 41148
github, level 0 with dict dms, advanced streaming, 41148
github, level 0 with dict dds, advanced streaming, 41148
github, level 0 with dict copy, advanced streaming, 41124
github, level 0 with dict load, advanced streaming, 42252
github, level 1, advanced streaming, 142465 github, level 1, advanced streaming, 142465
github, level 1 with dict, advanced streaming, 41682 github, level 1 with dict, advanced streaming, 41682
github, level 1 with dict dms, advanced streaming, 41682
github, level 1 with dict dds, advanced streaming, 41682
github, level 1 with dict copy, advanced streaming, 41674
github, level 1 with dict load, advanced streaming, 43755
github, level 3, advanced streaming, 136335 github, level 3, advanced streaming, 136335
github, level 3 with dict, advanced streaming, 41148 github, level 3 with dict, advanced streaming, 41148
github, level 3 with dict dms, advanced streaming, 41148
github, level 3 with dict dds, advanced streaming, 41148
github, level 3 with dict copy, advanced streaming, 41124
github, level 3 with dict load, advanced streaming, 42252
github, level 4, advanced streaming, 136199 github, level 4, advanced streaming, 136199
github, level 4 with dict, advanced streaming, 41251 github, level 4 with dict, advanced streaming, 41251
github, level 4 with dict dms, advanced streaming, 41251
github, level 4 with dict dds, advanced streaming, 41251
github, level 4 with dict copy, advanced streaming, 41216
github, level 4 with dict load, advanced streaming, 41159
github, level 5 row 1, advanced streaming, 135121
github, level 5 row 1 with dict dms, advanced streaming, 38938
github, level 5 row 1 with dict dds, advanced streaming, 38732
github, level 5 row 1 with dict copy, advanced streaming, 38934
github, level 5 row 1 with dict load, advanced streaming, 40725
github, level 5 row 2, advanced streaming, 134584
github, level 5 row 2 with dict dms, advanced streaming, 38758
github, level 5 row 2 with dict dds, advanced streaming, 38728
github, level 5 row 2 with dict copy, advanced streaming, 38759
github, level 5 row 2 with dict load, advanced streaming, 41518
github, level 5, advanced streaming, 135121 github, level 5, advanced streaming, 135121
github, level 5 with dict, advanced streaming, 38758 github, level 5 with dict, advanced streaming, 38938
github, level 5 with dict dms, advanced streaming, 38758
github, level 5 with dict dds, advanced streaming, 38728
github, level 5 with dict copy, advanced streaming, 38759
github, level 5 with dict load, advanced streaming, 40725
github, level 6, advanced streaming, 135122 github, level 6, advanced streaming, 135122
github, level 6 with dict, advanced streaming, 38671 github, level 6 with dict, advanced streaming, 38632
github, level 6 with dict dms, advanced streaming, 38671
github, level 6 with dict dds, advanced streaming, 38630
github, level 6 with dict copy, advanced streaming, 38669
github, level 6 with dict load, advanced streaming, 40695
github, level 7 row 1, advanced streaming, 135122
github, level 7 row 1 with dict dms, advanced streaming, 38771
github, level 7 row 1 with dict dds, advanced streaming, 38771
github, level 7 row 1 with dict copy, advanced streaming, 38745
github, level 7 row 1 with dict load, advanced streaming, 40695
github, level 7 row 2, advanced streaming, 134584
github, level 7 row 2 with dict dms, advanced streaming, 38758
github, level 7 row 2 with dict dds, advanced streaming, 38747
github, level 7 row 2 with dict copy, advanced streaming, 38755
github, level 7 row 2 with dict load, advanced streaming, 41030
github, level 7, advanced streaming, 135122 github, level 7, advanced streaming, 135122
github, level 7 with dict, advanced streaming, 38758 github, level 7 with dict, advanced streaming, 38771
github, level 7 with dict dms, advanced streaming, 38758
github, level 7 with dict dds, advanced streaming, 38747
github, level 7 with dict copy, advanced streaming, 38755
github, level 7 with dict load, advanced streaming, 40695
github, level 9, advanced streaming, 135122 github, level 9, advanced streaming, 135122
github, level 9 with dict, advanced streaming, 39437 github, level 9 with dict, advanced streaming, 39332
github, level 9 with dict dms, advanced streaming, 39437
github, level 9 with dict dds, advanced streaming, 39338
github, level 9 with dict copy, advanced streaming, 39398
github, level 9 with dict load, advanced streaming, 41710
github, level 12 row 1, advanced streaming, 134180
github, level 12 row 1 with dict dms, advanced streaming, 39677
github, level 12 row 1 with dict dds, advanced streaming, 39677
github, level 12 row 1 with dict copy, advanced streaming, 39677
github, level 12 row 1 with dict load, advanced streaming, 41166
github, level 12 row 2, advanced streaming, 134180
github, level 12 row 2 with dict dms, advanced streaming, 39677
github, level 12 row 2 with dict dds, advanced streaming, 39677
github, level 12 row 2 with dict copy, advanced streaming, 39677
github, level 12 row 2 with dict load, advanced streaming, 41166
github, level 13, advanced streaming, 134064 github, level 13, advanced streaming, 134064
github, level 13 with dict, advanced streaming, 39743 github, level 13 with dict, advanced streaming, 39900
github, level 13 with dict dms, advanced streaming, 39743
github, level 13 with dict dds, advanced streaming, 39743
github, level 13 with dict copy, advanced streaming, 39948
github, level 13 with dict load, advanced streaming, 42626
github, level 16, advanced streaming, 134064 github, level 16, advanced streaming, 134064
github, level 16 with dict, advanced streaming, 37577 github, level 16 with dict, advanced streaming, 37577
github, level 16 with dict dms, advanced streaming, 37577
github, level 16 with dict dds, advanced streaming, 37577
github, level 16 with dict copy, advanced streaming, 37568
github, level 16 with dict load, advanced streaming, 42340
github, level 19, advanced streaming, 134064 github, level 19, advanced streaming, 134064
github, level 19 with dict, advanced streaming, 37576 github, level 19 with dict, advanced streaming, 37576
github, level 19 with dict dms, advanced streaming, 37576
github, level 19 with dict dds, advanced streaming, 37576
github, level 19 with dict copy, advanced streaming, 37567
github, level 19 with dict load, advanced streaming, 39613
github, no source size, advanced streaming, 136335 github, no source size, advanced streaming, 136335
github, no source size with dict, advanced streaming, 41148 github, no source size with dict, advanced streaming, 41148
github, long distance mode, advanced streaming, 136335 github, long distance mode, advanced streaming, 136335
@@ -996,116 +590,42 @@ github, uncompressed literals optimal, advanced
github, huffman literals, advanced streaming, 142465 github, huffman literals, advanced streaming, 142465
github, multithreaded with advanced params, advanced streaming, 165915 github, multithreaded with advanced params, advanced streaming, 165915
github.tar, level -5, advanced streaming, 46747 github.tar, level -5, advanced streaming, 46747
github.tar, level -5 with dict, advanced streaming, 44440 github.tar, level -5 with dict, advanced streaming, 43971
github.tar, level -3, advanced streaming, 43537 github.tar, level -3, advanced streaming, 43537
github.tar, level -3 with dict, advanced streaming, 41112 github.tar, level -3 with dict, advanced streaming, 40805
github.tar, level -1, advanced streaming, 42465 github.tar, level -1, advanced streaming, 42465
github.tar, level -1 with dict, advanced streaming, 41196 github.tar, level -1 with dict, advanced streaming, 41122
github.tar, level 0, advanced streaming, 38441 github.tar, level 0, advanced streaming, 38441
github.tar, level 0 with dict, advanced streaming, 37995 github.tar, level 0 with dict, advanced streaming, 37995
github.tar, level 0 with dict dms, advanced streaming, 38003
github.tar, level 0 with dict dds, advanced streaming, 38003
github.tar, level 0 with dict copy, advanced streaming, 37995
github.tar, level 0 with dict load, advanced streaming, 37956
github.tar, level 1, advanced streaming, 39342 github.tar, level 1, advanced streaming, 39342
github.tar, level 1 with dict, advanced streaming, 38293 github.tar, level 1 with dict, advanced streaming, 38309
github.tar, level 1 with dict dms, advanced streaming, 38303
github.tar, level 1 with dict dds, advanced streaming, 38303
github.tar, level 1 with dict copy, advanced streaming, 38293
github.tar, level 1 with dict load, advanced streaming, 38766
github.tar, level 3, advanced streaming, 38441 github.tar, level 3, advanced streaming, 38441
github.tar, level 3 with dict, advanced streaming, 37995 github.tar, level 3 with dict, advanced streaming, 37995
github.tar, level 3 with dict dms, advanced streaming, 38003
github.tar, level 3 with dict dds, advanced streaming, 38003
github.tar, level 3 with dict copy, advanced streaming, 37995
github.tar, level 3 with dict load, advanced streaming, 37956
github.tar, level 4, advanced streaming, 38467 github.tar, level 4, advanced streaming, 38467
github.tar, level 4 with dict, advanced streaming, 37948 github.tar, level 4 with dict, advanced streaming, 37948
github.tar, level 4 with dict dms, advanced streaming, 37954 github.tar, level 5, advanced streaming, 39788
github.tar, level 4 with dict dds, advanced streaming, 37954 github.tar, level 5 with dict, advanced streaming, 39715
github.tar, level 4 with dict copy, advanced streaming, 37948 github.tar, level 6, advanced streaming, 39603
github.tar, level 4 with dict load, advanced streaming, 37927 github.tar, level 6 with dict, advanced streaming, 38800
github.tar, level 5 row 1, advanced streaming, 39788 github.tar, level 7, advanced streaming, 39206
github.tar, level 5 row 1 with dict dms, advanced streaming, 39365 github.tar, level 7 with dict, advanced streaming, 38071
github.tar, level 5 row 1 with dict dds, advanced streaming, 39233 github.tar, level 9, advanced streaming, 36717
github.tar, level 5 row 1 with dict copy, advanced streaming, 39715 github.tar, level 9 with dict, advanced streaming, 36898
github.tar, level 5 row 1 with dict load, advanced streaming, 39209
github.tar, level 5 row 2, advanced streaming, 39693
github.tar, level 5 row 2 with dict dms, advanced streaming, 39024
github.tar, level 5 row 2 with dict dds, advanced streaming, 39028
github.tar, level 5 row 2 with dict copy, advanced streaming, 39040
github.tar, level 5 row 2 with dict load, advanced streaming, 39037
github.tar, level 5, advanced streaming, 39693
github.tar, level 5 with dict, advanced streaming, 39040
github.tar, level 5 with dict dms, advanced streaming, 39024
github.tar, level 5 with dict dds, advanced streaming, 39028
github.tar, level 5 with dict copy, advanced streaming, 39040
github.tar, level 5 with dict load, advanced streaming, 39037
github.tar, level 6, advanced streaming, 39621
github.tar, level 6 with dict, advanced streaming, 38622
github.tar, level 6 with dict dms, advanced streaming, 38608
github.tar, level 6 with dict dds, advanced streaming, 38610
github.tar, level 6 with dict copy, advanced streaming, 38622
github.tar, level 6 with dict load, advanced streaming, 38962
github.tar, level 7 row 1, advanced streaming, 39206
github.tar, level 7 row 1 with dict dms, advanced streaming, 37954
github.tar, level 7 row 1 with dict dds, advanced streaming, 37954
github.tar, level 7 row 1 with dict copy, advanced streaming, 38071
github.tar, level 7 row 1 with dict load, advanced streaming, 38584
github.tar, level 7 row 2, advanced streaming, 39213
github.tar, level 7 row 2 with dict dms, advanced streaming, 37848
github.tar, level 7 row 2 with dict dds, advanced streaming, 37867
github.tar, level 7 row 2 with dict copy, advanced streaming, 37848
github.tar, level 7 row 2 with dict load, advanced streaming, 38582
github.tar, level 7, advanced streaming, 39213
github.tar, level 7 with dict, advanced streaming, 37848
github.tar, level 7 with dict dms, advanced streaming, 37848
github.tar, level 7 with dict dds, advanced streaming, 37867
github.tar, level 7 with dict copy, advanced streaming, 37848
github.tar, level 7 with dict load, advanced streaming, 38582
github.tar, level 9, advanced streaming, 36758
github.tar, level 9 with dict, advanced streaming, 36457
github.tar, level 9 with dict dms, advanced streaming, 36549
github.tar, level 9 with dict dds, advanced streaming, 36637
github.tar, level 9 with dict copy, advanced streaming, 36457
github.tar, level 9 with dict load, advanced streaming, 36350
github.tar, level 12 row 1, advanced streaming, 36435
github.tar, level 12 row 1 with dict dms, advanced streaming, 36986
github.tar, level 12 row 1 with dict dds, advanced streaming, 36986
github.tar, level 12 row 1 with dict copy, advanced streaming, 36609
github.tar, level 12 row 1 with dict load, advanced streaming, 36419
github.tar, level 12 row 2, advanced streaming, 36435
github.tar, level 12 row 2 with dict dms, advanced streaming, 36986
github.tar, level 12 row 2 with dict dds, advanced streaming, 36986
github.tar, level 12 row 2 with dict copy, advanced streaming, 36609
github.tar, level 12 row 2 with dict load, advanced streaming, 36424
github.tar, level 13, advanced streaming, 35621 github.tar, level 13, advanced streaming, 35621
github.tar, level 13 with dict, advanced streaming, 38726 github.tar, level 13 with dict, advanced streaming, 38726
github.tar, level 13 with dict dms, advanced streaming, 38903
github.tar, level 13 with dict dds, advanced streaming, 38903
github.tar, level 13 with dict copy, advanced streaming, 38726
github.tar, level 13 with dict load, advanced streaming, 36372
github.tar, level 16, advanced streaming, 40255 github.tar, level 16, advanced streaming, 40255
github.tar, level 16 with dict, advanced streaming, 33639 github.tar, level 16 with dict, advanced streaming, 33639
github.tar, level 16 with dict dms, advanced streaming, 33544
github.tar, level 16 with dict dds, advanced streaming, 33544
github.tar, level 16 with dict copy, advanced streaming, 33639
github.tar, level 16 with dict load, advanced streaming, 39353
github.tar, level 19, advanced streaming, 32837 github.tar, level 19, advanced streaming, 32837
github.tar, level 19 with dict, advanced streaming, 32895 github.tar, level 19 with dict, advanced streaming, 32895
github.tar, level 19 with dict dms, advanced streaming, 32672
github.tar, level 19 with dict dds, advanced streaming, 32672
github.tar, level 19 with dict copy, advanced streaming, 32895
github.tar, level 19 with dict load, advanced streaming, 32676
github.tar, no source size, advanced streaming, 38438 github.tar, no source size, advanced streaming, 38438
github.tar, no source size with dict, advanced streaming, 38000 github.tar, no source size with dict, advanced streaming, 38000
github.tar, long distance mode, advanced streaming, 39757 github.tar, long distance mode, advanced streaming, 39722
github.tar, multithreaded, advanced streaming, 38441 github.tar, multithreaded, advanced streaming, 38441
github.tar, multithreaded long distance mode, advanced streaming, 39726 github.tar, multithreaded long distance mode, advanced streaming, 39722
github.tar, small window log, advanced streaming, 199558 github.tar, small window log, advanced streaming, 199558
github.tar, small hash log, advanced streaming, 129870 github.tar, small hash log, advanced streaming, 129870
github.tar, small chain log, advanced streaming, 41669 github.tar, small chain log, advanced streaming, 41669
github.tar, explicit params, advanced streaming, 41227 github.tar, explicit params, advanced streaming, 41199
github.tar, uncompressed literals, advanced streaming, 41122 github.tar, uncompressed literals, advanced streaming, 41122
github.tar, uncompressed literals optimal, advanced streaming, 35388 github.tar, uncompressed literals optimal, advanced streaming, 35388
github.tar, huffman literals, advanced streaming, 38800 github.tar, huffman literals, advanced streaming, 38800
@@ -1117,16 +637,16 @@ silesia, level 0, old stre
silesia, level 1, old streaming, 5314162 silesia, level 1, old streaming, 5314162
silesia, level 3, old streaming, 4849552 silesia, level 3, old streaming, 4849552
silesia, level 4, old streaming, 4786970 silesia, level 4, old streaming, 4786970
silesia, level 5, old streaming, 4707794 silesia, level 5, old streaming, 4710236
silesia, level 6, old streaming, 4666383 silesia, level 6, old streaming, 4660056
silesia, level 7, old streaming, 4603381 silesia, level 7, old streaming, 4596296
silesia, level 9, old streaming, 4546001 silesia, level 9, old streaming, 4543925
silesia, level 13, old streaming, 4482135 silesia, level 13, old streaming, 4482135
silesia, level 16, old streaming, 4360251 silesia, level 16, old streaming, 4377465
silesia, level 19, old streaming, 4283237 silesia, level 19, old streaming, 4293330
silesia, no source size, old streaming, 4849516 silesia, no source size, old streaming, 4849516
silesia, uncompressed literals, old streaming, 4849552 silesia, uncompressed literals, old streaming, 4849552
silesia, uncompressed literals optimal, old streaming, 4283237 silesia, uncompressed literals optimal, old streaming, 4293330
silesia, huffman literals, old streaming, 6183403 silesia, huffman literals, old streaming, 6183403
silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -5, old streaming, 6982759
silesia.tar, level -3, old streaming, 6641283 silesia.tar, level -3, old streaming, 6641283
@@ -1135,16 +655,16 @@ silesia.tar, level 0, old stre
silesia.tar, level 1, old streaming, 5336939 silesia.tar, level 1, old streaming, 5336939
silesia.tar, level 3, old streaming, 4861427 silesia.tar, level 3, old streaming, 4861427
silesia.tar, level 4, old streaming, 4799630 silesia.tar, level 4, old streaming, 4799630
silesia.tar, level 5, old streaming, 4719261 silesia.tar, level 5, old streaming, 4722329
silesia.tar, level 6, old streaming, 4677729 silesia.tar, level 6, old streaming, 4672288
silesia.tar, level 7, old streaming, 4613544 silesia.tar, level 7, old streaming, 4606715
silesia.tar, level 9, old streaming, 4555432 silesia.tar, level 9, old streaming, 4554154
silesia.tar, level 13, old streaming, 4491765 silesia.tar, level 13, old streaming, 4491765
silesia.tar, level 16, old streaming, 4356834 silesia.tar, level 16, old streaming, 4381350
silesia.tar, level 19, old streaming, 4264392 silesia.tar, level 19, old streaming, 4281562
silesia.tar, no source size, old streaming, 4861423 silesia.tar, no source size, old streaming, 4861423
silesia.tar, uncompressed literals, old streaming, 4861427 silesia.tar, uncompressed literals, old streaming, 4861427
silesia.tar, uncompressed literals optimal, old streaming, 4264392 silesia.tar, uncompressed literals optimal, old streaming, 4281562
silesia.tar, huffman literals, old streaming, 6190795 silesia.tar, huffman literals, old streaming, 6190795
github, level -5, old streaming, 205285 github, level -5, old streaming, 205285
github, level -5 with dict, old streaming, 46718 github, level -5 with dict, old streaming, 46718
@@ -1161,15 +681,15 @@ github, level 3 with dict, old stre
github, level 4, old streaming, 136199 github, level 4, old streaming, 136199
github, level 4 with dict, old streaming, 41251 github, level 4 with dict, old streaming, 41251
github, level 5, old streaming, 135121 github, level 5, old streaming, 135121
github, level 5 with dict, old streaming, 38758 github, level 5 with dict, old streaming, 38938
github, level 6, old streaming, 135122 github, level 6, old streaming, 135122
github, level 6 with dict, old streaming, 38671 github, level 6 with dict, old streaming, 38632
github, level 7, old streaming, 135122 github, level 7, old streaming, 135122
github, level 7 with dict, old streaming, 38758 github, level 7 with dict, old streaming, 38771
github, level 9, old streaming, 135122 github, level 9, old streaming, 135122
github, level 9 with dict, old streaming, 39437 github, level 9 with dict, old streaming, 39332
github, level 13, old streaming, 134064 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, old streaming, 134064
github, level 16 with dict, old streaming, 37577 github, level 16 with dict, old streaming, 37577
github, level 19, old streaming, 134064 github, level 19, old streaming, 134064
@@ -1180,27 +700,27 @@ github, uncompressed literals, old stre
github, uncompressed literals optimal, old streaming, 134064 github, uncompressed literals optimal, old streaming, 134064
github, huffman literals, old streaming, 175568 github, huffman literals, old streaming, 175568
github.tar, level -5, old streaming, 46747 github.tar, level -5, old streaming, 46747
github.tar, level -5 with dict, old streaming, 44440 github.tar, level -5 with dict, old streaming, 43971
github.tar, level -3, old streaming, 43537 github.tar, level -3, old streaming, 43537
github.tar, level -3 with dict, old streaming, 41112 github.tar, level -3 with dict, old streaming, 40805
github.tar, level -1, old streaming, 42465 github.tar, level -1, old streaming, 42465
github.tar, level -1 with dict, old streaming, 41196 github.tar, level -1 with dict, old streaming, 41122
github.tar, level 0, old streaming, 38441 github.tar, level 0, old streaming, 38441
github.tar, level 0 with dict, old streaming, 37995 github.tar, level 0 with dict, old streaming, 37995
github.tar, level 1, old streaming, 39342 github.tar, level 1, old streaming, 39342
github.tar, level 1 with dict, old streaming, 38293 github.tar, level 1 with dict, old streaming, 38309
github.tar, level 3, old streaming, 38441 github.tar, level 3, old streaming, 38441
github.tar, level 3 with dict, old streaming, 37995 github.tar, level 3 with dict, old streaming, 37995
github.tar, level 4, old streaming, 38467 github.tar, level 4, old streaming, 38467
github.tar, level 4 with dict, old streaming, 37948 github.tar, level 4 with dict, old streaming, 37948
github.tar, level 5, old streaming, 39693 github.tar, level 5, old streaming, 39788
github.tar, level 5 with dict, old streaming, 39040 github.tar, level 5 with dict, old streaming, 39715
github.tar, level 6, old streaming, 39621 github.tar, level 6, old streaming, 39603
github.tar, level 6 with dict, old streaming, 38622 github.tar, level 6 with dict, old streaming, 38800
github.tar, level 7, old streaming, 39213 github.tar, level 7, old streaming, 39206
github.tar, level 7 with dict, old streaming, 37848 github.tar, level 7 with dict, old streaming, 38071
github.tar, level 9, old streaming, 36758 github.tar, level 9, old streaming, 36717
github.tar, level 9 with dict, old streaming, 36457 github.tar, level 9 with dict, old streaming, 36898
github.tar, level 13, old streaming, 35621 github.tar, level 13, old streaming, 35621
github.tar, level 13 with dict, old streaming, 38726 github.tar, level 13 with dict, old streaming, 38726
github.tar, level 16, old streaming, 40255 github.tar, level 16, old streaming, 40255
@@ -1219,23 +739,23 @@ silesia, level 0, old stre
silesia, level 1, old streaming advanced, 5314162 silesia, level 1, old streaming advanced, 5314162
silesia, level 3, old streaming advanced, 4849552 silesia, level 3, old streaming advanced, 4849552
silesia, level 4, old streaming advanced, 4786970 silesia, level 4, old streaming advanced, 4786970
silesia, level 5, old streaming advanced, 4707794 silesia, level 5, old streaming advanced, 4710236
silesia, level 6, old streaming advanced, 4666383 silesia, level 6, old streaming advanced, 4660056
silesia, level 7, old streaming advanced, 4603381 silesia, level 7, old streaming advanced, 4596296
silesia, level 9, old streaming advanced, 4546001 silesia, level 9, old streaming advanced, 4543925
silesia, level 13, old streaming advanced, 4482135 silesia, level 13, old streaming advanced, 4482135
silesia, level 16, old streaming advanced, 4360251 silesia, level 16, old streaming advanced, 4377465
silesia, level 19, old streaming advanced, 4283237 silesia, level 19, old streaming advanced, 4293330
silesia, no source size, old streaming advanced, 4849516 silesia, no source size, old streaming advanced, 4849516
silesia, long distance mode, old streaming advanced, 4849552 silesia, long distance mode, old streaming advanced, 4849552
silesia, multithreaded, old streaming advanced, 4849552 silesia, multithreaded, old streaming advanced, 4849552
silesia, multithreaded long distance mode, old streaming advanced, 4849552 silesia, multithreaded long distance mode, old streaming advanced, 4849552
silesia, small window log, old streaming advanced, 7112062 silesia, small window log, old streaming advanced, 7112062
silesia, small hash log, old streaming advanced, 6526141 silesia, small hash log, old streaming advanced, 6555021
silesia, small chain log, old streaming advanced, 4912197 silesia, small chain log, old streaming advanced, 4931148
silesia, explicit params, old streaming advanced, 4795887 silesia, explicit params, old streaming advanced, 4797112
silesia, uncompressed literals, old streaming advanced, 4849552 silesia, uncompressed literals, old streaming advanced, 4849552
silesia, uncompressed literals optimal, old streaming advanced, 4283237 silesia, uncompressed literals optimal, old streaming advanced, 4293330
silesia, huffman literals, old streaming advanced, 6183403 silesia, huffman literals, old streaming advanced, 6183403
silesia, multithreaded with advanced params, old streaming advanced, 4849552 silesia, multithreaded with advanced params, old streaming advanced, 4849552
silesia.tar, level -5, old streaming advanced, 6982759 silesia.tar, level -5, old streaming advanced, 6982759
@@ -1245,23 +765,23 @@ silesia.tar, level 0, old stre
silesia.tar, level 1, old streaming advanced, 5336939 silesia.tar, level 1, old streaming advanced, 5336939
silesia.tar, level 3, old streaming advanced, 4861427 silesia.tar, level 3, old streaming advanced, 4861427
silesia.tar, level 4, old streaming advanced, 4799630 silesia.tar, level 4, old streaming advanced, 4799630
silesia.tar, level 5, old streaming advanced, 4719261 silesia.tar, level 5, old streaming advanced, 4722329
silesia.tar, level 6, old streaming advanced, 4677729 silesia.tar, level 6, old streaming advanced, 4672288
silesia.tar, level 7, old streaming advanced, 4613544 silesia.tar, level 7, old streaming advanced, 4606715
silesia.tar, level 9, old streaming advanced, 4555432 silesia.tar, level 9, old streaming advanced, 4554154
silesia.tar, level 13, old streaming advanced, 4491765 silesia.tar, level 13, old streaming advanced, 4491765
silesia.tar, level 16, old streaming advanced, 4356834 silesia.tar, level 16, old streaming advanced, 4381350
silesia.tar, level 19, old streaming advanced, 4264392 silesia.tar, level 19, old streaming advanced, 4281562
silesia.tar, no source size, old streaming advanced, 4861423 silesia.tar, no source size, old streaming advanced, 4861423
silesia.tar, long distance mode, old streaming advanced, 4861427 silesia.tar, long distance mode, old streaming advanced, 4861427
silesia.tar, multithreaded, old streaming advanced, 4861427 silesia.tar, multithreaded, old streaming advanced, 4861427
silesia.tar, multithreaded long distance mode, old streaming advanced, 4861427 silesia.tar, multithreaded long distance mode, old streaming advanced, 4861427
silesia.tar, small window log, old streaming advanced, 7118772 silesia.tar, small window log, old streaming advanced, 7118772
silesia.tar, small hash log, old streaming advanced, 6529235 silesia.tar, small hash log, old streaming advanced, 6587952
silesia.tar, small chain log, old streaming advanced, 4917021 silesia.tar, small chain log, old streaming advanced, 4943312
silesia.tar, explicit params, old streaming advanced, 4807401 silesia.tar, explicit params, old streaming advanced, 4808618
silesia.tar, uncompressed literals, old streaming advanced, 4861427 silesia.tar, uncompressed literals, old streaming advanced, 4861427
silesia.tar, uncompressed literals optimal, old streaming advanced, 4264392 silesia.tar, uncompressed literals optimal, old streaming advanced, 4281562
silesia.tar, huffman literals, old streaming advanced, 6190795 silesia.tar, huffman literals, old streaming advanced, 6190795
silesia.tar, multithreaded with advanced params, old streaming advanced, 4861427 silesia.tar, multithreaded with advanced params, old streaming advanced, 4861427
github, level -5, old streaming advanced, 216734 github, level -5, old streaming advanced, 216734
@@ -1279,13 +799,13 @@ github, level 3 with dict, old stre
github, level 4, old streaming advanced, 141104 github, level 4, old streaming advanced, 141104
github, level 4 with dict, old streaming advanced, 41084 github, level 4 with dict, old streaming advanced, 41084
github, level 5, old streaming advanced, 139399 github, level 5, old streaming advanced, 139399
github, level 5 with dict, old streaming advanced, 38633 github, level 5 with dict, old streaming advanced, 39159
github, level 6, old streaming advanced, 139402 github, level 6, old streaming advanced, 139402
github, level 6 with dict, old streaming advanced, 38723 github, level 6 with dict, old streaming advanced, 38749
github, level 7, old streaming advanced, 138676 github, level 7, old streaming advanced, 138676
github, level 7 with dict, old streaming advanced, 38744 github, level 7 with dict, old streaming advanced, 38746
github, level 9, old streaming advanced, 138676 github, level 9, old streaming advanced, 138676
github, level 9 with dict, old streaming advanced, 38981 github, level 9 with dict, old streaming advanced, 38993
github, level 13, old streaming advanced, 138676 github, level 13, old streaming advanced, 138676
github, level 13 with dict, old streaming advanced, 39731 github, level 13 with dict, old streaming advanced, 39731
github, level 16, old streaming advanced, 138676 github, level 16, old streaming advanced, 138676
@@ -1319,14 +839,14 @@ github.tar, level 3, old stre
github.tar, level 3 with dict, old streaming advanced, 38013 github.tar, level 3 with dict, old streaming advanced, 38013
github.tar, level 4, old streaming advanced, 38467 github.tar, level 4, old streaming advanced, 38467
github.tar, level 4 with dict, old streaming advanced, 38063 github.tar, level 4 with dict, old streaming advanced, 38063
github.tar, level 5, old streaming advanced, 39693 github.tar, level 5, old streaming advanced, 39788
github.tar, level 5 with dict, old streaming advanced, 39049 github.tar, level 5 with dict, old streaming advanced, 39310
github.tar, level 6, old streaming advanced, 39621 github.tar, level 6, old streaming advanced, 39603
github.tar, level 6 with dict, old streaming advanced, 38959 github.tar, level 6 with dict, old streaming advanced, 39279
github.tar, level 7, old streaming advanced, 39213 github.tar, level 7, old streaming advanced, 39206
github.tar, level 7 with dict, old streaming advanced, 38573 github.tar, level 7 with dict, old streaming advanced, 38728
github.tar, level 9, old streaming advanced, 36758 github.tar, level 9, old streaming advanced, 36717
github.tar, level 9 with dict, old streaming advanced, 36233 github.tar, level 9 with dict, old streaming advanced, 36504
github.tar, level 13, old streaming advanced, 35621 github.tar, level 13, old streaming advanced, 35621
github.tar, level 13 with dict, old streaming advanced, 36035 github.tar, level 13 with dict, old streaming advanced, 36035
github.tar, level 16, old streaming advanced, 40255 github.tar, level 16, old streaming advanced, 40255
@@ -1341,41 +861,41 @@ github.tar, multithreaded long distance mode, old stre
github.tar, small window log, old streaming advanced, 199561 github.tar, small window log, old streaming advanced, 199561
github.tar, small hash log, old streaming advanced, 129870 github.tar, small hash log, old streaming advanced, 129870
github.tar, small chain log, old streaming advanced, 41669 github.tar, small chain log, old streaming advanced, 41669
github.tar, explicit params, old streaming advanced, 41227 github.tar, explicit params, old streaming advanced, 41199
github.tar, uncompressed literals, old streaming advanced, 38441 github.tar, uncompressed literals, old streaming advanced, 38441
github.tar, uncompressed literals optimal, old streaming advanced, 32837 github.tar, uncompressed literals optimal, old streaming advanced, 32837
github.tar, huffman literals, old streaming advanced, 42465 github.tar, huffman literals, old streaming advanced, 42465
github.tar, multithreaded with advanced params, old streaming advanced, 38441 github.tar, multithreaded with advanced params, old streaming advanced, 38441
github, level -5 with dict, old streaming cdict, 46718 github, level -5 with dict, old streaming cdcit, 46718
github, level -3 with dict, old streaming cdict, 45395 github, level -3 with dict, old streaming cdcit, 45395
github, level -1 with dict, old streaming cdict, 43170 github, level -1 with dict, old streaming cdcit, 43170
github, level 0 with dict, old streaming cdict, 41148 github, level 0 with dict, old streaming cdcit, 41148
github, level 1 with dict, old streaming cdict, 41682 github, level 1 with dict, old streaming cdcit, 41682
github, level 3 with dict, old streaming cdict, 41148 github, level 3 with dict, old streaming cdcit, 41148
github, level 4 with dict, old streaming cdict, 41251 github, level 4 with dict, old streaming cdcit, 41251
github, level 5 with dict, old streaming cdict, 38758 github, level 5 with dict, old streaming cdcit, 38938
github, level 6 with dict, old streaming cdict, 38671 github, level 6 with dict, old streaming cdcit, 38632
github, level 7 with dict, old streaming cdict, 38758 github, level 7 with dict, old streaming cdcit, 38771
github, level 9 with dict, old streaming cdict, 39437 github, level 9 with dict, old streaming cdcit, 39332
github, level 13 with dict, old streaming cdict, 39743 github, level 13 with dict, old streaming cdcit, 39900
github, level 16 with dict, old streaming cdict, 37577 github, level 16 with dict, old streaming cdcit, 37577
github, level 19 with dict, old streaming cdict, 37576 github, level 19 with dict, old streaming cdcit, 37576
github, no source size with dict, old streaming cdict, 40654 github, no source size with dict, old streaming cdcit, 40654
github.tar, level -5 with dict, old streaming cdict, 45018 github.tar, level -5 with dict, old streaming cdcit, 45018
github.tar, level -3 with dict, old streaming cdict, 41886 github.tar, level -3 with dict, old streaming cdcit, 41886
github.tar, level -1 with dict, old streaming cdict, 41636 github.tar, level -1 with dict, old streaming cdcit, 41636
github.tar, level 0 with dict, old streaming cdict, 37956 github.tar, level 0 with dict, old streaming cdcit, 37956
github.tar, level 1 with dict, old streaming cdict, 38766 github.tar, level 1 with dict, old streaming cdcit, 38766
github.tar, level 3 with dict, old streaming cdict, 37956 github.tar, level 3 with dict, old streaming cdcit, 37956
github.tar, level 4 with dict, old streaming cdict, 37927 github.tar, level 4 with dict, old streaming cdcit, 37927
github.tar, level 5 with dict, old streaming cdict, 39037 github.tar, level 5 with dict, old streaming cdcit, 39209
github.tar, level 6 with dict, old streaming cdict, 38962 github.tar, level 6 with dict, old streaming cdcit, 38983
github.tar, level 7 with dict, old streaming cdict, 38582 github.tar, level 7 with dict, old streaming cdcit, 38584
github.tar, level 9 with dict, old streaming cdict, 36350 github.tar, level 9 with dict, old streaming cdcit, 36363
github.tar, level 13 with dict, old streaming cdict, 36372 github.tar, level 13 with dict, old streaming cdcit, 36372
github.tar, level 16 with dict, old streaming cdict, 39353 github.tar, level 16 with dict, old streaming cdcit, 39353
github.tar, level 19 with dict, old streaming cdict, 32676 github.tar, level 19 with dict, old streaming cdcit, 32676
github.tar, no source size with dict, old streaming cdict, 38000 github.tar, no source size with dict, old streaming cdcit, 38000
github, level -5 with dict, old streaming advanced cdict, 49562 github, level -5 with dict, old streaming advanced cdict, 49562
github, level -3 with dict, old streaming advanced cdict, 44956 github, level -3 with dict, old streaming advanced cdict, 44956
github, level -1 with dict, old streaming advanced cdict, 42383 github, level -1 with dict, old streaming advanced cdict, 42383
@@ -1383,10 +903,10 @@ github, level 0 with dict, old stre
github, level 1 with dict, old streaming advanced cdict, 42430 github, level 1 with dict, old streaming advanced cdict, 42430
github, level 3 with dict, old streaming advanced cdict, 41113 github, level 3 with dict, old streaming advanced cdict, 41113
github, level 4 with dict, old streaming advanced cdict, 41084 github, level 4 with dict, old streaming advanced cdict, 41084
github, level 5 with dict, old streaming advanced cdict, 38633 github, level 5 with dict, old streaming advanced cdict, 39159
github, level 6 with dict, old streaming advanced cdict, 38723 github, level 6 with dict, old streaming advanced cdict, 38749
github, level 7 with dict, old streaming advanced cdict, 38744 github, level 7 with dict, old streaming advanced cdict, 38746
github, level 9 with dict, old streaming advanced cdict, 38981 github, level 9 with dict, old streaming advanced cdict, 38993
github, level 13 with dict, old streaming advanced cdict, 39731 github, level 13 with dict, old streaming advanced cdict, 39731
github, level 16 with dict, old streaming advanced cdict, 40789 github, level 16 with dict, old streaming advanced cdict, 40789
github, level 19 with dict, old streaming advanced cdict, 37576 github, level 19 with dict, old streaming advanced cdict, 37576
@@ -1398,10 +918,10 @@ github.tar, level 0 with dict, old stre
github.tar, level 1 with dict, old streaming advanced cdict, 39002 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 3 with dict, old streaming advanced cdict, 38013
github.tar, level 4 with dict, old streaming advanced cdict, 38063 github.tar, level 4 with dict, old streaming advanced cdict, 38063
github.tar, level 5 with dict, old streaming advanced cdict, 39049 github.tar, level 5 with dict, old streaming advanced cdict, 39310
github.tar, level 6 with dict, old streaming advanced cdict, 38959 github.tar, level 6 with dict, old streaming advanced cdict, 39279
github.tar, level 7 with dict, old streaming advanced cdict, 38573 github.tar, level 7 with dict, old streaming advanced cdict, 38728
github.tar, level 9 with dict, old streaming advanced cdict, 36233 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 13 with dict, old streaming advanced cdict, 36035
github.tar, level 16 with dict, old streaming advanced cdict, 38736 github.tar, level 16 with dict, old streaming advanced cdict, 38736
github.tar, level 19 with dict, old streaming advanced cdict, 32876 github.tar, level 19 with dict, old streaming advanced cdict, 32876
1 Data Config Method Total compressed size
6 silesia.tar level 1 compress simple 5334885
7 silesia.tar level 3 compress simple 4861425
8 silesia.tar level 4 compress simple 4799630
9 silesia.tar level 5 compress simple 4719256 4722324
10 silesia.tar level 6 compress simple 4677721 4672279
11 silesia.tar level 7 compress simple 4613541 4606715
12 silesia.tar level 9 compress simple 4555426 4554147
13 silesia.tar level 13 compress simple 4491764
14 silesia.tar level 16 compress simple 4381332
15 silesia.tar level 19 compress simple 4281605
23 github.tar level 1 compress simple 39265
24 github.tar level 3 compress simple 38441
25 github.tar level 4 compress simple 38467
26 github.tar level 5 compress simple 39693 39788
27 github.tar level 6 compress simple 39621 39603
28 github.tar level 7 compress simple 39213 39206
29 github.tar level 9 compress simple 36758 36717
30 github.tar level 13 compress simple 35621
31 github.tar level 16 compress simple 40255
32 github.tar level 19 compress simple 32837
40 silesia level 1 compress cctx 5313204
41 silesia level 3 compress cctx 4849552
42 silesia level 4 compress cctx 4786970
43 silesia level 5 compress cctx 4707794 4710236
44 silesia level 6 compress cctx 4666383 4660056
45 silesia level 7 compress cctx 4603381 4596296
46 silesia level 9 compress cctx 4546001 4543925
47 silesia level 13 compress cctx 4482135
48 silesia level 16 compress cctx 4377465
49 silesia level 19 compress cctx 4293330
53 silesia small window log compress cctx 7084179
54 silesia small hash log compress cctx 6555021
55 silesia small chain log compress cctx 4931148
56 silesia explicit params compress cctx 4794479 4794677
57 silesia uncompressed literals compress cctx 4849552
58 silesia uncompressed literals optimal compress cctx 4293330
59 silesia huffman literals compress cctx 6178460
73 github level 4 compress cctx 136199
74 github level 4 with dict compress cctx 41725
75 github level 5 compress cctx 135121
76 github level 5 with dict compress cctx 38759 38934
77 github level 6 compress cctx 135122
78 github level 6 with dict compress cctx 38669 38628
79 github level 7 compress cctx 135122
80 github level 7 with dict compress cctx 38755 38745
81 github level 9 compress cctx 135122
82 github level 9 with dict compress cctx 39398 39341
83 github level 13 compress cctx 134064
84 github level 13 with dict compress cctx 39948
85 github level 16 compress cctx 134064
97 github uncompressed literals optimal compress cctx 134064
98 github huffman literals compress cctx 175568
99 github multithreaded with advanced params compress cctx 141102
100 silesia level -5 zstdcli 6737655 6882553
101 silesia level -3 zstdcli 6444725 6568424
102 silesia level -1 zstdcli 6178508 6183451
103 silesia level 0 zstdcli 4849600
104 silesia level 1 zstdcli 5313252 5314210
105 silesia level 3 zstdcli 4849600
106 silesia level 4 zstdcli 4787018
107 silesia level 5 zstdcli 4707842 4710284
108 silesia level 6 zstdcli 4666431 4660104
109 silesia level 7 zstdcli 4603429 4596344
110 silesia level 9 zstdcli 4546049 4543973
111 silesia level 13 zstdcli 4482183
112 silesia level 16 zstdcli 4360299 4377513
113 silesia level 19 zstdcli 4283285 4293378
114 silesia long distance mode zstdcli 4840806 4840792
115 silesia multithreaded zstdcli 4849600
116 silesia multithreaded long distance mode zstdcli 4840806 4840792
117 silesia small window log zstdcli 7095967 7111012
118 silesia small hash log zstdcli 6526189 6555069
119 silesia small chain log zstdcli 4912245 4931196
120 silesia explicit params zstdcli 4795856 4797112
121 silesia uncompressed literals zstdcli 5128030
122 silesia uncompressed literals optimal zstdcli 4317944 4325520
123 silesia huffman literals zstdcli 5326316 5331216
124 silesia multithreaded with advanced params zstdcli 5128030
125 silesia.tar level -5 zstdcli 6738934
126 silesia.tar level -3 zstdcli 6448419
129 silesia.tar level 1 zstdcli 5336318
130 silesia.tar level 3 zstdcli 4861512
131 silesia.tar level 4 zstdcli 4800529
132 silesia.tar level 5 zstdcli 4720121 4723364
133 silesia.tar level 6 zstdcli 4678661 4673663
134 silesia.tar level 7 zstdcli 4614424 4608403
135 silesia.tar level 9 zstdcli 4556062 4554751
136 silesia.tar level 13 zstdcli 4491768
137 silesia.tar level 16 zstdcli 4356831 4381336
138 silesia.tar level 19 zstdcli 4264491 4281609
139 silesia.tar no source size zstdcli 4861508
140 silesia.tar long distance mode zstdcli 4853226 4853153
141 silesia.tar multithreaded zstdcli 4861512
142 silesia.tar multithreaded long distance mode zstdcli 4853226 4853153
143 silesia.tar small window log zstdcli 7101576
144 silesia.tar small hash log zstdcli 6529290 6587959
145 silesia.tar small chain log zstdcli 4917022 4943310
146 silesia.tar explicit params zstdcli 4821274 4822362
147 silesia.tar uncompressed literals zstdcli 5129559
148 silesia.tar uncompressed literals optimal zstdcli 4307457 4320931
149 silesia.tar huffman literals zstdcli 5347610
150 silesia.tar multithreaded with advanced params zstdcli 5129559
151 github level -5 zstdcli 207285
163 github level 4 zstdcli 138199
164 github level 4 with dict zstdcli 43251
165 github level 5 zstdcli 137121
166 github level 5 with dict zstdcli 40728 40741
167 github level 6 zstdcli 137122
168 github level 6 with dict zstdcli 40630 40632
169 github level 7 zstdcli 137122
170 github level 7 with dict zstdcli 40747 40771
171 github level 9 zstdcli 137122
172 github level 9 with dict zstdcli 41338 41332
173 github level 13 zstdcli 136064
174 github level 13 with dict zstdcli 41743 41900
175 github level 16 zstdcli 136064
176 github level 16 with dict zstdcli 39577
177 github level 19 zstdcli 136064
187 github uncompressed literals optimal zstdcli 159227
188 github huffman literals zstdcli 144465
189 github multithreaded with advanced params zstdcli 167915
190 github.tar level -5 zstdcli 46860 46751
191 github.tar level -5 with dict zstdcli 44575 43975
192 github.tar level -3 zstdcli 43758 43541
193 github.tar level -3 with dict zstdcli 41451 40809
194 github.tar level -1 zstdcli 42494 42469
195 github.tar level -1 with dict zstdcli 41135 41126
196 github.tar level 0 zstdcli 38445
197 github.tar level 0 with dict zstdcli 37999
198 github.tar level 1 zstdcli 39269 39346
199 github.tar level 1 with dict zstdcli 38284 38313
200 github.tar level 3 zstdcli 38445
201 github.tar level 3 with dict zstdcli 37999
202 github.tar level 4 zstdcli 38471
203 github.tar level 4 with dict zstdcli 37952
204 github.tar level 5 zstdcli 39697 39792
205 github.tar level 5 with dict zstdcli 39032 39231
206 github.tar level 6 zstdcli 39625 39607
207 github.tar level 6 with dict zstdcli 38614 38669
208 github.tar level 7 zstdcli 39217 39210
209 github.tar level 7 with dict zstdcli 37871 37958
210 github.tar level 9 zstdcli 36762 36721
211 github.tar level 9 with dict zstdcli 36641 36886
212 github.tar level 13 zstdcli 35625
213 github.tar level 13 with dict zstdcli 38730
214 github.tar level 16 zstdcli 40259
217 github.tar level 19 with dict zstdcli 32899
218 github.tar no source size zstdcli 38442
219 github.tar no source size with dict zstdcli 38004
220 github.tar long distance mode zstdcli 39730 39726
221 github.tar multithreaded zstdcli 38445
222 github.tar multithreaded long distance mode zstdcli 39730 39726
223 github.tar small window log zstdcli 198544 199432
224 github.tar small hash log zstdcli 129874
225 github.tar small chain log zstdcli 41673
226 github.tar explicit params zstdcli 41227 41199
227 github.tar uncompressed literals zstdcli 41126
228 github.tar uncompressed literals optimal zstdcli 35392
229 github.tar huffman literals zstdcli 38781 38804
230 github.tar multithreaded with advanced params zstdcli 41126
231 silesia level -5 advanced one pass 6737607
232 silesia level -3 advanced one pass 6444677
235 silesia level 1 advanced one pass 5313204
236 silesia level 3 advanced one pass 4849552
237 silesia level 4 advanced one pass 4786970
238 silesia level 5 row 1 level 5 advanced one pass 4710236
239 silesia level 5 row 2 level 6 advanced one pass 4707794 4660056
240 silesia level 5 level 7 advanced one pass 4707794 4596296
241 silesia level 6 level 9 advanced one pass 4666383 4543925
silesia level 7 row 1 advanced one pass 4596296
silesia level 7 row 2 advanced one pass 4603381
silesia level 7 advanced one pass 4603381
silesia level 9 advanced one pass 4546001
silesia level 12 row 1 advanced one pass 4519288
silesia level 12 row 2 advanced one pass 4521397
242 silesia level 13 advanced one pass 4482135
243 silesia level 16 advanced one pass 4360251 4377465
244 silesia level 19 advanced one pass 4283237 4293330
245 silesia no source size advanced one pass 4849552
246 silesia long distance mode advanced one pass 4840738 4840744
247 silesia multithreaded advanced one pass 4849552
248 silesia multithreaded long distance mode advanced one pass 4840758 4840744
249 silesia small window log advanced one pass 7095919
250 silesia small hash log advanced one pass 6526141 6555021
251 silesia small chain log advanced one pass 4912197 4931148
252 silesia explicit params advanced one pass 4795856 4797095
253 silesia uncompressed literals advanced one pass 5127982
254 silesia uncompressed literals optimal advanced one pass 4317896 4325472
255 silesia huffman literals advanced one pass 5326268
256 silesia multithreaded with advanced params advanced one pass 5127982
257 silesia.tar level -5 advanced one pass 6738593
261 silesia.tar level 1 advanced one pass 5334885
262 silesia.tar level 3 advanced one pass 4861425
263 silesia.tar level 4 advanced one pass 4799630
264 silesia.tar level 5 row 1 level 5 advanced one pass 4722324
265 silesia.tar level 5 row 2 level 6 advanced one pass 4719256 4672279
266 silesia.tar level 5 level 7 advanced one pass 4719256 4606715
267 silesia.tar level 6 level 9 advanced one pass 4677721 4554147
silesia.tar level 7 row 1 advanced one pass 4606715
silesia.tar level 7 row 2 advanced one pass 4613541
silesia.tar level 7 advanced one pass 4613541
silesia.tar level 9 advanced one pass 4555426
silesia.tar level 12 row 1 advanced one pass 4529459
silesia.tar level 12 row 2 advanced one pass 4530256
268 silesia.tar level 13 advanced one pass 4491764
269 silesia.tar level 16 advanced one pass 4356827 4381332
270 silesia.tar level 19 advanced one pass 4264487 4281605
271 silesia.tar no source size advanced one pass 4861425
272 silesia.tar long distance mode advanced one pass 4847754 4847735
273 silesia.tar multithreaded advanced one pass 4861508
274 silesia.tar multithreaded long distance mode advanced one pass 4853222 4853149
275 silesia.tar small window log advanced one pass 7101530
276 silesia.tar small hash log advanced one pass 6529232 6587951
277 silesia.tar small chain log advanced one pass 4917041 4943307
278 silesia.tar explicit params advanced one pass 4807380 4808589
279 silesia.tar uncompressed literals advanced one pass 5129458
280 silesia.tar uncompressed literals optimal advanced one pass 4307453 4320927
281 silesia.tar huffman literals advanced one pass 5347335
282 silesia.tar multithreaded with advanced params advanced one pass 5129555
283 github level -5 advanced one pass 205285
288 github level -1 with dict advanced one pass 43170
289 github level 0 advanced one pass 136335
290 github level 0 with dict advanced one pass 41148
github level 0 with dict dms advanced one pass 41148
github level 0 with dict dds advanced one pass 41148
github level 0 with dict copy advanced one pass 41124
github level 0 with dict load advanced one pass 42252
291 github level 1 advanced one pass 142465
292 github level 1 with dict advanced one pass 41682
github level 1 with dict dms advanced one pass 41682
github level 1 with dict dds advanced one pass 41682
github level 1 with dict copy advanced one pass 41674
github level 1 with dict load advanced one pass 43755
293 github level 3 advanced one pass 136335
294 github level 3 with dict advanced one pass 41148
github level 3 with dict dms advanced one pass 41148
github level 3 with dict dds advanced one pass 41148
github level 3 with dict copy advanced one pass 41124
github level 3 with dict load advanced one pass 42252
295 github level 4 advanced one pass 136199
296 github level 4 with dict advanced one pass 41251
github level 4 with dict dms advanced one pass 41251
github level 4 with dict dds advanced one pass 41251
github level 4 with dict copy advanced one pass 41216
github level 4 with dict load advanced one pass 41159
github level 5 row 1 advanced one pass 135121
github level 5 row 1 with dict dms advanced one pass 38938
github level 5 row 1 with dict dds advanced one pass 38732
github level 5 row 1 with dict copy advanced one pass 38934
github level 5 row 1 with dict load advanced one pass 40725
github level 5 row 2 advanced one pass 134584
github level 5 row 2 with dict dms advanced one pass 38758
github level 5 row 2 with dict dds advanced one pass 38728
github level 5 row 2 with dict copy advanced one pass 38759
github level 5 row 2 with dict load advanced one pass 41518
297 github level 5 advanced one pass 135121
298 github level 5 with dict advanced one pass 38758 38938
github level 5 with dict dms advanced one pass 38758
github level 5 with dict dds advanced one pass 38728
github level 5 with dict copy advanced one pass 38759
github level 5 with dict load advanced one pass 40725
299 github level 6 advanced one pass 135122
300 github level 6 with dict advanced one pass 38671 38632
github level 6 with dict dms advanced one pass 38671
github level 6 with dict dds advanced one pass 38630
github level 6 with dict copy advanced one pass 38669
github level 6 with dict load advanced one pass 40695
github level 7 row 1 advanced one pass 135122
github level 7 row 1 with dict dms advanced one pass 38771
github level 7 row 1 with dict dds advanced one pass 38771
github level 7 row 1 with dict copy advanced one pass 38745
github level 7 row 1 with dict load advanced one pass 40695
github level 7 row 2 advanced one pass 134584
github level 7 row 2 with dict dms advanced one pass 38758
github level 7 row 2 with dict dds advanced one pass 38747
github level 7 row 2 with dict copy advanced one pass 38755
github level 7 row 2 with dict load advanced one pass 41030
301 github level 7 advanced one pass 135122
302 github level 7 with dict advanced one pass 38758 38771
github level 7 with dict dms advanced one pass 38758
github level 7 with dict dds advanced one pass 38747
github level 7 with dict copy advanced one pass 38755
github level 7 with dict load advanced one pass 40695
303 github level 9 advanced one pass 135122
304 github level 9 with dict advanced one pass 39437 39332
github level 9 with dict dms advanced one pass 39437
github level 9 with dict dds advanced one pass 39338
github level 9 with dict copy advanced one pass 39398
github level 9 with dict load advanced one pass 41710
github level 12 row 1 advanced one pass 134180
github level 12 row 1 with dict dms advanced one pass 39677
github level 12 row 1 with dict dds advanced one pass 39677
github level 12 row 1 with dict copy advanced one pass 39677
github level 12 row 1 with dict load advanced one pass 41166
github level 12 row 2 advanced one pass 134180
github level 12 row 2 with dict dms advanced one pass 39677
github level 12 row 2 with dict dds advanced one pass 39677
github level 12 row 2 with dict copy advanced one pass 39677
github level 12 row 2 with dict load advanced one pass 41166
305 github level 13 advanced one pass 134064
306 github level 13 with dict advanced one pass 39743 39900
github level 13 with dict dms advanced one pass 39743
github level 13 with dict dds advanced one pass 39743
github level 13 with dict copy advanced one pass 39948
github level 13 with dict load advanced one pass 42626
307 github level 16 advanced one pass 134064
308 github level 16 with dict advanced one pass 37577
github level 16 with dict dms advanced one pass 37577
github level 16 with dict dds advanced one pass 37577
github level 16 with dict copy advanced one pass 37568
github level 16 with dict load advanced one pass 42340
309 github level 19 advanced one pass 134064
310 github level 19 with dict advanced one pass 37576
github level 19 with dict dms advanced one pass 37576
github level 19 with dict dds advanced one pass 37576
github level 19 with dict copy advanced one pass 37567
github level 19 with dict load advanced one pass 39613
311 github no source size advanced one pass 136335
312 github no source size with dict advanced one pass 41148
313 github long distance mode advanced one pass 136335
322 github huffman literals advanced one pass 142465
323 github multithreaded with advanced params advanced one pass 165915
324 github.tar level -5 advanced one pass 46856
325 github.tar level -5 with dict advanced one pass 44571 43971
326 github.tar level -3 advanced one pass 43754
327 github.tar level -3 with dict advanced one pass 41447 40805
328 github.tar level -1 advanced one pass 42490
329 github.tar level -1 with dict advanced one pass 41131 41122
330 github.tar level 0 advanced one pass 38441
331 github.tar level 0 with dict advanced one pass 37995
github.tar level 0 with dict dms advanced one pass 38003
github.tar level 0 with dict dds advanced one pass 38003
github.tar level 0 with dict copy advanced one pass 37995
github.tar level 0 with dict load advanced one pass 37956
332 github.tar level 1 advanced one pass 39265
333 github.tar level 1 with dict advanced one pass 38280 38309
github.tar level 1 with dict dms advanced one pass 38290
github.tar level 1 with dict dds advanced one pass 38290
github.tar level 1 with dict copy advanced one pass 38280
github.tar level 1 with dict load advanced one pass 38729
334 github.tar level 3 advanced one pass 38441
335 github.tar level 3 with dict advanced one pass 37995
github.tar level 3 with dict dms advanced one pass 38003
github.tar level 3 with dict dds advanced one pass 38003
github.tar level 3 with dict copy advanced one pass 37995
github.tar level 3 with dict load advanced one pass 37956
336 github.tar level 4 advanced one pass 38467
337 github.tar level 4 with dict advanced one pass 37948
338 github.tar level 4 with dict dms level 5 advanced one pass 37954 39788
339 github.tar level 4 with dict dds level 5 with dict advanced one pass 37954 39715
340 github.tar level 4 with dict copy level 6 advanced one pass 37948 39603
341 github.tar level 4 with dict load level 6 with dict advanced one pass 37927 38800
342 github.tar level 5 row 1 level 7 advanced one pass 39788 39206
343 github.tar level 5 row 1 with dict dms level 7 with dict advanced one pass 39365 38071
344 github.tar level 5 row 1 with dict dds level 9 advanced one pass 39233 36717
345 github.tar level 5 row 1 with dict copy level 9 with dict advanced one pass 39715 36898
github.tar level 5 row 1 with dict load advanced one pass 39209
github.tar level 5 row 2 advanced one pass 39693
github.tar level 5 row 2 with dict dms advanced one pass 39024
github.tar level 5 row 2 with dict dds advanced one pass 39028
github.tar level 5 row 2 with dict copy advanced one pass 39040
github.tar level 5 row 2 with dict load advanced one pass 39037
github.tar level 5 advanced one pass 39693
github.tar level 5 with dict advanced one pass 39040
github.tar level 5 with dict dms advanced one pass 39024
github.tar level 5 with dict dds advanced one pass 39028
github.tar level 5 with dict copy advanced one pass 39040
github.tar level 5 with dict load advanced one pass 39037
github.tar level 6 advanced one pass 39621
github.tar level 6 with dict advanced one pass 38622
github.tar level 6 with dict dms advanced one pass 38608
github.tar level 6 with dict dds advanced one pass 38610
github.tar level 6 with dict copy advanced one pass 38622
github.tar level 6 with dict load advanced one pass 38962
github.tar level 7 row 1 advanced one pass 39206
github.tar level 7 row 1 with dict dms advanced one pass 37954
github.tar level 7 row 1 with dict dds advanced one pass 37954
github.tar level 7 row 1 with dict copy advanced one pass 38071
github.tar level 7 row 1 with dict load advanced one pass 38584
github.tar level 7 row 2 advanced one pass 39213
github.tar level 7 row 2 with dict dms advanced one pass 37848
github.tar level 7 row 2 with dict dds advanced one pass 37867
github.tar level 7 row 2 with dict copy advanced one pass 37848
github.tar level 7 row 2 with dict load advanced one pass 38582
github.tar level 7 advanced one pass 39213
github.tar level 7 with dict advanced one pass 37848
github.tar level 7 with dict dms advanced one pass 37848
github.tar level 7 with dict dds advanced one pass 37867
github.tar level 7 with dict copy advanced one pass 37848
github.tar level 7 with dict load advanced one pass 38582
github.tar level 9 advanced one pass 36758
github.tar level 9 with dict advanced one pass 36457
github.tar level 9 with dict dms advanced one pass 36549
github.tar level 9 with dict dds advanced one pass 36637
github.tar level 9 with dict copy advanced one pass 36457
github.tar level 9 with dict load advanced one pass 36350
github.tar level 12 row 1 advanced one pass 36435
github.tar level 12 row 1 with dict dms advanced one pass 36986
github.tar level 12 row 1 with dict dds advanced one pass 36986
github.tar level 12 row 1 with dict copy advanced one pass 36609
github.tar level 12 row 1 with dict load advanced one pass 36419
github.tar level 12 row 2 advanced one pass 36435
github.tar level 12 row 2 with dict dms advanced one pass 36986
github.tar level 12 row 2 with dict dds advanced one pass 36986
github.tar level 12 row 2 with dict copy advanced one pass 36609
github.tar level 12 row 2 with dict load advanced one pass 36424
346 github.tar level 13 advanced one pass 35621
347 github.tar level 13 with dict advanced one pass 38726
github.tar level 13 with dict dms advanced one pass 38903
github.tar level 13 with dict dds advanced one pass 38903
github.tar level 13 with dict copy advanced one pass 38726
github.tar level 13 with dict load advanced one pass 36372
348 github.tar level 16 advanced one pass 40255
349 github.tar level 16 with dict advanced one pass 33639
github.tar level 16 with dict dms advanced one pass 33544
github.tar level 16 with dict dds advanced one pass 33544
github.tar level 16 with dict copy advanced one pass 33639
github.tar level 16 with dict load advanced one pass 39353
350 github.tar level 19 advanced one pass 32837
351 github.tar level 19 with dict advanced one pass 32895
github.tar level 19 with dict dms advanced one pass 32672
github.tar level 19 with dict dds advanced one pass 32672
github.tar level 19 with dict copy advanced one pass 32895
github.tar level 19 with dict load advanced one pass 32676
352 github.tar no source size advanced one pass 38441
353 github.tar no source size with dict advanced one pass 37995
354 github.tar long distance mode advanced one pass 39757 39722
355 github.tar multithreaded advanced one pass 38441
356 github.tar multithreaded long distance mode advanced one pass 39726 39722
357 github.tar small window log advanced one pass 198540
358 github.tar small hash log advanced one pass 129870
359 github.tar small chain log advanced one pass 41669
360 github.tar explicit params advanced one pass 41227 41199
361 github.tar uncompressed literals advanced one pass 41122
362 github.tar uncompressed literals optimal advanced one pass 35388
363 github.tar huffman literals advanced one pass 38777
369 silesia level 1 advanced one pass small out 5313204
370 silesia level 3 advanced one pass small out 4849552
371 silesia level 4 advanced one pass small out 4786970
372 silesia level 5 row 1 level 5 advanced one pass small out 4710236
373 silesia level 5 row 2 level 6 advanced one pass small out 4707794 4660056
374 silesia level 5 level 7 advanced one pass small out 4707794 4596296
375 silesia level 6 level 9 advanced one pass small out 4666383 4543925
silesia level 7 row 1 advanced one pass small out 4596296
silesia level 7 row 2 advanced one pass small out 4603381
silesia level 7 advanced one pass small out 4603381
silesia level 9 advanced one pass small out 4546001
silesia level 12 row 1 advanced one pass small out 4519288
silesia level 12 row 2 advanced one pass small out 4521397
376 silesia level 13 advanced one pass small out 4482135
377 silesia level 16 advanced one pass small out 4360251 4377465
378 silesia level 19 advanced one pass small out 4283237 4293330
379 silesia no source size advanced one pass small out 4849552
380 silesia long distance mode advanced one pass small out 4840738 4840744
381 silesia multithreaded advanced one pass small out 4849552
382 silesia multithreaded long distance mode advanced one pass small out 4840758 4840744
383 silesia small window log advanced one pass small out 7095919
384 silesia small hash log advanced one pass small out 6526141 6555021
385 silesia small chain log advanced one pass small out 4912197 4931148
386 silesia explicit params advanced one pass small out 4795856 4797095
387 silesia uncompressed literals advanced one pass small out 5127982
388 silesia uncompressed literals optimal advanced one pass small out 4317896 4325472
389 silesia huffman literals advanced one pass small out 5326268
390 silesia multithreaded with advanced params advanced one pass small out 5127982
391 silesia.tar level -5 advanced one pass small out 6738593
395 silesia.tar level 1 advanced one pass small out 5334885
396 silesia.tar level 3 advanced one pass small out 4861425
397 silesia.tar level 4 advanced one pass small out 4799630
398 silesia.tar level 5 row 1 level 5 advanced one pass small out 4722324
399 silesia.tar level 5 row 2 level 6 advanced one pass small out 4719256 4672279
400 silesia.tar level 5 level 7 advanced one pass small out 4719256 4606715
401 silesia.tar level 6 level 9 advanced one pass small out 4677721 4554147
silesia.tar level 7 row 1 advanced one pass small out 4606715
silesia.tar level 7 row 2 advanced one pass small out 4613541
silesia.tar level 7 advanced one pass small out 4613541
silesia.tar level 9 advanced one pass small out 4555426
silesia.tar level 12 row 1 advanced one pass small out 4529459
silesia.tar level 12 row 2 advanced one pass small out 4530256
402 silesia.tar level 13 advanced one pass small out 4491764
403 silesia.tar level 16 advanced one pass small out 4356827 4381332
404 silesia.tar level 19 advanced one pass small out 4264487 4281605
405 silesia.tar no source size advanced one pass small out 4861425
406 silesia.tar long distance mode advanced one pass small out 4847754 4847735
407 silesia.tar multithreaded advanced one pass small out 4861508
408 silesia.tar multithreaded long distance mode advanced one pass small out 4853222 4853149
409 silesia.tar small window log advanced one pass small out 7101530
410 silesia.tar small hash log advanced one pass small out 6529232 6587951
411 silesia.tar small chain log advanced one pass small out 4917041 4943307
412 silesia.tar explicit params advanced one pass small out 4807380 4808589
413 silesia.tar uncompressed literals advanced one pass small out 5129458
414 silesia.tar uncompressed literals optimal advanced one pass small out 4307453 4320927
415 silesia.tar huffman literals advanced one pass small out 5347335
416 silesia.tar multithreaded with advanced params advanced one pass small out 5129555
417 github level -5 advanced one pass small out 205285
422 github level -1 with dict advanced one pass small out 43170
423 github level 0 advanced one pass small out 136335
424 github level 0 with dict advanced one pass small out 41148
github level 0 with dict dms advanced one pass small out 41148
github level 0 with dict dds advanced one pass small out 41148
github level 0 with dict copy advanced one pass small out 41124
github level 0 with dict load advanced one pass small out 42252
425 github level 1 advanced one pass small out 142465
426 github level 1 with dict advanced one pass small out 41682
github level 1 with dict dms advanced one pass small out 41682
github level 1 with dict dds advanced one pass small out 41682
github level 1 with dict copy advanced one pass small out 41674
github level 1 with dict load advanced one pass small out 43755
427 github level 3 advanced one pass small out 136335
428 github level 3 with dict advanced one pass small out 41148
github level 3 with dict dms advanced one pass small out 41148
github level 3 with dict dds advanced one pass small out 41148
github level 3 with dict copy advanced one pass small out 41124
github level 3 with dict load advanced one pass small out 42252
429 github level 4 advanced one pass small out 136199
430 github level 4 with dict advanced one pass small out 41251
github level 4 with dict dms advanced one pass small out 41251
github level 4 with dict dds advanced one pass small out 41251
github level 4 with dict copy advanced one pass small out 41216
github level 4 with dict load advanced one pass small out 41159
github level 5 row 1 advanced one pass small out 135121
github level 5 row 1 with dict dms advanced one pass small out 38938
github level 5 row 1 with dict dds advanced one pass small out 38732
github level 5 row 1 with dict copy advanced one pass small out 38934
github level 5 row 1 with dict load advanced one pass small out 40725
github level 5 row 2 advanced one pass small out 134584
github level 5 row 2 with dict dms advanced one pass small out 38758
github level 5 row 2 with dict dds advanced one pass small out 38728
github level 5 row 2 with dict copy advanced one pass small out 38759
github level 5 row 2 with dict load advanced one pass small out 41518
431 github level 5 advanced one pass small out 135121
432 github level 5 with dict advanced one pass small out 38758 38938
github level 5 with dict dms advanced one pass small out 38758
github level 5 with dict dds advanced one pass small out 38728
github level 5 with dict copy advanced one pass small out 38759
github level 5 with dict load advanced one pass small out 40725
433 github level 6 advanced one pass small out 135122
434 github level 6 with dict advanced one pass small out 38671 38632
github level 6 with dict dms advanced one pass small out 38671
github level 6 with dict dds advanced one pass small out 38630
github level 6 with dict copy advanced one pass small out 38669
github level 6 with dict load advanced one pass small out 40695
github level 7 row 1 advanced one pass small out 135122
github level 7 row 1 with dict dms advanced one pass small out 38771
github level 7 row 1 with dict dds advanced one pass small out 38771
github level 7 row 1 with dict copy advanced one pass small out 38745
github level 7 row 1 with dict load advanced one pass small out 40695
github level 7 row 2 advanced one pass small out 134584
github level 7 row 2 with dict dms advanced one pass small out 38758
github level 7 row 2 with dict dds advanced one pass small out 38747
github level 7 row 2 with dict copy advanced one pass small out 38755
github level 7 row 2 with dict load advanced one pass small out 41030
435 github level 7 advanced one pass small out 135122
436 github level 7 with dict advanced one pass small out 38758 38771
github level 7 with dict dms advanced one pass small out 38758
github level 7 with dict dds advanced one pass small out 38747
github level 7 with dict copy advanced one pass small out 38755
github level 7 with dict load advanced one pass small out 40695
437 github level 9 advanced one pass small out 135122
438 github level 9 with dict advanced one pass small out 39437 39332
github level 9 with dict dms advanced one pass small out 39437
github level 9 with dict dds advanced one pass small out 39338
github level 9 with dict copy advanced one pass small out 39398
github level 9 with dict load advanced one pass small out 41710
github level 12 row 1 advanced one pass small out 134180
github level 12 row 1 with dict dms advanced one pass small out 39677
github level 12 row 1 with dict dds advanced one pass small out 39677
github level 12 row 1 with dict copy advanced one pass small out 39677
github level 12 row 1 with dict load advanced one pass small out 41166
github level 12 row 2 advanced one pass small out 134180
github level 12 row 2 with dict dms advanced one pass small out 39677
github level 12 row 2 with dict dds advanced one pass small out 39677
github level 12 row 2 with dict copy advanced one pass small out 39677
github level 12 row 2 with dict load advanced one pass small out 41166
439 github level 13 advanced one pass small out 134064
440 github level 13 with dict advanced one pass small out 39743 39900
github level 13 with dict dms advanced one pass small out 39743
github level 13 with dict dds advanced one pass small out 39743
github level 13 with dict copy advanced one pass small out 39948
github level 13 with dict load advanced one pass small out 42626
441 github level 16 advanced one pass small out 134064
442 github level 16 with dict advanced one pass small out 37577
github level 16 with dict dms advanced one pass small out 37577
github level 16 with dict dds advanced one pass small out 37577
github level 16 with dict copy advanced one pass small out 37568
github level 16 with dict load advanced one pass small out 42340
443 github level 19 advanced one pass small out 134064
444 github level 19 with dict advanced one pass small out 37576
github level 19 with dict dms advanced one pass small out 37576
github level 19 with dict dds advanced one pass small out 37576
github level 19 with dict copy advanced one pass small out 37567
github level 19 with dict load advanced one pass small out 39613
445 github no source size advanced one pass small out 136335
446 github no source size with dict advanced one pass small out 41148
447 github long distance mode advanced one pass small out 136335
456 github huffman literals advanced one pass small out 142465
457 github multithreaded with advanced params advanced one pass small out 165915
458 github.tar level -5 advanced one pass small out 46856
459 github.tar level -5 with dict advanced one pass small out 44571 43971
460 github.tar level -3 advanced one pass small out 43754
461 github.tar level -3 with dict advanced one pass small out 41447 40805
462 github.tar level -1 advanced one pass small out 42490
463 github.tar level -1 with dict advanced one pass small out 41131 41122
464 github.tar level 0 advanced one pass small out 38441
465 github.tar level 0 with dict advanced one pass small out 37995
github.tar level 0 with dict dms advanced one pass small out 38003
github.tar level 0 with dict dds advanced one pass small out 38003
github.tar level 0 with dict copy advanced one pass small out 37995
github.tar level 0 with dict load advanced one pass small out 37956
466 github.tar level 1 advanced one pass small out 39265
467 github.tar level 1 with dict advanced one pass small out 38280 38309
github.tar level 1 with dict dms advanced one pass small out 38290
github.tar level 1 with dict dds advanced one pass small out 38290
github.tar level 1 with dict copy advanced one pass small out 38280
github.tar level 1 with dict load advanced one pass small out 38729
468 github.tar level 3 advanced one pass small out 38441
469 github.tar level 3 with dict advanced one pass small out 37995
github.tar level 3 with dict dms advanced one pass small out 38003
github.tar level 3 with dict dds advanced one pass small out 38003
github.tar level 3 with dict copy advanced one pass small out 37995
github.tar level 3 with dict load advanced one pass small out 37956
470 github.tar level 4 advanced one pass small out 38467
471 github.tar level 4 with dict advanced one pass small out 37948
472 github.tar level 4 with dict dms level 5 advanced one pass small out 37954 39788
473 github.tar level 4 with dict dds level 5 with dict advanced one pass small out 37954 39715
474 github.tar level 4 with dict copy level 6 advanced one pass small out 37948 39603
475 github.tar level 4 with dict load level 6 with dict advanced one pass small out 37927 38800
476 github.tar level 5 row 1 level 7 advanced one pass small out 39788 39206
477 github.tar level 5 row 1 with dict dms level 7 with dict advanced one pass small out 39365 38071
478 github.tar level 5 row 1 with dict dds level 9 advanced one pass small out 39233 36717
479 github.tar level 5 row 1 with dict copy level 9 with dict advanced one pass small out 39715 36898
github.tar level 5 row 1 with dict load advanced one pass small out 39209
github.tar level 5 row 2 advanced one pass small out 39693
github.tar level 5 row 2 with dict dms advanced one pass small out 39024
github.tar level 5 row 2 with dict dds advanced one pass small out 39028
github.tar level 5 row 2 with dict copy advanced one pass small out 39040
github.tar level 5 row 2 with dict load advanced one pass small out 39037
github.tar level 5 advanced one pass small out 39693
github.tar level 5 with dict advanced one pass small out 39040
github.tar level 5 with dict dms advanced one pass small out 39024
github.tar level 5 with dict dds advanced one pass small out 39028
github.tar level 5 with dict copy advanced one pass small out 39040
github.tar level 5 with dict load advanced one pass small out 39037
github.tar level 6 advanced one pass small out 39621
github.tar level 6 with dict advanced one pass small out 38622
github.tar level 6 with dict dms advanced one pass small out 38608
github.tar level 6 with dict dds advanced one pass small out 38610
github.tar level 6 with dict copy advanced one pass small out 38622
github.tar level 6 with dict load advanced one pass small out 38962
github.tar level 7 row 1 advanced one pass small out 39206
github.tar level 7 row 1 with dict dms advanced one pass small out 37954
github.tar level 7 row 1 with dict dds advanced one pass small out 37954
github.tar level 7 row 1 with dict copy advanced one pass small out 38071
github.tar level 7 row 1 with dict load advanced one pass small out 38584
github.tar level 7 row 2 advanced one pass small out 39213
github.tar level 7 row 2 with dict dms advanced one pass small out 37848
github.tar level 7 row 2 with dict dds advanced one pass small out 37867
github.tar level 7 row 2 with dict copy advanced one pass small out 37848
github.tar level 7 row 2 with dict load advanced one pass small out 38582
github.tar level 7 advanced one pass small out 39213
github.tar level 7 with dict advanced one pass small out 37848
github.tar level 7 with dict dms advanced one pass small out 37848
github.tar level 7 with dict dds advanced one pass small out 37867
github.tar level 7 with dict copy advanced one pass small out 37848
github.tar level 7 with dict load advanced one pass small out 38582
github.tar level 9 advanced one pass small out 36758
github.tar level 9 with dict advanced one pass small out 36457
github.tar level 9 with dict dms advanced one pass small out 36549
github.tar level 9 with dict dds advanced one pass small out 36637
github.tar level 9 with dict copy advanced one pass small out 36457
github.tar level 9 with dict load advanced one pass small out 36350
github.tar level 12 row 1 advanced one pass small out 36435
github.tar level 12 row 1 with dict dms advanced one pass small out 36986
github.tar level 12 row 1 with dict dds advanced one pass small out 36986
github.tar level 12 row 1 with dict copy advanced one pass small out 36609
github.tar level 12 row 1 with dict load advanced one pass small out 36419
github.tar level 12 row 2 advanced one pass small out 36435
github.tar level 12 row 2 with dict dms advanced one pass small out 36986
github.tar level 12 row 2 with dict dds advanced one pass small out 36986
github.tar level 12 row 2 with dict copy advanced one pass small out 36609
github.tar level 12 row 2 with dict load advanced one pass small out 36424
480 github.tar level 13 advanced one pass small out 35621
481 github.tar level 13 with dict advanced one pass small out 38726
github.tar level 13 with dict dms advanced one pass small out 38903
github.tar level 13 with dict dds advanced one pass small out 38903
github.tar level 13 with dict copy advanced one pass small out 38726
github.tar level 13 with dict load advanced one pass small out 36372
482 github.tar level 16 advanced one pass small out 40255
483 github.tar level 16 with dict advanced one pass small out 33639
github.tar level 16 with dict dms advanced one pass small out 33544
github.tar level 16 with dict dds advanced one pass small out 33544
github.tar level 16 with dict copy advanced one pass small out 33639
github.tar level 16 with dict load advanced one pass small out 39353
484 github.tar level 19 advanced one pass small out 32837
485 github.tar level 19 with dict advanced one pass small out 32895
github.tar level 19 with dict dms advanced one pass small out 32672
github.tar level 19 with dict dds advanced one pass small out 32672
github.tar level 19 with dict copy advanced one pass small out 32895
github.tar level 19 with dict load advanced one pass small out 32676
486 github.tar no source size advanced one pass small out 38441
487 github.tar no source size with dict advanced one pass small out 37995
488 github.tar long distance mode advanced one pass small out 39757 39722
489 github.tar multithreaded advanced one pass small out 38441
490 github.tar multithreaded long distance mode advanced one pass small out 39726 39722
491 github.tar small window log advanced one pass small out 198540
492 github.tar small hash log advanced one pass small out 129870
493 github.tar small chain log advanced one pass small out 41669
494 github.tar explicit params advanced one pass small out 41227 41199
495 github.tar uncompressed literals advanced one pass small out 41122
496 github.tar uncompressed literals optimal advanced one pass small out 35388
497 github.tar huffman literals advanced one pass small out 38777
503 silesia level 1 advanced streaming 5314162
504 silesia level 3 advanced streaming 4849552
505 silesia level 4 advanced streaming 4786970
506 silesia level 5 row 1 level 5 advanced streaming 4710236
507 silesia level 5 row 2 level 6 advanced streaming 4707794 4660056
508 silesia level 5 level 7 advanced streaming 4707794 4596296
509 silesia level 6 level 9 advanced streaming 4666383 4543925
silesia level 7 row 1 advanced streaming 4596296
silesia level 7 row 2 advanced streaming 4603381
silesia level 7 advanced streaming 4603381
silesia level 9 advanced streaming 4546001
silesia level 12 row 1 advanced streaming 4519288
silesia level 12 row 2 advanced streaming 4521397
510 silesia level 13 advanced streaming 4482135
511 silesia level 16 advanced streaming 4360251 4377465
512 silesia level 19 advanced streaming 4283237 4293330
513 silesia no source size advanced streaming 4849516
514 silesia long distance mode advanced streaming 4840738 4840744
515 silesia multithreaded advanced streaming 4849552
516 silesia multithreaded long distance mode advanced streaming 4840758 4840744
517 silesia small window log advanced streaming 7112062
518 silesia small hash log advanced streaming 6526141 6555021
519 silesia small chain log advanced streaming 4912197 4931148
520 silesia explicit params advanced streaming 4795887 4797112
521 silesia uncompressed literals advanced streaming 5127982
522 silesia uncompressed literals optimal advanced streaming 4317896 4325472
523 silesia huffman literals advanced streaming 5331168
524 silesia multithreaded with advanced params advanced streaming 5127982
525 silesia.tar level -5 advanced streaming 6982759
529 silesia.tar level 1 advanced streaming 5336939
530 silesia.tar level 3 advanced streaming 4861427
531 silesia.tar level 4 advanced streaming 4799630
532 silesia.tar level 5 row 1 level 5 advanced streaming 4722329
533 silesia.tar level 5 row 2 level 6 advanced streaming 4719261 4672288
534 silesia.tar level 5 level 7 advanced streaming 4719261 4606715
535 silesia.tar level 6 level 9 advanced streaming 4677729 4554154
silesia.tar level 7 row 1 advanced streaming 4606715
silesia.tar level 7 row 2 advanced streaming 4613544
silesia.tar level 7 advanced streaming 4613544
silesia.tar level 9 advanced streaming 4555432
silesia.tar level 12 row 1 advanced streaming 4529459
silesia.tar level 12 row 2 advanced streaming 4530258
536 silesia.tar level 13 advanced streaming 4491765
537 silesia.tar level 16 advanced streaming 4356834 4381350
538 silesia.tar level 19 advanced streaming 4264392 4281562
539 silesia.tar no source size advanced streaming 4861423
540 silesia.tar long distance mode advanced streaming 4847754 4847735
541 silesia.tar multithreaded advanced streaming 4861508
542 silesia.tar multithreaded long distance mode advanced streaming 4853222 4853149
543 silesia.tar small window log advanced streaming 7118769
544 silesia.tar small hash log advanced streaming 6529235 6587952
545 silesia.tar small chain log advanced streaming 4917021 4943312
546 silesia.tar explicit params advanced streaming 4807401 4808618
547 silesia.tar uncompressed literals advanced streaming 5129461
548 silesia.tar uncompressed literals optimal advanced streaming 4307400 4320858
549 silesia.tar huffman literals advanced streaming 5352360
550 silesia.tar multithreaded with advanced params advanced streaming 5129555
551 github level -5 advanced streaming 205285
556 github level -1 with dict advanced streaming 43170
557 github level 0 advanced streaming 136335
558 github level 0 with dict advanced streaming 41148
github level 0 with dict dms advanced streaming 41148
github level 0 with dict dds advanced streaming 41148
github level 0 with dict copy advanced streaming 41124
github level 0 with dict load advanced streaming 42252
559 github level 1 advanced streaming 142465
560 github level 1 with dict advanced streaming 41682
github level 1 with dict dms advanced streaming 41682
github level 1 with dict dds advanced streaming 41682
github level 1 with dict copy advanced streaming 41674
github level 1 with dict load advanced streaming 43755
561 github level 3 advanced streaming 136335
562 github level 3 with dict advanced streaming 41148
github level 3 with dict dms advanced streaming 41148
github level 3 with dict dds advanced streaming 41148
github level 3 with dict copy advanced streaming 41124
github level 3 with dict load advanced streaming 42252
563 github level 4 advanced streaming 136199
564 github level 4 with dict advanced streaming 41251
github level 4 with dict dms advanced streaming 41251
github level 4 with dict dds advanced streaming 41251
github level 4 with dict copy advanced streaming 41216
github level 4 with dict load advanced streaming 41159
github level 5 row 1 advanced streaming 135121
github level 5 row 1 with dict dms advanced streaming 38938
github level 5 row 1 with dict dds advanced streaming 38732
github level 5 row 1 with dict copy advanced streaming 38934
github level 5 row 1 with dict load advanced streaming 40725
github level 5 row 2 advanced streaming 134584
github level 5 row 2 with dict dms advanced streaming 38758
github level 5 row 2 with dict dds advanced streaming 38728
github level 5 row 2 with dict copy advanced streaming 38759
github level 5 row 2 with dict load advanced streaming 41518
565 github level 5 advanced streaming 135121
566 github level 5 with dict advanced streaming 38758 38938
github level 5 with dict dms advanced streaming 38758
github level 5 with dict dds advanced streaming 38728
github level 5 with dict copy advanced streaming 38759
github level 5 with dict load advanced streaming 40725
567 github level 6 advanced streaming 135122
568 github level 6 with dict advanced streaming 38671 38632
github level 6 with dict dms advanced streaming 38671
github level 6 with dict dds advanced streaming 38630
github level 6 with dict copy advanced streaming 38669
github level 6 with dict load advanced streaming 40695
github level 7 row 1 advanced streaming 135122
github level 7 row 1 with dict dms advanced streaming 38771
github level 7 row 1 with dict dds advanced streaming 38771
github level 7 row 1 with dict copy advanced streaming 38745
github level 7 row 1 with dict load advanced streaming 40695
github level 7 row 2 advanced streaming 134584
github level 7 row 2 with dict dms advanced streaming 38758
github level 7 row 2 with dict dds advanced streaming 38747
github level 7 row 2 with dict copy advanced streaming 38755
github level 7 row 2 with dict load advanced streaming 41030
569 github level 7 advanced streaming 135122
570 github level 7 with dict advanced streaming 38758 38771
github level 7 with dict dms advanced streaming 38758
github level 7 with dict dds advanced streaming 38747
github level 7 with dict copy advanced streaming 38755
github level 7 with dict load advanced streaming 40695
571 github level 9 advanced streaming 135122
572 github level 9 with dict advanced streaming 39437 39332
github level 9 with dict dms advanced streaming 39437
github level 9 with dict dds advanced streaming 39338
github level 9 with dict copy advanced streaming 39398
github level 9 with dict load advanced streaming 41710
github level 12 row 1 advanced streaming 134180
github level 12 row 1 with dict dms advanced streaming 39677
github level 12 row 1 with dict dds advanced streaming 39677
github level 12 row 1 with dict copy advanced streaming 39677
github level 12 row 1 with dict load advanced streaming 41166
github level 12 row 2 advanced streaming 134180
github level 12 row 2 with dict dms advanced streaming 39677
github level 12 row 2 with dict dds advanced streaming 39677
github level 12 row 2 with dict copy advanced streaming 39677
github level 12 row 2 with dict load advanced streaming 41166
573 github level 13 advanced streaming 134064
574 github level 13 with dict advanced streaming 39743 39900
github level 13 with dict dms advanced streaming 39743
github level 13 with dict dds advanced streaming 39743
github level 13 with dict copy advanced streaming 39948
github level 13 with dict load advanced streaming 42626
575 github level 16 advanced streaming 134064
576 github level 16 with dict advanced streaming 37577
github level 16 with dict dms advanced streaming 37577
github level 16 with dict dds advanced streaming 37577
github level 16 with dict copy advanced streaming 37568
github level 16 with dict load advanced streaming 42340
577 github level 19 advanced streaming 134064
578 github level 19 with dict advanced streaming 37576
github level 19 with dict dms advanced streaming 37576
github level 19 with dict dds advanced streaming 37576
github level 19 with dict copy advanced streaming 37567
github level 19 with dict load advanced streaming 39613
579 github no source size advanced streaming 136335
580 github no source size with dict advanced streaming 41148
581 github long distance mode advanced streaming 136335
590 github huffman literals advanced streaming 142465
591 github multithreaded with advanced params advanced streaming 165915
592 github.tar level -5 advanced streaming 46747
593 github.tar level -5 with dict advanced streaming 44440 43971
594 github.tar level -3 advanced streaming 43537
595 github.tar level -3 with dict advanced streaming 41112 40805
596 github.tar level -1 advanced streaming 42465
597 github.tar level -1 with dict advanced streaming 41196 41122
598 github.tar level 0 advanced streaming 38441
599 github.tar level 0 with dict advanced streaming 37995
github.tar level 0 with dict dms advanced streaming 38003
github.tar level 0 with dict dds advanced streaming 38003
github.tar level 0 with dict copy advanced streaming 37995
github.tar level 0 with dict load advanced streaming 37956
600 github.tar level 1 advanced streaming 39342
601 github.tar level 1 with dict advanced streaming 38293 38309
github.tar level 1 with dict dms advanced streaming 38303
github.tar level 1 with dict dds advanced streaming 38303
github.tar level 1 with dict copy advanced streaming 38293
github.tar level 1 with dict load advanced streaming 38766
602 github.tar level 3 advanced streaming 38441
603 github.tar level 3 with dict advanced streaming 37995
github.tar level 3 with dict dms advanced streaming 38003
github.tar level 3 with dict dds advanced streaming 38003
github.tar level 3 with dict copy advanced streaming 37995
github.tar level 3 with dict load advanced streaming 37956
604 github.tar level 4 advanced streaming 38467
605 github.tar level 4 with dict advanced streaming 37948
606 github.tar level 4 with dict dms level 5 advanced streaming 37954 39788
607 github.tar level 4 with dict dds level 5 with dict advanced streaming 37954 39715
608 github.tar level 4 with dict copy level 6 advanced streaming 37948 39603
609 github.tar level 4 with dict load level 6 with dict advanced streaming 37927 38800
610 github.tar level 5 row 1 level 7 advanced streaming 39788 39206
611 github.tar level 5 row 1 with dict dms level 7 with dict advanced streaming 39365 38071
612 github.tar level 5 row 1 with dict dds level 9 advanced streaming 39233 36717
613 github.tar level 5 row 1 with dict copy level 9 with dict advanced streaming 39715 36898
github.tar level 5 row 1 with dict load advanced streaming 39209
github.tar level 5 row 2 advanced streaming 39693
github.tar level 5 row 2 with dict dms advanced streaming 39024
github.tar level 5 row 2 with dict dds advanced streaming 39028
github.tar level 5 row 2 with dict copy advanced streaming 39040
github.tar level 5 row 2 with dict load advanced streaming 39037
github.tar level 5 advanced streaming 39693
github.tar level 5 with dict advanced streaming 39040
github.tar level 5 with dict dms advanced streaming 39024
github.tar level 5 with dict dds advanced streaming 39028
github.tar level 5 with dict copy advanced streaming 39040
github.tar level 5 with dict load advanced streaming 39037
github.tar level 6 advanced streaming 39621
github.tar level 6 with dict advanced streaming 38622
github.tar level 6 with dict dms advanced streaming 38608
github.tar level 6 with dict dds advanced streaming 38610
github.tar level 6 with dict copy advanced streaming 38622
github.tar level 6 with dict load advanced streaming 38962
github.tar level 7 row 1 advanced streaming 39206
github.tar level 7 row 1 with dict dms advanced streaming 37954
github.tar level 7 row 1 with dict dds advanced streaming 37954
github.tar level 7 row 1 with dict copy advanced streaming 38071
github.tar level 7 row 1 with dict load advanced streaming 38584
github.tar level 7 row 2 advanced streaming 39213
github.tar level 7 row 2 with dict dms advanced streaming 37848
github.tar level 7 row 2 with dict dds advanced streaming 37867
github.tar level 7 row 2 with dict copy advanced streaming 37848
github.tar level 7 row 2 with dict load advanced streaming 38582
github.tar level 7 advanced streaming 39213
github.tar level 7 with dict advanced streaming 37848
github.tar level 7 with dict dms advanced streaming 37848
github.tar level 7 with dict dds advanced streaming 37867
github.tar level 7 with dict copy advanced streaming 37848
github.tar level 7 with dict load advanced streaming 38582
github.tar level 9 advanced streaming 36758
github.tar level 9 with dict advanced streaming 36457
github.tar level 9 with dict dms advanced streaming 36549
github.tar level 9 with dict dds advanced streaming 36637
github.tar level 9 with dict copy advanced streaming 36457
github.tar level 9 with dict load advanced streaming 36350
github.tar level 12 row 1 advanced streaming 36435
github.tar level 12 row 1 with dict dms advanced streaming 36986
github.tar level 12 row 1 with dict dds advanced streaming 36986
github.tar level 12 row 1 with dict copy advanced streaming 36609
github.tar level 12 row 1 with dict load advanced streaming 36419
github.tar level 12 row 2 advanced streaming 36435
github.tar level 12 row 2 with dict dms advanced streaming 36986
github.tar level 12 row 2 with dict dds advanced streaming 36986
github.tar level 12 row 2 with dict copy advanced streaming 36609
github.tar level 12 row 2 with dict load advanced streaming 36424
614 github.tar level 13 advanced streaming 35621
615 github.tar level 13 with dict advanced streaming 38726
github.tar level 13 with dict dms advanced streaming 38903
github.tar level 13 with dict dds advanced streaming 38903
github.tar level 13 with dict copy advanced streaming 38726
github.tar level 13 with dict load advanced streaming 36372
616 github.tar level 16 advanced streaming 40255
617 github.tar level 16 with dict advanced streaming 33639
github.tar level 16 with dict dms advanced streaming 33544
github.tar level 16 with dict dds advanced streaming 33544
github.tar level 16 with dict copy advanced streaming 33639
github.tar level 16 with dict load advanced streaming 39353
618 github.tar level 19 advanced streaming 32837
619 github.tar level 19 with dict advanced streaming 32895
github.tar level 19 with dict dms advanced streaming 32672
github.tar level 19 with dict dds advanced streaming 32672
github.tar level 19 with dict copy advanced streaming 32895
github.tar level 19 with dict load advanced streaming 32676
620 github.tar no source size advanced streaming 38438
621 github.tar no source size with dict advanced streaming 38000
622 github.tar long distance mode advanced streaming 39757 39722
623 github.tar multithreaded advanced streaming 38441
624 github.tar multithreaded long distance mode advanced streaming 39726 39722
625 github.tar small window log advanced streaming 199558
626 github.tar small hash log advanced streaming 129870
627 github.tar small chain log advanced streaming 41669
628 github.tar explicit params advanced streaming 41227 41199
629 github.tar uncompressed literals advanced streaming 41122
630 github.tar uncompressed literals optimal advanced streaming 35388
631 github.tar huffman literals advanced streaming 38800
637 silesia level 1 old streaming 5314162
638 silesia level 3 old streaming 4849552
639 silesia level 4 old streaming 4786970
640 silesia level 5 old streaming 4707794 4710236
641 silesia level 6 old streaming 4666383 4660056
642 silesia level 7 old streaming 4603381 4596296
643 silesia level 9 old streaming 4546001 4543925
644 silesia level 13 old streaming 4482135
645 silesia level 16 old streaming 4360251 4377465
646 silesia level 19 old streaming 4283237 4293330
647 silesia no source size old streaming 4849516
648 silesia uncompressed literals old streaming 4849552
649 silesia uncompressed literals optimal old streaming 4283237 4293330
650 silesia huffman literals old streaming 6183403
651 silesia.tar level -5 old streaming 6982759
652 silesia.tar level -3 old streaming 6641283
655 silesia.tar level 1 old streaming 5336939
656 silesia.tar level 3 old streaming 4861427
657 silesia.tar level 4 old streaming 4799630
658 silesia.tar level 5 old streaming 4719261 4722329
659 silesia.tar level 6 old streaming 4677729 4672288
660 silesia.tar level 7 old streaming 4613544 4606715
661 silesia.tar level 9 old streaming 4555432 4554154
662 silesia.tar level 13 old streaming 4491765
663 silesia.tar level 16 old streaming 4356834 4381350
664 silesia.tar level 19 old streaming 4264392 4281562
665 silesia.tar no source size old streaming 4861423
666 silesia.tar uncompressed literals old streaming 4861427
667 silesia.tar uncompressed literals optimal old streaming 4264392 4281562
668 silesia.tar huffman literals old streaming 6190795
669 github level -5 old streaming 205285
670 github level -5 with dict old streaming 46718
681 github level 4 old streaming 136199
682 github level 4 with dict old streaming 41251
683 github level 5 old streaming 135121
684 github level 5 with dict old streaming 38758 38938
685 github level 6 old streaming 135122
686 github level 6 with dict old streaming 38671 38632
687 github level 7 old streaming 135122
688 github level 7 with dict old streaming 38758 38771
689 github level 9 old streaming 135122
690 github level 9 with dict old streaming 39437 39332
691 github level 13 old streaming 134064
692 github level 13 with dict old streaming 39743 39900
693 github level 16 old streaming 134064
694 github level 16 with dict old streaming 37577
695 github level 19 old streaming 134064
700 github uncompressed literals optimal old streaming 134064
701 github huffman literals old streaming 175568
702 github.tar level -5 old streaming 46747
703 github.tar level -5 with dict old streaming 44440 43971
704 github.tar level -3 old streaming 43537
705 github.tar level -3 with dict old streaming 41112 40805
706 github.tar level -1 old streaming 42465
707 github.tar level -1 with dict old streaming 41196 41122
708 github.tar level 0 old streaming 38441
709 github.tar level 0 with dict old streaming 37995
710 github.tar level 1 old streaming 39342
711 github.tar level 1 with dict old streaming 38293 38309
712 github.tar level 3 old streaming 38441
713 github.tar level 3 with dict old streaming 37995
714 github.tar level 4 old streaming 38467
715 github.tar level 4 with dict old streaming 37948
716 github.tar level 5 old streaming 39693 39788
717 github.tar level 5 with dict old streaming 39040 39715
718 github.tar level 6 old streaming 39621 39603
719 github.tar level 6 with dict old streaming 38622 38800
720 github.tar level 7 old streaming 39213 39206
721 github.tar level 7 with dict old streaming 37848 38071
722 github.tar level 9 old streaming 36758 36717
723 github.tar level 9 with dict old streaming 36457 36898
724 github.tar level 13 old streaming 35621
725 github.tar level 13 with dict old streaming 38726
726 github.tar level 16 old streaming 40255
739 silesia level 1 old streaming advanced 5314162
740 silesia level 3 old streaming advanced 4849552
741 silesia level 4 old streaming advanced 4786970
742 silesia level 5 old streaming advanced 4707794 4710236
743 silesia level 6 old streaming advanced 4666383 4660056
744 silesia level 7 old streaming advanced 4603381 4596296
745 silesia level 9 old streaming advanced 4546001 4543925
746 silesia level 13 old streaming advanced 4482135
747 silesia level 16 old streaming advanced 4360251 4377465
748 silesia level 19 old streaming advanced 4283237 4293330
749 silesia no source size old streaming advanced 4849516
750 silesia long distance mode old streaming advanced 4849552
751 silesia multithreaded old streaming advanced 4849552
752 silesia multithreaded long distance mode old streaming advanced 4849552
753 silesia small window log old streaming advanced 7112062
754 silesia small hash log old streaming advanced 6526141 6555021
755 silesia small chain log old streaming advanced 4912197 4931148
756 silesia explicit params old streaming advanced 4795887 4797112
757 silesia uncompressed literals old streaming advanced 4849552
758 silesia uncompressed literals optimal old streaming advanced 4283237 4293330
759 silesia huffman literals old streaming advanced 6183403
760 silesia multithreaded with advanced params old streaming advanced 4849552
761 silesia.tar level -5 old streaming advanced 6982759
765 silesia.tar level 1 old streaming advanced 5336939
766 silesia.tar level 3 old streaming advanced 4861427
767 silesia.tar level 4 old streaming advanced 4799630
768 silesia.tar level 5 old streaming advanced 4719261 4722329
769 silesia.tar level 6 old streaming advanced 4677729 4672288
770 silesia.tar level 7 old streaming advanced 4613544 4606715
771 silesia.tar level 9 old streaming advanced 4555432 4554154
772 silesia.tar level 13 old streaming advanced 4491765
773 silesia.tar level 16 old streaming advanced 4356834 4381350
774 silesia.tar level 19 old streaming advanced 4264392 4281562
775 silesia.tar no source size old streaming advanced 4861423
776 silesia.tar long distance mode old streaming advanced 4861427
777 silesia.tar multithreaded old streaming advanced 4861427
778 silesia.tar multithreaded long distance mode old streaming advanced 4861427
779 silesia.tar small window log old streaming advanced 7118772
780 silesia.tar small hash log old streaming advanced 6529235 6587952
781 silesia.tar small chain log old streaming advanced 4917021 4943312
782 silesia.tar explicit params old streaming advanced 4807401 4808618
783 silesia.tar uncompressed literals old streaming advanced 4861427
784 silesia.tar uncompressed literals optimal old streaming advanced 4264392 4281562
785 silesia.tar huffman literals old streaming advanced 6190795
786 silesia.tar multithreaded with advanced params old streaming advanced 4861427
787 github level -5 old streaming advanced 216734
799 github level 4 old streaming advanced 141104
800 github level 4 with dict old streaming advanced 41084
801 github level 5 old streaming advanced 139399
802 github level 5 with dict old streaming advanced 38633 39159
803 github level 6 old streaming advanced 139402
804 github level 6 with dict old streaming advanced 38723 38749
805 github level 7 old streaming advanced 138676
806 github level 7 with dict old streaming advanced 38744 38746
807 github level 9 old streaming advanced 138676
808 github level 9 with dict old streaming advanced 38981 38993
809 github level 13 old streaming advanced 138676
810 github level 13 with dict old streaming advanced 39731
811 github level 16 old streaming advanced 138676
839 github.tar level 3 with dict old streaming advanced 38013
840 github.tar level 4 old streaming advanced 38467
841 github.tar level 4 with dict old streaming advanced 38063
842 github.tar level 5 old streaming advanced 39693 39788
843 github.tar level 5 with dict old streaming advanced 39049 39310
844 github.tar level 6 old streaming advanced 39621 39603
845 github.tar level 6 with dict old streaming advanced 38959 39279
846 github.tar level 7 old streaming advanced 39213 39206
847 github.tar level 7 with dict old streaming advanced 38573 38728
848 github.tar level 9 old streaming advanced 36758 36717
849 github.tar level 9 with dict old streaming advanced 36233 36504
850 github.tar level 13 old streaming advanced 35621
851 github.tar level 13 with dict old streaming advanced 36035
852 github.tar level 16 old streaming advanced 40255
861 github.tar small window log old streaming advanced 199561
862 github.tar small hash log old streaming advanced 129870
863 github.tar small chain log old streaming advanced 41669
864 github.tar explicit params old streaming advanced 41227 41199
865 github.tar uncompressed literals old streaming advanced 38441
866 github.tar uncompressed literals optimal old streaming advanced 32837
867 github.tar huffman literals old streaming advanced 42465
868 github.tar multithreaded with advanced params old streaming advanced 38441
869 github level -5 with dict old streaming cdict old streaming cdcit 46718
870 github level -3 with dict old streaming cdict old streaming cdcit 45395
871 github level -1 with dict old streaming cdict old streaming cdcit 43170
872 github level 0 with dict old streaming cdict old streaming cdcit 41148
873 github level 1 with dict old streaming cdict old streaming cdcit 41682
874 github level 3 with dict old streaming cdict old streaming cdcit 41148
875 github level 4 with dict old streaming cdict old streaming cdcit 41251
876 github level 5 with dict old streaming cdict old streaming cdcit 38758 38938
877 github level 6 with dict old streaming cdict old streaming cdcit 38671 38632
878 github level 7 with dict old streaming cdict old streaming cdcit 38758 38771
879 github level 9 with dict old streaming cdict old streaming cdcit 39437 39332
880 github level 13 with dict old streaming cdict old streaming cdcit 39743 39900
881 github level 16 with dict old streaming cdict old streaming cdcit 37577
882 github level 19 with dict old streaming cdict old streaming cdcit 37576
883 github no source size with dict old streaming cdict old streaming cdcit 40654
884 github.tar level -5 with dict old streaming cdict old streaming cdcit 45018
885 github.tar level -3 with dict old streaming cdict old streaming cdcit 41886
886 github.tar level -1 with dict old streaming cdict old streaming cdcit 41636
887 github.tar level 0 with dict old streaming cdict old streaming cdcit 37956
888 github.tar level 1 with dict old streaming cdict old streaming cdcit 38766
889 github.tar level 3 with dict old streaming cdict old streaming cdcit 37956
890 github.tar level 4 with dict old streaming cdict old streaming cdcit 37927
891 github.tar level 5 with dict old streaming cdict old streaming cdcit 39037 39209
892 github.tar level 6 with dict old streaming cdict old streaming cdcit 38962 38983
893 github.tar level 7 with dict old streaming cdict old streaming cdcit 38582 38584
894 github.tar level 9 with dict old streaming cdict old streaming cdcit 36350 36363
895 github.tar level 13 with dict old streaming cdict old streaming cdcit 36372
896 github.tar level 16 with dict old streaming cdict old streaming cdcit 39353
897 github.tar level 19 with dict old streaming cdict old streaming cdcit 32676
898 github.tar no source size with dict old streaming cdict old streaming cdcit 38000
899 github level -5 with dict old streaming advanced cdict 49562
900 github level -3 with dict old streaming advanced cdict 44956
901 github level -1 with dict old streaming advanced cdict 42383
903 github level 1 with dict old streaming advanced cdict 42430
904 github level 3 with dict old streaming advanced cdict 41113
905 github level 4 with dict old streaming advanced cdict 41084
906 github level 5 with dict old streaming advanced cdict 38633 39159
907 github level 6 with dict old streaming advanced cdict 38723 38749
908 github level 7 with dict old streaming advanced cdict 38744 38746
909 github level 9 with dict old streaming advanced cdict 38981 38993
910 github level 13 with dict old streaming advanced cdict 39731
911 github level 16 with dict old streaming advanced cdict 40789
912 github level 19 with dict old streaming advanced cdict 37576
918 github.tar level 1 with dict old streaming advanced cdict 39002
919 github.tar level 3 with dict old streaming advanced cdict 38013
920 github.tar level 4 with dict old streaming advanced cdict 38063
921 github.tar level 5 with dict old streaming advanced cdict 39049 39310
922 github.tar level 6 with dict old streaming advanced cdict 38959 39279
923 github.tar level 7 with dict old streaming advanced cdict 38573 38728
924 github.tar level 9 with dict old streaming advanced cdict 36233 36504
925 github.tar level 13 with dict old streaming advanced cdict 36035
926 github.tar level 16 with dict old streaming advanced cdict 38736
927 github.tar level 19 with dict old streaming advanced cdict 32876
+625
View File
@@ -0,0 +1,625 @@
/*
* 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.
*/
/*-************************************
* Compiler specific
**************************************/
#ifdef _MSC_VER /* Visual Studio */
# define _CRT_SECURE_NO_WARNINGS /* fgets */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
# pragma warning(disable : 4146) /* disable: C4146: minus unsigned expression */
#endif
/*-************************************
* Includes
**************************************/
#include <stdlib.h> /* free */
#include <stdio.h> /* fgets, sscanf */
#include <string.h> /* strcmp */
#include "timefn.h" /* UTIL_time_t */
#include "mem.h"
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
#include "zstd.h" /* ZSTD_compressBound */
#define ZBUFF_STATIC_LINKING_ONLY /* ZBUFF_createCCtx_advanced */
#include "zbuff.h" /* ZBUFF_isError */
#include "datagen.h" /* RDG_genBuffer */
#define XXH_STATIC_LINKING_ONLY
#include "xxhash.h" /* XXH64_* */
#include "util.h"
#include "assert.h"
/*-************************************
* Constants
**************************************/
#define KB *(1U<<10)
#define MB *(1U<<20)
#define GB *(1U<<30)
static const U32 nbTestsDefault = 10000;
#define COMPRESSIBLE_NOISE_LENGTH (10 MB)
#define FUZ_COMPRESSIBILITY_DEFAULT 50
static const U32 prime1 = 2654435761U;
static const U32 prime2 = 2246822519U;
/*-************************************
* Display Macros
**************************************/
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); }
static U32 g_displayLevel = 2;
static const U64 g_refreshRate = SEC_TO_MICRO / 6;
static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER;
#define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \
if ((UTIL_clockSpanMicro(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \
{ g_displayClock = UTIL_getTime(); DISPLAY(__VA_ARGS__); \
if (g_displayLevel>=4) fflush(stderr); } }
static U64 g_clockTime = 0;
/*-*******************************************************
* Fuzzer functions
*********************************************************/
#undef MIN
#undef MAX
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
/*! FUZ_rand() :
@return : a 27 bits random value, from a 32-bits `seed`.
`seed` is also modified */
# define FUZ_rotl32(x,r) ((x << r) | (x >> (32 - r)))
static unsigned int FUZ_rand(unsigned int* seedPtr)
{
U32 rand32 = *seedPtr;
rand32 *= prime1;
rand32 += prime2;
rand32 = FUZ_rotl32(rand32, 13);
*seedPtr = rand32;
return rand32 >> 5;
}
/*
static unsigned FUZ_highbit32(U32 v32)
{
unsigned nbBits = 0;
if (v32==0) return 0;
for ( ; v32 ; v32>>=1) nbBits++;
return nbBits;
}
*/
static void* ZBUFF_allocFunction(void* opaque, size_t size)
{
void* address = malloc(size);
(void)opaque;
/* DISPLAYLEVEL(4, "alloc %p, %d opaque=%p \n", address, (int)size, opaque); */
return address;
}
static void ZBUFF_freeFunction(void* opaque, void* address)
{
(void)opaque;
/* if (address) DISPLAYLEVEL(4, "free %p opaque=%p \n", address, opaque); */
free(address);
}
static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem customMem)
{
int testResult = 0;
size_t CNBufferSize = COMPRESSIBLE_NOISE_LENGTH;
void* CNBuffer = malloc(CNBufferSize);
size_t const skippableFrameSize = 11;
size_t const compressedBufferSize = (8 + skippableFrameSize) + ZSTD_compressBound(COMPRESSIBLE_NOISE_LENGTH);
void* compressedBuffer = malloc(compressedBufferSize);
size_t const decodedBufferSize = CNBufferSize;
void* decodedBuffer = malloc(decodedBufferSize);
size_t cSize, readSize, readSkipSize, genSize;
U32 testNb=0;
ZBUFF_CCtx* zc = ZBUFF_createCCtx_advanced(customMem);
ZBUFF_DCtx* zd = ZBUFF_createDCtx_advanced(customMem);
/* Create compressible test buffer */
if (!CNBuffer || !compressedBuffer || !decodedBuffer || !zc || !zd) {
DISPLAY("Not enough memory, aborting\n");
goto _output_error;
}
RDG_genBuffer(CNBuffer, CNBufferSize, compressibility, 0., seed);
/* generate skippable frame */
MEM_writeLE32(compressedBuffer, ZSTD_MAGIC_SKIPPABLE_START);
MEM_writeLE32(((char*)compressedBuffer)+4, (U32)skippableFrameSize);
cSize = skippableFrameSize + 8;
/* Basic compression test */
DISPLAYLEVEL(4, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
ZBUFF_compressInitDictionary(zc, CNBuffer, 128 KB, 1);
readSize = CNBufferSize;
genSize = compressedBufferSize;
{ size_t const r = ZBUFF_compressContinue(zc, ((char*)compressedBuffer)+cSize, &genSize, CNBuffer, &readSize);
if (ZBUFF_isError(r)) goto _output_error; }
if (readSize != CNBufferSize) goto _output_error; /* entire input should be consumed */
cSize += genSize;
genSize = compressedBufferSize - cSize;
{ size_t const r = ZBUFF_compressEnd(zc, ((char*)compressedBuffer)+cSize, &genSize);
if (r != 0) goto _output_error; } /* error, or some data not flushed */
cSize += genSize;
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
/* skippable frame test */
DISPLAYLEVEL(4, "test%3i : decompress skippable frame : ", testNb++);
ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
readSkipSize = cSize;
genSize = CNBufferSize;
{ size_t const r = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, compressedBuffer, &readSkipSize);
if (r != 0) goto _output_error; }
if (genSize != 0) goto _output_error; /* skippable frame len is 0 */
DISPLAYLEVEL(4, "OK \n");
/* Basic decompression test */
DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
readSize = cSize - readSkipSize;
genSize = CNBufferSize;
{ size_t const r = ZBUFF_decompressContinue(zd, decodedBuffer, &genSize, ((char*)compressedBuffer)+readSkipSize, &readSize);
if (r != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */
if (genSize != CNBufferSize) goto _output_error; /* should regenerate the same amount */
if (readSize+readSkipSize != cSize) goto _output_error; /* should have read the entire frame */
DISPLAYLEVEL(4, "OK \n");
DISPLAYLEVEL(4, "test%3i : ZBUFF_recommendedCInSize : ", testNb++); { assert(ZBUFF_recommendedCInSize() != 0); } DISPLAYLEVEL(4, "OK \n");
DISPLAYLEVEL(4, "test%3i : ZBUFF_recommendedCOutSize : ", testNb++); { assert(ZBUFF_recommendedCOutSize() != 0); } DISPLAYLEVEL(4, "OK \n");
DISPLAYLEVEL(4, "test%3i : ZBUFF_recommendedDInSize : ", testNb++); { assert(ZBUFF_recommendedDInSize() != 0); } DISPLAYLEVEL(4, "OK \n");
DISPLAYLEVEL(4, "test%3i : ZBUFF_recommendedDOutSize : ", testNb++); { assert(ZBUFF_recommendedDOutSize() != 0); } DISPLAYLEVEL(4, "OK \n");
/* check regenerated data is byte exact */
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
{ size_t i;
for (i=0; i<CNBufferSize; i++) {
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;
} }
DISPLAYLEVEL(4, "OK \n");
/* Byte-by-byte decompression test */
DISPLAYLEVEL(4, "test%3i : decompress byte-by-byte : ", testNb++);
{ size_t r, pIn=0, pOut=0;
do
{ ZBUFF_decompressInitDictionary(zd, CNBuffer, 128 KB);
r = 1;
while (r) {
size_t inS = 1;
size_t outS = 1;
r = ZBUFF_decompressContinue(zd, ((BYTE*)decodedBuffer)+pOut, &outS, ((BYTE*)compressedBuffer)+pIn, &inS);
pIn += inS;
pOut += outS;
}
readSize = pIn;
genSize = pOut;
} while (genSize==0);
}
if (genSize != CNBufferSize) goto _output_error; /* should regenerate the same amount */
if (readSize != cSize) goto _output_error; /* should have read the entire frame */
DISPLAYLEVEL(4, "OK \n");
/* check regenerated data is byte exact */
DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++);
{ size_t i;
for (i=0; i<CNBufferSize; i++) {
if (((BYTE*)decodedBuffer)[i] != ((BYTE*)CNBuffer)[i]) goto _output_error;
} }
DISPLAYLEVEL(4, "OK \n");
_end:
ZBUFF_freeCCtx(zc);
ZBUFF_freeDCtx(zd);
free(CNBuffer);
free(compressedBuffer);
free(decodedBuffer);
return testResult;
_output_error:
testResult = 1;
DISPLAY("Error detected in Unit tests ! \n");
goto _end;
}
static size_t findDiff(const void* buf1, const void* buf2, size_t max)
{
const BYTE* b1 = (const BYTE*)buf1;
const BYTE* b2 = (const BYTE*)buf2;
size_t u;
for (u=0; u<max; u++) {
if (b1[u] != b2[u]) break;
}
return u;
}
static size_t FUZ_rLogLength(U32* seed, U32 logLength)
{
size_t const lengthMask = ((size_t)1 << logLength) - 1;
return (lengthMask+1) + (FUZ_rand(seed) & lengthMask);
}
static size_t FUZ_randomLength(U32* seed, U32 maxLog)
{
U32 const logLength = FUZ_rand(seed) % maxLog;
return FUZ_rLogLength(seed, logLength);
}
#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; }
static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility)
{
static const U32 maxSrcLog = 24;
static const U32 maxSampleLog = 19;
BYTE* cNoiseBuffer[5];
size_t const srcBufferSize = (size_t)1<<maxSrcLog;
BYTE* copyBuffer;
size_t const copyBufferSize= srcBufferSize + (1<<maxSampleLog);
BYTE* cBuffer;
size_t const cBufferSize = ZSTD_compressBound(srcBufferSize);
BYTE* dstBuffer;
size_t dstBufferSize = srcBufferSize;
U32 result = 0;
U32 testNb = 0;
U32 coreSeed = seed;
ZBUFF_CCtx* zc;
ZBUFF_DCtx* zd;
UTIL_time_t startClock = UTIL_getTime();
/* allocations */
zc = ZBUFF_createCCtx();
zd = ZBUFF_createDCtx();
cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
cNoiseBuffer[1] = (BYTE*)malloc (srcBufferSize);
cNoiseBuffer[2] = (BYTE*)malloc (srcBufferSize);
cNoiseBuffer[3] = (BYTE*)malloc (srcBufferSize);
cNoiseBuffer[4] = (BYTE*)malloc (srcBufferSize);
copyBuffer= (BYTE*)malloc (copyBufferSize);
dstBuffer = (BYTE*)malloc (dstBufferSize);
cBuffer = (BYTE*)malloc (cBufferSize);
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4] ||
!copyBuffer || !dstBuffer || !cBuffer || !zc || !zd,
"Not enough memory, fuzzer tests cancelled");
/* Create initial samples */
RDG_genBuffer(cNoiseBuffer[0], srcBufferSize, 0.00, 0., coreSeed); /* pure noise */
RDG_genBuffer(cNoiseBuffer[1], srcBufferSize, 0.05, 0., coreSeed); /* barely compressible */
RDG_genBuffer(cNoiseBuffer[2], srcBufferSize, compressibility, 0., coreSeed);
RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed); /* highly compressible */
RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed); /* sparse content */
memset(copyBuffer, 0x65, copyBufferSize); /* make copyBuffer considered initialized */
/* catch up testNb */
for (testNb=1; testNb < startTest; testNb++)
FUZ_rand(&coreSeed);
/* test loop */
for ( ; (testNb <= nbTests) || (UTIL_clockSpanMicro(startClock) < g_clockTime) ; testNb++ ) {
U32 lseed;
const BYTE* srcBuffer;
const BYTE* dict;
size_t maxTestSize, dictSize;
size_t cSize, totalTestSize, totalCSize, totalGenSize;
size_t errorCode;
U32 n, nbChunks;
XXH64_state_t xxhState;
U64 crcOrig;
/* init */
DISPLAYUPDATE(2, "\r%6u", testNb);
if (nbTests >= testNb) DISPLAYUPDATE(2, "/%6u ", nbTests);
FUZ_rand(&coreSeed);
lseed = coreSeed ^ prime1;
/* states full reset (unsynchronized) */
/* some issues only happen when reusing states in a specific sequence of parameters */
if ((FUZ_rand(&lseed) & 0xFF) == 131) { ZBUFF_freeCCtx(zc); zc = ZBUFF_createCCtx(); }
if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZBUFF_freeDCtx(zd); zd = ZBUFF_createDCtx(); }
/* srcBuffer selection [0-4] */
{ U32 buffNb = FUZ_rand(&lseed) & 0x7F;
if (buffNb & 7) buffNb=2; /* most common : compressible (P) */
else {
buffNb >>= 3;
if (buffNb & 7) {
const U32 tnb[2] = { 1, 3 }; /* barely/highly compressible */
buffNb = tnb[buffNb >> 3];
} else {
const U32 tnb[2] = { 0, 4 }; /* not compressible / sparse */
buffNb = tnb[buffNb >> 3];
} }
srcBuffer = cNoiseBuffer[buffNb];
}
/* compression init */
{ U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
U32 const cLevel = (FUZ_rand(&lseed) % (ZSTD_maxCLevel() - (testLog/3))) + 1;
maxTestSize = FUZ_rLogLength(&lseed, testLog);
dictSize = (FUZ_rand(&lseed)==1) ? FUZ_randomLength(&lseed, maxSampleLog) : 0;
/* random dictionary selection */
{ size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
dict = srcBuffer + dictStart;
}
{ ZSTD_parameters params = ZSTD_getParams(cLevel, 0, dictSize);
params.fParams.checksumFlag = FUZ_rand(&lseed) & 1;
params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1;
{ size_t const initError = ZBUFF_compressInit_advanced(zc, dict, dictSize, params, ZSTD_CONTENTSIZE_UNKNOWN);
CHECK (ZBUFF_isError(initError),"init error : %s", ZBUFF_getErrorName(initError));
} } }
/* multi-segments compression test */
XXH64_reset(&xxhState, 0);
nbChunks = (FUZ_rand(&lseed) & 127) + 2;
for (n=0, cSize=0, totalTestSize=0 ; (n<nbChunks) && (totalTestSize < maxTestSize) ; n++) {
/* compress random chunk into random size dst buffer */
{ size_t readChunkSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - readChunkSize);
size_t const compressionError = ZBUFF_compressContinue(zc, cBuffer+cSize, &dstBuffSize, srcBuffer+srcStart, &readChunkSize);
CHECK (ZBUFF_isError(compressionError), "compression error : %s", ZBUFF_getErrorName(compressionError));
XXH64_update(&xxhState, srcBuffer+srcStart, readChunkSize);
memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, readChunkSize);
cSize += dstBuffSize;
totalTestSize += readChunkSize;
}
/* random flush operation, to mess around */
if ((FUZ_rand(&lseed) & 15) == 0) {
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
size_t const flushError = ZBUFF_compressFlush(zc, cBuffer+cSize, &dstBuffSize);
CHECK (ZBUFF_isError(flushError), "flush error : %s", ZBUFF_getErrorName(flushError));
cSize += dstBuffSize;
} }
/* final frame epilogue */
{ size_t remainingToFlush = (size_t)(-1);
while (remainingToFlush) {
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
U32 const enoughDstSize = dstBuffSize >= remainingToFlush;
remainingToFlush = ZBUFF_compressEnd(zc, cBuffer+cSize, &dstBuffSize);
CHECK (ZBUFF_isError(remainingToFlush), "flush error : %s", ZBUFF_getErrorName(remainingToFlush));
CHECK (enoughDstSize && remainingToFlush, "ZBUFF_compressEnd() not fully flushed (%u remaining), but enough space available", (U32)remainingToFlush);
cSize += dstBuffSize;
} }
crcOrig = XXH64_digest(&xxhState);
/* multi - fragments decompression test */
ZBUFF_decompressInitDictionary(zd, dict, dictSize);
errorCode = 1;
for (totalCSize = 0, totalGenSize = 0 ; errorCode ; ) {
size_t readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
errorCode = ZBUFF_decompressContinue(zd, dstBuffer+totalGenSize, &dstBuffSize, cBuffer+totalCSize, &readCSrcSize);
CHECK (ZBUFF_isError(errorCode), "decompression error : %s", ZBUFF_getErrorName(errorCode));
totalGenSize += dstBuffSize;
totalCSize += readCSrcSize;
}
CHECK (errorCode != 0, "frame not fully decoded");
CHECK (totalGenSize != totalTestSize, "decompressed data : wrong size")
CHECK (totalCSize != cSize, "compressed data should be fully read")
{ U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
CHECK (crcDest!=crcOrig, "decompressed data corrupted"); }
/*===== noisy/erroneous src decompression test =====*/
/* add some noise */
{ U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2;
U32 nn; for (nn=0; nn<nbNoiseChunks; nn++) {
size_t const randomNoiseSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t const noiseSize = MIN((cSize/3) , randomNoiseSize);
size_t const noiseStart = FUZ_rand(&lseed) % (srcBufferSize - noiseSize);
size_t const cStart = FUZ_rand(&lseed) % (cSize - noiseSize);
memcpy(cBuffer+cStart, srcBuffer+noiseStart, noiseSize);
} }
/* try decompression on noisy data */
ZBUFF_decompressInit(zd);
totalCSize = 0;
totalGenSize = 0;
while ( (totalCSize < cSize) && (totalGenSize < dstBufferSize) ) {
size_t readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
size_t dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
size_t const decompressError = ZBUFF_decompressContinue(zd, dstBuffer+totalGenSize, &dstBuffSize, cBuffer+totalCSize, &readCSrcSize);
if (ZBUFF_isError(decompressError)) break; /* error correctly detected */
totalGenSize += dstBuffSize;
totalCSize += readCSrcSize;
} }
DISPLAY("\r%u fuzzer tests completed \n", testNb);
_cleanup:
ZBUFF_freeCCtx(zc);
ZBUFF_freeDCtx(zd);
free(cNoiseBuffer[0]);
free(cNoiseBuffer[1]);
free(cNoiseBuffer[2]);
free(cNoiseBuffer[3]);
free(cNoiseBuffer[4]);
free(copyBuffer);
free(cBuffer);
free(dstBuffer);
return result;
_output_error:
result = 1;
goto _cleanup;
}
/*-*******************************************************
* Command line
*********************************************************/
static int FUZ_usage(const char* programName)
{
DISPLAY( "Usage :\n");
DISPLAY( " %s [args]\n", programName);
DISPLAY( "\n");
DISPLAY( "Arguments :\n");
DISPLAY( " -i# : Nb of tests (default:%u) \n", nbTestsDefault);
DISPLAY( " -s# : Select seed (default:prompt user)\n");
DISPLAY( " -t# : Select starting test number (default:0)\n");
DISPLAY( " -P# : Select compressibility in %% (default:%i%%)\n", FUZ_COMPRESSIBILITY_DEFAULT);
DISPLAY( " -v : verbose\n");
DISPLAY( " -p : pause at the end\n");
DISPLAY( " -h : display help and exit\n");
return 0;
}
int main(int argc, const char** argv)
{
U32 seed=0;
int seedset=0;
int argNb;
int nbTests = nbTestsDefault;
int testNb = 0;
int proba = FUZ_COMPRESSIBILITY_DEFAULT;
int result=0;
U32 mainPause = 0;
const char* programName = argv[0];
ZSTD_customMem customMem = { ZBUFF_allocFunction, ZBUFF_freeFunction, NULL };
ZSTD_customMem customNULL = { NULL, NULL, NULL };
/* Check command line */
for(argNb=1; argNb<argc; argNb++) {
const char* argument = argv[argNb];
if(!argument) continue; /* Protection if argument empty */
/* Parsing commands. Aggregated commands are allowed */
if (argument[0]=='-') {
argument++;
while (*argument!=0) {
switch(*argument)
{
case 'h':
return FUZ_usage(programName);
case 'v':
argument++;
g_displayLevel=4;
break;
case 'q':
argument++;
g_displayLevel--;
break;
case 'p': /* pause at the end */
argument++;
mainPause = 1;
break;
case 'i':
argument++;
nbTests=0; g_clockTime=0;
while ((*argument>='0') && (*argument<='9')) {
nbTests *= 10;
nbTests += *argument - '0';
argument++;
}
break;
case 'T':
argument++;
nbTests=0; g_clockTime=0;
while ((*argument>='0') && (*argument<='9')) {
g_clockTime *= 10;
g_clockTime += *argument - '0';
argument++;
}
if (*argument=='m') g_clockTime *=60, argument++;
if (*argument=='n') argument++;
g_clockTime *= SEC_TO_MICRO;
break;
case 's':
argument++;
seed=0;
seedset=1;
while ((*argument>='0') && (*argument<='9')) {
seed *= 10;
seed += *argument - '0';
argument++;
}
break;
case 't':
argument++;
testNb=0;
while ((*argument>='0') && (*argument<='9')) {
testNb *= 10;
testNb += *argument - '0';
argument++;
}
break;
case 'P': /* compressibility % */
argument++;
proba=0;
while ((*argument>='0') && (*argument<='9')) {
proba *= 10;
proba += *argument - '0';
argument++;
}
if (proba<0) proba=0;
if (proba>100) proba=100;
break;
default:
return FUZ_usage(programName);
}
} } } /* for(argNb=1; argNb<argc; argNb++) */
/* Get Seed */
DISPLAY("Starting zstd_buffered tester (%i-bits, %s)\n", (int)(sizeof(size_t)*8), ZSTD_VERSION_STRING);
if (!seedset) {
time_t const t = time(NULL);
U32 const h = XXH32(&t, sizeof(t), 1);
seed = h % 10000;
}
DISPLAY("Seed = %u\n", seed);
if (proba!=FUZ_COMPRESSIBILITY_DEFAULT) DISPLAY("Compressibility : %i%%\n", proba);
if (nbTests<=0) nbTests=1;
if (testNb==0) {
result = basicUnitTests(0, ((double)proba) / 100, customNULL); /* constant seed for predictability */
if (!result) {
DISPLAYLEVEL(4, "Unit tests using customMem :\n")
result = basicUnitTests(0, ((double)proba) / 100, customMem); /* use custom memory allocation functions */
} }
if (!result)
result = fuzzerTests(seed, nbTests, testNb, ((double)proba) / 100);
if (mainPause) {
int unused;
DISPLAY("Press Enter \n");
unused = getchar();
(void)unused;
}
return result;
}
+23 -46
View File
@@ -28,7 +28,6 @@
#include <assert.h> /* assert */ #include <assert.h> /* assert */
#include "timefn.h" /* UTIL_time_t, UTIL_getTime */ #include "timefn.h" /* UTIL_time_t, UTIL_getTime */
#include "mem.h" #include "mem.h"
#define ZSTD_DISABLE_DEPRECATE_WARNINGS /* No deprecation warnings, we still test some deprecated functions */
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel, ZSTD_customMem, ZSTD_getDictID_fromFrame */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel, ZSTD_customMem, ZSTD_getDictID_fromFrame */
#include "zstd.h" /* ZSTD_compressBound */ #include "zstd.h" /* ZSTD_compressBound */
#include "zstd_errors.h" /* ZSTD_error_srcSize_wrong */ #include "zstd_errors.h" /* ZSTD_error_srcSize_wrong */
@@ -322,9 +321,7 @@ static int basicUnitTests(U32 seed, double compressibility)
/* Basic compression test using dict */ /* Basic compression test using dict */
DISPLAYLEVEL(3, "test%3i : skipframe + compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH); DISPLAYLEVEL(3, "test%3i : skipframe + compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); CHECK_Z( ZSTD_initCStream_usingDict(zc, CNBuffer, dictSize, 1 /* cLevel */) );
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, 1) );
CHECK_Z( ZSTD_CCtx_loadDictionary(zc, CNBuffer, dictSize) );
outBuff.dst = (char*)(compressedBuffer)+cSize; outBuff.dst = (char*)(compressedBuffer)+cSize;
assert(compressedBufferSize > cSize); assert(compressedBufferSize > cSize);
outBuff.size = compressedBufferSize - cSize; outBuff.size = compressedBufferSize - cSize;
@@ -371,7 +368,7 @@ static int basicUnitTests(U32 seed, double compressibility)
} }
/* Attempt bad compression parameters */ /* Attempt bad compression parameters */
DISPLAYLEVEL(3, "test%3i : use bad compression parameters with ZSTD_initCStream_advanced : ", testNb++); DISPLAYLEVEL(3, "test%3i : use bad compression parameters : ", testNb++);
{ size_t r; { size_t r;
ZSTD_parameters params = ZSTD_getParams(1, 0, 0); ZSTD_parameters params = ZSTD_getParams(1, 0, 0);
params.cParams.minMatch = 2; params.cParams.minMatch = 2;
@@ -542,10 +539,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(3, "OK\n"); DISPLAYLEVEL(3, "OK\n");
/* _srcSize compression test */ /* _srcSize compression test */
DISPLAYLEVEL(3, "test%3i : compress_srcSize %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH); DISPLAYLEVEL(3, "test%3i : compress_srcSize %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); CHECK_Z( ZSTD_initCStream_srcSize(zc, 1, CNBufferSize) );
CHECK_Z( ZSTD_CCtx_refCDict(zc, NULL) );
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, 1) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, CNBufferSize) );
outBuff.dst = (char*)(compressedBuffer); outBuff.dst = (char*)(compressedBuffer);
outBuff.size = compressedBufferSize; outBuff.size = compressedBufferSize;
outBuff.pos = 0; outBuff.pos = 0;
@@ -565,10 +559,7 @@ static int basicUnitTests(U32 seed, double compressibility)
/* wrong _srcSize compression test */ /* wrong _srcSize compression test */
DISPLAYLEVEL(3, "test%3i : too large srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); DISPLAYLEVEL(3, "test%3i : too large srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1);
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_initCStream_srcSize(zc, 1, CNBufferSize+1);
CHECK_Z( ZSTD_CCtx_refCDict(zc, NULL) );
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, 1) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, CNBufferSize+1) );
outBuff.dst = (char*)(compressedBuffer); outBuff.dst = (char*)(compressedBuffer);
outBuff.size = compressedBufferSize; outBuff.size = compressedBufferSize;
outBuff.pos = 0; outBuff.pos = 0;
@@ -583,10 +574,7 @@ static int basicUnitTests(U32 seed, double compressibility)
/* wrong _srcSize compression test */ /* wrong _srcSize compression test */
DISPLAYLEVEL(3, "test%3i : too small srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); DISPLAYLEVEL(3, "test%3i : too small srcSize : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1);
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_initCStream_srcSize(zc, 1, CNBufferSize-1);
CHECK_Z( ZSTD_CCtx_refCDict(zc, NULL) );
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, 1) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, CNBufferSize-1) );
outBuff.dst = (char*)(compressedBuffer); outBuff.dst = (char*)(compressedBuffer);
outBuff.size = compressedBufferSize; outBuff.size = compressedBufferSize;
outBuff.pos = 0; outBuff.pos = 0;
@@ -599,9 +587,9 @@ static int basicUnitTests(U32 seed, double compressibility)
} }
DISPLAYLEVEL(3, "test%3i : wrong srcSize !contentSizeFlag : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1); DISPLAYLEVEL(3, "test%3i : wrong srcSize !contentSizeFlag : %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH-1);
{ CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); { ZSTD_parameters params = ZSTD_getParams(1, CNBufferSize, 0);
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_contentSizeFlag, 0) ); params.fParams.contentSizeFlag = 0;
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, CNBufferSize - MIN(CNBufferSize, 200 KB)) ); CHECK_Z(ZSTD_initCStream_advanced(zc, NULL, 0, params, CNBufferSize - MIN(CNBufferSize, 200 KB)));
outBuff.dst = (char*)compressedBuffer; outBuff.dst = (char*)compressedBuffer;
outBuff.size = compressedBufferSize; outBuff.size = compressedBufferSize;
outBuff.pos = 0; outBuff.pos = 0;
@@ -621,9 +609,7 @@ static int basicUnitTests(U32 seed, double compressibility)
/* use 1 */ /* use 1 */
{ size_t const inSize = 513; { size_t const inSize = 513;
DISPLAYLEVEL(5, "use1 "); DISPLAYLEVEL(5, "use1 ");
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_initCStream_advanced(zc, NULL, 0, ZSTD_getParams(19, inSize, 0), inSize); /* needs btopt + search3 to trigger hashLog3 */
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, 19) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, inSize) );
inBuff.src = CNBuffer; inBuff.src = CNBuffer;
inBuff.size = inSize; inBuff.size = inSize;
inBuff.pos = 0; inBuff.pos = 0;
@@ -640,9 +626,7 @@ static int basicUnitTests(U32 seed, double compressibility)
/* use 2 */ /* use 2 */
{ size_t const inSize = 1025; /* will not continue, because tables auto-adjust and are therefore different size */ { size_t const inSize = 1025; /* will not continue, because tables auto-adjust and are therefore different size */
DISPLAYLEVEL(5, "use2 "); DISPLAYLEVEL(5, "use2 ");
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_initCStream_advanced(zc, NULL, 0, ZSTD_getParams(19, inSize, 0), inSize); /* needs btopt + search3 to trigger hashLog3 */
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, 19) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, inSize) );
inBuff.src = CNBuffer; inBuff.src = CNBuffer;
inBuff.size = inSize; inBuff.size = inSize;
inBuff.pos = 0; inBuff.pos = 0;
@@ -688,7 +672,7 @@ static int basicUnitTests(U32 seed, double compressibility)
cSize = ZSTD_compress(compressedBuffer, compressedBufferSize, CNBuffer, CNBufferSize, 1); cSize = ZSTD_compress(compressedBuffer, compressedBufferSize, CNBuffer, CNBufferSize, 1);
CHECK_Z(cSize); CHECK_Z(cSize);
{ ZSTD_DCtx* dctx = ZSTD_createDCtx(); { ZSTD_DCtx* dctx = ZSTD_createDCtx();
size_t const dctxSize0 = ZSTD_sizeof_DCtx(dctx); size_t const dctxSize0 = ZSTD_sizeof_DCtx(dctx);
size_t dctxSize1; size_t dctxSize1;
CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_stableOutBuffer, 1)); CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_stableOutBuffer, 1));
@@ -751,7 +735,7 @@ static int basicUnitTests(U32 seed, double compressibility)
CHECK(ZSTD_getErrorCode(r) != ZSTD_error_dstBuffer_wrong, "Must error but got %s", ZSTD_getErrorName(r)); CHECK(ZSTD_getErrorCode(r) != ZSTD_error_dstBuffer_wrong, "Must error but got %s", ZSTD_getErrorName(r));
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : ZSTD_decompressStream() buffered output : ", testNb++); DISPLAYLEVEL(3, "test%3i : ZSTD_decompressStream() buffered output : ", testNb++);
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only); ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only);
CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_stableOutBuffer, 0)); CHECK_Z(ZSTD_DCtx_setParameter(dctx, ZSTD_d_stableOutBuffer, 0));
@@ -1290,7 +1274,7 @@ static int basicUnitTests(U32 seed, double compressibility)
if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != 0) goto _output_error; if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != 0) goto _output_error;
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
DISPLAYLEVEL(3, "test%3i : pledgedSrcSize == 0 behaves properly with ZSTD_initCStream_advanced : ", testNb++); DISPLAYLEVEL(3, "test%3i : pledgedSrcSize == 0 behaves properly : ", testNb++);
{ ZSTD_parameters params = ZSTD_getParams(5, 0, 0); { ZSTD_parameters params = ZSTD_getParams(5, 0, 0);
params.fParams.contentSizeFlag = 1; params.fParams.contentSizeFlag = 1;
CHECK_Z( ZSTD_initCStream_advanced(zc, NULL, 0, params, 0) ); CHECK_Z( ZSTD_initCStream_advanced(zc, NULL, 0, params, 0) );
@@ -1306,8 +1290,7 @@ static int basicUnitTests(U32 seed, double compressibility)
cSize = outBuff.pos; cSize = outBuff.pos;
if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != 0) goto _output_error; if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != 0) goto _output_error;
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_resetCStream(zc, 0); /* resetCStream should treat 0 as unknown */
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, ZSTD_CONTENTSIZE_UNKNOWN) );
outBuff.dst = compressedBuffer; outBuff.dst = compressedBuffer;
outBuff.size = compressedBufferSize; outBuff.size = compressedBufferSize;
outBuff.pos = 0; outBuff.pos = 0;
@@ -1451,8 +1434,7 @@ static int basicUnitTests(U32 seed, double compressibility)
CHECK_Z(ZSTD_initCStream_srcSize(zc, 11, ZSTD_CONTENTSIZE_UNKNOWN)); CHECK_Z(ZSTD_initCStream_srcSize(zc, 11, ZSTD_CONTENTSIZE_UNKNOWN));
CHECK_Z(ZSTD_CCtx_getParameter(zc, ZSTD_c_compressionLevel, &level)); CHECK_Z(ZSTD_CCtx_getParameter(zc, ZSTD_c_compressionLevel, &level));
CHECK(level != 11, "Compression level does not match"); CHECK(level != 11, "Compression level does not match");
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_resetCStream(zc, ZSTD_CONTENTSIZE_UNKNOWN);
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, ZSTD_CONTENTSIZE_UNKNOWN) );
CHECK_Z(ZSTD_CCtx_getParameter(zc, ZSTD_c_compressionLevel, &level)); CHECK_Z(ZSTD_CCtx_getParameter(zc, ZSTD_c_compressionLevel, &level));
CHECK(level != 11, "Compression level does not match"); CHECK(level != 11, "Compression level does not match");
} }
@@ -1462,8 +1444,7 @@ static int basicUnitTests(U32 seed, double compressibility)
{ ZSTD_parameters const params = ZSTD_getParams(9, 0, 0); { ZSTD_parameters const params = ZSTD_getParams(9, 0, 0);
CHECK_Z(ZSTD_initCStream_advanced(zc, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN)); CHECK_Z(ZSTD_initCStream_advanced(zc, NULL, 0, params, ZSTD_CONTENTSIZE_UNKNOWN));
CHECK(badParameters(zc, params), "Compression parameters do not match"); CHECK(badParameters(zc, params), "Compression parameters do not match");
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_resetCStream(zc, ZSTD_CONTENTSIZE_UNKNOWN);
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, ZSTD_CONTENTSIZE_UNKNOWN) );
CHECK(badParameters(zc, params), "Compression parameters do not match"); CHECK(badParameters(zc, params), "Compression parameters do not match");
} }
DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "OK \n");
@@ -1855,9 +1836,8 @@ static int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double co
&& oldTestLog /* at least one test happened */ && resetAllowed) { && oldTestLog /* at least one test happened */ && resetAllowed) {
maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2); maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
maxTestSize = MIN(maxTestSize, srcBufferSize-16); maxTestSize = MIN(maxTestSize, srcBufferSize-16);
{ U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize;
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); CHECK_Z( ZSTD_resetCStream(zc, pledgedSrcSize) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
} }
} else { } else {
U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
@@ -1875,13 +1855,11 @@ static int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double co
dict = srcBuffer + dictStart; dict = srcBuffer + dictStart;
} }
{ U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize;
CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize);
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_compressionLevel, cLevel) ); params.fParams.checksumFlag = FUZ_rand(&lseed) & 1;
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_checksumFlag, FUZ_rand(&lseed) & 1) ); params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1;
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_contentSizeFlag, FUZ_rand(&lseed) & 1) ); params.fParams.contentSizeFlag = FUZ_rand(&lseed) & 1;
CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_c_dictIDFlag, FUZ_rand(&lseed) & 1) ); CHECK_Z ( ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize) );
CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
} } } }
/* multi-segments compression test */ /* multi-segments compression test */
@@ -2237,7 +2215,6 @@ static int fuzzerTests_newAPI(U32 seed, int nbTests, int startTest,
} }
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_c_forceMaxWindow, FUZ_rand(&lseed) & 1, opaqueAPI) ); if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_c_forceMaxWindow, FUZ_rand(&lseed) & 1, opaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_c_deterministicRefPrefix, FUZ_rand(&lseed) & 1, opaqueAPI) );
/* Apply parameters */ /* Apply parameters */
if (opaqueAPI) { if (opaqueAPI) {
+2 -15
View File
@@ -264,22 +264,9 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
ZSTD_outBuffer outBuffer; ZSTD_outBuffer outBuffer;
ZSTD_CStream* zbc = ZSTD_createCStream(); ZSTD_CStream* zbc = ZSTD_createCStream();
size_t rSize; size_t rSize;
ZSTD_CCtx_params* cctxParams = ZSTD_createCCtxParams();
if (!cctxParams) EXM_THROW(1, "ZSTD_createCCtxParams() allocation failure");
if (zbc == NULL) EXM_THROW(1, "ZSTD_createCStream() allocation failure"); if (zbc == NULL) EXM_THROW(1, "ZSTD_createCStream() allocation failure");
rSize = ZSTD_initCStream_advanced(zbc, dictBuffer, dictBufferSize, zparams, avgSize);
{ int initErr = 0; if (ZSTD_isError(rSize)) EXM_THROW(1, "ZSTD_initCStream_advanced() failed : %s", ZSTD_getErrorName(rSize));
initErr |= ZSTD_isError(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only));
initErr |= ZSTD_isError(ZSTD_CCtxParams_init_advanced(cctxParams, zparams));
initErr |= ZSTD_isError(ZSTD_CCtx_setParametersUsingCCtxParams(zbc, cctxParams));
initErr |= ZSTD_isError(ZSTD_CCtx_setPledgedSrcSize(zbc, avgSize));
initErr |= ZSTD_isError(ZSTD_CCtx_loadDictionary(zbc, dictBuffer, dictBufferSize));
ZSTD_freeCCtxParams(cctxParams);
if (initErr) EXM_THROW(1, "CCtx init failed!");
}
do { do {
U32 blockNb; U32 blockNb;
for (blockNb=0; blockNb<nbBlocks; blockNb++) { for (blockNb=0; blockNb<nbBlocks; blockNb++) {
+4 -13
View File
@@ -205,21 +205,12 @@ static int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dic
if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR; if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR;
if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize; if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize;
{ unsigned initErr = 0; { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize);
ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize); size_t initErr;
ZSTD_CCtx_params* cctxParams = ZSTD_createCCtxParams();
if (!cctxParams) return Z_STREAM_ERROR;
LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d minMatch=%d strategy=%d\n", LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d minMatch=%d strategy=%d\n",
(int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.minMatch, params.cParams.strategy); (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.minMatch, params.cParams.strategy);
initErr = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize);
initErr |= ZSTD_isError(ZSTD_CCtx_reset(zwc->zbc, ZSTD_reset_session_only)); if (ZSTD_isError(initErr)) return Z_STREAM_ERROR;
initErr |= ZSTD_isError(ZSTD_CCtxParams_init_advanced(cctxParams, params));
initErr |= ZSTD_isError(ZSTD_CCtx_setParametersUsingCCtxParams(zwc->zbc, cctxParams));
initErr |= ZSTD_isError(ZSTD_CCtx_setPledgedSrcSize(zwc->zbc, pledgedSrcSize));
initErr |= ZSTD_isError(ZSTD_CCtx_loadDictionary(zwc->zbc, dict, dictSize));
ZSTD_freeCCtxParams(cctxParams);
if (initErr) return Z_STREAM_ERROR;
} }
return Z_OK; return Z_OK;