dropshell release 2025.0513.2134
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
Some checks failed
Dropshell Test / Build_and_Test (push) Has been cancelled
This commit is contained in:
41
build_amd64/_deps/zstd-src/programs/.gitignore
vendored
Normal file
41
build_amd64/_deps/zstd-src/programs/.gitignore
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# local binary (Makefile)
|
||||
zstd
|
||||
zstd32
|
||||
zstd4
|
||||
zstd-compress
|
||||
zstd-decompress
|
||||
zstd-frugal
|
||||
zstd-small
|
||||
zstd-nolegacy
|
||||
zstd-dictBuilder
|
||||
zstd-dll
|
||||
zstd_arm64
|
||||
zstd_x64
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
default.profraw
|
||||
have_zlib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Default result files
|
||||
dictionary
|
||||
grillResults.txt
|
||||
_*
|
||||
tmp*
|
||||
*.zst
|
||||
result
|
||||
out
|
||||
|
||||
# fuzzer
|
||||
afl
|
||||
|
||||
# Misc files
|
||||
*.bat
|
||||
!windres/generate_res.bat
|
||||
dirTest*
|
44
build_amd64/_deps/zstd-src/programs/BUCK
Normal file
44
build_amd64/_deps/zstd-src/programs/BUCK
Normal file
@@ -0,0 +1,44 @@
|
||||
cxx_binary(
|
||||
name='zstd',
|
||||
headers=glob(['*.h'], excludes=['datagen.h', 'platform.h', 'util.h']),
|
||||
srcs=glob(['*.c'], excludes=['datagen.c']),
|
||||
deps=[
|
||||
':datagen',
|
||||
':util',
|
||||
'//lib:zstd',
|
||||
'//lib:zdict',
|
||||
'//lib:mem',
|
||||
'//lib:xxhash',
|
||||
],
|
||||
preprocessor_flags=[
|
||||
'-DZSTD_GZCOMPRESS',
|
||||
'-DZSTD_GZDECOMPRESS',
|
||||
'-DZSTD_LZMACOMPRESS',
|
||||
'-DZSTD_LZMADECOMPRES',
|
||||
'-DZSTD_LZ4COMPRESS',
|
||||
'-DZSTD_LZ4DECOMPRES',
|
||||
],
|
||||
linker_flags=[
|
||||
'-lz',
|
||||
'-llzma',
|
||||
'-llz4',
|
||||
],
|
||||
)
|
||||
|
||||
cxx_library(
|
||||
name='datagen',
|
||||
visibility=['PUBLIC'],
|
||||
header_namespace='',
|
||||
exported_headers=['datagen.h'],
|
||||
srcs=['datagen.c'],
|
||||
deps=['//lib:mem'],
|
||||
)
|
||||
|
||||
|
||||
cxx_library(
|
||||
name='util',
|
||||
visibility=['PUBLIC'],
|
||||
header_namespace='',
|
||||
exported_headers=['util.h', 'platform.h'],
|
||||
deps=['//lib:mem'],
|
||||
)
|
344
build_amd64/_deps/zstd-src/programs/README.md
Normal file
344
build_amd64/_deps/zstd-src/programs/README.md
Normal file
@@ -0,0 +1,344 @@
|
||||
Command Line Interface for Zstandard library
|
||||
============================================
|
||||
|
||||
Command Line Interface (CLI) can be created using the `make` command without any additional parameters.
|
||||
There are however other Makefile targets that create different variations of CLI:
|
||||
- `zstd` : default CLI supporting gzip-like arguments; includes dictionary builder, benchmark, and supports decompression of legacy zstd formats
|
||||
- `zstd_nolegacy` : Same as `zstd` but without support for legacy zstd formats
|
||||
- `zstd-small` : CLI optimized for minimal size; no dictionary builder, no benchmark, and no support for legacy zstd formats
|
||||
- `zstd-compress` : version of CLI which can only compress into zstd format
|
||||
- `zstd-decompress` : version of CLI which can only decompress zstd format
|
||||
|
||||
|
||||
### Compilation variables
|
||||
`zstd` scope can be altered by modifying the following `make` variables :
|
||||
|
||||
- __HAVE_THREAD__ : multithreading is automatically enabled when `pthread` is detected.
|
||||
It's possible to disable multithread support, by setting `HAVE_THREAD=0`.
|
||||
Example : `make zstd HAVE_THREAD=0`
|
||||
It's also possible to force multithread support, using `HAVE_THREAD=1`.
|
||||
In which case, linking stage will fail if neither `pthread` nor `windows.h` library can be found.
|
||||
This is useful to ensure this feature is not silently disabled.
|
||||
|
||||
- __ZSTD_LEGACY_SUPPORT__ : `zstd` can decompress files compressed by older versions of `zstd`.
|
||||
Starting v0.8.0, all versions of `zstd` produce frames compliant with the [specification](../doc/zstd_compression_format.md), and are therefore compatible.
|
||||
But older versions (< v0.8.0) produced different, incompatible, frames.
|
||||
By default, `zstd` supports decoding legacy formats >= v0.4.0 (`ZSTD_LEGACY_SUPPORT=4`).
|
||||
This can be altered by modifying this compilation variable.
|
||||
`ZSTD_LEGACY_SUPPORT=1` means "support all formats >= v0.1.0".
|
||||
`ZSTD_LEGACY_SUPPORT=2` means "support all formats >= v0.2.0", and so on.
|
||||
`ZSTD_LEGACY_SUPPORT=0` means _DO NOT_ support any legacy format.
|
||||
if `ZSTD_LEGACY_SUPPORT >= 8`, it's the same as `0`, since there is no legacy format after `7`.
|
||||
Note : `zstd` only supports decoding older formats, and cannot generate any legacy format.
|
||||
|
||||
- __HAVE_ZLIB__ : `zstd` can compress and decompress files in `.gz` format.
|
||||
This is ordered through command `--format=gzip`.
|
||||
Alternatively, symlinks named `gzip` or `gunzip` will mimic intended behavior.
|
||||
`.gz` support is automatically enabled when `zlib` library is detected at build time.
|
||||
It's possible to disable `.gz` support, by setting `HAVE_ZLIB=0`.
|
||||
Example : `make zstd HAVE_ZLIB=0`
|
||||
It's also possible to force compilation with zlib support, using `HAVE_ZLIB=1`.
|
||||
In which case, linking stage will fail if `zlib` library cannot be found.
|
||||
This is useful to prevent silent feature disabling.
|
||||
|
||||
- __HAVE_LZMA__ : `zstd` can compress and decompress files in `.xz` and `.lzma` formats.
|
||||
This is ordered through commands `--format=xz` and `--format=lzma` respectively.
|
||||
Alternatively, symlinks named `xz`, `unxz`, `lzma`, or `unlzma` will mimic intended behavior.
|
||||
`.xz` and `.lzma` support is automatically enabled when `lzma` library is detected at build time.
|
||||
It's possible to disable `.xz` and `.lzma` support, by setting `HAVE_LZMA=0`.
|
||||
Example : `make zstd HAVE_LZMA=0`
|
||||
It's also possible to force compilation with lzma support, using `HAVE_LZMA=1`.
|
||||
In which case, linking stage will fail if `lzma` library cannot be found.
|
||||
This is useful to prevent silent feature disabling.
|
||||
|
||||
- __HAVE_LZ4__ : `zstd` can compress and decompress files in `.lz4` formats.
|
||||
This is ordered through commands `--format=lz4`.
|
||||
Alternatively, symlinks named `lz4`, or `unlz4` will mimic intended behavior.
|
||||
`.lz4` support is automatically enabled when `lz4` library is detected at build time.
|
||||
It's possible to disable `.lz4` support, by setting `HAVE_LZ4=0` .
|
||||
Example : `make zstd HAVE_LZ4=0`
|
||||
It's also possible to force compilation with lz4 support, using `HAVE_LZ4=1`.
|
||||
In which case, linking stage will fail if `lz4` library cannot be found.
|
||||
This is useful to prevent silent feature disabling.
|
||||
|
||||
- __ZSTD_NOBENCH__ : `zstd` cli will be compiled without its integrated benchmark module.
|
||||
This can be useful to produce smaller binaries.
|
||||
In this case, the corresponding unit can also be excluded from compilation target.
|
||||
|
||||
- __ZSTD_NODICT__ : `zstd` cli will be compiled without support for the integrated dictionary builder.
|
||||
This can be useful to produce smaller binaries.
|
||||
In this case, the corresponding unit can also be excluded from compilation target.
|
||||
|
||||
- __ZSTD_NOCOMPRESS__ : `zstd` cli will be compiled without support for compression.
|
||||
The resulting binary will only be able to decompress files.
|
||||
This can be useful to produce smaller binaries.
|
||||
A corresponding `Makefile` target using this ability is `zstd-decompress`.
|
||||
|
||||
- __ZSTD_NODECOMPRESS__ : `zstd` cli will be compiled without support for decompression.
|
||||
The resulting binary will only be able to compress files.
|
||||
This can be useful to produce smaller binaries.
|
||||
A corresponding `Makefile` target using this ability is `zstd-compress`.
|
||||
|
||||
- __BACKTRACE__ : `zstd` can display a stack backtrace when execution
|
||||
generates a runtime exception. By default, this feature may be
|
||||
degraded/disabled on some platforms unless additional compiler directives are
|
||||
applied. When triaging a runtime issue, enabling this feature can provide
|
||||
more context to determine the location of the fault.
|
||||
Example : `make zstd BACKTRACE=1`
|
||||
|
||||
|
||||
### Aggregation of parameters
|
||||
CLI supports aggregation of parameters i.e. `-b1`, `-e18`, and `-i1` can be joined into `-b1e18i1`.
|
||||
|
||||
|
||||
### Symlink shortcuts
|
||||
It's possible to invoke `zstd` through a symlink.
|
||||
When the name of the symlink has a specific value, it triggers an associated behavior.
|
||||
- `zstdmt` : compress using all cores available on local system.
|
||||
- `zcat` : will decompress and output target file using any of the supported formats. `gzcat` and `zstdcat` are also equivalent.
|
||||
- `gzip` : if zlib support is enabled, will mimic `gzip` by compressing file using `.gz` format, removing source file by default (use `--keep` to preserve). If zlib is not supported, triggers an error.
|
||||
- `xz` : if lzma support is enabled, will mimic `xz` by compressing file using `.xz` format, removing source file by default (use `--keep` to preserve). If xz is not supported, triggers an error.
|
||||
- `lzma` : if lzma support is enabled, will mimic `lzma` by compressing file using `.lzma` format, removing source file by default (use `--keep` to preserve). If lzma is not supported, triggers an error.
|
||||
- `lz4` : if lz4 support is enabled, will mimic `lz4` by compressing file using `.lz4` format. If lz4 is not supported, triggers an error.
|
||||
- `unzstd` and `unlz4` will decompress any of the supported format.
|
||||
- `ungz`, `unxz` and `unlzma` will do the same, and will also remove source file by default (use `--keep` to preserve).
|
||||
|
||||
|
||||
### Dictionary builder in Command Line Interface
|
||||
Zstd offers a training mode, which can be used to tune the algorithm for a selected
|
||||
type of data, by providing it with a few samples. The result of the training is stored
|
||||
in a file selected with the `-o` option (default name is `dictionary`),
|
||||
which can be loaded before compression and decompression.
|
||||
|
||||
Using a dictionary, the compression ratio achievable on small data improves dramatically.
|
||||
These compression gains are achieved while simultaneously providing faster compression and decompression speeds.
|
||||
Dictionary work if there is some correlation in a family of small data (there is no universal dictionary).
|
||||
Hence, deploying one dictionary per type of data will provide the greater benefits.
|
||||
Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm
|
||||
will rely more and more on previously decoded content to compress the rest of the file.
|
||||
|
||||
Usage of the dictionary builder and created dictionaries with CLI:
|
||||
|
||||
1. Create the dictionary : `zstd --train PathToTrainingSet/* -o dictionaryName`
|
||||
2. Compress with the dictionary: `zstd FILE -D dictionaryName`
|
||||
3. Decompress with the dictionary: `zstd --decompress FILE.zst -D dictionaryName`
|
||||
|
||||
|
||||
### Benchmark in Command Line Interface
|
||||
CLI includes in-memory compression benchmark module for zstd.
|
||||
The benchmark is conducted using given filenames. The files are read into memory and joined together.
|
||||
It makes benchmark more precise as it eliminates I/O overhead.
|
||||
Multiple filenames can be supplied, as multiple parameters, with wildcards,
|
||||
or directory names can be used with `-r` option.
|
||||
If no file is provided, the benchmark will use a procedurally generated "lorem ipsum" content.
|
||||
|
||||
The benchmark measures ratio, compressed size, compression and decompression speed.
|
||||
One can select compression levels starting from `-b` and ending with `-e`.
|
||||
The `-i` parameter selects minimal time used for each of tested levels.
|
||||
|
||||
The benchmark can also be used to test specific parameters,
|
||||
such as number of threads (`-T#`), or advanced parameters (`--zstd=#`), or dictionary compression (`-D DICTIONARY`),
|
||||
and many others available on command for regular compression and decompression.
|
||||
|
||||
|
||||
### Usage of Command Line Interface
|
||||
The full list of options can be obtained with `-h` or `-H` parameter:
|
||||
```
|
||||
*** Zstandard CLI (64-bit) v1.5.6, by Yann Collet ***
|
||||
|
||||
Compress or decompress the INPUT file(s); reads from STDIN if INPUT is `-` or not provided.
|
||||
|
||||
Usage: zstd [OPTIONS...] [INPUT... | -] [-o OUTPUT]
|
||||
|
||||
Options:
|
||||
-o OUTPUT Write output to a single file, OUTPUT.
|
||||
-k, --keep Preserve INPUT file(s). [Default]
|
||||
--rm Remove INPUT file(s) after successful (de)compression.
|
||||
|
||||
-# Desired compression level, where `#` is a number between 1 and 19;
|
||||
lower numbers provide faster compression, higher numbers yield
|
||||
better compression ratios. [Default: 3]
|
||||
|
||||
-d, --decompress Perform decompression.
|
||||
-D DICT Use DICT as the dictionary for compression or decompression.
|
||||
|
||||
-f, --force Disable input and output checks. Allows overwriting existing files,
|
||||
receiving input from the console, printing output to STDOUT, and
|
||||
operating on links, block devices, etc. Unrecognized formats will be
|
||||
passed-through through as-is.
|
||||
|
||||
-h Display short usage and exit.
|
||||
-H, --help Display full help and exit.
|
||||
-V, --version Display the program version and exit.
|
||||
|
||||
Advanced options:
|
||||
-c, --stdout Write to STDOUT (even if it is a console) and keep the INPUT file(s).
|
||||
|
||||
-v, --verbose Enable verbose output; pass multiple times to increase verbosity.
|
||||
-q, --quiet Suppress warnings; pass twice to suppress errors.
|
||||
--trace LOG Log tracing information to LOG.
|
||||
|
||||
--[no-]progress Forcibly show/hide the progress counter. NOTE: Any (de)compressed
|
||||
output to terminal will mix with progress counter text.
|
||||
|
||||
-r Operate recursively on directories.
|
||||
--filelist LIST Read a list of files to operate on from LIST.
|
||||
--output-dir-flat DIR Store processed files in DIR.
|
||||
--output-dir-mirror DIR Store processed files in DIR, respecting original directory structure.
|
||||
--[no-]asyncio Use asynchronous IO. [Default: Enabled]
|
||||
|
||||
--[no-]check Add XXH64 integrity checksums during compression. [Default: Add, Validate]
|
||||
If `-d` is present, ignore/validate checksums during decompression.
|
||||
|
||||
-- Treat remaining arguments after `--` as files.
|
||||
|
||||
Advanced compression options:
|
||||
--ultra Enable levels beyond 19, up to 22; requires more memory.
|
||||
--fast[=#] Use to very fast compression levels. [Default: 1]
|
||||
--adapt Dynamically adapt compression level to I/O conditions.
|
||||
--long[=#] Enable long distance matching with window log #. [Default: 27]
|
||||
--patch-from=REF Use REF as the reference point for Zstandard's diff engine.
|
||||
|
||||
-T# Spawn # compression threads. [Default: 1; pass 0 for core count.]
|
||||
--single-thread Share a single thread for I/O and compression (slightly different than `-T1`).
|
||||
--auto-threads={physical|logical}
|
||||
Use physical/logical cores when using `-T0`. [Default: Physical]
|
||||
|
||||
-B# Set job size to #. [Default: 0 (automatic)]
|
||||
--rsyncable Compress using a rsync-friendly method (`-B` sets block size).
|
||||
|
||||
--exclude-compressed Only compress files that are not already compressed.
|
||||
|
||||
--stream-size=# Specify size of streaming input from STDIN.
|
||||
--size-hint=# Optimize compression parameters for streaming input of approximately size #.
|
||||
--target-compressed-block-size=#
|
||||
Generate compressed blocks of approximately # size.
|
||||
|
||||
--no-dictID Don't write `dictID` into the header (dictionary compression only).
|
||||
--[no-]compress-literals Force (un)compressed literals.
|
||||
--[no-]row-match-finder Explicitly enable/disable the fast, row-based matchfinder for
|
||||
the 'greedy', 'lazy', and 'lazy2' strategies.
|
||||
|
||||
--format=zstd Compress files to the `.zst` format. [Default]
|
||||
--[no-]mmap-dict Memory-map dictionary file rather than mallocing and loading all at once
|
||||
--format=gzip Compress files to the `.gz` format.
|
||||
--format=xz Compress files to the `.xz` format.
|
||||
--format=lzma Compress files to the `.lzma` format.
|
||||
--format=lz4 Compress files to the `.lz4` format.
|
||||
|
||||
Advanced decompression options:
|
||||
-l Print information about Zstandard-compressed files.
|
||||
--test Test compressed file integrity.
|
||||
-M# Set the memory usage limit to # megabytes.
|
||||
--[no-]sparse Enable sparse mode. [Default: Enabled for files, disabled for STDOUT.]
|
||||
--[no-]pass-through Pass through uncompressed files as-is. [Default: Disabled]
|
||||
|
||||
Dictionary builder:
|
||||
--train Create a dictionary from a training set of files.
|
||||
|
||||
--train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]]
|
||||
Use the cover algorithm (with optional arguments).
|
||||
--train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]]
|
||||
Use the fast cover algorithm (with optional arguments).
|
||||
|
||||
--train-legacy[=s=#] Use the legacy algorithm with selectivity #. [Default: 9]
|
||||
-o NAME Use NAME as dictionary name. [Default: dictionary]
|
||||
--maxdict=# Limit dictionary to specified size #. [Default: 112640]
|
||||
--dictID=# Force dictionary ID to #. [Default: Random]
|
||||
|
||||
Benchmark options:
|
||||
-b# Perform benchmarking with compression level #. [Default: 3]
|
||||
-e# Test all compression levels up to #; starting level is `-b#`. [Default: 1]
|
||||
-i# Set the minimum evaluation to time # seconds. [Default: 3]
|
||||
-B# Cut file into independent chunks of size #. [Default: No chunking]
|
||||
-S Output one benchmark result per input file. [Default: Consolidated result]
|
||||
-D dictionary Benchmark using dictionary
|
||||
--priority=rt Set process priority to real-time.
|
||||
```
|
||||
|
||||
### Passing parameters through Environment Variables
|
||||
There is no "generic" way to pass "any kind of parameter" to `zstd` in a pass-through manner.
|
||||
Using environment variables for this purpose has security implications.
|
||||
Therefore, this avenue is intentionally restricted and only supports `ZSTD_CLEVEL` and `ZSTD_NBTHREADS`.
|
||||
|
||||
`ZSTD_CLEVEL` can be used to modify the default compression level of `zstd`
|
||||
(usually set to `3`) to another value between 1 and 19 (the "normal" range).
|
||||
|
||||
`ZSTD_NBTHREADS` can be used to specify a number of threads
|
||||
that `zstd` will use for compression, which by default is `1`.
|
||||
This functionality only exists when `zstd` is compiled with multithread support.
|
||||
`0` means "use as many threads as detected cpu cores on local system".
|
||||
The max # of threads is capped at `ZSTDMT_NBWORKERS_MAX`,
|
||||
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.
|
||||
One such scenario is `tar --zstd`.
|
||||
As `ZSTD_CLEVEL` and `ZSTD_NBTHREADS` only replace the default compression level
|
||||
and number of threads respectively, they can both be overridden by corresponding command line arguments:
|
||||
`-#` for compression level and `-T#` for number of threads.
|
||||
|
||||
|
||||
### Long distance matching mode
|
||||
The long distance matching mode, enabled with `--long`, is designed to improve
|
||||
the compression ratio for files with long matches at a large distance (up to the
|
||||
maximum window size, `128 MiB`) while still maintaining compression speed.
|
||||
|
||||
Enabling this mode sets the window size to `128 MiB` and thus increases the memory
|
||||
usage for both the compressor and decompressor. Performance in terms of speed is
|
||||
dependent on long matches being found. Compression speed may degrade if few long
|
||||
matches are found. Decompression speed usually improves when there are many long
|
||||
distance matches.
|
||||
|
||||
Below are graphs comparing the compression speed, compression ratio, and
|
||||
decompression speed with and without long distance matching on an ideal use
|
||||
case: a tar of four versions of clang (versions `3.4.1`, `3.4.2`, `3.5.0`,
|
||||
`3.5.1`) with a total size of `244889600 B`. This is an ideal use case as there
|
||||
are many long distance matches within the maximum window size of `128 MiB` (each
|
||||
version is less than `128 MiB`).
|
||||
|
||||
Compression Speed vs Ratio | Decompression Speed
|
||||
---------------------------|---------------------
|
||||
 | 
|
||||
|
||||
| Method | Compression ratio | Compression speed | Decompression speed |
|
||||
|:-------|------------------:|-------------------------:|---------------------------:|
|
||||
| `zstd -1` | `5.065` | `284.8 MB/s` | `759.3 MB/s` |
|
||||
| `zstd -5` | `5.826` | `124.9 MB/s` | `674.0 MB/s` |
|
||||
| `zstd -10` | `6.504` | `29.5 MB/s` | `771.3 MB/s` |
|
||||
| `zstd -1 --long` | `17.426` | `220.6 MB/s` | `1638.4 MB/s` |
|
||||
| `zstd -5 --long` | `19.661` | `165.5 MB/s` | `1530.6 MB/s` |
|
||||
| `zstd -10 --long`| `21.949` | `75.6 MB/s` | `1632.6 MB/s` |
|
||||
|
||||
On this file, the compression ratio improves significantly with minimal impact
|
||||
on compression speed, and the decompression speed doubles.
|
||||
|
||||
On the other extreme, compressing a file with few long distance matches (such as
|
||||
the [Silesia compression corpus]) will likely lead to a deterioration in
|
||||
compression speed (for lower levels) with minimal change in compression ratio.
|
||||
|
||||
The below table illustrates this on the [Silesia compression corpus].
|
||||
|
||||
[Silesia compression corpus]: https://sun.aei.polsl.pl//~sdeor/index.php?page=silesia
|
||||
|
||||
| Method | Compression ratio | Compression speed | Decompression speed |
|
||||
|:-------|------------------:|------------------:|---------------------:|
|
||||
| `zstd -1` | `2.878` | `231.7 MB/s` | `594.4 MB/s` |
|
||||
| `zstd -1 --long` | `2.929` | `106.5 MB/s` | `517.9 MB/s` |
|
||||
| `zstd -5` | `3.274` | `77.1 MB/s` | `464.2 MB/s` |
|
||||
| `zstd -5 --long` | `3.319` | `51.7 MB/s` | `371.9 MB/s` |
|
||||
| `zstd -10` | `3.523` | `16.4 MB/s` | `489.2 MB/s` |
|
||||
| `zstd -10 --long`| `3.566` | `16.2 MB/s` | `415.7 MB/s` |
|
||||
|
||||
|
||||
### zstdgrep
|
||||
|
||||
`zstdgrep` is a utility which makes it possible to `grep` directly a `.zst` compressed file.
|
||||
It's used the same way as normal `grep`, for example :
|
||||
`zstdgrep pattern file.zst`
|
||||
|
||||
`zstdgrep` is _not_ compatible with dictionary compression.
|
||||
|
||||
To search into a file compressed with a dictionary,
|
||||
it's necessary to decompress it using `zstd` or `zstdcat`,
|
||||
and then pipe the result to `grep`. For example :
|
||||
`zstdcat -D dictionary -qc -- file.zst | grep pattern`
|
256
build_amd64/_deps/zstd-src/programs/benchfn.c
Normal file
256
build_amd64/_deps/zstd-src/programs/benchfn.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* *************************************
|
||||
* Includes
|
||||
***************************************/
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memset */
|
||||
#include <assert.h> /* assert */
|
||||
|
||||
#include "timefn.h" /* UTIL_time_t, UTIL_getTime */
|
||||
#include "benchfn.h"
|
||||
|
||||
|
||||
/* *************************************
|
||||
* Constants
|
||||
***************************************/
|
||||
#define TIMELOOP_MICROSEC SEC_TO_MICRO /* 1 second */
|
||||
#define TIMELOOP_NANOSEC (1*1000000000ULL) /* 1 second */
|
||||
|
||||
#define KB *(1 <<10)
|
||||
#define MB *(1 <<20)
|
||||
#define GB *(1U<<30)
|
||||
|
||||
|
||||
/* *************************************
|
||||
* Debug errors
|
||||
***************************************/
|
||||
#if defined(DEBUG) && (DEBUG >= 1)
|
||||
# include <stdio.h> /* fprintf */
|
||||
# define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
||||
# define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); }
|
||||
#else
|
||||
# define DEBUGOUTPUT(...)
|
||||
#endif
|
||||
|
||||
|
||||
/* error without displaying */
|
||||
#define RETURN_QUIET_ERROR(retValue, ...) { \
|
||||
DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \
|
||||
DEBUGOUTPUT("Error : "); \
|
||||
DEBUGOUTPUT(__VA_ARGS__); \
|
||||
DEBUGOUTPUT(" \n"); \
|
||||
return retValue; \
|
||||
}
|
||||
|
||||
/* Abort execution if a condition is not met */
|
||||
#define CONTROL(c) { if (!(c)) { DEBUGOUTPUT("error: %s \n", #c); abort(); } }
|
||||
|
||||
|
||||
/* *************************************
|
||||
* Benchmarking an arbitrary function
|
||||
***************************************/
|
||||
|
||||
int BMK_isSuccessful_runOutcome(BMK_runOutcome_t outcome)
|
||||
{
|
||||
return outcome.error_tag_never_ever_use_directly == 0;
|
||||
}
|
||||
|
||||
/* warning : this function will stop program execution if outcome is invalid !
|
||||
* check outcome validity first, using BMK_isValid_runResult() */
|
||||
BMK_runTime_t BMK_extract_runTime(BMK_runOutcome_t outcome)
|
||||
{
|
||||
CONTROL(outcome.error_tag_never_ever_use_directly == 0);
|
||||
return outcome.internal_never_ever_use_directly;
|
||||
}
|
||||
|
||||
size_t BMK_extract_errorResult(BMK_runOutcome_t outcome)
|
||||
{
|
||||
CONTROL(outcome.error_tag_never_ever_use_directly != 0);
|
||||
return outcome.error_result_never_ever_use_directly;
|
||||
}
|
||||
|
||||
static BMK_runOutcome_t BMK_runOutcome_error(size_t errorResult)
|
||||
{
|
||||
BMK_runOutcome_t b;
|
||||
memset(&b, 0, sizeof(b));
|
||||
b.error_tag_never_ever_use_directly = 1;
|
||||
b.error_result_never_ever_use_directly = errorResult;
|
||||
return b;
|
||||
}
|
||||
|
||||
static BMK_runOutcome_t BMK_setValid_runTime(BMK_runTime_t runTime)
|
||||
{
|
||||
BMK_runOutcome_t outcome;
|
||||
outcome.error_tag_never_ever_use_directly = 0;
|
||||
outcome.internal_never_ever_use_directly = runTime;
|
||||
return outcome;
|
||||
}
|
||||
|
||||
|
||||
/* initFn will be measured once, benchFn will be measured `nbLoops` times */
|
||||
/* initFn is optional, provide NULL if none */
|
||||
/* benchFn must return a size_t value that errorFn can interpret */
|
||||
/* takes # of blocks and list of size & stuff for each. */
|
||||
/* can report result of benchFn for each block into blockResult. */
|
||||
/* blockResult is optional, provide NULL if this information is not required */
|
||||
/* note : time per loop can be reported as zero if run time < timer resolution */
|
||||
BMK_runOutcome_t BMK_benchFunction(BMK_benchParams_t p,
|
||||
unsigned nbLoops)
|
||||
{
|
||||
nbLoops += !nbLoops; /* minimum nbLoops is 1 */
|
||||
|
||||
/* init */
|
||||
{ size_t i;
|
||||
for(i = 0; i < p.blockCount; i++) {
|
||||
memset(p.dstBuffers[i], 0xE5, p.dstCapacities[i]); /* warm up and erase result buffer */
|
||||
} }
|
||||
|
||||
/* benchmark */
|
||||
{ size_t dstSize = 0;
|
||||
UTIL_time_t const clockStart = UTIL_getTime();
|
||||
unsigned loopNb, blockNb;
|
||||
if (p.initFn != NULL) p.initFn(p.initPayload);
|
||||
for (loopNb = 0; loopNb < nbLoops; loopNb++) {
|
||||
for (blockNb = 0; blockNb < p.blockCount; blockNb++) {
|
||||
size_t const res = p.benchFn(p.srcBuffers[blockNb], p.srcSizes[blockNb],
|
||||
p.dstBuffers[blockNb], p.dstCapacities[blockNb],
|
||||
p.benchPayload);
|
||||
if (loopNb == 0) {
|
||||
if (p.blockResults != NULL) p.blockResults[blockNb] = res;
|
||||
if ((p.errorFn != NULL) && (p.errorFn(res))) {
|
||||
RETURN_QUIET_ERROR(BMK_runOutcome_error(res),
|
||||
"Function benchmark failed on block %u (of size %u) with error %i",
|
||||
blockNb, (unsigned)p.srcSizes[blockNb], (int)res);
|
||||
}
|
||||
dstSize += res;
|
||||
} }
|
||||
} /* for (loopNb = 0; loopNb < nbLoops; loopNb++) */
|
||||
|
||||
{ PTime const totalTime = UTIL_clockSpanNano(clockStart);
|
||||
BMK_runTime_t rt;
|
||||
rt.nanoSecPerRun = (double)totalTime / nbLoops;
|
||||
rt.sumOfReturn = dstSize;
|
||||
return BMK_setValid_runTime(rt);
|
||||
} }
|
||||
}
|
||||
|
||||
|
||||
/* ==== Benchmarking any function, providing intermediate results ==== */
|
||||
|
||||
struct BMK_timedFnState_s {
|
||||
PTime timeSpent_ns;
|
||||
PTime timeBudget_ns;
|
||||
PTime runBudget_ns;
|
||||
BMK_runTime_t fastestRun;
|
||||
unsigned nbLoops;
|
||||
UTIL_time_t coolTime;
|
||||
}; /* typedef'd to BMK_timedFnState_t within bench.h */
|
||||
|
||||
BMK_timedFnState_t* BMK_createTimedFnState(unsigned total_ms, unsigned run_ms)
|
||||
{
|
||||
BMK_timedFnState_t* const r = (BMK_timedFnState_t*)malloc(sizeof(*r));
|
||||
if (r == NULL) return NULL; /* malloc() error */
|
||||
BMK_resetTimedFnState(r, total_ms, run_ms);
|
||||
return r;
|
||||
}
|
||||
|
||||
void BMK_freeTimedFnState(BMK_timedFnState_t* state) { free(state); }
|
||||
|
||||
BMK_timedFnState_t*
|
||||
BMK_initStatic_timedFnState(void* buffer, size_t size, unsigned total_ms, unsigned run_ms)
|
||||
{
|
||||
typedef char check_size[ 2 * (sizeof(BMK_timedFnState_shell) >= sizeof(struct BMK_timedFnState_s)) - 1]; /* static assert : a compilation failure indicates that BMK_timedFnState_shell is not large enough */
|
||||
typedef struct { check_size c; BMK_timedFnState_t tfs; } tfs_align; /* force tfs to be aligned at its next best position */
|
||||
size_t const tfs_alignment = offsetof(tfs_align, tfs); /* provides the minimal alignment restriction for BMK_timedFnState_t */
|
||||
BMK_timedFnState_t* const r = (BMK_timedFnState_t*)buffer;
|
||||
if (buffer == NULL) return NULL;
|
||||
if (size < sizeof(struct BMK_timedFnState_s)) return NULL;
|
||||
if ((size_t)buffer % tfs_alignment) return NULL; /* buffer must be properly aligned */
|
||||
BMK_resetTimedFnState(r, total_ms, run_ms);
|
||||
return r;
|
||||
}
|
||||
|
||||
void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, unsigned run_ms)
|
||||
{
|
||||
if (!total_ms) total_ms = 1 ;
|
||||
if (!run_ms) run_ms = 1;
|
||||
if (run_ms > total_ms) run_ms = total_ms;
|
||||
timedFnState->timeSpent_ns = 0;
|
||||
timedFnState->timeBudget_ns = (PTime)total_ms * TIMELOOP_NANOSEC / 1000;
|
||||
timedFnState->runBudget_ns = (PTime)run_ms * TIMELOOP_NANOSEC / 1000;
|
||||
timedFnState->fastestRun.nanoSecPerRun = (double)TIMELOOP_NANOSEC * 2000000000; /* hopefully large enough : must be larger than any potential measurement */
|
||||
timedFnState->fastestRun.sumOfReturn = (size_t)(-1LL);
|
||||
timedFnState->nbLoops = 1;
|
||||
timedFnState->coolTime = UTIL_getTime();
|
||||
}
|
||||
|
||||
/* Tells if nb of seconds set in timedFnState for all runs is spent.
|
||||
* note : this function will return 1 if BMK_benchFunctionTimed() has actually errored. */
|
||||
int BMK_isCompleted_TimedFn(const BMK_timedFnState_t* timedFnState)
|
||||
{
|
||||
return (timedFnState->timeSpent_ns >= timedFnState->timeBudget_ns);
|
||||
}
|
||||
|
||||
|
||||
#undef MIN
|
||||
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
||||
|
||||
#define MINUSABLETIME (TIMELOOP_NANOSEC / 2) /* 0.5 seconds */
|
||||
|
||||
BMK_runOutcome_t BMK_benchTimedFn(BMK_timedFnState_t* cont,
|
||||
BMK_benchParams_t p)
|
||||
{
|
||||
PTime const runBudget_ns = cont->runBudget_ns;
|
||||
PTime const runTimeMin_ns = runBudget_ns / 2;
|
||||
int completed = 0;
|
||||
BMK_runTime_t bestRunTime = cont->fastestRun;
|
||||
|
||||
while (!completed) {
|
||||
BMK_runOutcome_t const runResult = BMK_benchFunction(p, cont->nbLoops);
|
||||
|
||||
if(!BMK_isSuccessful_runOutcome(runResult)) { /* error : move out */
|
||||
return runResult;
|
||||
}
|
||||
|
||||
{ BMK_runTime_t const newRunTime = BMK_extract_runTime(runResult);
|
||||
double const loopDuration_ns = newRunTime.nanoSecPerRun * cont->nbLoops;
|
||||
|
||||
cont->timeSpent_ns += (unsigned long long)loopDuration_ns;
|
||||
|
||||
/* estimate nbLoops for next run to last approximately 1 second */
|
||||
if (loopDuration_ns > ((double)runBudget_ns / 50)) {
|
||||
double const fastestRun_ns = MIN(bestRunTime.nanoSecPerRun, newRunTime.nanoSecPerRun);
|
||||
cont->nbLoops = (unsigned)((double)runBudget_ns / fastestRun_ns) + 1;
|
||||
} else {
|
||||
/* previous run was too short : blindly increase workload by x multiplier */
|
||||
const unsigned multiplier = 10;
|
||||
assert(cont->nbLoops < ((unsigned)-1) / multiplier); /* avoid overflow */
|
||||
cont->nbLoops *= multiplier;
|
||||
}
|
||||
|
||||
if(loopDuration_ns < (double)runTimeMin_ns) {
|
||||
/* don't report results for which benchmark run time was too small : increased risks of rounding errors */
|
||||
assert(completed == 0);
|
||||
continue;
|
||||
} else {
|
||||
if(newRunTime.nanoSecPerRun < bestRunTime.nanoSecPerRun) {
|
||||
bestRunTime = newRunTime;
|
||||
}
|
||||
completed = 1;
|
||||
}
|
||||
}
|
||||
} /* while (!completed) */
|
||||
|
||||
return BMK_setValid_runTime(bestRunTime);
|
||||
}
|
173
build_amd64/_deps/zstd-src/programs/benchfn.h
Normal file
173
build_amd64/_deps/zstd-src/programs/benchfn.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
/* benchfn :
|
||||
* benchmark any function on a set of input
|
||||
* providing result in nanoSecPerRun
|
||||
* or detecting and returning an error
|
||||
*/
|
||||
|
||||
#ifndef BENCH_FN_H_23876
|
||||
#define BENCH_FN_H_23876
|
||||
|
||||
/* === Dependencies === */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
/* ==== Benchmark any function, iterated on a set of blocks ==== */
|
||||
|
||||
/* BMK_runTime_t: valid result return type */
|
||||
|
||||
typedef struct {
|
||||
double nanoSecPerRun; /* time per iteration (over all blocks) */
|
||||
size_t sumOfReturn; /* sum of return values */
|
||||
} BMK_runTime_t;
|
||||
|
||||
|
||||
/* BMK_runOutcome_t:
|
||||
* type expressing the outcome of a benchmark run by BMK_benchFunction(),
|
||||
* which can be either valid or invalid.
|
||||
* benchmark outcome can be invalid if errorFn is provided.
|
||||
* BMK_runOutcome_t must be considered "opaque" : never access its members directly.
|
||||
* Instead, use its assigned methods :
|
||||
* BMK_isSuccessful_runOutcome, BMK_extract_runTime, BMK_extract_errorResult.
|
||||
* The structure is only described here to allow its allocation on stack. */
|
||||
|
||||
typedef struct {
|
||||
BMK_runTime_t internal_never_ever_use_directly;
|
||||
size_t error_result_never_ever_use_directly;
|
||||
int error_tag_never_ever_use_directly;
|
||||
} BMK_runOutcome_t;
|
||||
|
||||
|
||||
/* prototypes for benchmarked functions */
|
||||
typedef size_t (*BMK_benchFn_t)(const void* src, size_t srcSize, void* dst, size_t dstCapacity, void* customPayload);
|
||||
typedef size_t (*BMK_initFn_t)(void* initPayload);
|
||||
typedef unsigned (*BMK_errorFn_t)(size_t);
|
||||
|
||||
|
||||
/* BMK_benchFunction() parameters are provided via the following structure.
|
||||
* A structure is preferable for readability,
|
||||
* as the number of parameters required is fairly large.
|
||||
* No initializer is provided, because it doesn't make sense to provide some "default" :
|
||||
* all parameters must be specified by the caller.
|
||||
* optional parameters are labelled explicitly, and accept value NULL when not used */
|
||||
typedef struct {
|
||||
BMK_benchFn_t benchFn; /* the function to benchmark, over the set of blocks */
|
||||
void* benchPayload; /* pass custom parameters to benchFn :
|
||||
* (*benchFn)(srcBuffers[i], srcSizes[i], dstBuffers[i], dstCapacities[i], benchPayload) */
|
||||
BMK_initFn_t initFn; /* (*initFn)(initPayload) is run once per run, at the beginning. */
|
||||
void* initPayload; /* Both arguments can be NULL, in which case nothing is run. */
|
||||
BMK_errorFn_t errorFn; /* errorFn will check each return value of benchFn over each block, to determine if it failed or not.
|
||||
* errorFn can be NULL, in which case no check is performed.
|
||||
* errorFn must return 0 when benchFn was successful, and >= 1 if it detects an error.
|
||||
* Execution is stopped as soon as an error is detected.
|
||||
* the triggering return value can be retrieved using BMK_extract_errorResult(). */
|
||||
size_t blockCount; /* number of blocks to operate benchFn on.
|
||||
* It's also the size of all array parameters :
|
||||
* srcBuffers, srcSizes, dstBuffers, dstCapacities, blockResults */
|
||||
const void *const * srcBuffers; /* read-only array of buffers to be operated on by benchFn */
|
||||
const size_t* srcSizes; /* read-only array containing sizes of srcBuffers */
|
||||
void *const * dstBuffers; /* array of buffers to be written into by benchFn. This array is not optional, it must be provided even if unused by benchfn. */
|
||||
const size_t* dstCapacities; /* read-only array containing capacities of dstBuffers. This array must be present. */
|
||||
size_t* blockResults; /* Optional: store the return value of benchFn for each block. Use NULL if this result is not requested. */
|
||||
} BMK_benchParams_t;
|
||||
|
||||
|
||||
/* BMK_benchFunction() :
|
||||
* This function benchmarks benchFn and initFn, providing a result.
|
||||
*
|
||||
* params : see description of BMK_benchParams_t above.
|
||||
* nbLoops: defines number of times benchFn is run over the full set of blocks.
|
||||
* Minimum value is 1. A 0 is interpreted as a 1.
|
||||
*
|
||||
* @return: can express either an error or a successful result.
|
||||
* Use BMK_isSuccessful_runOutcome() to check if benchmark was successful.
|
||||
* If yes, extract the result with BMK_extract_runTime(),
|
||||
* it will contain :
|
||||
* .sumOfReturn : the sum of all return values of benchFn through all of blocks
|
||||
* .nanoSecPerRun : time per run of benchFn + (time for initFn / nbLoops)
|
||||
* .sumOfReturn is generally intended for functions which return a # of bytes written into dstBuffer,
|
||||
* in which case, this value will be the total amount of bytes written into dstBuffer.
|
||||
*
|
||||
* blockResults : when provided (!= NULL), and when benchmark is successful,
|
||||
* params.blockResults contains all return values of `benchFn` over all blocks.
|
||||
* when provided (!= NULL), and when benchmark failed,
|
||||
* params.blockResults contains return values of `benchFn` over all blocks preceding and including the failed block.
|
||||
*/
|
||||
BMK_runOutcome_t BMK_benchFunction(BMK_benchParams_t params, unsigned nbLoops);
|
||||
|
||||
|
||||
|
||||
/* check first if the benchmark was successful or not */
|
||||
int BMK_isSuccessful_runOutcome(BMK_runOutcome_t outcome);
|
||||
|
||||
/* If the benchmark was successful, extract the result.
|
||||
* note : this function will abort() program execution if benchmark failed !
|
||||
* always check if benchmark was successful first !
|
||||
*/
|
||||
BMK_runTime_t BMK_extract_runTime(BMK_runOutcome_t outcome);
|
||||
|
||||
/* when benchmark failed, it means one invocation of `benchFn` failed.
|
||||
* The failure was detected by `errorFn`, operating on return values of `benchFn`.
|
||||
* Returns the faulty return value.
|
||||
* note : this function will abort() program execution if benchmark did not fail.
|
||||
* always check if benchmark failed first !
|
||||
*/
|
||||
size_t BMK_extract_errorResult(BMK_runOutcome_t outcome);
|
||||
|
||||
|
||||
|
||||
/* ==== Benchmark any function, returning intermediate results ==== */
|
||||
|
||||
/* state information tracking benchmark session */
|
||||
typedef struct BMK_timedFnState_s BMK_timedFnState_t;
|
||||
|
||||
/* BMK_benchTimedFn() :
|
||||
* Similar to BMK_benchFunction(), most arguments being identical.
|
||||
* Automatically determines `nbLoops` so that each result is regularly produced at interval of about run_ms.
|
||||
* Note : minimum `nbLoops` is 1, therefore a run may last more than run_ms, and possibly even more than total_ms.
|
||||
* Usage - initialize timedFnState, select benchmark duration (total_ms) and each measurement duration (run_ms)
|
||||
* call BMK_benchTimedFn() repetitively, each measurement is supposed to last about run_ms
|
||||
* Check if total time budget is spent or exceeded, using BMK_isCompleted_TimedFn()
|
||||
*/
|
||||
BMK_runOutcome_t BMK_benchTimedFn(BMK_timedFnState_t* timedFnState,
|
||||
BMK_benchParams_t params);
|
||||
|
||||
/* Tells if duration of all benchmark runs has exceeded total_ms
|
||||
*/
|
||||
int BMK_isCompleted_TimedFn(const BMK_timedFnState_t* timedFnState);
|
||||
|
||||
/* BMK_createTimedFnState() and BMK_resetTimedFnState() :
|
||||
* Create/Set BMK_timedFnState_t for next benchmark session,
|
||||
* which shall last a minimum of total_ms milliseconds,
|
||||
* producing intermediate results, paced at interval of (approximately) run_ms.
|
||||
*/
|
||||
BMK_timedFnState_t* BMK_createTimedFnState(unsigned total_ms, unsigned run_ms);
|
||||
void BMK_resetTimedFnState(BMK_timedFnState_t* timedFnState, unsigned total_ms, unsigned run_ms);
|
||||
void BMK_freeTimedFnState(BMK_timedFnState_t* state);
|
||||
|
||||
|
||||
/* BMK_timedFnState_shell and BMK_initStatic_timedFnState() :
|
||||
* Makes it possible to statically allocate a BMK_timedFnState_t on stack.
|
||||
* BMK_timedFnState_shell is only there to allocate space,
|
||||
* never ever access its members.
|
||||
* BMK_timedFnState_t() actually accepts any buffer.
|
||||
* It will check if provided buffer is large enough and is correctly aligned,
|
||||
* and will return NULL if conditions are not respected.
|
||||
*/
|
||||
#define BMK_TIMEDFNSTATE_SIZE 64
|
||||
typedef union {
|
||||
char never_access_space[BMK_TIMEDFNSTATE_SIZE];
|
||||
long long alignment_enforcer; /* must be aligned on 8-bytes boundaries */
|
||||
} BMK_timedFnState_shell;
|
||||
BMK_timedFnState_t* BMK_initStatic_timedFnState(void* buffer, size_t size, unsigned total_ms, unsigned run_ms);
|
||||
|
||||
#endif /* BENCH_FN_H_23876 */
|
1281
build_amd64/_deps/zstd-src/programs/benchzstd.c
Normal file
1281
build_amd64/_deps/zstd-src/programs/benchzstd.c
Normal file
File diff suppressed because it is too large
Load Diff
191
build_amd64/_deps/zstd-src/programs/benchzstd.h
Normal file
191
build_amd64/_deps/zstd-src/programs/benchzstd.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/* benchzstd :
|
||||
* benchmark Zstandard compression / decompression
|
||||
* over a set of files or buffers
|
||||
* and display progress result and final summary
|
||||
*/
|
||||
|
||||
#ifndef BENCH_ZSTD_H_3242387
|
||||
#define BENCH_ZSTD_H_3242387
|
||||
|
||||
/* === Dependencies === */
|
||||
#include <stddef.h> /* size_t */
|
||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
|
||||
#include "../lib/zstd.h" /* ZSTD_compressionParameters */
|
||||
|
||||
/* === Constants === */
|
||||
|
||||
#define MB_UNIT 1000000
|
||||
|
||||
|
||||
/* === Benchmark functions === */
|
||||
|
||||
/* Creates a variant `typeName`, able to express "error or valid result".
|
||||
* Functions with return type `typeName`
|
||||
* must first check if result is valid, using BMK_isSuccessful_*(),
|
||||
* and only then can extract `baseType`.
|
||||
*/
|
||||
#define VARIANT_ERROR_RESULT(baseType, variantName) \
|
||||
\
|
||||
typedef struct { \
|
||||
baseType internal_never_use_directly; \
|
||||
int tag; \
|
||||
} variantName
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t cSize;
|
||||
unsigned long long cSpeed; /* bytes / sec */
|
||||
unsigned long long dSpeed;
|
||||
size_t cMem; /* memory usage during compression */
|
||||
} BMK_benchResult_t;
|
||||
|
||||
VARIANT_ERROR_RESULT(BMK_benchResult_t, BMK_benchOutcome_t);
|
||||
|
||||
/* check first if the return structure represents an error or a valid result */
|
||||
int BMK_isSuccessful_benchOutcome(BMK_benchOutcome_t outcome);
|
||||
|
||||
/* extract result from variant type.
|
||||
* note : this function will abort() program execution if result is not valid
|
||||
* check result validity first, by using BMK_isSuccessful_benchOutcome()
|
||||
*/
|
||||
BMK_benchResult_t BMK_extract_benchResult(BMK_benchOutcome_t outcome);
|
||||
|
||||
|
||||
/*! BMK_benchFiles() -- called by zstdcli */
|
||||
/* Loads files from fileNamesTable into memory,
|
||||
* and an optional dictionary from dictFileName (can be NULL),
|
||||
* then uses benchMem().
|
||||
* fileNamesTable - name of files to benchmark.
|
||||
* nbFiles - number of files (size of fileNamesTable), must be > 0.
|
||||
* dictFileName - name of dictionary file to load.
|
||||
* cLevel - compression level to benchmark, errors if invalid.
|
||||
* compressionParams - advanced compression Parameters.
|
||||
* displayLevel - what gets printed:
|
||||
* 0 : no display;
|
||||
* 1 : errors;
|
||||
* 2 : + result + interaction + warnings;
|
||||
* 3 : + information;
|
||||
* 4 : + debug
|
||||
* @return: 0 on success, !0 on error
|
||||
*/
|
||||
int BMK_benchFiles(
|
||||
const char* const * fileNamesTable, unsigned nbFiles,
|
||||
const char* dictFileName,
|
||||
int cLevel, const ZSTD_compressionParameters* compressionParams,
|
||||
int displayLevel);
|
||||
|
||||
|
||||
typedef enum {
|
||||
BMK_both = 0,
|
||||
BMK_decodeOnly = 1,
|
||||
BMK_compressOnly = 2
|
||||
} BMK_mode_t;
|
||||
|
||||
typedef struct {
|
||||
BMK_mode_t mode; /* 0: all, 1: compress only 2: decode only */
|
||||
unsigned nbSeconds; /* default timing is in nbSeconds */
|
||||
size_t blockSize; /* Maximum size of each block*/
|
||||
size_t targetCBlockSize;/* Approximative size of compressed blocks */
|
||||
int nbWorkers; /* multithreading */
|
||||
unsigned realTime; /* real time priority */
|
||||
int additionalParam; /* used by python speed benchmark */
|
||||
int ldmFlag; /* enables long distance matching */
|
||||
int ldmMinMatch; /* below: parameters for long distance matching, see zstd.1.md */
|
||||
int ldmHashLog;
|
||||
int ldmBucketSizeLog;
|
||||
int ldmHashRateLog;
|
||||
ZSTD_ParamSwitch_e literalCompressionMode;
|
||||
int useRowMatchFinder; /* use row-based matchfinder if possible */
|
||||
} BMK_advancedParams_t;
|
||||
|
||||
/* returns default parameters used by nonAdvanced functions */
|
||||
BMK_advancedParams_t BMK_initAdvancedParams(void);
|
||||
|
||||
/*! BMK_benchFilesAdvanced():
|
||||
* Same as BMK_benchFiles(),
|
||||
* with more controls, provided through advancedParams_t structure */
|
||||
int BMK_benchFilesAdvanced(
|
||||
const char* const * fileNamesTable, unsigned nbFiles,
|
||||
const char* dictFileName,
|
||||
int startCLevel, int endCLevel,
|
||||
const ZSTD_compressionParameters* compressionParams,
|
||||
int displayLevel, const BMK_advancedParams_t* adv);
|
||||
|
||||
/*! BMK_syntheticTest() -- called from zstdcli */
|
||||
/* Generates a sample with datagen, using @compressibility argument
|
||||
* @cLevel - compression level to benchmark, errors if invalid
|
||||
* @compressibility - determines compressibility of sample, range [0.0 - 1.0]
|
||||
* if @compressibility < 0.0, uses the lorem ipsum generator
|
||||
* @compressionParams - basic compression Parameters
|
||||
* @displayLevel - see benchFiles
|
||||
* @adv - see advanced_Params_t
|
||||
* @return: 0 on success, !0 on error
|
||||
*/
|
||||
int BMK_syntheticTest(double compressibility,
|
||||
int startingCLevel, int endCLevel,
|
||||
const ZSTD_compressionParameters* compressionParams,
|
||||
int displayLevel, const BMK_advancedParams_t* adv);
|
||||
|
||||
|
||||
|
||||
/* === Benchmark Zstandard in a memory-to-memory scenario === */
|
||||
|
||||
/** BMK_benchMem() -- core benchmarking function, called in paramgrill
|
||||
* applies ZSTD_compress_generic() and ZSTD_decompress_generic() on data in srcBuffer
|
||||
* with specific compression parameters provided by other arguments using benchFunction
|
||||
* (cLevel, comprParams + adv in advanced Mode) */
|
||||
/* srcBuffer - data source, expected to be valid compressed data if in Decode Only Mode
|
||||
* srcSize - size of data in srcBuffer
|
||||
* fileSizes - srcBuffer is considered cut into 1+ segments, to compress separately.
|
||||
* note : sum(fileSizes) must be == srcSize. (<== ensure it's properly checked)
|
||||
* nbFiles - nb of segments
|
||||
* cLevel - compression level
|
||||
* comprParams - basic compression parameters
|
||||
* dictBuffer - a dictionary if used, null otherwise
|
||||
* dictBufferSize - size of dictBuffer, 0 otherwise
|
||||
* displayLevel - see BMK_benchFiles
|
||||
* displayName - name used by display
|
||||
* @return:
|
||||
* a variant, which expresses either an error, or a valid result.
|
||||
* Use BMK_isSuccessful_benchOutcome() to check if function was successful.
|
||||
* If yes, extract the valid result with BMK_extract_benchResult(),
|
||||
* it will contain :
|
||||
* .cSpeed: compression speed in bytes per second,
|
||||
* .dSpeed: decompression speed in bytes per second,
|
||||
* .cSize : compressed size, in bytes
|
||||
* .cMem : memory budget required for the compression context
|
||||
*/
|
||||
BMK_benchOutcome_t BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
||||
const size_t* fileSizes, unsigned nbFiles,
|
||||
int cLevel, const ZSTD_compressionParameters* comprParams,
|
||||
const void* dictBuffer, size_t dictBufferSize,
|
||||
int displayLevel, const char* displayName);
|
||||
|
||||
|
||||
/* BMK_benchMemAdvanced() : used by Paramgrill
|
||||
* same as BMK_benchMem() with following additional options :
|
||||
* dstBuffer - destination buffer to write compressed output in, NULL if none provided.
|
||||
* dstCapacity - capacity of destination buffer, give 0 if dstBuffer = NULL
|
||||
* adv = see advancedParams_t
|
||||
*/
|
||||
BMK_benchOutcome_t BMK_benchMemAdvanced(const void* srcBuffer, size_t srcSize,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const size_t* fileSizes, unsigned nbFiles,
|
||||
int cLevel, const ZSTD_compressionParameters* comprParams,
|
||||
const void* dictBuffer, size_t dictBufferSize,
|
||||
int displayLevel, const char* displayName,
|
||||
const BMK_advancedParams_t* adv);
|
||||
|
||||
|
||||
|
||||
#endif /* BENCH_ZSTD_H_3242387 */
|
186
build_amd64/_deps/zstd-src/programs/datagen.c
Normal file
186
build_amd64/_deps/zstd-src/programs/datagen.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Dependencies
|
||||
**************************************/
|
||||
#include "datagen.h"
|
||||
#include "platform.h" /* SET_BINARY_MODE */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <stdio.h> /* FILE, fwrite, fprintf */
|
||||
#include <string.h> /* memcpy */
|
||||
#include "../lib/common/mem.h" /* U32 */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Macros
|
||||
**************************************/
|
||||
#define KB *(1 <<10)
|
||||
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
|
||||
|
||||
#define RDG_DEBUG 0
|
||||
#define TRACE(...) if (RDG_DEBUG) fprintf(stderr, __VA_ARGS__ )
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Local constants
|
||||
**************************************/
|
||||
#define LTLOG 13
|
||||
#define LTSIZE (1<<LTLOG)
|
||||
#define LTMASK (LTSIZE-1)
|
||||
|
||||
|
||||
/*-*******************************************************
|
||||
* Local Functions
|
||||
*********************************************************/
|
||||
#define RDG_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
||||
static U32 RDG_rand(U32* src)
|
||||
{
|
||||
static const U32 prime1 = 2654435761U;
|
||||
static const U32 prime2 = 2246822519U;
|
||||
U32 rand32 = *src;
|
||||
rand32 *= prime1;
|
||||
rand32 ^= prime2;
|
||||
rand32 = RDG_rotl32(rand32, 13);
|
||||
*src = rand32;
|
||||
return rand32 >> 5;
|
||||
}
|
||||
|
||||
typedef U32 fixedPoint_24_8;
|
||||
|
||||
static void RDG_fillLiteralDistrib(BYTE* ldt, fixedPoint_24_8 ld)
|
||||
{
|
||||
BYTE const firstChar = (ld<=0.0) ? 0 : '(';
|
||||
BYTE const lastChar = (ld<=0.0) ? 255 : '}';
|
||||
BYTE character = (ld<=0.0) ? 0 : '0';
|
||||
U32 u;
|
||||
|
||||
if (ld<=0) ld = 0;
|
||||
for (u=0; u<LTSIZE; ) {
|
||||
U32 const weight = (((LTSIZE - u) * ld) >> 8) + 1;
|
||||
U32 const end = MIN ( u + weight , LTSIZE);
|
||||
while (u < end) ldt[u++] = character;
|
||||
character++;
|
||||
if (character > lastChar) character = firstChar;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static BYTE RDG_genChar(U32* seed, const BYTE* ldt)
|
||||
{
|
||||
U32 const id = RDG_rand(seed) & LTMASK;
|
||||
return ldt[id]; /* memory-sanitizer fails here, stating "uninitialized value" when table initialized with P==0.0. Checked : table is fully initialized */
|
||||
}
|
||||
|
||||
|
||||
static U32 RDG_rand15Bits (U32* seedPtr)
|
||||
{
|
||||
return RDG_rand(seedPtr) & 0x7FFF;
|
||||
}
|
||||
|
||||
static U32 RDG_randLength(U32* seedPtr)
|
||||
{
|
||||
if (RDG_rand(seedPtr) & 7) return (RDG_rand(seedPtr) & 0xF); /* small length */
|
||||
return (RDG_rand(seedPtr) & 0x1FF) + 0xF;
|
||||
}
|
||||
|
||||
static void RDG_genBlock(void* buffer, size_t buffSize, size_t prefixSize,
|
||||
double matchProba, const BYTE* ldt, U32* seedPtr)
|
||||
{
|
||||
BYTE* const buffPtr = (BYTE*)buffer;
|
||||
U32 const matchProba32 = (U32)(32768 * matchProba);
|
||||
size_t pos = prefixSize;
|
||||
U32 prevOffset = 1;
|
||||
|
||||
/* special case : sparse content */
|
||||
while (matchProba >= 1.0) {
|
||||
size_t size0 = RDG_rand(seedPtr) & 3;
|
||||
size0 = (size_t)1 << (16 + size0 * 2);
|
||||
size0 += RDG_rand(seedPtr) & (size0-1); /* because size0 is power of 2*/
|
||||
if (buffSize < pos + size0) {
|
||||
memset(buffPtr+pos, 0, buffSize-pos);
|
||||
return;
|
||||
}
|
||||
memset(buffPtr+pos, 0, size0);
|
||||
pos += size0;
|
||||
buffPtr[pos-1] = RDG_genChar(seedPtr, ldt);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* init */
|
||||
if (pos==0) buffPtr[0] = RDG_genChar(seedPtr, ldt), pos=1;
|
||||
|
||||
/* Generate compressible data */
|
||||
while (pos < buffSize) {
|
||||
/* Select : Literal (char) or Match (within 32K) */
|
||||
if (RDG_rand15Bits(seedPtr) < matchProba32) {
|
||||
/* Copy (within 32K) */
|
||||
U32 const length = RDG_randLength(seedPtr) + 4;
|
||||
U32 const d = (U32) MIN(pos + length , buffSize);
|
||||
U32 const repeatOffset = (RDG_rand(seedPtr) & 15) == 2;
|
||||
U32 const randOffset = RDG_rand15Bits(seedPtr) + 1;
|
||||
U32 const offset = repeatOffset ? prevOffset : (U32) MIN(randOffset , pos);
|
||||
size_t match = pos - offset;
|
||||
while (pos < d) { buffPtr[pos++] = buffPtr[match++]; /* correctly manages overlaps */ }
|
||||
prevOffset = offset;
|
||||
} else {
|
||||
/* Literal (noise) */
|
||||
U32 const length = RDG_randLength(seedPtr);
|
||||
U32 const d = (U32) MIN(pos + length, buffSize);
|
||||
while (pos < d) { buffPtr[pos++] = RDG_genChar(seedPtr, ldt); }
|
||||
} }
|
||||
}
|
||||
|
||||
|
||||
void RDG_genBuffer(void* buffer, size_t size, double matchProba, double litProba, unsigned seed)
|
||||
{
|
||||
U32 seed32 = seed;
|
||||
BYTE ldt[LTSIZE];
|
||||
memset(ldt, '0', sizeof(ldt)); /* yes, character '0', this is intentional */
|
||||
if (litProba<=0.0) litProba = matchProba / 4.5;
|
||||
RDG_fillLiteralDistrib(ldt, (fixedPoint_24_8)(litProba * 256 + 0.001));
|
||||
RDG_genBlock(buffer, size, 0, matchProba, ldt, &seed32);
|
||||
}
|
||||
|
||||
|
||||
void RDG_genStdout(unsigned long long size, double matchProba, double litProba, unsigned seed)
|
||||
{
|
||||
U32 seed32 = seed;
|
||||
size_t const stdBlockSize = 128 KB;
|
||||
size_t const stdDictSize = 32 KB;
|
||||
BYTE* const buff = (BYTE*)malloc(stdDictSize + stdBlockSize);
|
||||
U64 total = 0;
|
||||
BYTE ldt[LTSIZE]; /* literals distribution table */
|
||||
|
||||
/* init */
|
||||
if (buff==NULL) { perror("datagen"); exit(1); }
|
||||
if (litProba<=0.0) litProba = matchProba / 4.5;
|
||||
memset(ldt, '0', sizeof(ldt)); /* yes, character '0', this is intentional */
|
||||
RDG_fillLiteralDistrib(ldt, (fixedPoint_24_8)(litProba * 256 + 0.001));
|
||||
SET_BINARY_MODE(stdout);
|
||||
|
||||
/* Generate initial dict */
|
||||
RDG_genBlock(buff, stdDictSize, 0, matchProba, ldt, &seed32);
|
||||
|
||||
/* Generate compressible data */
|
||||
while (total < size) {
|
||||
size_t const genBlockSize = (size_t) (MIN (stdBlockSize, size-total));
|
||||
RDG_genBlock(buff, stdDictSize+stdBlockSize, stdDictSize, matchProba, ldt, &seed32);
|
||||
total += genBlockSize;
|
||||
{ size_t const unused = fwrite(buff, 1, genBlockSize, stdout); (void)unused; }
|
||||
/* update dict */
|
||||
memcpy(buff, buff + stdBlockSize, stdDictSize);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
free(buff);
|
||||
}
|
38
build_amd64/_deps/zstd-src/programs/datagen.h
Normal file
38
build_amd64/_deps/zstd-src/programs/datagen.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DATAGEN_H
|
||||
#define DATAGEN_H
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void RDG_genStdout(unsigned long long size, double matchProba, double litProba, unsigned seed);
|
||||
void RDG_genBuffer(void* buffer, size_t size, double matchProba, double litProba, unsigned seed);
|
||||
/*!RDG_genBuffer
|
||||
Generate 'size' bytes of compressible data into 'buffer'.
|
||||
Compressibility can be controlled using 'matchProba', which is floating point value between 0 and 1.
|
||||
'LitProba' is optional, it affect variability of individual bytes. If litProba==0.0, default value will be used.
|
||||
Generated data pattern can be modified using different 'seed'.
|
||||
For a triplet (matchProba, litProba, seed), the function always generate the same content.
|
||||
|
||||
RDG_genStdout
|
||||
Same as RDG_genBuffer, but generates data into stdout
|
||||
*/
|
||||
|
||||
#if defined (__cplusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
440
build_amd64/_deps/zstd-src/programs/dibio.c
Normal file
440
build_amd64/_deps/zstd-src/programs/dibio.c
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* **************************************
|
||||
* Compiler Warnings
|
||||
****************************************/
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||
#endif
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Includes
|
||||
***************************************/
|
||||
#include "platform.h" /* Large Files support */
|
||||
#include "util.h" /* UTIL_getFileSize, UTIL_getTotalFileSize */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* memset */
|
||||
#include <stdio.h> /* fprintf, fopen, ftello64 */
|
||||
#include <errno.h> /* errno */
|
||||
|
||||
#include "timefn.h" /* UTIL_time_t, UTIL_clockSpanMicro, UTIL_getTime */
|
||||
#include "../lib/common/debug.h" /* assert */
|
||||
#include "../lib/common/mem.h" /* read */
|
||||
#include "../lib/zstd_errors.h"
|
||||
#include "dibio.h"
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Constants
|
||||
***************************************/
|
||||
#define KB *(1 <<10)
|
||||
#define MB *(1 <<20)
|
||||
#define GB *(1U<<30)
|
||||
|
||||
#define SAMPLESIZE_MAX (128 KB)
|
||||
#define MEMMULT 11 /* rough estimation : memory cost to analyze 1 byte of sample */
|
||||
#define COVER_MEMMULT 9 /* rough estimation : memory cost to analyze 1 byte of sample */
|
||||
#define FASTCOVER_MEMMULT 1 /* rough estimation : memory cost to analyze 1 byte of sample */
|
||||
static const size_t g_maxMemory = (sizeof(size_t) == 4) ? (2 GB - 64 MB) : ((size_t)(512 MB) << sizeof(size_t));
|
||||
|
||||
#define NOISELENGTH 32
|
||||
#define MAX_SAMPLES_SIZE (2 GB) /* training dataset limited to 2GB */
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Console display
|
||||
***************************************/
|
||||
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); }
|
||||
|
||||
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
|
||||
***************************************/
|
||||
#ifndef DEBUG
|
||||
# define DEBUG 0
|
||||
#endif
|
||||
#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
|
||||
#define EXM_THROW(error, ...) \
|
||||
{ \
|
||||
DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
|
||||
DISPLAY("Error %i : ", error); \
|
||||
DISPLAY(__VA_ARGS__); \
|
||||
DISPLAY("\n"); \
|
||||
exit(error); \
|
||||
}
|
||||
|
||||
|
||||
/* ********************************************************
|
||||
* Helper functions
|
||||
**********************************************************/
|
||||
#undef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
/**
|
||||
Returns the size of a file.
|
||||
If error returns -1.
|
||||
*/
|
||||
static S64 DiB_getFileSize (const char * fileName)
|
||||
{
|
||||
U64 const fileSize = UTIL_getFileSize(fileName);
|
||||
return (fileSize == UTIL_FILESIZE_UNKNOWN) ? -1 : (S64)fileSize;
|
||||
}
|
||||
|
||||
/* ********************************************************
|
||||
* File related operations
|
||||
**********************************************************/
|
||||
/** DiB_loadFiles() :
|
||||
* load samples from files listed in fileNamesTable into buffer.
|
||||
* works even if buffer is too small to load all samples.
|
||||
* Also provides the size of each sample into sampleSizes table
|
||||
* which must be sized correctly, using DiB_fileStats().
|
||||
* @return : nb of samples effectively loaded into `buffer`
|
||||
* *bufferSizePtr is modified, it provides the amount data loaded within buffer.
|
||||
* sampleSizes is filled with the size of each sample.
|
||||
*/
|
||||
static int DiB_loadFiles(
|
||||
void* buffer, size_t* bufferSizePtr,
|
||||
size_t* sampleSizes, int sstSize,
|
||||
const char** fileNamesTable, int nbFiles,
|
||||
size_t targetChunkSize, int displayLevel )
|
||||
{
|
||||
char* const buff = (char*)buffer;
|
||||
size_t totalDataLoaded = 0;
|
||||
int nbSamplesLoaded = 0;
|
||||
int fileIndex = 0;
|
||||
FILE * f = NULL;
|
||||
|
||||
assert(targetChunkSize <= SAMPLESIZE_MAX);
|
||||
|
||||
while ( nbSamplesLoaded < sstSize && fileIndex < nbFiles ) {
|
||||
size_t fileDataLoaded;
|
||||
S64 const fileSize = DiB_getFileSize(fileNamesTable[fileIndex]);
|
||||
if (fileSize <= 0) {
|
||||
/* skip if zero-size or file error */
|
||||
++fileIndex;
|
||||
continue;
|
||||
}
|
||||
|
||||
f = fopen( fileNamesTable[fileIndex], "rb");
|
||||
if (f == NULL)
|
||||
EXM_THROW(10, "zstd: dictBuilder: %s %s ", fileNamesTable[fileIndex], strerror(errno));
|
||||
DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[fileIndex]);
|
||||
|
||||
/* Load the first chunk of data from the file */
|
||||
fileDataLoaded = targetChunkSize > 0 ?
|
||||
(size_t)MIN(fileSize, (S64)targetChunkSize) :
|
||||
(size_t)MIN(fileSize, SAMPLESIZE_MAX );
|
||||
if (totalDataLoaded + fileDataLoaded > *bufferSizePtr)
|
||||
break;
|
||||
if (fread( buff+totalDataLoaded, 1, fileDataLoaded, f ) != fileDataLoaded)
|
||||
EXM_THROW(11, "Pb reading %s", fileNamesTable[fileIndex]);
|
||||
sampleSizes[nbSamplesLoaded++] = fileDataLoaded;
|
||||
totalDataLoaded += fileDataLoaded;
|
||||
|
||||
/* If file-chunking is enabled, load the rest of the file as more samples */
|
||||
if (targetChunkSize > 0) {
|
||||
while( (S64)fileDataLoaded < fileSize && nbSamplesLoaded < sstSize ) {
|
||||
size_t const chunkSize = MIN((size_t)(fileSize-fileDataLoaded), targetChunkSize);
|
||||
if (totalDataLoaded + chunkSize > *bufferSizePtr) /* buffer is full */
|
||||
break;
|
||||
|
||||
if (fread( buff+totalDataLoaded, 1, chunkSize, f ) != chunkSize)
|
||||
EXM_THROW(11, "Pb reading %s", fileNamesTable[fileIndex]);
|
||||
sampleSizes[nbSamplesLoaded++] = chunkSize;
|
||||
totalDataLoaded += chunkSize;
|
||||
fileDataLoaded += chunkSize;
|
||||
}
|
||||
}
|
||||
fileIndex += 1;
|
||||
fclose(f); f = NULL;
|
||||
}
|
||||
if (f != NULL)
|
||||
fclose(f);
|
||||
|
||||
DISPLAYLEVEL(2, "\r%79s\r", "");
|
||||
DISPLAYLEVEL(4, "Loaded %d KB total training data, %d nb samples \n",
|
||||
(int)(totalDataLoaded / (1 KB)), nbSamplesLoaded );
|
||||
*bufferSizePtr = totalDataLoaded;
|
||||
return nbSamplesLoaded;
|
||||
}
|
||||
|
||||
#define DiB_rotl32(x,r) ((x << r) | (x >> (32 - r)))
|
||||
static U32 DiB_rand(U32* src)
|
||||
{
|
||||
static const U32 prime1 = 2654435761U;
|
||||
static const U32 prime2 = 2246822519U;
|
||||
U32 rand32 = *src;
|
||||
rand32 *= prime1;
|
||||
rand32 ^= prime2;
|
||||
rand32 = DiB_rotl32(rand32, 13);
|
||||
*src = rand32;
|
||||
return rand32 >> 5;
|
||||
}
|
||||
|
||||
/* DiB_shuffle() :
|
||||
* shuffle a table of file names in a semi-random way
|
||||
* It improves dictionary quality by reducing "locality" impact, so if sample set is very large,
|
||||
* it will load random elements from it, instead of just the first ones. */
|
||||
static void DiB_shuffle(const char** fileNamesTable, unsigned nbFiles) {
|
||||
U32 seed = 0xFD2FB528;
|
||||
unsigned i;
|
||||
if (nbFiles == 0)
|
||||
return;
|
||||
for (i = nbFiles - 1; i > 0; --i) {
|
||||
unsigned const j = DiB_rand(&seed) % (i + 1);
|
||||
const char* const tmp = fileNamesTable[j];
|
||||
fileNamesTable[j] = fileNamesTable[i];
|
||||
fileNamesTable[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-********************************************************
|
||||
* Dictionary training functions
|
||||
**********************************************************/
|
||||
static size_t DiB_findMaxMem(unsigned long long requiredMem)
|
||||
{
|
||||
size_t const step = 8 MB;
|
||||
void* testmem = NULL;
|
||||
|
||||
requiredMem = (((requiredMem >> 23) + 1) << 23);
|
||||
requiredMem += step;
|
||||
if (requiredMem > g_maxMemory) requiredMem = g_maxMemory;
|
||||
|
||||
while (!testmem) {
|
||||
testmem = malloc((size_t)requiredMem);
|
||||
requiredMem -= step;
|
||||
}
|
||||
|
||||
free(testmem);
|
||||
return (size_t)requiredMem;
|
||||
}
|
||||
|
||||
|
||||
static void DiB_fillNoise(void* buffer, size_t length)
|
||||
{
|
||||
unsigned const prime1 = 2654435761U;
|
||||
unsigned const prime2 = 2246822519U;
|
||||
unsigned acc = prime1;
|
||||
size_t p=0;
|
||||
|
||||
for (p=0; p<length; p++) {
|
||||
acc *= prime2;
|
||||
((unsigned char*)buffer)[p] = (unsigned char)(acc >> 21);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void DiB_saveDict(const char* dictFileName,
|
||||
const void* buff, size_t buffSize)
|
||||
{
|
||||
FILE* const f = fopen(dictFileName, "wb");
|
||||
if (f==NULL) EXM_THROW(3, "cannot open %s ", dictFileName);
|
||||
|
||||
{ size_t const n = fwrite(buff, 1, buffSize, f);
|
||||
if (n!=buffSize) EXM_THROW(4, "%s : write error", dictFileName) }
|
||||
|
||||
{ size_t const n = (size_t)fclose(f);
|
||||
if (n!=0) EXM_THROW(5, "%s : flush error", dictFileName) }
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
S64 totalSizeToLoad;
|
||||
int nbSamples;
|
||||
int oneSampleTooLarge;
|
||||
} fileStats;
|
||||
|
||||
/*! DiB_fileStats() :
|
||||
* Given a list of files, and a chunkSize (0 == no chunk, whole files)
|
||||
* provides the amount of data to be loaded and the resulting nb of samples.
|
||||
* This is useful primarily for allocation purpose => sample buffer, and sample sizes table.
|
||||
*/
|
||||
static fileStats DiB_fileStats(const char** fileNamesTable, int nbFiles, size_t chunkSize, int displayLevel)
|
||||
{
|
||||
fileStats fs;
|
||||
int n;
|
||||
memset(&fs, 0, sizeof(fs));
|
||||
|
||||
/* We assume that if chunking is requested, the chunk size is < SAMPLESIZE_MAX */
|
||||
assert( chunkSize <= SAMPLESIZE_MAX );
|
||||
|
||||
for (n=0; n<nbFiles; n++) {
|
||||
S64 const fileSize = DiB_getFileSize(fileNamesTable[n]);
|
||||
/* TODO: is there a minimum sample size? What if the file is 1-byte? */
|
||||
if (fileSize == 0) {
|
||||
DISPLAYLEVEL(3, "Sample file '%s' has zero size, skipping...\n", fileNamesTable[n]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the case where we are breaking up files in sample chunks */
|
||||
if (chunkSize > 0) {
|
||||
/* TODO: is there a minimum sample size? Can we have a 1-byte sample? */
|
||||
fs.nbSamples += (int)((fileSize + chunkSize-1) / chunkSize);
|
||||
fs.totalSizeToLoad += fileSize;
|
||||
}
|
||||
else {
|
||||
/* the case where one file is one sample */
|
||||
if (fileSize > SAMPLESIZE_MAX) {
|
||||
/* flag excessively large sample files */
|
||||
fs.oneSampleTooLarge |= (fileSize > 2*SAMPLESIZE_MAX);
|
||||
|
||||
/* Limit to the first SAMPLESIZE_MAX (128kB) of the file */
|
||||
DISPLAYLEVEL(3, "Sample file '%s' is too large, limiting to %d KB\n",
|
||||
fileNamesTable[n], SAMPLESIZE_MAX / (1 KB));
|
||||
}
|
||||
fs.nbSamples += 1;
|
||||
fs.totalSizeToLoad += MIN(fileSize, SAMPLESIZE_MAX);
|
||||
}
|
||||
}
|
||||
DISPLAYLEVEL(4, "Found training data %d files, %d KB, %d samples\n", nbFiles, (int)(fs.totalSizeToLoad / (1 KB)), fs.nbSamples);
|
||||
return fs;
|
||||
}
|
||||
|
||||
int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize,
|
||||
const char** fileNamesTable, int nbFiles, size_t chunkSize,
|
||||
ZDICT_legacy_params_t* params, ZDICT_cover_params_t* coverParams,
|
||||
ZDICT_fastCover_params_t* fastCoverParams, int optimize, unsigned memLimit)
|
||||
{
|
||||
fileStats fs;
|
||||
size_t* sampleSizes; /* vector of sample sizes. Each sample can be up to SAMPLESIZE_MAX */
|
||||
int nbSamplesLoaded; /* nb of samples effectively loaded in srcBuffer */
|
||||
size_t loadedSize; /* total data loaded in srcBuffer for all samples */
|
||||
void* srcBuffer /* contiguous buffer with training data/samples */;
|
||||
void* const dictBuffer = malloc(maxDictSize);
|
||||
int result = 0;
|
||||
|
||||
int const displayLevel = params ? params->zParams.notificationLevel :
|
||||
coverParams ? coverParams->zParams.notificationLevel :
|
||||
fastCoverParams ? fastCoverParams->zParams.notificationLevel : 0;
|
||||
|
||||
/* Shuffle input files before we start assessing how much sample datA to load.
|
||||
The purpose of the shuffle is to pick random samples when the sample
|
||||
set is larger than what we can load in memory. */
|
||||
DISPLAYLEVEL(3, "Shuffling input files\n");
|
||||
DiB_shuffle(fileNamesTable, nbFiles);
|
||||
|
||||
/* Figure out how much sample data to load with how many samples */
|
||||
fs = DiB_fileStats(fileNamesTable, nbFiles, chunkSize, displayLevel);
|
||||
|
||||
{
|
||||
int const memMult = params ? MEMMULT :
|
||||
coverParams ? COVER_MEMMULT:
|
||||
FASTCOVER_MEMMULT;
|
||||
size_t const maxMem = DiB_findMaxMem(fs.totalSizeToLoad * memMult) / memMult;
|
||||
/* Limit the size of the training data to the free memory */
|
||||
/* Limit the size of the training data to 2GB */
|
||||
/* TODO: there is opportunity to stop DiB_fileStats() early when the data limit is reached */
|
||||
loadedSize = (size_t)MIN( MIN((S64)maxMem, fs.totalSizeToLoad), MAX_SAMPLES_SIZE );
|
||||
if (memLimit != 0) {
|
||||
DISPLAYLEVEL(2, "! Warning : setting manual memory limit for dictionary training data at %u MB \n",
|
||||
(unsigned)(memLimit / (1 MB)));
|
||||
loadedSize = (size_t)MIN(loadedSize, memLimit);
|
||||
}
|
||||
srcBuffer = malloc(loadedSize+NOISELENGTH);
|
||||
sampleSizes = (size_t*)malloc(fs.nbSamples * sizeof(size_t));
|
||||
}
|
||||
|
||||
/* Checks */
|
||||
if ((fs.nbSamples && !sampleSizes) || (!srcBuffer) || (!dictBuffer))
|
||||
EXM_THROW(12, "not enough memory for DiB_trainFiles"); /* should not happen */
|
||||
if (fs.oneSampleTooLarge) {
|
||||
DISPLAYLEVEL(2, "! Warning : some sample(s) are very large \n");
|
||||
DISPLAYLEVEL(2, "! Note that dictionary is only useful for small samples. \n");
|
||||
DISPLAYLEVEL(2, "! As a consequence, only the first %u bytes of each sample are loaded \n", SAMPLESIZE_MAX);
|
||||
}
|
||||
if (fs.nbSamples < 5) {
|
||||
DISPLAYLEVEL(2, "! Warning : nb of samples too low for proper processing ! \n");
|
||||
DISPLAYLEVEL(2, "! Please provide _one file per sample_. \n");
|
||||
DISPLAYLEVEL(2, "! Alternatively, split files into fixed-size blocks representative of samples, with -B# \n");
|
||||
EXM_THROW(14, "nb of samples too low"); /* we now clearly forbid this case */
|
||||
}
|
||||
if (fs.totalSizeToLoad < (S64)maxDictSize * 8) {
|
||||
DISPLAYLEVEL(2, "! Warning : data size of samples too small for target dictionary size \n");
|
||||
DISPLAYLEVEL(2, "! Samples should be about 100x larger than target dictionary size \n");
|
||||
}
|
||||
|
||||
/* init */
|
||||
if ((S64)loadedSize < fs.totalSizeToLoad)
|
||||
DISPLAYLEVEL(1, "Training samples set too large (%u MB); training on %u MB only...\n",
|
||||
(unsigned)(fs.totalSizeToLoad / (1 MB)),
|
||||
(unsigned)(loadedSize / (1 MB)));
|
||||
|
||||
/* Load input buffer */
|
||||
nbSamplesLoaded = DiB_loadFiles(
|
||||
srcBuffer, &loadedSize, sampleSizes, fs.nbSamples, fileNamesTable,
|
||||
nbFiles, chunkSize, displayLevel);
|
||||
|
||||
{ size_t dictSize = ZSTD_error_GENERIC;
|
||||
if (params) {
|
||||
DiB_fillNoise((char*)srcBuffer + loadedSize, NOISELENGTH); /* guard band, for end of buffer condition */
|
||||
dictSize = ZDICT_trainFromBuffer_legacy(dictBuffer, maxDictSize,
|
||||
srcBuffer, sampleSizes, nbSamplesLoaded,
|
||||
*params);
|
||||
} else if (coverParams) {
|
||||
if (optimize) {
|
||||
dictSize = ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, maxDictSize,
|
||||
srcBuffer, sampleSizes, nbSamplesLoaded,
|
||||
coverParams);
|
||||
if (!ZDICT_isError(dictSize)) {
|
||||
unsigned splitPercentage = (unsigned)(coverParams->splitPoint * 100);
|
||||
DISPLAYLEVEL(2, "k=%u\nd=%u\nsteps=%u\nsplit=%u\n", coverParams->k, coverParams->d,
|
||||
coverParams->steps, splitPercentage);
|
||||
}
|
||||
} else {
|
||||
dictSize = ZDICT_trainFromBuffer_cover(dictBuffer, maxDictSize, srcBuffer,
|
||||
sampleSizes, nbSamplesLoaded, *coverParams);
|
||||
}
|
||||
} else if (fastCoverParams != NULL) {
|
||||
if (optimize) {
|
||||
dictSize = ZDICT_optimizeTrainFromBuffer_fastCover(dictBuffer, maxDictSize,
|
||||
srcBuffer, sampleSizes, nbSamplesLoaded,
|
||||
fastCoverParams);
|
||||
if (!ZDICT_isError(dictSize)) {
|
||||
unsigned splitPercentage = (unsigned)(fastCoverParams->splitPoint * 100);
|
||||
DISPLAYLEVEL(2, "k=%u\nd=%u\nf=%u\nsteps=%u\nsplit=%u\naccel=%u\n", fastCoverParams->k,
|
||||
fastCoverParams->d, fastCoverParams->f, fastCoverParams->steps, splitPercentage,
|
||||
fastCoverParams->accel);
|
||||
}
|
||||
} else {
|
||||
dictSize = ZDICT_trainFromBuffer_fastCover(dictBuffer, maxDictSize, srcBuffer,
|
||||
sampleSizes, nbSamplesLoaded, *fastCoverParams);
|
||||
}
|
||||
} else {
|
||||
assert(0 /* Impossible */);
|
||||
}
|
||||
if (ZDICT_isError(dictSize)) {
|
||||
DISPLAYLEVEL(1, "dictionary training failed : %s \n", ZDICT_getErrorName(dictSize)); /* should not happen */
|
||||
result = 1;
|
||||
goto _cleanup;
|
||||
}
|
||||
/* save dict */
|
||||
DISPLAYLEVEL(2, "Save dictionary of size %u into file %s \n", (unsigned)dictSize, dictFileName);
|
||||
DiB_saveDict(dictFileName, dictBuffer, dictSize);
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
_cleanup:
|
||||
free(srcBuffer);
|
||||
free(sampleSizes);
|
||||
free(dictBuffer);
|
||||
return result;
|
||||
}
|
39
build_amd64/_deps/zstd-src/programs/dibio.h
Normal file
39
build_amd64/_deps/zstd-src/programs/dibio.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/* This library is designed for a single-threaded console application.
|
||||
* It exit() and printf() into stderr when it encounters an error condition. */
|
||||
|
||||
#ifndef DIBIO_H_003
|
||||
#define DIBIO_H_003
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Dependencies
|
||||
***************************************/
|
||||
#define ZDICT_STATIC_LINKING_ONLY
|
||||
#include "../lib/zdict.h" /* ZDICT_params_t */
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Public functions
|
||||
***************************************/
|
||||
/*! DiB_trainFromFiles() :
|
||||
Train a dictionary from a set of files provided by `fileNamesTable`.
|
||||
Resulting dictionary is written into file `dictFileName`.
|
||||
`parameters` is optional and can be provided with values set to 0, meaning "default".
|
||||
@return : 0 == ok. Any other : error.
|
||||
*/
|
||||
int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize,
|
||||
const char** fileNamesTable, int nbFiles, size_t chunkSize,
|
||||
ZDICT_legacy_params_t* params, ZDICT_cover_params_t* coverParams,
|
||||
ZDICT_fastCover_params_t* fastCoverParams, int optimize, unsigned memLimit);
|
||||
|
||||
#endif
|
3464
build_amd64/_deps/zstd-src/programs/fileio.c
Normal file
3464
build_amd64/_deps/zstd-src/programs/fileio.c
Normal file
File diff suppressed because it is too large
Load Diff
171
build_amd64/_deps/zstd-src/programs/fileio.h
Normal file
171
build_amd64/_deps/zstd-src/programs/fileio.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FILEIO_H_23981798732
|
||||
#define FILEIO_H_23981798732
|
||||
|
||||
#include "fileio_types.h"
|
||||
#include "util.h" /* FileNamesTable */
|
||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
|
||||
#include "../lib/zstd.h" /* ZSTD_* */
|
||||
|
||||
/* *************************************
|
||||
* Special i/o constants
|
||||
**************************************/
|
||||
#define stdinmark "/*stdin*\\"
|
||||
#define stdoutmark "/*stdout*\\"
|
||||
#ifdef _WIN32
|
||||
# define nulmark "NUL"
|
||||
#else
|
||||
# define nulmark "/dev/null"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* We test whether the extension we found starts with 't', and if so, we append
|
||||
* ".tar" to the end of the output name.
|
||||
*/
|
||||
#define LZMA_EXTENSION ".lzma"
|
||||
#define XZ_EXTENSION ".xz"
|
||||
#define TXZ_EXTENSION ".txz"
|
||||
|
||||
#define GZ_EXTENSION ".gz"
|
||||
#define TGZ_EXTENSION ".tgz"
|
||||
|
||||
#define ZSTD_EXTENSION ".zst"
|
||||
#define TZSTD_EXTENSION ".tzst"
|
||||
#define ZSTD_ALT_EXTENSION ".zstd" /* allow decompression of .zstd files */
|
||||
|
||||
#define LZ4_EXTENSION ".lz4"
|
||||
#define TLZ4_EXTENSION ".tlz4"
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Types
|
||||
***************************************/
|
||||
FIO_prefs_t* FIO_createPreferences(void);
|
||||
void FIO_freePreferences(FIO_prefs_t* const prefs);
|
||||
|
||||
/* Mutable struct containing relevant context and state regarding (de)compression with respect to file I/O */
|
||||
typedef struct FIO_ctx_s FIO_ctx_t;
|
||||
|
||||
FIO_ctx_t* FIO_createContext(void);
|
||||
void FIO_freeContext(FIO_ctx_t* const fCtx);
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Parameters
|
||||
***************************************/
|
||||
/* FIO_prefs_t functions */
|
||||
void FIO_setCompressionType(FIO_prefs_t* const prefs, FIO_compressionType_t compressionType);
|
||||
void FIO_overwriteMode(FIO_prefs_t* const prefs);
|
||||
void FIO_setAdaptiveMode(FIO_prefs_t* const prefs, int adapt);
|
||||
void FIO_setAdaptMin(FIO_prefs_t* const prefs, int minCLevel);
|
||||
void FIO_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel);
|
||||
void FIO_setUseRowMatchFinder(FIO_prefs_t* const prefs, int useRowMatchFinder);
|
||||
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize);
|
||||
void FIO_setChecksumFlag(FIO_prefs_t* const prefs, int checksumFlag);
|
||||
void FIO_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag);
|
||||
void FIO_setLdmBucketSizeLog(FIO_prefs_t* const prefs, int ldmBucketSizeLog);
|
||||
void FIO_setLdmFlag(FIO_prefs_t* const prefs, unsigned ldmFlag);
|
||||
void FIO_setLdmHashRateLog(FIO_prefs_t* const prefs, int ldmHashRateLog);
|
||||
void FIO_setLdmHashLog(FIO_prefs_t* const prefs, int ldmHashLog);
|
||||
void FIO_setLdmMinMatch(FIO_prefs_t* const prefs, int ldmMinMatch);
|
||||
void FIO_setMemLimit(FIO_prefs_t* const prefs, unsigned memLimit);
|
||||
void FIO_setNbWorkers(FIO_prefs_t* const prefs, int nbWorkers);
|
||||
void FIO_setOverlapLog(FIO_prefs_t* const prefs, int overlapLog);
|
||||
void FIO_setRemoveSrcFile(FIO_prefs_t* const prefs, int flag);
|
||||
void FIO_setSparseWrite(FIO_prefs_t* const prefs, int sparse); /**< 0: no sparse; 1: disable on stdout; 2: always enabled */
|
||||
void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable);
|
||||
void FIO_setStreamSrcSize(FIO_prefs_t* const prefs, size_t streamSrcSize);
|
||||
void FIO_setTargetCBlockSize(FIO_prefs_t* const prefs, size_t targetCBlockSize);
|
||||
void FIO_setSrcSizeHint(FIO_prefs_t* const prefs, size_t srcSizeHint);
|
||||
void FIO_setTestMode(FIO_prefs_t* const prefs, int testMode);
|
||||
void FIO_setLiteralCompressionMode(
|
||||
FIO_prefs_t* const prefs,
|
||||
ZSTD_ParamSwitch_e mode);
|
||||
|
||||
void FIO_setProgressSetting(FIO_progressSetting_e progressSetting);
|
||||
void FIO_setNotificationLevel(int level);
|
||||
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_setContentSize(FIO_prefs_t* const prefs, int value);
|
||||
void FIO_displayCompressionParameters(const FIO_prefs_t* prefs);
|
||||
void FIO_setAsyncIOFlag(FIO_prefs_t* const prefs, int value);
|
||||
void FIO_setPassThroughFlag(FIO_prefs_t* const prefs, int value);
|
||||
void FIO_setMMapDict(FIO_prefs_t* const prefs, ZSTD_ParamSwitch_e value);
|
||||
|
||||
/* FIO_ctx_t functions */
|
||||
void FIO_setNbFilesTotal(FIO_ctx_t* const fCtx, int value);
|
||||
void FIO_setHasStdoutOutput(FIO_ctx_t* const fCtx, int value);
|
||||
void FIO_determineHasStdinInput(FIO_ctx_t* const fCtx, const FileNamesTable* const filenames);
|
||||
|
||||
/*-*************************************
|
||||
* Single File functions
|
||||
***************************************/
|
||||
/** FIO_compressFilename() :
|
||||
* @return : 0 == ok; 1 == pb with src file. */
|
||||
int FIO_compressFilename (FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs,
|
||||
const char* outfilename, const char* infilename,
|
||||
const char* dictFileName, int compressionLevel,
|
||||
ZSTD_compressionParameters comprParams);
|
||||
|
||||
/** FIO_decompressFilename() :
|
||||
* @return : 0 == ok; 1 == pb with src file. */
|
||||
int FIO_decompressFilename (FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs,
|
||||
const char* outfilename, const char* infilename, const char* dictFileName);
|
||||
|
||||
int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int displayLevel);
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Multiple File functions
|
||||
***************************************/
|
||||
/** FIO_compressMultipleFilenames() :
|
||||
* @return : nb of missing files */
|
||||
int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
FIO_prefs_t* const prefs,
|
||||
const char** inFileNamesTable,
|
||||
const char* outMirroredDirName,
|
||||
const char* outDirName,
|
||||
const char* outFileName, const char* suffix,
|
||||
const char* dictFileName, int compressionLevel,
|
||||
ZSTD_compressionParameters comprParams);
|
||||
|
||||
/** FIO_decompressMultipleFilenames() :
|
||||
* @return : nb of missing or skipped files */
|
||||
int FIO_decompressMultipleFilenames(FIO_ctx_t* const fCtx,
|
||||
FIO_prefs_t* const prefs,
|
||||
const char** srcNamesTable,
|
||||
const char* outMirroredDirName,
|
||||
const char* outDirName,
|
||||
const char* outFileName,
|
||||
const char* dictFileName);
|
||||
|
||||
/* FIO_checkFilenameCollisions() :
|
||||
* Checks for and warns if there are any files that would have the same output path
|
||||
*/
|
||||
int FIO_checkFilenameCollisions(const char** filenameTable, unsigned nbFiles);
|
||||
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Advanced stuff (should actually be hosted elsewhere)
|
||||
***************************************/
|
||||
|
||||
/* custom crash signal handler */
|
||||
void FIO_addAbortHandler(void);
|
||||
|
||||
char const* FIO_zlibVersion(void);
|
||||
char const* FIO_lz4Version(void);
|
||||
char const* FIO_lzmaVersion(void);
|
||||
|
||||
#endif /* FILEIO_H_23981798732 */
|
663
build_amd64/_deps/zstd-src/programs/fileio_asyncio.c
Normal file
663
build_amd64/_deps/zstd-src/programs/fileio_asyncio.c
Normal file
@@ -0,0 +1,663 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include "platform.h"
|
||||
#include <stdio.h> /* fprintf, open, fdopen, fread, _fileno, stdin, stdout */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <assert.h>
|
||||
#include <errno.h> /* errno */
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
# include <sys/stat.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include "fileio_asyncio.h"
|
||||
#include "fileio_common.h"
|
||||
|
||||
/* **********************************************************************
|
||||
* Sparse write
|
||||
************************************************************************/
|
||||
|
||||
/** AIO_fwriteSparse() :
|
||||
* @return : storedSkips,
|
||||
* argument for next call to AIO_fwriteSparse() or AIO_fwriteSparseEnd() */
|
||||
static unsigned
|
||||
AIO_fwriteSparse(FILE* file,
|
||||
const void* buffer, size_t bufferSize,
|
||||
const FIO_prefs_t* const prefs,
|
||||
unsigned storedSkips)
|
||||
{
|
||||
const size_t* const bufferT = (const size_t*)buffer; /* Buffer is supposed malloc'ed, hence aligned on size_t */
|
||||
size_t bufferSizeT = bufferSize / sizeof(size_t);
|
||||
const size_t* const bufferTEnd = bufferT + bufferSizeT;
|
||||
const size_t* ptrT = bufferT;
|
||||
static const size_t segmentSizeT = (32 KB) / sizeof(size_t); /* check every 32 KB */
|
||||
|
||||
if (prefs->testMode) return 0; /* do not output anything in test mode */
|
||||
|
||||
if (!prefs->sparseFileSupport) { /* normal write */
|
||||
size_t const sizeCheck = fwrite(buffer, 1, bufferSize, file);
|
||||
if (sizeCheck != bufferSize)
|
||||
EXM_THROW(70, "Write error : cannot write block : %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* avoid int overflow */
|
||||
if (storedSkips > 1 GB) {
|
||||
if (LONG_SEEK(file, 1 GB, SEEK_CUR) != 0)
|
||||
EXM_THROW(91, "1 GB skip error (sparse file support)");
|
||||
storedSkips -= 1 GB;
|
||||
}
|
||||
|
||||
while (ptrT < bufferTEnd) {
|
||||
size_t nb0T;
|
||||
|
||||
/* adjust last segment if < 32 KB */
|
||||
size_t seg0SizeT = segmentSizeT;
|
||||
if (seg0SizeT > bufferSizeT) seg0SizeT = bufferSizeT;
|
||||
bufferSizeT -= seg0SizeT;
|
||||
|
||||
/* count leading zeroes */
|
||||
for (nb0T=0; (nb0T < seg0SizeT) && (ptrT[nb0T] == 0); nb0T++) ;
|
||||
storedSkips += (unsigned)(nb0T * sizeof(size_t));
|
||||
|
||||
if (nb0T != seg0SizeT) { /* not all 0s */
|
||||
size_t const nbNon0ST = seg0SizeT - nb0T;
|
||||
/* skip leading zeros */
|
||||
if (LONG_SEEK(file, storedSkips, SEEK_CUR) != 0)
|
||||
EXM_THROW(92, "Sparse skip error ; try --no-sparse");
|
||||
storedSkips = 0;
|
||||
/* write the rest */
|
||||
if (fwrite(ptrT + nb0T, sizeof(size_t), nbNon0ST, file) != nbNon0ST)
|
||||
EXM_THROW(93, "Write error : cannot write block : %s",
|
||||
strerror(errno));
|
||||
}
|
||||
ptrT += seg0SizeT;
|
||||
}
|
||||
|
||||
{ static size_t const maskT = sizeof(size_t)-1;
|
||||
if (bufferSize & maskT) {
|
||||
/* size not multiple of sizeof(size_t) : implies end of block */
|
||||
const char* const restStart = (const char*)bufferTEnd;
|
||||
const char* restPtr = restStart;
|
||||
const char* const restEnd = (const char*)buffer + bufferSize;
|
||||
assert(restEnd > restStart && restEnd < restStart + sizeof(size_t));
|
||||
for ( ; (restPtr < restEnd) && (*restPtr == 0); restPtr++) ;
|
||||
storedSkips += (unsigned) (restPtr - restStart);
|
||||
if (restPtr != restEnd) {
|
||||
/* not all remaining bytes are 0 */
|
||||
size_t const restSize = (size_t)(restEnd - restPtr);
|
||||
if (LONG_SEEK(file, storedSkips, SEEK_CUR) != 0)
|
||||
EXM_THROW(92, "Sparse skip error ; try --no-sparse");
|
||||
if (fwrite(restPtr, 1, restSize, file) != restSize)
|
||||
EXM_THROW(95, "Write error : cannot write end of decoded block : %s",
|
||||
strerror(errno));
|
||||
storedSkips = 0;
|
||||
} } }
|
||||
|
||||
return storedSkips;
|
||||
}
|
||||
|
||||
static void
|
||||
AIO_fwriteSparseEnd(const FIO_prefs_t* const prefs, FILE* file, unsigned storedSkips)
|
||||
{
|
||||
if (prefs->testMode) assert(storedSkips == 0);
|
||||
if (storedSkips>0) {
|
||||
assert(prefs->sparseFileSupport > 0); /* storedSkips>0 implies sparse support is enabled */
|
||||
(void)prefs; /* assert can be disabled, in which case prefs becomes unused */
|
||||
if (LONG_SEEK(file, storedSkips-1, SEEK_CUR) != 0)
|
||||
EXM_THROW(69, "Final skip error (sparse file support)");
|
||||
/* last zero must be explicitly written,
|
||||
* so that skipped ones get implicitly translated as zero by FS */
|
||||
{ const char lastZeroByte[1] = { 0 };
|
||||
if (fwrite(lastZeroByte, 1, 1, file) != 1)
|
||||
EXM_THROW(69, "Write error : cannot write last zero : %s", strerror(errno));
|
||||
} }
|
||||
}
|
||||
|
||||
|
||||
/* **********************************************************************
|
||||
* AsyncIO functionality
|
||||
************************************************************************/
|
||||
|
||||
/* AIO_supported:
|
||||
* Returns 1 if AsyncIO is supported on the system, 0 otherwise. */
|
||||
int AIO_supported(void) {
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ***********************************
|
||||
* Generic IoPool implementation
|
||||
*************************************/
|
||||
|
||||
static IOJob_t *AIO_IOPool_createIoJob(IOPoolCtx_t *ctx, size_t bufferSize) {
|
||||
IOJob_t* const job = (IOJob_t*) malloc(sizeof(IOJob_t));
|
||||
void* const buffer = malloc(bufferSize);
|
||||
if(!job || !buffer)
|
||||
EXM_THROW(101, "Allocation error : not enough memory");
|
||||
job->buffer = buffer;
|
||||
job->bufferSize = bufferSize;
|
||||
job->usedBufferSize = 0;
|
||||
job->file = NULL;
|
||||
job->ctx = ctx;
|
||||
job->offset = 0;
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
/* AIO_IOPool_createThreadPool:
|
||||
* Creates a thread pool and a mutex for threaded IO pool.
|
||||
* Displays warning if asyncio is requested but MT isn't available. */
|
||||
static void AIO_IOPool_createThreadPool(IOPoolCtx_t* ctx, const FIO_prefs_t* prefs) {
|
||||
ctx->threadPool = NULL;
|
||||
ctx->threadPoolActive = 0;
|
||||
if(prefs->asyncIO) {
|
||||
if (ZSTD_pthread_mutex_init(&ctx->ioJobsMutex, NULL))
|
||||
EXM_THROW(102,"Failed creating ioJobsMutex mutex");
|
||||
/* We want MAX_IO_JOBS-2 queue items because we need to always have 1 free buffer to
|
||||
* decompress into and 1 buffer that's actively written to disk and owned by the writing thread. */
|
||||
assert(MAX_IO_JOBS >= 2);
|
||||
ctx->threadPool = POOL_create(1, MAX_IO_JOBS - 2);
|
||||
ctx->threadPoolActive = 1;
|
||||
if (!ctx->threadPool)
|
||||
EXM_THROW(104, "Failed creating I/O thread pool");
|
||||
}
|
||||
}
|
||||
|
||||
/* AIO_IOPool_init:
|
||||
* Allocates and sets and a new I/O thread pool including its included availableJobs. */
|
||||
static void AIO_IOPool_init(IOPoolCtx_t* ctx, const FIO_prefs_t* prefs, POOL_function poolFunction, size_t bufferSize) {
|
||||
int i;
|
||||
AIO_IOPool_createThreadPool(ctx, prefs);
|
||||
ctx->prefs = prefs;
|
||||
ctx->poolFunction = poolFunction;
|
||||
ctx->totalIoJobs = ctx->threadPool ? MAX_IO_JOBS : 2;
|
||||
ctx->availableJobsCount = ctx->totalIoJobs;
|
||||
for(i=0; i < ctx->availableJobsCount; i++) {
|
||||
ctx->availableJobs[i] = AIO_IOPool_createIoJob(ctx, bufferSize);
|
||||
}
|
||||
ctx->jobBufferSize = bufferSize;
|
||||
ctx->file = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* AIO_IOPool_threadPoolActive:
|
||||
* Check if current operation uses thread pool.
|
||||
* Note that in some cases we have a thread pool initialized but choose not to use it. */
|
||||
static int AIO_IOPool_threadPoolActive(IOPoolCtx_t* ctx) {
|
||||
return ctx->threadPool && ctx->threadPoolActive;
|
||||
}
|
||||
|
||||
|
||||
/* AIO_IOPool_lockJobsMutex:
|
||||
* Locks the IO jobs mutex if threading is active */
|
||||
static void AIO_IOPool_lockJobsMutex(IOPoolCtx_t* ctx) {
|
||||
if(AIO_IOPool_threadPoolActive(ctx))
|
||||
ZSTD_pthread_mutex_lock(&ctx->ioJobsMutex);
|
||||
}
|
||||
|
||||
/* AIO_IOPool_unlockJobsMutex:
|
||||
* Unlocks the IO jobs mutex if threading is active */
|
||||
static void AIO_IOPool_unlockJobsMutex(IOPoolCtx_t* ctx) {
|
||||
if(AIO_IOPool_threadPoolActive(ctx))
|
||||
ZSTD_pthread_mutex_unlock(&ctx->ioJobsMutex);
|
||||
}
|
||||
|
||||
/* AIO_IOPool_releaseIoJob:
|
||||
* Releases an acquired job back to the pool. Doesn't execute the job. */
|
||||
static void AIO_IOPool_releaseIoJob(IOJob_t* job) {
|
||||
IOPoolCtx_t* const ctx = (IOPoolCtx_t *) job->ctx;
|
||||
AIO_IOPool_lockJobsMutex(ctx);
|
||||
assert(ctx->availableJobsCount < ctx->totalIoJobs);
|
||||
ctx->availableJobs[ctx->availableJobsCount++] = job;
|
||||
AIO_IOPool_unlockJobsMutex(ctx);
|
||||
}
|
||||
|
||||
/* AIO_IOPool_join:
|
||||
* Waits for all tasks in the pool to finish executing. */
|
||||
static void AIO_IOPool_join(IOPoolCtx_t* ctx) {
|
||||
if(AIO_IOPool_threadPoolActive(ctx))
|
||||
POOL_joinJobs(ctx->threadPool);
|
||||
}
|
||||
|
||||
/* AIO_IOPool_setThreaded:
|
||||
* Allows (de)activating threaded mode, to be used when the expected overhead
|
||||
* of threading costs more than the expected gains. */
|
||||
static void AIO_IOPool_setThreaded(IOPoolCtx_t* ctx, int threaded) {
|
||||
assert(threaded == 0 || threaded == 1);
|
||||
assert(ctx != NULL);
|
||||
if(ctx->threadPoolActive != threaded) {
|
||||
AIO_IOPool_join(ctx);
|
||||
ctx->threadPoolActive = threaded;
|
||||
}
|
||||
}
|
||||
|
||||
/* AIO_IOPool_free:
|
||||
* Release a previously allocated IO thread pool. Makes sure all tasks are done and released. */
|
||||
static void AIO_IOPool_destroy(IOPoolCtx_t* ctx) {
|
||||
int i;
|
||||
if(ctx->threadPool) {
|
||||
/* Make sure we finish all tasks and then free the resources */
|
||||
AIO_IOPool_join(ctx);
|
||||
/* Make sure we are not leaking availableJobs */
|
||||
assert(ctx->availableJobsCount == ctx->totalIoJobs);
|
||||
POOL_free(ctx->threadPool);
|
||||
ZSTD_pthread_mutex_destroy(&ctx->ioJobsMutex);
|
||||
}
|
||||
assert(ctx->file == NULL);
|
||||
for(i=0; i<ctx->availableJobsCount; i++) {
|
||||
IOJob_t* job = (IOJob_t*) ctx->availableJobs[i];
|
||||
free(job->buffer);
|
||||
free(job);
|
||||
}
|
||||
}
|
||||
|
||||
/* AIO_IOPool_acquireJob:
|
||||
* Returns an available io job to be used for a future io. */
|
||||
static IOJob_t* AIO_IOPool_acquireJob(IOPoolCtx_t* ctx) {
|
||||
IOJob_t* job;
|
||||
assert(ctx->file != NULL || ctx->prefs->testMode);
|
||||
AIO_IOPool_lockJobsMutex(ctx);
|
||||
assert(ctx->availableJobsCount > 0);
|
||||
job = (IOJob_t*) ctx->availableJobs[--ctx->availableJobsCount];
|
||||
AIO_IOPool_unlockJobsMutex(ctx);
|
||||
job->usedBufferSize = 0;
|
||||
job->file = ctx->file;
|
||||
job->offset = 0;
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
/* AIO_IOPool_setFile:
|
||||
* Sets the destination file for future files in the pool.
|
||||
* Requires completion of all queued jobs and release of all otherwise acquired jobs. */
|
||||
static void AIO_IOPool_setFile(IOPoolCtx_t* ctx, FILE* file) {
|
||||
assert(ctx!=NULL);
|
||||
AIO_IOPool_join(ctx);
|
||||
assert(ctx->availableJobsCount == ctx->totalIoJobs);
|
||||
ctx->file = file;
|
||||
}
|
||||
|
||||
static FILE* AIO_IOPool_getFile(const IOPoolCtx_t* ctx) {
|
||||
return ctx->file;
|
||||
}
|
||||
|
||||
/* AIO_IOPool_enqueueJob:
|
||||
* Enqueues an io job for execution.
|
||||
* The queued job shouldn't be used directly after queueing it. */
|
||||
static void AIO_IOPool_enqueueJob(IOJob_t* job) {
|
||||
IOPoolCtx_t* const ctx = (IOPoolCtx_t *)job->ctx;
|
||||
if(AIO_IOPool_threadPoolActive(ctx))
|
||||
POOL_add(ctx->threadPool, ctx->poolFunction, job);
|
||||
else
|
||||
ctx->poolFunction(job);
|
||||
}
|
||||
|
||||
/* ***********************************
|
||||
* WritePool implementation
|
||||
*************************************/
|
||||
|
||||
/* AIO_WritePool_acquireJob:
|
||||
* Returns an available write job to be used for a future write. */
|
||||
IOJob_t* AIO_WritePool_acquireJob(WritePoolCtx_t* ctx) {
|
||||
return AIO_IOPool_acquireJob(&ctx->base);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_enqueueAndReacquireWriteJob:
|
||||
* Queues a write job for execution and acquires a new one.
|
||||
* After execution `job`'s pointed value would change to the newly acquired job.
|
||||
* Make sure to set `usedBufferSize` to the wanted length before call.
|
||||
* The queued job shouldn't be used directly after queueing it. */
|
||||
void AIO_WritePool_enqueueAndReacquireWriteJob(IOJob_t **job) {
|
||||
AIO_IOPool_enqueueJob(*job);
|
||||
*job = AIO_IOPool_acquireJob((IOPoolCtx_t *)(*job)->ctx);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_sparseWriteEnd:
|
||||
* Ends sparse writes to the current file.
|
||||
* Blocks on completion of all current write jobs before executing. */
|
||||
void AIO_WritePool_sparseWriteEnd(WritePoolCtx_t* ctx) {
|
||||
assert(ctx != NULL);
|
||||
AIO_IOPool_join(&ctx->base);
|
||||
AIO_fwriteSparseEnd(ctx->base.prefs, ctx->base.file, ctx->storedSkips);
|
||||
ctx->storedSkips = 0;
|
||||
}
|
||||
|
||||
/* AIO_WritePool_setFile:
|
||||
* Sets the destination file for future writes in the pool.
|
||||
* Requires completion of all queues write jobs and release of all otherwise acquired jobs.
|
||||
* Also requires ending of sparse write if a previous file was used in sparse mode. */
|
||||
void AIO_WritePool_setFile(WritePoolCtx_t* ctx, FILE* file) {
|
||||
AIO_IOPool_setFile(&ctx->base, file);
|
||||
assert(ctx->storedSkips == 0);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_getFile:
|
||||
* Returns the file the writePool is currently set to write to. */
|
||||
FILE* AIO_WritePool_getFile(const WritePoolCtx_t* ctx) {
|
||||
return AIO_IOPool_getFile(&ctx->base);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_releaseIoJob:
|
||||
* Releases an acquired job back to the pool. Doesn't execute the job. */
|
||||
void AIO_WritePool_releaseIoJob(IOJob_t* job) {
|
||||
AIO_IOPool_releaseIoJob(job);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_closeFile:
|
||||
* Ends sparse write and closes the writePool's current file and sets the file to NULL.
|
||||
* Requires completion of all queues write jobs and release of all otherwise acquired jobs. */
|
||||
int AIO_WritePool_closeFile(WritePoolCtx_t* ctx) {
|
||||
FILE* const dstFile = ctx->base.file;
|
||||
assert(dstFile!=NULL || ctx->base.prefs->testMode!=0);
|
||||
AIO_WritePool_sparseWriteEnd(ctx);
|
||||
AIO_IOPool_setFile(&ctx->base, NULL);
|
||||
return fclose(dstFile);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_executeWriteJob:
|
||||
* Executes a write job synchronously. Can be used as a function for a thread pool. */
|
||||
static void AIO_WritePool_executeWriteJob(void* opaque){
|
||||
IOJob_t* const job = (IOJob_t*) opaque;
|
||||
WritePoolCtx_t* const ctx = (WritePoolCtx_t*) job->ctx;
|
||||
ctx->storedSkips = AIO_fwriteSparse(job->file, job->buffer, job->usedBufferSize, ctx->base.prefs, ctx->storedSkips);
|
||||
AIO_IOPool_releaseIoJob(job);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_create:
|
||||
* Allocates and sets and a new write pool including its included jobs. */
|
||||
WritePoolCtx_t* AIO_WritePool_create(const FIO_prefs_t* prefs, size_t bufferSize) {
|
||||
WritePoolCtx_t* const ctx = (WritePoolCtx_t*) malloc(sizeof(WritePoolCtx_t));
|
||||
if(!ctx) EXM_THROW(100, "Allocation error : not enough memory");
|
||||
AIO_IOPool_init(&ctx->base, prefs, AIO_WritePool_executeWriteJob, bufferSize);
|
||||
ctx->storedSkips = 0;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/* AIO_WritePool_free:
|
||||
* Frees and releases a writePool and its resources. Closes destination file if needs to. */
|
||||
void AIO_WritePool_free(WritePoolCtx_t* ctx) {
|
||||
/* Make sure we finish all tasks and then free the resources */
|
||||
if(AIO_WritePool_getFile(ctx))
|
||||
AIO_WritePool_closeFile(ctx);
|
||||
AIO_IOPool_destroy(&ctx->base);
|
||||
assert(ctx->storedSkips==0);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/* AIO_WritePool_setAsync:
|
||||
* Allows (de)activating async mode, to be used when the expected overhead
|
||||
* of asyncio costs more than the expected gains. */
|
||||
void AIO_WritePool_setAsync(WritePoolCtx_t* ctx, int async) {
|
||||
AIO_IOPool_setThreaded(&ctx->base, async);
|
||||
}
|
||||
|
||||
|
||||
/* ***********************************
|
||||
* ReadPool implementation
|
||||
*************************************/
|
||||
static void AIO_ReadPool_releaseAllCompletedJobs(ReadPoolCtx_t* ctx) {
|
||||
int i;
|
||||
for(i=0; i<ctx->completedJobsCount; i++) {
|
||||
IOJob_t* job = (IOJob_t*) ctx->completedJobs[i];
|
||||
AIO_IOPool_releaseIoJob(job);
|
||||
}
|
||||
ctx->completedJobsCount = 0;
|
||||
}
|
||||
|
||||
static void AIO_ReadPool_addJobToCompleted(IOJob_t* job) {
|
||||
ReadPoolCtx_t* const ctx = (ReadPoolCtx_t *)job->ctx;
|
||||
AIO_IOPool_lockJobsMutex(&ctx->base);
|
||||
assert(ctx->completedJobsCount < MAX_IO_JOBS);
|
||||
ctx->completedJobs[ctx->completedJobsCount++] = job;
|
||||
if(AIO_IOPool_threadPoolActive(&ctx->base)) {
|
||||
ZSTD_pthread_cond_signal(&ctx->jobCompletedCond);
|
||||
}
|
||||
AIO_IOPool_unlockJobsMutex(&ctx->base);
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_findNextWaitingOffsetCompletedJob_locked:
|
||||
* Looks through the completed jobs for a job matching the waitingOnOffset and returns it,
|
||||
* if job wasn't found returns NULL.
|
||||
* IMPORTANT: assumes ioJobsMutex is locked. */
|
||||
static IOJob_t* AIO_ReadPool_findNextWaitingOffsetCompletedJob_locked(ReadPoolCtx_t* ctx) {
|
||||
IOJob_t *job = NULL;
|
||||
int i;
|
||||
/* This implementation goes through all completed jobs and looks for the one matching the next offset.
|
||||
* While not strictly needed for a single threaded reader implementation (as in such a case we could expect
|
||||
* reads to be completed in order) this implementation was chosen as it better fits other asyncio
|
||||
* interfaces (such as io_uring) that do not provide promises regarding order of completion. */
|
||||
for (i=0; i<ctx->completedJobsCount; i++) {
|
||||
job = (IOJob_t *) ctx->completedJobs[i];
|
||||
if (job->offset == ctx->waitingOnOffset) {
|
||||
ctx->completedJobs[i] = ctx->completedJobs[--ctx->completedJobsCount];
|
||||
return job;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_numReadsInFlight:
|
||||
* Returns the number of IO read jobs currently in flight. */
|
||||
static size_t AIO_ReadPool_numReadsInFlight(ReadPoolCtx_t* ctx) {
|
||||
const int jobsHeld = (ctx->currentJobHeld==NULL ? 0 : 1);
|
||||
return (size_t)(ctx->base.totalIoJobs - (ctx->base.availableJobsCount + ctx->completedJobsCount + jobsHeld));
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_getNextCompletedJob:
|
||||
* Returns a completed IOJob_t for the next read in line based on waitingOnOffset and advances waitingOnOffset.
|
||||
* Would block. */
|
||||
static IOJob_t* AIO_ReadPool_getNextCompletedJob(ReadPoolCtx_t* ctx) {
|
||||
IOJob_t *job = NULL;
|
||||
AIO_IOPool_lockJobsMutex(&ctx->base);
|
||||
|
||||
job = AIO_ReadPool_findNextWaitingOffsetCompletedJob_locked(ctx);
|
||||
|
||||
/* As long as we didn't find the job matching the next read, and we have some reads in flight continue waiting */
|
||||
while (!job && (AIO_ReadPool_numReadsInFlight(ctx) > 0)) {
|
||||
assert(ctx->base.threadPool != NULL); /* we shouldn't be here if we work in sync mode */
|
||||
ZSTD_pthread_cond_wait(&ctx->jobCompletedCond, &ctx->base.ioJobsMutex);
|
||||
job = AIO_ReadPool_findNextWaitingOffsetCompletedJob_locked(ctx);
|
||||
}
|
||||
|
||||
if(job) {
|
||||
assert(job->offset == ctx->waitingOnOffset);
|
||||
ctx->waitingOnOffset += job->usedBufferSize;
|
||||
}
|
||||
|
||||
AIO_IOPool_unlockJobsMutex(&ctx->base);
|
||||
return job;
|
||||
}
|
||||
|
||||
|
||||
/* AIO_ReadPool_executeReadJob:
|
||||
* Executes a read job synchronously. Can be used as a function for a thread pool. */
|
||||
static void AIO_ReadPool_executeReadJob(void* opaque){
|
||||
IOJob_t* const job = (IOJob_t*) opaque;
|
||||
ReadPoolCtx_t* const ctx = (ReadPoolCtx_t *)job->ctx;
|
||||
if(ctx->reachedEof) {
|
||||
job->usedBufferSize = 0;
|
||||
AIO_ReadPool_addJobToCompleted(job);
|
||||
return;
|
||||
}
|
||||
job->usedBufferSize = fread(job->buffer, 1, job->bufferSize, job->file);
|
||||
if(job->usedBufferSize < job->bufferSize) {
|
||||
if(ferror(job->file)) {
|
||||
EXM_THROW(37, "Read error");
|
||||
} else if(feof(job->file)) {
|
||||
ctx->reachedEof = 1;
|
||||
} else {
|
||||
EXM_THROW(37, "Unexpected short read");
|
||||
}
|
||||
}
|
||||
AIO_ReadPool_addJobToCompleted(job);
|
||||
}
|
||||
|
||||
static void AIO_ReadPool_enqueueRead(ReadPoolCtx_t* ctx) {
|
||||
IOJob_t* const job = AIO_IOPool_acquireJob(&ctx->base);
|
||||
job->offset = ctx->nextReadOffset;
|
||||
ctx->nextReadOffset += job->bufferSize;
|
||||
AIO_IOPool_enqueueJob(job);
|
||||
}
|
||||
|
||||
static void AIO_ReadPool_startReading(ReadPoolCtx_t* ctx) {
|
||||
while(ctx->base.availableJobsCount) {
|
||||
AIO_ReadPool_enqueueRead(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_setFile:
|
||||
* Sets the source file for future read in the pool. Initiates reading immediately if file is not NULL.
|
||||
* Waits for all current enqueued tasks to complete if a previous file was set. */
|
||||
void AIO_ReadPool_setFile(ReadPoolCtx_t* ctx, FILE* file) {
|
||||
assert(ctx!=NULL);
|
||||
AIO_IOPool_join(&ctx->base);
|
||||
AIO_ReadPool_releaseAllCompletedJobs(ctx);
|
||||
if (ctx->currentJobHeld) {
|
||||
AIO_IOPool_releaseIoJob((IOJob_t *)ctx->currentJobHeld);
|
||||
ctx->currentJobHeld = NULL;
|
||||
}
|
||||
AIO_IOPool_setFile(&ctx->base, file);
|
||||
ctx->nextReadOffset = 0;
|
||||
ctx->waitingOnOffset = 0;
|
||||
ctx->srcBuffer = ctx->coalesceBuffer;
|
||||
ctx->srcBufferLoaded = 0;
|
||||
ctx->reachedEof = 0;
|
||||
if(file != NULL)
|
||||
AIO_ReadPool_startReading(ctx);
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_create:
|
||||
* Allocates and sets and a new readPool including its included jobs.
|
||||
* bufferSize should be set to the maximal buffer we want to read at a time, will also be used
|
||||
* as our basic read size. */
|
||||
ReadPoolCtx_t* AIO_ReadPool_create(const FIO_prefs_t* prefs, size_t bufferSize) {
|
||||
ReadPoolCtx_t* const ctx = (ReadPoolCtx_t*) malloc(sizeof(ReadPoolCtx_t));
|
||||
if(!ctx) EXM_THROW(100, "Allocation error : not enough memory");
|
||||
AIO_IOPool_init(&ctx->base, prefs, AIO_ReadPool_executeReadJob, bufferSize);
|
||||
|
||||
ctx->coalesceBuffer = (U8*) malloc(bufferSize * 2);
|
||||
if(!ctx->coalesceBuffer) EXM_THROW(100, "Allocation error : not enough memory");
|
||||
ctx->srcBuffer = ctx->coalesceBuffer;
|
||||
ctx->srcBufferLoaded = 0;
|
||||
ctx->completedJobsCount = 0;
|
||||
ctx->currentJobHeld = NULL;
|
||||
|
||||
if(ctx->base.threadPool)
|
||||
if (ZSTD_pthread_cond_init(&ctx->jobCompletedCond, NULL))
|
||||
EXM_THROW(103,"Failed creating jobCompletedCond cond");
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_free:
|
||||
* Frees and releases a readPool and its resources. Closes source file. */
|
||||
void AIO_ReadPool_free(ReadPoolCtx_t* ctx) {
|
||||
if(AIO_ReadPool_getFile(ctx))
|
||||
AIO_ReadPool_closeFile(ctx);
|
||||
if(ctx->base.threadPool)
|
||||
ZSTD_pthread_cond_destroy(&ctx->jobCompletedCond);
|
||||
AIO_IOPool_destroy(&ctx->base);
|
||||
free(ctx->coalesceBuffer);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_consumeBytes:
|
||||
* Consumes byes from srcBuffer's beginning and updates srcBufferLoaded accordingly. */
|
||||
void AIO_ReadPool_consumeBytes(ReadPoolCtx_t* ctx, size_t n) {
|
||||
assert(n <= ctx->srcBufferLoaded);
|
||||
ctx->srcBufferLoaded -= n;
|
||||
ctx->srcBuffer += n;
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_releaseCurrentlyHeldAndGetNext:
|
||||
* Release the current held job and get the next one, returns NULL if no next job available. */
|
||||
static IOJob_t* AIO_ReadPool_releaseCurrentHeldAndGetNext(ReadPoolCtx_t* ctx) {
|
||||
if (ctx->currentJobHeld) {
|
||||
AIO_IOPool_releaseIoJob((IOJob_t *)ctx->currentJobHeld);
|
||||
ctx->currentJobHeld = NULL;
|
||||
AIO_ReadPool_enqueueRead(ctx);
|
||||
}
|
||||
ctx->currentJobHeld = AIO_ReadPool_getNextCompletedJob(ctx);
|
||||
return (IOJob_t*) ctx->currentJobHeld;
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_fillBuffer:
|
||||
* Tries to fill the buffer with at least n or jobBufferSize bytes (whichever is smaller).
|
||||
* Returns if srcBuffer has at least the expected number of bytes loaded or if we've reached the end of the file.
|
||||
* Return value is the number of bytes added to the buffer.
|
||||
* Note that srcBuffer might have up to 2 times jobBufferSize bytes. */
|
||||
size_t AIO_ReadPool_fillBuffer(ReadPoolCtx_t* ctx, size_t n) {
|
||||
IOJob_t *job;
|
||||
int useCoalesce = 0;
|
||||
if(n > ctx->base.jobBufferSize)
|
||||
n = ctx->base.jobBufferSize;
|
||||
|
||||
/* We are good, don't read anything */
|
||||
if (ctx->srcBufferLoaded >= n)
|
||||
return 0;
|
||||
|
||||
/* We still have bytes loaded, but not enough to satisfy caller. We need to get the next job
|
||||
* and coalesce the remaining bytes with the next job's buffer */
|
||||
if (ctx->srcBufferLoaded > 0) {
|
||||
useCoalesce = 1;
|
||||
memcpy(ctx->coalesceBuffer, ctx->srcBuffer, ctx->srcBufferLoaded);
|
||||
ctx->srcBuffer = ctx->coalesceBuffer;
|
||||
}
|
||||
|
||||
/* Read the next chunk */
|
||||
job = AIO_ReadPool_releaseCurrentHeldAndGetNext(ctx);
|
||||
if(!job)
|
||||
return 0;
|
||||
if(useCoalesce) {
|
||||
assert(ctx->srcBufferLoaded + job->usedBufferSize <= 2*ctx->base.jobBufferSize);
|
||||
memcpy(ctx->coalesceBuffer + ctx->srcBufferLoaded, job->buffer, job->usedBufferSize);
|
||||
ctx->srcBufferLoaded += job->usedBufferSize;
|
||||
}
|
||||
else {
|
||||
ctx->srcBuffer = (U8 *) job->buffer;
|
||||
ctx->srcBufferLoaded = job->usedBufferSize;
|
||||
}
|
||||
return job->usedBufferSize;
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_consumeAndRefill:
|
||||
* Consumes the current buffer and refills it with bufferSize bytes. */
|
||||
size_t AIO_ReadPool_consumeAndRefill(ReadPoolCtx_t* ctx) {
|
||||
AIO_ReadPool_consumeBytes(ctx, ctx->srcBufferLoaded);
|
||||
return AIO_ReadPool_fillBuffer(ctx, ctx->base.jobBufferSize);
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_getFile:
|
||||
* Returns the current file set for the read pool. */
|
||||
FILE* AIO_ReadPool_getFile(const ReadPoolCtx_t* ctx) {
|
||||
return AIO_IOPool_getFile(&ctx->base);
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_closeFile:
|
||||
* Closes the current set file. Waits for all current enqueued tasks to complete and resets state. */
|
||||
int AIO_ReadPool_closeFile(ReadPoolCtx_t* ctx) {
|
||||
FILE* const file = AIO_ReadPool_getFile(ctx);
|
||||
AIO_ReadPool_setFile(ctx, NULL);
|
||||
return fclose(file);
|
||||
}
|
||||
|
||||
/* AIO_ReadPool_setAsync:
|
||||
* Allows (de)activating async mode, to be used when the expected overhead
|
||||
* of asyncio costs more than the expected gains. */
|
||||
void AIO_ReadPool_setAsync(ReadPoolCtx_t* ctx, int async) {
|
||||
AIO_IOPool_setThreaded(&ctx->base, async);
|
||||
}
|
195
build_amd64/_deps/zstd-src/programs/fileio_asyncio.h
Normal file
195
build_amd64/_deps/zstd-src/programs/fileio_asyncio.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/*
|
||||
* FileIO AsyncIO exposes read/write IO pools that allow doing IO asynchronously.
|
||||
* Current implementation relies on having one thread that reads and one that
|
||||
* writes.
|
||||
* Each IO pool supports up to `MAX_IO_JOBS` that can be enqueued for work, but
|
||||
* are performed serially by the appropriate worker thread.
|
||||
* Most systems exposes better primitives to perform asynchronous IO, such as
|
||||
* io_uring on newer linux systems. The API is built in such a way that in the
|
||||
* future we could replace the threads with better solutions when available.
|
||||
*/
|
||||
|
||||
#ifndef ZSTD_FILEIO_ASYNCIO_H
|
||||
#define ZSTD_FILEIO_ASYNCIO_H
|
||||
|
||||
#include "../lib/common/mem.h" /* U32, U64 */
|
||||
#include "fileio_types.h"
|
||||
#include "platform.h"
|
||||
#include "util.h"
|
||||
#include "../lib/common/pool.h"
|
||||
#include "../lib/common/threading.h"
|
||||
|
||||
#define MAX_IO_JOBS (10)
|
||||
|
||||
typedef struct {
|
||||
/* These struct fields should be set only on creation and not changed afterwards */
|
||||
POOL_ctx* threadPool;
|
||||
int threadPoolActive;
|
||||
int totalIoJobs;
|
||||
const FIO_prefs_t* prefs;
|
||||
POOL_function poolFunction;
|
||||
|
||||
/* Controls the file we currently write to, make changes only by using provided utility functions */
|
||||
FILE* file;
|
||||
|
||||
/* The jobs and availableJobsCount fields are accessed by both the main and worker threads and should
|
||||
* only be mutated after locking the mutex */
|
||||
ZSTD_pthread_mutex_t ioJobsMutex;
|
||||
void* availableJobs[MAX_IO_JOBS];
|
||||
int availableJobsCount;
|
||||
size_t jobBufferSize;
|
||||
} IOPoolCtx_t;
|
||||
|
||||
typedef struct {
|
||||
IOPoolCtx_t base;
|
||||
|
||||
/* State regarding the currently read file */
|
||||
int reachedEof;
|
||||
U64 nextReadOffset;
|
||||
U64 waitingOnOffset;
|
||||
|
||||
/* We may hold an IOJob object as needed if we actively expose its buffer. */
|
||||
void *currentJobHeld;
|
||||
|
||||
/* Coalesce buffer is used to join two buffers in case where we need to read more bytes than left in
|
||||
* the first of them. Shouldn't be accessed from outside ot utility functions. */
|
||||
U8 *coalesceBuffer;
|
||||
|
||||
/* Read buffer can be used by consumer code, take care when copying this pointer aside as it might
|
||||
* change when consuming / refilling buffer. */
|
||||
U8 *srcBuffer;
|
||||
size_t srcBufferLoaded;
|
||||
|
||||
/* We need to know what tasks completed so we can use their buffers when their time comes.
|
||||
* Should only be accessed after locking base.ioJobsMutex . */
|
||||
void* completedJobs[MAX_IO_JOBS];
|
||||
int completedJobsCount;
|
||||
ZSTD_pthread_cond_t jobCompletedCond;
|
||||
} ReadPoolCtx_t;
|
||||
|
||||
typedef struct {
|
||||
IOPoolCtx_t base;
|
||||
unsigned storedSkips;
|
||||
} WritePoolCtx_t;
|
||||
|
||||
typedef struct {
|
||||
/* These fields are automatically set and shouldn't be changed by non WritePool code. */
|
||||
void *ctx;
|
||||
FILE* file;
|
||||
void *buffer;
|
||||
size_t bufferSize;
|
||||
|
||||
/* This field should be changed before a job is queued for execution and should contain the number
|
||||
* of bytes to write from the buffer. */
|
||||
size_t usedBufferSize;
|
||||
U64 offset;
|
||||
} IOJob_t;
|
||||
|
||||
/* AIO_supported:
|
||||
* Returns 1 if AsyncIO is supported on the system, 0 otherwise. */
|
||||
int AIO_supported(void);
|
||||
|
||||
|
||||
/* AIO_WritePool_releaseIoJob:
|
||||
* Releases an acquired job back to the pool. Doesn't execute the job. */
|
||||
void AIO_WritePool_releaseIoJob(IOJob_t *job);
|
||||
|
||||
/* AIO_WritePool_acquireJob:
|
||||
* Returns an available write job to be used for a future write. */
|
||||
IOJob_t* AIO_WritePool_acquireJob(WritePoolCtx_t *ctx);
|
||||
|
||||
/* AIO_WritePool_enqueueAndReacquireWriteJob:
|
||||
* Enqueues a write job for execution and acquires a new one.
|
||||
* After execution `job`'s pointed value would change to the newly acquired job.
|
||||
* Make sure to set `usedBufferSize` to the wanted length before call.
|
||||
* The queued job shouldn't be used directly after queueing it. */
|
||||
void AIO_WritePool_enqueueAndReacquireWriteJob(IOJob_t **job);
|
||||
|
||||
/* AIO_WritePool_sparseWriteEnd:
|
||||
* Ends sparse writes to the current file.
|
||||
* Blocks on completion of all current write jobs before executing. */
|
||||
void AIO_WritePool_sparseWriteEnd(WritePoolCtx_t *ctx);
|
||||
|
||||
/* AIO_WritePool_setFile:
|
||||
* Sets the destination file for future writes in the pool.
|
||||
* Requires completion of all queues write jobs and release of all otherwise acquired jobs.
|
||||
* Also requires ending of sparse write if a previous file was used in sparse mode. */
|
||||
void AIO_WritePool_setFile(WritePoolCtx_t *ctx, FILE* file);
|
||||
|
||||
/* AIO_WritePool_getFile:
|
||||
* Returns the file the writePool is currently set to write to. */
|
||||
FILE* AIO_WritePool_getFile(const WritePoolCtx_t* ctx);
|
||||
|
||||
/* AIO_WritePool_closeFile:
|
||||
* Ends sparse write and closes the writePool's current file and sets the file to NULL.
|
||||
* Requires completion of all queues write jobs and release of all otherwise acquired jobs. */
|
||||
int AIO_WritePool_closeFile(WritePoolCtx_t *ctx);
|
||||
|
||||
/* AIO_WritePool_create:
|
||||
* Allocates and sets and a new write pool including its included jobs.
|
||||
* bufferSize should be set to the maximal buffer we want to write to at a time. */
|
||||
WritePoolCtx_t* AIO_WritePool_create(const FIO_prefs_t* prefs, size_t bufferSize);
|
||||
|
||||
/* AIO_WritePool_free:
|
||||
* Frees and releases a writePool and its resources. Closes destination file. */
|
||||
void AIO_WritePool_free(WritePoolCtx_t* ctx);
|
||||
|
||||
/* AIO_WritePool_setAsync:
|
||||
* Allows (de)activating async mode, to be used when the expected overhead
|
||||
* of asyncio costs more than the expected gains. */
|
||||
void AIO_WritePool_setAsync(WritePoolCtx_t* ctx, int async);
|
||||
|
||||
/* AIO_ReadPool_create:
|
||||
* Allocates and sets and a new readPool including its included jobs.
|
||||
* bufferSize should be set to the maximal buffer we want to read at a time, will also be used
|
||||
* as our basic read size. */
|
||||
ReadPoolCtx_t* AIO_ReadPool_create(const FIO_prefs_t* prefs, size_t bufferSize);
|
||||
|
||||
/* AIO_ReadPool_free:
|
||||
* Frees and releases a readPool and its resources. Closes source file. */
|
||||
void AIO_ReadPool_free(ReadPoolCtx_t* ctx);
|
||||
|
||||
/* AIO_ReadPool_setAsync:
|
||||
* Allows (de)activating async mode, to be used when the expected overhead
|
||||
* of asyncio costs more than the expected gains. */
|
||||
void AIO_ReadPool_setAsync(ReadPoolCtx_t* ctx, int async);
|
||||
|
||||
/* AIO_ReadPool_consumeBytes:
|
||||
* Consumes byes from srcBuffer's beginning and updates srcBufferLoaded accordingly. */
|
||||
void AIO_ReadPool_consumeBytes(ReadPoolCtx_t *ctx, size_t n);
|
||||
|
||||
/* AIO_ReadPool_fillBuffer:
|
||||
* Makes sure buffer has at least n bytes loaded (as long as n is not bigger than the initialized bufferSize).
|
||||
* Returns if srcBuffer has at least n bytes loaded or if we've reached the end of the file.
|
||||
* Return value is the number of bytes added to the buffer.
|
||||
* Note that srcBuffer might have up to 2 times bufferSize bytes. */
|
||||
size_t AIO_ReadPool_fillBuffer(ReadPoolCtx_t *ctx, size_t n);
|
||||
|
||||
/* AIO_ReadPool_consumeAndRefill:
|
||||
* Consumes the current buffer and refills it with bufferSize bytes. */
|
||||
size_t AIO_ReadPool_consumeAndRefill(ReadPoolCtx_t *ctx);
|
||||
|
||||
/* AIO_ReadPool_setFile:
|
||||
* Sets the source file for future read in the pool. Initiates reading immediately if file is not NULL.
|
||||
* Waits for all current enqueued tasks to complete if a previous file was set. */
|
||||
void AIO_ReadPool_setFile(ReadPoolCtx_t *ctx, FILE* file);
|
||||
|
||||
/* AIO_ReadPool_getFile:
|
||||
* Returns the current file set for the read pool. */
|
||||
FILE* AIO_ReadPool_getFile(const ReadPoolCtx_t *ctx);
|
||||
|
||||
/* AIO_ReadPool_closeFile:
|
||||
* Closes the current set file. Waits for all current enqueued tasks to complete and resets state. */
|
||||
int AIO_ReadPool_closeFile(ReadPoolCtx_t *ctx);
|
||||
|
||||
#endif /* ZSTD_FILEIO_ASYNCIO_H */
|
121
build_amd64/_deps/zstd-src/programs/fileio_common.h
Normal file
121
build_amd64/_deps/zstd-src/programs/fileio_common.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef ZSTD_FILEIO_COMMON_H
|
||||
#define ZSTD_FILEIO_COMMON_H
|
||||
|
||||
#include "../lib/common/mem.h" /* U32, U64 */
|
||||
#include "fileio_types.h"
|
||||
#include "platform.h"
|
||||
#include "timefn.h" /* UTIL_getTime, UTIL_clockSpanMicro */
|
||||
|
||||
/*-*************************************
|
||||
* Macros
|
||||
***************************************/
|
||||
#define KB *(1 <<10)
|
||||
#define MB *(1 <<20)
|
||||
#define GB *(1U<<30)
|
||||
#undef MAX
|
||||
#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||
#undef MIN /* in case it would be already defined */
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
extern FIO_display_prefs_t g_display_prefs;
|
||||
|
||||
#define DISPLAY_F(f, ...) fprintf((f), __VA_ARGS__)
|
||||
#define DISPLAYOUT(...) DISPLAY_F(stdout, __VA_ARGS__)
|
||||
#define DISPLAY(...) DISPLAY_F(stderr, __VA_ARGS__)
|
||||
#define DISPLAYLEVEL(l, ...) { if (g_display_prefs.displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
|
||||
|
||||
extern UTIL_time_t g_displayClock;
|
||||
|
||||
#define REFRESH_RATE ((U64)(SEC_TO_MICRO / 6))
|
||||
#define READY_FOR_UPDATE() (UTIL_clockSpanMicro(g_displayClock) > REFRESH_RATE || g_display_prefs.displayLevel >= 4)
|
||||
#define DELAY_NEXT_UPDATE() { g_displayClock = UTIL_getTime(); }
|
||||
#define DISPLAYUPDATE(l, ...) { \
|
||||
if (g_display_prefs.displayLevel>=l && (g_display_prefs.progressSetting != FIO_ps_never)) { \
|
||||
if (READY_FOR_UPDATE()) { \
|
||||
DELAY_NEXT_UPDATE(); \
|
||||
DISPLAY(__VA_ARGS__); \
|
||||
if (g_display_prefs.displayLevel>=4) fflush(stderr); \
|
||||
} } }
|
||||
|
||||
#define SHOULD_DISPLAY_SUMMARY() \
|
||||
(g_display_prefs.displayLevel >= 2 || g_display_prefs.progressSetting == FIO_ps_always)
|
||||
#define SHOULD_DISPLAY_PROGRESS() \
|
||||
(g_display_prefs.progressSetting != FIO_ps_never && SHOULD_DISPLAY_SUMMARY())
|
||||
#define DISPLAY_PROGRESS(...) { if (SHOULD_DISPLAY_PROGRESS()) { DISPLAYLEVEL(1, __VA_ARGS__); }}
|
||||
#define DISPLAYUPDATE_PROGRESS(...) { if (SHOULD_DISPLAY_PROGRESS()) { DISPLAYUPDATE(1, __VA_ARGS__); }}
|
||||
#define DISPLAY_SUMMARY(...) { if (SHOULD_DISPLAY_SUMMARY()) { DISPLAYLEVEL(1, __VA_ARGS__); } }
|
||||
|
||||
#define EXM_THROW(error, ...) \
|
||||
{ \
|
||||
DISPLAYLEVEL(1, "zstd: "); \
|
||||
DISPLAYLEVEL(5, "Error defined at %s, line %i : \n", __FILE__, __LINE__); \
|
||||
DISPLAYLEVEL(1, "error %i : ", error); \
|
||||
DISPLAYLEVEL(1, __VA_ARGS__); \
|
||||
DISPLAYLEVEL(1, " \n"); \
|
||||
exit(error); \
|
||||
}
|
||||
|
||||
#define CHECK_V(v, f) \
|
||||
v = f; \
|
||||
if (ZSTD_isError(v)) { \
|
||||
DISPLAYLEVEL(5, "%s \n", #f); \
|
||||
EXM_THROW(11, "%s", ZSTD_getErrorName(v)); \
|
||||
}
|
||||
#define CHECK(f) { size_t err; CHECK_V(err, f); }
|
||||
|
||||
|
||||
/* Avoid fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW */
|
||||
#if defined(LIBC_NO_FSEEKO)
|
||||
/* Some older libc implementations don't include these functions (e.g. Bionic < 24) */
|
||||
# define LONG_SEEK fseek
|
||||
# define LONG_TELL ftell
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
# define LONG_SEEK _fseeki64
|
||||
# define LONG_TELL _ftelli64
|
||||
#elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
|
||||
# define LONG_SEEK fseeko
|
||||
# define LONG_TELL ftello
|
||||
#elif defined(__MINGW32__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS) && defined(__MSVCRT__)
|
||||
# define LONG_SEEK fseeko64
|
||||
# define LONG_TELL ftello64
|
||||
#elif defined(_WIN32) && !defined(__DJGPP__)
|
||||
# include <windows.h>
|
||||
static int LONG_SEEK(FILE* file, __int64 offset, int origin) {
|
||||
LARGE_INTEGER off;
|
||||
DWORD method;
|
||||
off.QuadPart = offset;
|
||||
if (origin == SEEK_END)
|
||||
method = FILE_END;
|
||||
else if (origin == SEEK_CUR)
|
||||
method = FILE_CURRENT;
|
||||
else
|
||||
method = FILE_BEGIN;
|
||||
|
||||
if (SetFilePointerEx((HANDLE) _get_osfhandle(_fileno(file)), off, NULL, method))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
static __int64 LONG_TELL(FILE* file) {
|
||||
LARGE_INTEGER off, newOff;
|
||||
off.QuadPart = 0;
|
||||
newOff.QuadPart = 0;
|
||||
SetFilePointerEx((HANDLE) _get_osfhandle(_fileno(file)), off, &newOff, FILE_CURRENT);
|
||||
return newOff.QuadPart;
|
||||
}
|
||||
#else
|
||||
# define LONG_SEEK fseek
|
||||
# define LONG_TELL ftell
|
||||
#endif
|
||||
|
||||
#endif /* ZSTD_FILEIO_COMMON_H */
|
86
build_amd64/_deps/zstd-src/programs/fileio_types.h
Normal file
86
build_amd64/_deps/zstd-src/programs/fileio_types.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef FILEIO_TYPES_HEADER
|
||||
#define FILEIO_TYPES_HEADER
|
||||
|
||||
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
|
||||
#include "../lib/zstd.h" /* ZSTD_* */
|
||||
|
||||
/*-*************************************
|
||||
* Parameters: FIO_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;
|
||||
|
||||
struct FIO_display_prefs_s {
|
||||
int displayLevel; /* 0 : no display; 1: errors; 2: + result + interaction + warnings; 3: + progression; 4: + information */
|
||||
FIO_progressSetting_e progressSetting;
|
||||
};
|
||||
|
||||
|
||||
typedef enum { FIO_zstdCompression, FIO_gzipCompression, FIO_xzCompression, FIO_lzmaCompression, FIO_lz4Compression } FIO_compressionType_t;
|
||||
|
||||
typedef struct FIO_prefs_s {
|
||||
|
||||
/* Algorithm preferences */
|
||||
FIO_compressionType_t compressionType;
|
||||
int sparseFileSupport; /* 0: no sparse allowed; 1: auto (file yes, stdout no); 2: force sparse */
|
||||
int dictIDFlag;
|
||||
int checksumFlag;
|
||||
int blockSize;
|
||||
int overlapLog;
|
||||
int adaptiveMode;
|
||||
int useRowMatchFinder;
|
||||
int rsyncable;
|
||||
int minAdaptLevel;
|
||||
int maxAdaptLevel;
|
||||
int ldmFlag;
|
||||
int ldmHashLog;
|
||||
int ldmMinMatch;
|
||||
int ldmBucketSizeLog;
|
||||
int ldmHashRateLog;
|
||||
size_t streamSrcSize;
|
||||
size_t targetCBlockSize;
|
||||
int srcSizeHint;
|
||||
int testMode;
|
||||
ZSTD_ParamSwitch_e literalCompressionMode;
|
||||
|
||||
/* IO preferences */
|
||||
int removeSrcFile;
|
||||
int overwrite;
|
||||
int asyncIO;
|
||||
|
||||
/* Computation resources preferences */
|
||||
unsigned memLimit;
|
||||
int nbWorkers;
|
||||
|
||||
int excludeCompressedFiles;
|
||||
int patchFromMode;
|
||||
int contentSize;
|
||||
int allowBlockDevices;
|
||||
int passThrough;
|
||||
ZSTD_ParamSwitch_e mmapDict;
|
||||
} FIO_prefs_t;
|
||||
|
||||
typedef enum {FIO_mallocDict, FIO_mmapDict} FIO_dictBufferType_t;
|
||||
|
||||
typedef struct {
|
||||
void* dictBuffer;
|
||||
size_t dictBufferSize;
|
||||
FIO_dictBufferType_t dictBufferType;
|
||||
#if defined(_MSC_VER) || defined(_WIN32)
|
||||
HANDLE dictHandle;
|
||||
#endif
|
||||
} FIO_Dict_t;
|
||||
|
||||
#endif /* FILEIO_TYPES_HEADER */
|
285
build_amd64/_deps/zstd-src/programs/lorem.c
Normal file
285
build_amd64/_deps/zstd-src/programs/lorem.c
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/* Implementation notes:
|
||||
*
|
||||
* This is a very simple lorem ipsum generator
|
||||
* which features a static list of words
|
||||
* and print them one after another randomly
|
||||
* with a fake sentence / paragraph structure.
|
||||
*
|
||||
* The goal is to generate a printable text
|
||||
* that can be used to fake a text compression scenario.
|
||||
* The resulting compression / ratio curve of the lorem ipsum generator
|
||||
* is more satisfying than the previous statistical generator,
|
||||
* which was initially designed for entropy compression,
|
||||
* and lacks a regularity more representative of text.
|
||||
*
|
||||
* The compression ratio achievable on the generated lorem ipsum
|
||||
* is still a bit too good, presumably because the dictionary is a bit too
|
||||
* small. It would be possible to create some more complex scheme, notably by
|
||||
* enlarging the dictionary with a word generator, and adding grammatical rules
|
||||
* (composition) and syntax rules. But that's probably overkill for the intended
|
||||
* goal.
|
||||
*/
|
||||
|
||||
#include "lorem.h"
|
||||
#include <assert.h>
|
||||
#include <limits.h> /* INT_MAX */
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
#define WORD_MAX_SIZE 20
|
||||
|
||||
/* Define the word pool */
|
||||
static const char* kWords[] = {
|
||||
"lorem", "ipsum", "dolor", "sit", "amet",
|
||||
"consectetur", "adipiscing", "elit", "sed", "do",
|
||||
"eiusmod", "tempor", "incididunt", "ut", "labore",
|
||||
"et", "dolore", "magna", "aliqua", "dis",
|
||||
"lectus", "vestibulum", "mattis", "ullamcorper", "velit",
|
||||
"commodo", "a", "lacus", "arcu", "magnis",
|
||||
"parturient", "montes", "nascetur", "ridiculus", "mus",
|
||||
"mauris", "nulla", "malesuada", "pellentesque", "eget",
|
||||
"gravida", "in", "dictum", "non", "erat",
|
||||
"nam", "voluptat", "maecenas", "blandit", "aliquam",
|
||||
"etiam", "enim", "lobortis", "scelerisque", "fermentum",
|
||||
"dui", "faucibus", "ornare", "at", "elementum",
|
||||
"eu", "facilisis", "odio", "morbi", "quis",
|
||||
"eros", "donec", "ac", "orci", "purus",
|
||||
"turpis", "cursus", "leo", "vel", "porta",
|
||||
"consequat", "interdum", "varius", "vulputate", "aliquet",
|
||||
"pharetra", "nunc", "auctor", "urna", "id",
|
||||
"metus", "viverra", "nibh", "cras", "mi",
|
||||
"unde", "omnis", "iste", "natus", "error",
|
||||
"perspiciatis", "voluptatem", "accusantium", "doloremque", "laudantium",
|
||||
"totam", "rem", "aperiam", "eaque", "ipsa",
|
||||
"quae", "ab", "illo", "inventore", "veritatis",
|
||||
"quasi", "architecto", "beatae", "vitae", "dicta",
|
||||
"sunt", "explicabo", "nemo", "ipsam", "quia",
|
||||
"voluptas", "aspernatur", "aut", "odit", "fugit",
|
||||
"consequuntur", "magni", "dolores", "eos", "qui",
|
||||
"ratione", "sequi", "nesciunt", "neque", "porro",
|
||||
"quisquam", "est", "dolorem", "adipisci", "numquam",
|
||||
"eius", "modi", "tempora", "incidunt", "magnam",
|
||||
"quaerat", "ad", "minima", "veniam", "nostrum",
|
||||
"ullam", "corporis", "suscipit", "laboriosam", "nisi",
|
||||
"aliquid", "ex", "ea", "commodi", "consequatur",
|
||||
"autem", "eum", "iure", "voluptate", "esse",
|
||||
"quam", "nihil", "molestiae", "illum", "fugiat",
|
||||
"quo", "pariatur", "vero", "accusamus", "iusto",
|
||||
"dignissimos", "ducimus", "blanditiis", "praesentium", "voluptatum",
|
||||
"deleniti", "atque", "corrupti", "quos", "quas",
|
||||
"molestias", "excepturi", "sint", "occaecati", "cupiditate",
|
||||
"provident", "similique", "culpa", "officia", "deserunt",
|
||||
"mollitia", "animi", "laborum", "dolorum", "fuga",
|
||||
"harum", "quidem", "rerum", "facilis", "expedita",
|
||||
"distinctio", "libero", "tempore", "cum", "soluta",
|
||||
"nobis", "eligendi", "optio", "cumque", "impedit",
|
||||
"minus", "quod", "maxime", "placeat", "facere",
|
||||
"possimus", "assumenda", "repellendus", "temporibus", "quibusdam",
|
||||
"officiis", "debitis", "saepe", "eveniet", "voluptates",
|
||||
"repudiandae", "recusandae", "itaque", "earum", "hic",
|
||||
"tenetur", "sapiente", "delectus", "reiciendis", "cillum",
|
||||
"maiores", "alias", "perferendis", "doloribus", "asperiores",
|
||||
"repellat", "minim", "nostrud", "exercitation", "ullamco",
|
||||
"laboris", "aliquip", "duis", "aute", "irure",
|
||||
};
|
||||
static const unsigned kNbWords = sizeof(kWords) / sizeof(kWords[0]);
|
||||
|
||||
/* simple 1-dimension distribution, based on word's length, favors small words
|
||||
*/
|
||||
static const int kWeights[] = { 0, 8, 6, 4, 3, 2 };
|
||||
static const size_t kNbWeights = sizeof(kWeights) / sizeof(kWeights[0]);
|
||||
|
||||
#define DISTRIB_SIZE_MAX 650
|
||||
static int g_distrib[DISTRIB_SIZE_MAX] = { 0 };
|
||||
static unsigned g_distribCount = 0;
|
||||
|
||||
static void countFreqs(
|
||||
const char* words[],
|
||||
size_t nbWords,
|
||||
const int* weights,
|
||||
size_t nbWeights)
|
||||
{
|
||||
unsigned total = 0;
|
||||
size_t w;
|
||||
for (w = 0; w < nbWords; w++) {
|
||||
size_t len = strlen(words[w]);
|
||||
int lmax;
|
||||
if (len >= nbWeights)
|
||||
len = nbWeights - 1;
|
||||
lmax = weights[len];
|
||||
total += (unsigned)lmax;
|
||||
}
|
||||
g_distribCount = total;
|
||||
assert(g_distribCount <= DISTRIB_SIZE_MAX);
|
||||
}
|
||||
|
||||
static void init_word_distrib(
|
||||
const char* words[],
|
||||
size_t nbWords,
|
||||
const int* weights,
|
||||
size_t nbWeights)
|
||||
{
|
||||
size_t w, d = 0;
|
||||
countFreqs(words, nbWords, weights, nbWeights);
|
||||
for (w = 0; w < nbWords; w++) {
|
||||
size_t len = strlen(words[w]);
|
||||
int l, lmax;
|
||||
if (len >= nbWeights)
|
||||
len = nbWeights - 1;
|
||||
lmax = weights[len];
|
||||
for (l = 0; l < lmax; l++) {
|
||||
g_distrib[d++] = (int)w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: this unit only works when invoked sequentially.
|
||||
* No concurrent access is allowed */
|
||||
static char* g_ptr = NULL;
|
||||
static size_t g_nbChars = 0;
|
||||
static size_t g_maxChars = 10000000;
|
||||
static unsigned g_randRoot = 0;
|
||||
|
||||
#define RDG_rotl32(x, r) ((x << r) | (x >> (32 - r)))
|
||||
static unsigned LOREM_rand(unsigned range)
|
||||
{
|
||||
static const unsigned prime1 = 2654435761U;
|
||||
static const unsigned prime2 = 2246822519U;
|
||||
unsigned rand32 = g_randRoot;
|
||||
rand32 *= prime1;
|
||||
rand32 ^= prime2;
|
||||
rand32 = RDG_rotl32(rand32, 13);
|
||||
g_randRoot = rand32;
|
||||
return (unsigned)(((unsigned long long)rand32 * range) >> 32);
|
||||
}
|
||||
|
||||
static void writeLastCharacters(void)
|
||||
{
|
||||
size_t lastChars = g_maxChars - g_nbChars;
|
||||
assert(g_maxChars >= g_nbChars);
|
||||
if (lastChars == 0)
|
||||
return;
|
||||
g_ptr[g_nbChars++] = '.';
|
||||
if (lastChars > 2) {
|
||||
memset(g_ptr + g_nbChars, ' ', lastChars - 2);
|
||||
}
|
||||
if (lastChars > 1) {
|
||||
g_ptr[g_maxChars - 1] = '\n';
|
||||
}
|
||||
g_nbChars = g_maxChars;
|
||||
}
|
||||
|
||||
static void generateWord(const char* word, const char* separator, int upCase)
|
||||
{
|
||||
size_t const len = strlen(word) + strlen(separator);
|
||||
if (g_nbChars + len > g_maxChars) {
|
||||
writeLastCharacters();
|
||||
return;
|
||||
}
|
||||
memcpy(g_ptr + g_nbChars, word, strlen(word));
|
||||
if (upCase) {
|
||||
static const char toUp = 'A' - 'a';
|
||||
g_ptr[g_nbChars] = (char)(g_ptr[g_nbChars] + toUp);
|
||||
}
|
||||
g_nbChars += strlen(word);
|
||||
memcpy(g_ptr + g_nbChars, separator, strlen(separator));
|
||||
g_nbChars += strlen(separator);
|
||||
}
|
||||
|
||||
static int about(unsigned target)
|
||||
{
|
||||
return (int)(LOREM_rand(target) + LOREM_rand(target) + 1);
|
||||
}
|
||||
|
||||
/* Function to generate a random sentence */
|
||||
static void generateSentence(int nbWords)
|
||||
{
|
||||
int commaPos = about(9);
|
||||
int comma2 = commaPos + about(7);
|
||||
int qmark = (LOREM_rand(11) == 7);
|
||||
const char* endSep = qmark ? "? " : ". ";
|
||||
int i;
|
||||
for (i = 0; i < nbWords; i++) {
|
||||
int const wordID = g_distrib[LOREM_rand(g_distribCount)];
|
||||
const char* const word = kWords[wordID];
|
||||
const char* sep = " ";
|
||||
if (i == commaPos)
|
||||
sep = ", ";
|
||||
if (i == comma2)
|
||||
sep = ", ";
|
||||
if (i == nbWords - 1)
|
||||
sep = endSep;
|
||||
generateWord(word, sep, i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void generateParagraph(int nbSentences)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nbSentences; i++) {
|
||||
int wordsPerSentence = about(11);
|
||||
generateSentence(wordsPerSentence);
|
||||
}
|
||||
if (g_nbChars < g_maxChars) {
|
||||
g_ptr[g_nbChars++] = '\n';
|
||||
}
|
||||
if (g_nbChars < g_maxChars) {
|
||||
g_ptr[g_nbChars++] = '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/* It's "common" for lorem ipsum generators to start with the same first
|
||||
* pre-defined sentence */
|
||||
static void generateFirstSentence(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 18; i++) {
|
||||
const char* word = kWords[i];
|
||||
const char* separator = " ";
|
||||
if (i == 4)
|
||||
separator = ", ";
|
||||
if (i == 7)
|
||||
separator = ", ";
|
||||
generateWord(word, separator, i == 0);
|
||||
}
|
||||
generateWord(kWords[18], ". ", 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
LOREM_genBlock(void* buffer, size_t size, unsigned seed, int first, int fill)
|
||||
{
|
||||
g_ptr = (char*)buffer;
|
||||
assert(size < INT_MAX);
|
||||
g_maxChars = size;
|
||||
g_nbChars = 0;
|
||||
g_randRoot = seed;
|
||||
if (g_distribCount == 0) {
|
||||
init_word_distrib(kWords, kNbWords, kWeights, kNbWeights);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
generateFirstSentence();
|
||||
}
|
||||
while (g_nbChars < g_maxChars) {
|
||||
int sentencePerParagraph = about(7);
|
||||
generateParagraph(sentencePerParagraph);
|
||||
if (!fill)
|
||||
break; /* only generate one paragraph in not-fill mode */
|
||||
}
|
||||
g_ptr = NULL;
|
||||
return g_nbChars;
|
||||
}
|
||||
|
||||
void LOREM_genBuffer(void* buffer, size_t size, unsigned seed)
|
||||
{
|
||||
LOREM_genBlock(buffer, size, seed, 1, 1);
|
||||
}
|
32
build_amd64/_deps/zstd-src/programs/lorem.h
Normal file
32
build_amd64/_deps/zstd-src/programs/lorem.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
/* lorem ipsum generator */
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
/*
|
||||
* LOREM_genBuffer():
|
||||
* Generate @size bytes of compressible data using lorem ipsum generator
|
||||
* into provided @buffer.
|
||||
*/
|
||||
void LOREM_genBuffer(void* buffer, size_t size, unsigned seed);
|
||||
|
||||
/*
|
||||
* LOREM_genBlock():
|
||||
* Similar to LOREM_genBuffer, with additional controls :
|
||||
* - @first : generate the first sentence
|
||||
* - @fill : fill the entire @buffer,
|
||||
* if ==0: generate one paragraph at most.
|
||||
* @return : nb of bytes generated into @buffer.
|
||||
*/
|
||||
size_t LOREM_genBlock(void* buffer, size_t size,
|
||||
unsigned seed,
|
||||
int first, int fill);
|
217
build_amd64/_deps/zstd-src/programs/platform.h
Normal file
217
build_amd64/_deps/zstd-src/programs/platform.h
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_H_MODULE
|
||||
#define PLATFORM_H_MODULE
|
||||
|
||||
/* **************************************
|
||||
* Compiler Options
|
||||
****************************************/
|
||||
#if defined(_MSC_VER)
|
||||
# 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 */
|
||||
# define _CRT_SECURE_NO_DEPRECATE /* VS2005 - must be declared before <io.h> and <windows.h> */
|
||||
# define snprintf sprintf_s /* snprintf unsupported by Visual <= 2013 */
|
||||
# endif
|
||||
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
|
||||
#endif
|
||||
|
||||
|
||||
/* **************************************
|
||||
* Detect 64-bit OS
|
||||
* https://nadeausoftware.com/articles/2012/02/c_c_tip_how_detect_processor_type_using_compiler_predefined_macros
|
||||
****************************************/
|
||||
#if defined __ia64 || defined _M_IA64 /* Intel Itanium */ \
|
||||
|| defined __powerpc64__ || defined __ppc64__ || defined __PPC64__ /* POWER 64-bit */ \
|
||||
|| (defined __sparc && (defined __sparcv9 || defined __sparc_v9__ || defined __arch64__)) || defined __sparc64__ /* SPARC 64-bit */ \
|
||||
|| defined __x86_64__ || defined _M_X64 /* x86 64-bit */ \
|
||||
|| defined __arm64__ || defined __aarch64__ || defined __ARM64_ARCH_8__ /* ARM 64-bit */ \
|
||||
|| (defined __mips && (__mips == 64 || __mips == 4 || __mips == 3)) /* MIPS 64-bit */ \
|
||||
|| defined _LP64 || defined __LP64__ /* NetBSD, OpenBSD */ || defined __64BIT__ /* AIX */ || defined _ADDR64 /* Cray */ \
|
||||
|| (defined __SIZEOF_POINTER__ && __SIZEOF_POINTER__ == 8) /* gcc */
|
||||
# if !defined(__64BIT__)
|
||||
# define __64BIT__ 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* *********************************************************
|
||||
* Turn on Large Files support (>4GB) for 32-bit Linux/Unix
|
||||
***********************************************************/
|
||||
#if !defined(__64BIT__) || defined(__MINGW32__) /* No point defining Large file for 64 bit but MinGW-w64 requires it */
|
||||
# if !defined(_FILE_OFFSET_BITS)
|
||||
# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */
|
||||
# endif
|
||||
# if !defined(_LARGEFILE_SOURCE) /* obsolete macro, replaced with _FILE_OFFSET_BITS */
|
||||
# define _LARGEFILE_SOURCE 1 /* Large File Support extension (LFS) - fseeko, ftello */
|
||||
# endif
|
||||
# if defined(_AIX) || defined(__hpux)
|
||||
# define _LARGE_FILES /* Large file support on 32-bits AIX and HP-UX */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* ************************************************************
|
||||
* Detect POSIX version
|
||||
* PLATFORM_POSIX_VERSION = 0 for non-Unix e.g. Windows
|
||||
* PLATFORM_POSIX_VERSION = 1 for Unix-like but non-POSIX
|
||||
* PLATFORM_POSIX_VERSION > 1 is equal to found _POSIX_VERSION
|
||||
* Value of PLATFORM_POSIX_VERSION can be forced on command line
|
||||
***************************************************************/
|
||||
#ifndef PLATFORM_POSIX_VERSION
|
||||
|
||||
# if (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) /* POSIX.1-2001 (SUSv3) conformant */
|
||||
/* exception rule : force posix version to 200112L,
|
||||
* note: it's better to use unistd.h's _POSIX_VERSION whenever possible */
|
||||
# define PLATFORM_POSIX_VERSION 200112L
|
||||
|
||||
/* try to determine posix version through official unistd.h's _POSIX_VERSION (https://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html).
|
||||
* note : there is no simple way to know in advance if <unistd.h> is present or not on target system,
|
||||
* Posix specification mandates its presence and its content, but target system must respect this spec.
|
||||
* It's necessary to _not_ #include <unistd.h> whenever target OS is not unix-like
|
||||
* otherwise it will block preprocessing stage.
|
||||
* The following list of build macros tries to "guess" if target OS is likely unix-like, and therefore can #include <unistd.h>
|
||||
*/
|
||||
# elif !defined(_WIN32) \
|
||||
&& ( defined(__unix__) || defined(__unix) \
|
||||
|| defined(_QNX_SOURCE) || defined(__midipix__) || defined(__VMS) || defined(__HAIKU__) )
|
||||
|
||||
# if defined(__linux__) || defined(__linux) || defined(__CYGWIN__)
|
||||
# ifndef _POSIX_C_SOURCE
|
||||
# define _POSIX_C_SOURCE 200809L /* feature test macro : https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html */
|
||||
# endif
|
||||
# endif
|
||||
# include <unistd.h> /* declares _POSIX_VERSION */
|
||||
# if defined(_POSIX_VERSION) /* POSIX compliant */
|
||||
# define PLATFORM_POSIX_VERSION _POSIX_VERSION
|
||||
# else
|
||||
# define PLATFORM_POSIX_VERSION 1
|
||||
# endif
|
||||
|
||||
# ifdef __UCLIBC__
|
||||
# ifndef __USE_MISC
|
||||
# define __USE_MISC /* enable st_mtim on uclibc */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# else /* non-unix target platform (like Windows) */
|
||||
# define PLATFORM_POSIX_VERSION 0
|
||||
# endif
|
||||
|
||||
#endif /* PLATFORM_POSIX_VERSION */
|
||||
|
||||
|
||||
#if PLATFORM_POSIX_VERSION > 1
|
||||
/* glibc < 2.26 may not expose struct timespec def without this.
|
||||
* See issue #1920. */
|
||||
# ifndef _ATFILE_SOURCE
|
||||
# define _ATFILE_SOURCE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-*********************************************
|
||||
* Detect if isatty() and fileno() are available
|
||||
*
|
||||
* Note: Use UTIL_isConsole() for the zstd CLI
|
||||
* instead, as it allows faking is console for
|
||||
* testing.
|
||||
************************************************/
|
||||
#if (defined(__linux__) && (PLATFORM_POSIX_VERSION > 1)) \
|
||||
|| (PLATFORM_POSIX_VERSION >= 200112L) \
|
||||
|| defined(__DJGPP__)
|
||||
# include <unistd.h> /* isatty */
|
||||
# include <stdio.h> /* fileno */
|
||||
# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))
|
||||
#elif defined(MSDOS) || defined(OS2)
|
||||
# include <io.h> /* _isatty */
|
||||
# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))
|
||||
#elif defined(_WIN32)
|
||||
# include <io.h> /* _isatty */
|
||||
# include <windows.h> /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */
|
||||
# include <stdio.h> /* FILE */
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static __inline int IS_CONSOLE(FILE* stdStream) {
|
||||
DWORD dummy;
|
||||
return _isatty(_fileno(stdStream)) && GetConsoleMode((HANDLE)_get_osfhandle(_fileno(stdStream)), &dummy);
|
||||
}
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
# define IS_CONSOLE(stdStream) 0
|
||||
#endif
|
||||
|
||||
|
||||
/******************************
|
||||
* OS-specific IO behaviors
|
||||
******************************/
|
||||
#if defined(MSDOS) || defined(OS2) || defined(_WIN32)
|
||||
# include <fcntl.h> /* _O_BINARY */
|
||||
# include <io.h> /* _setmode, _fileno, _get_osfhandle */
|
||||
# if !defined(__DJGPP__)
|
||||
# include <windows.h> /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */
|
||||
# include <winioctl.h> /* FSCTL_SET_SPARSE */
|
||||
# define SET_BINARY_MODE(file) { int const unused=_setmode(_fileno(file), _O_BINARY); (void)unused; }
|
||||
# define SET_SPARSE_FILE_MODE(file) { DWORD dw; DeviceIoControl((HANDLE) _get_osfhandle(_fileno(file)), FSCTL_SET_SPARSE, 0, 0, 0, 0, &dw, 0); }
|
||||
# else
|
||||
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
|
||||
# define SET_SPARSE_FILE_MODE(file)
|
||||
# endif
|
||||
#else
|
||||
# define SET_BINARY_MODE(file)
|
||||
# define SET_SPARSE_FILE_MODE(file)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ZSTD_SPARSE_DEFAULT
|
||||
# if (defined(__APPLE__) && defined(__MACH__))
|
||||
# define ZSTD_SPARSE_DEFAULT 0
|
||||
# else
|
||||
# define ZSTD_SPARSE_DEFAULT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ZSTD_START_SYMBOLLIST_FRAME
|
||||
# ifdef __linux__
|
||||
# define ZSTD_START_SYMBOLLIST_FRAME 2
|
||||
# elif defined __APPLE__
|
||||
# define ZSTD_START_SYMBOLLIST_FRAME 4
|
||||
# else
|
||||
# define ZSTD_START_SYMBOLLIST_FRAME 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ZSTD_SETPRIORITY_SUPPORT
|
||||
/* mandates presence of <sys/resource.h> and support for setpriority() : https://man7.org/linux/man-pages/man2/setpriority.2.html */
|
||||
# define ZSTD_SETPRIORITY_SUPPORT (PLATFORM_POSIX_VERSION >= 200112L)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ZSTD_NANOSLEEP_SUPPORT
|
||||
/* mandates support of nanosleep() within <time.h> : https://man7.org/linux/man-pages/man2/nanosleep.2.html */
|
||||
# if (defined(__linux__) && (PLATFORM_POSIX_VERSION >= 199309L)) \
|
||||
|| (PLATFORM_POSIX_VERSION >= 200112L)
|
||||
# define ZSTD_NANOSLEEP_SUPPORT 1
|
||||
# else
|
||||
# define ZSTD_NANOSLEEP_SUPPORT 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* PLATFORM_H_MODULE */
|
168
build_amd64/_deps/zstd-src/programs/timefn.c
Normal file
168
build_amd64/_deps/zstd-src/programs/timefn.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
|
||||
/* === Dependencies === */
|
||||
|
||||
#include "timefn.h"
|
||||
#include "platform.h" /* set _POSIX_C_SOURCE */
|
||||
#include <time.h> /* CLOCK_MONOTONIC, TIME_UTC */
|
||||
|
||||
/*-****************************************
|
||||
* Time functions
|
||||
******************************************/
|
||||
|
||||
#if defined(_WIN32) /* Windows */
|
||||
|
||||
#include <windows.h> /* LARGE_INTEGER */
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <stdio.h> /* perror */
|
||||
|
||||
UTIL_time_t UTIL_getTime(void)
|
||||
{
|
||||
static LARGE_INTEGER ticksPerSecond;
|
||||
static int init = 0;
|
||||
if (!init) {
|
||||
if (!QueryPerformanceFrequency(&ticksPerSecond)) {
|
||||
perror("timefn::QueryPerformanceFrequency");
|
||||
abort();
|
||||
}
|
||||
init = 1;
|
||||
}
|
||||
{ UTIL_time_t r;
|
||||
LARGE_INTEGER x;
|
||||
QueryPerformanceCounter(&x);
|
||||
r.t = (PTime)(x.QuadPart * 1000000000ULL / ticksPerSecond.QuadPart);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
|
||||
#include <mach/mach_time.h> /* mach_timebase_info_data_t, mach_timebase_info, mach_absolute_time */
|
||||
|
||||
UTIL_time_t UTIL_getTime(void)
|
||||
{
|
||||
static mach_timebase_info_data_t rate;
|
||||
static int init = 0;
|
||||
if (!init) {
|
||||
mach_timebase_info(&rate);
|
||||
init = 1;
|
||||
}
|
||||
{ UTIL_time_t r;
|
||||
r.t = mach_absolute_time() * (PTime)rate.numer / (PTime)rate.denom;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* POSIX.1-2001 (optional) */
|
||||
#elif defined(CLOCK_MONOTONIC)
|
||||
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <stdio.h> /* perror */
|
||||
|
||||
UTIL_time_t UTIL_getTime(void)
|
||||
{
|
||||
/* time must be initialized, othersize it may fail msan test.
|
||||
* No good reason, likely a limitation of timespec_get() for some target */
|
||||
struct timespec time = { 0, 0 };
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &time) != 0) {
|
||||
perror("timefn::clock_gettime(CLOCK_MONOTONIC)");
|
||||
abort();
|
||||
}
|
||||
{ UTIL_time_t r;
|
||||
r.t = (PTime)time.tv_sec * 1000000000ULL + (PTime)time.tv_nsec;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* C11 requires support of timespec_get().
|
||||
* However, FreeBSD 11 claims C11 compliance while lacking timespec_get().
|
||||
* Double confirm timespec_get() support by checking the definition of TIME_UTC.
|
||||
* However, some versions of Android manage to simultaneously define TIME_UTC
|
||||
* and lack timespec_get() support... */
|
||||
#elif (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */) \
|
||||
&& defined(TIME_UTC) && !defined(__ANDROID__)
|
||||
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <stdio.h> /* perror */
|
||||
|
||||
UTIL_time_t UTIL_getTime(void)
|
||||
{
|
||||
/* time must be initialized, othersize it may fail msan test.
|
||||
* No good reason, likely a limitation of timespec_get() for some target */
|
||||
struct timespec time = { 0, 0 };
|
||||
if (timespec_get(&time, TIME_UTC) != TIME_UTC) {
|
||||
perror("timefn::timespec_get(TIME_UTC)");
|
||||
abort();
|
||||
}
|
||||
{ UTIL_time_t r;
|
||||
r.t = (PTime)time.tv_sec * 1000000000ULL + (PTime)time.tv_nsec;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else /* relies on standard C90 (note : clock_t produces wrong measurements for multi-threaded workloads) */
|
||||
|
||||
UTIL_time_t UTIL_getTime(void)
|
||||
{
|
||||
UTIL_time_t r;
|
||||
r.t = (PTime)clock() * 1000000000ULL / CLOCKS_PER_SEC;
|
||||
return r;
|
||||
}
|
||||
|
||||
#define TIME_MT_MEASUREMENTS_NOT_SUPPORTED
|
||||
|
||||
#endif
|
||||
|
||||
/* ==== Common functions, valid for all time API ==== */
|
||||
|
||||
PTime UTIL_getSpanTimeNano(UTIL_time_t clockStart, UTIL_time_t clockEnd)
|
||||
{
|
||||
return clockEnd.t - clockStart.t;
|
||||
}
|
||||
|
||||
PTime UTIL_getSpanTimeMicro(UTIL_time_t begin, UTIL_time_t end)
|
||||
{
|
||||
return UTIL_getSpanTimeNano(begin, end) / 1000ULL;
|
||||
}
|
||||
|
||||
PTime UTIL_clockSpanMicro(UTIL_time_t clockStart )
|
||||
{
|
||||
UTIL_time_t const clockEnd = UTIL_getTime();
|
||||
return UTIL_getSpanTimeMicro(clockStart, clockEnd);
|
||||
}
|
||||
|
||||
PTime UTIL_clockSpanNano(UTIL_time_t clockStart )
|
||||
{
|
||||
UTIL_time_t const clockEnd = UTIL_getTime();
|
||||
return UTIL_getSpanTimeNano(clockStart, clockEnd);
|
||||
}
|
||||
|
||||
void UTIL_waitForNextTick(void)
|
||||
{
|
||||
UTIL_time_t const clockStart = UTIL_getTime();
|
||||
UTIL_time_t clockEnd;
|
||||
do {
|
||||
clockEnd = UTIL_getTime();
|
||||
} while (UTIL_getSpanTimeNano(clockStart, clockEnd) == 0);
|
||||
}
|
||||
|
||||
int UTIL_support_MT_measurements(void)
|
||||
{
|
||||
# if defined(TIME_MT_MEASUREMENTS_NOT_SUPPORTED)
|
||||
return 0;
|
||||
# else
|
||||
return 1;
|
||||
# endif
|
||||
}
|
59
build_amd64/_deps/zstd-src/programs/timefn.h
Normal file
59
build_amd64/_deps/zstd-src/programs/timefn.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef TIME_FN_H_MODULE_287987
|
||||
#define TIME_FN_H_MODULE_287987
|
||||
|
||||
/*-****************************************
|
||||
* Types
|
||||
******************************************/
|
||||
|
||||
#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
|
||||
# if defined(_AIX)
|
||||
# include <inttypes.h>
|
||||
# else
|
||||
# include <stdint.h> /* uint64_t */
|
||||
# endif
|
||||
typedef uint64_t PTime; /* Precise Time */
|
||||
#else
|
||||
typedef unsigned long long PTime; /* does not support compilers without long long support */
|
||||
#endif
|
||||
|
||||
/* UTIL_time_t contains a nanosecond time counter.
|
||||
* The absolute value is not meaningful.
|
||||
* It's only valid to compute the difference between 2 measurements. */
|
||||
typedef struct { PTime t; } UTIL_time_t;
|
||||
#define UTIL_TIME_INITIALIZER { 0 }
|
||||
|
||||
|
||||
/*-****************************************
|
||||
* Time functions
|
||||
******************************************/
|
||||
|
||||
UTIL_time_t UTIL_getTime(void);
|
||||
|
||||
/* Timer resolution can be low on some platforms.
|
||||
* To improve accuracy, it's recommended to wait for a new tick
|
||||
* before starting benchmark measurements */
|
||||
void UTIL_waitForNextTick(void);
|
||||
/* tells if timefn will return correct time measurements
|
||||
* in presence of multi-threaded workload.
|
||||
* note : this is not the case if only C90 clock_t measurements are available */
|
||||
int UTIL_support_MT_measurements(void);
|
||||
|
||||
PTime UTIL_getSpanTimeNano(UTIL_time_t clockStart, UTIL_time_t clockEnd);
|
||||
PTime UTIL_clockSpanNano(UTIL_time_t clockStart);
|
||||
|
||||
PTime UTIL_getSpanTimeMicro(UTIL_time_t clockStart, UTIL_time_t clockEnd);
|
||||
PTime UTIL_clockSpanMicro(UTIL_time_t clockStart);
|
||||
|
||||
#define SEC_TO_MICRO ((PTime)1000000) /* nb of microseconds in a second */
|
||||
|
||||
#endif /* TIME_FN_H_MODULE_287987 */
|
1643
build_amd64/_deps/zstd-src/programs/util.c
Normal file
1643
build_amd64/_deps/zstd-src/programs/util.c
Normal file
File diff suppressed because it is too large
Load Diff
362
build_amd64/_deps/zstd-src/programs/util.h
Normal file
362
build_amd64/_deps/zstd-src/programs/util.h
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H_MODULE
|
||||
#define UTIL_H_MODULE
|
||||
|
||||
/*-****************************************
|
||||
* Dependencies
|
||||
******************************************/
|
||||
#include "platform.h" /* PLATFORM_POSIX_VERSION, ZSTD_NANOSLEEP_SUPPORT, ZSTD_SETPRIORITY_SUPPORT */
|
||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||
#include <stdio.h> /* FILE */
|
||||
#include <sys/types.h> /* stat, utime */
|
||||
#include <sys/stat.h> /* stat, chmod */
|
||||
#include "../lib/common/mem.h" /* U64 */
|
||||
#if !(defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__))
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
/*-************************************************************
|
||||
* Fix fseek()'s 2GiB barrier with MSVC, macOS, *BSD, MinGW
|
||||
***************************************************************/
|
||||
#if defined(LIBC_NO_FSEEKO)
|
||||
/* Some older libc implementations don't include these functions (e.g. Bionic < 24) */
|
||||
# define UTIL_fseek fseek
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
# define UTIL_fseek _fseeki64
|
||||
#elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */
|
||||
# define UTIL_fseek fseeko
|
||||
#elif defined(__MINGW32__) && defined(__MSVCRT__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS)
|
||||
# define UTIL_fseek fseeko64
|
||||
#else
|
||||
# define UTIL_fseek fseek
|
||||
#endif
|
||||
|
||||
/*-*************************************************
|
||||
* Sleep & priority functions: Windows - Posix - others
|
||||
***************************************************/
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)
|
||||
# define UTIL_sleep(s) Sleep(1000*s)
|
||||
# define UTIL_sleepMilli(milli) Sleep(milli)
|
||||
|
||||
#elif PLATFORM_POSIX_VERSION > 0 /* Unix-like operating system */
|
||||
# include <unistd.h> /* sleep */
|
||||
# define UTIL_sleep(s) sleep(s)
|
||||
# if ZSTD_NANOSLEEP_SUPPORT /* necessarily defined in platform.h */
|
||||
# define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); }
|
||||
# else
|
||||
# define UTIL_sleepMilli(milli) /* disabled */
|
||||
# endif
|
||||
# if ZSTD_SETPRIORITY_SUPPORT
|
||||
# include <sys/resource.h> /* setpriority */
|
||||
# define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20)
|
||||
# else
|
||||
# define SET_REALTIME_PRIORITY /* disabled */
|
||||
# endif
|
||||
|
||||
#else /* unknown non-unix operating system */
|
||||
# define UTIL_sleep(s) /* disabled */
|
||||
# define UTIL_sleepMilli(milli) /* disabled */
|
||||
# define SET_REALTIME_PRIORITY /* disabled */
|
||||
#endif
|
||||
|
||||
|
||||
/*-****************************************
|
||||
* Compiler specifics
|
||||
******************************************/
|
||||
#if defined(__INTEL_COMPILER)
|
||||
# pragma warning(disable : 177) /* disable: message #177: function was declared but never referenced, useful with UTIL_STATIC */
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
# define UTIL_STATIC static __attribute__((unused))
|
||||
#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||
# define UTIL_STATIC static inline
|
||||
#elif defined(_MSC_VER)
|
||||
# define UTIL_STATIC static __inline
|
||||
#else
|
||||
# define UTIL_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-****************************************
|
||||
* Console log
|
||||
******************************************/
|
||||
extern int g_utilDisplayLevel;
|
||||
|
||||
/**
|
||||
* Displays a message prompt and returns success (0) if first character from stdin
|
||||
* matches any from acceptableLetters. Otherwise, returns failure (1) and displays abortMsg.
|
||||
* If any of the inputs are stdin itself, then automatically return failure (1).
|
||||
*/
|
||||
int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const char* acceptableLetters, int hasStdinInput);
|
||||
|
||||
|
||||
/*-****************************************
|
||||
* File functions
|
||||
******************************************/
|
||||
#if defined(_MSC_VER)
|
||||
typedef struct __stat64 stat_t;
|
||||
typedef int mode_t;
|
||||
#elif defined(__MINGW32__) && defined (__MSVCRT__)
|
||||
typedef struct _stati64 stat_t;
|
||||
#else
|
||||
typedef struct stat stat_t;
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined (__MSVCRT__) /* windows support */
|
||||
#define PATH_SEP '\\'
|
||||
#define STRDUP(s) _strdup(s)
|
||||
#else
|
||||
#define PATH_SEP '/'
|
||||
#define STRDUP(s) strdup(s)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Calls platform's equivalent of stat() on filename and writes info to statbuf.
|
||||
* Returns success (1) or failure (0).
|
||||
*
|
||||
* UTIL_fstat() is like UTIL_stat() but takes an optional fd that refers to the
|
||||
* file in question. It turns out that this can be meaningfully faster. If fd is
|
||||
* -1, behaves just like UTIL_stat() (i.e., falls back to using the filename).
|
||||
*/
|
||||
int UTIL_stat(const char* filename, stat_t* statbuf);
|
||||
int UTIL_fstat(const int fd, const char* filename, stat_t* statbuf);
|
||||
|
||||
/**
|
||||
* Instead of getting a file's stats, this updates them with the info in the
|
||||
* provided stat_t. Currently sets owner, group, atime, and mtime. Will only
|
||||
* update this info for regular files.
|
||||
*
|
||||
* UTIL_setFDStat() also takes an fd, and will preferentially use that to
|
||||
* indicate which file to modify, If fd is -1, it will fall back to using the
|
||||
* filename.
|
||||
*/
|
||||
int UTIL_setFileStat(const char* filename, const stat_t* statbuf);
|
||||
int UTIL_setFDStat(const int fd, const char* filename, const stat_t* statbuf);
|
||||
|
||||
/**
|
||||
* Set atime to now and mtime to the st_mtim in statbuf.
|
||||
*
|
||||
* Directly wraps utime() or utimensat(). Returns -1 on error.
|
||||
* Does not validate filename is valid.
|
||||
*/
|
||||
int UTIL_utime(const char* filename, const stat_t *statbuf);
|
||||
|
||||
/*
|
||||
* These helpers operate on a pre-populated stat_t, i.e., the result of
|
||||
* calling one of the above functions.
|
||||
*/
|
||||
|
||||
int UTIL_isRegularFileStat(const stat_t* statbuf);
|
||||
int UTIL_isDirectoryStat(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);
|
||||
|
||||
/**
|
||||
* Like chmod(), but only modifies regular files. Provided statbuf may be NULL,
|
||||
* in which case this function will stat() the file internally, in order to
|
||||
* check whether it should be modified.
|
||||
*
|
||||
* If fd is -1, fd is ignored and the filename is used.
|
||||
*/
|
||||
int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions);
|
||||
int UTIL_fchmod(const int fd, char const* filename, const stat_t* statbuf, mode_t permissions);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* compute the needed information.
|
||||
*/
|
||||
|
||||
int UTIL_isRegularFile(const char* infilename);
|
||||
int UTIL_isDirectory(const char* infilename);
|
||||
int UTIL_isSameFile(const char* file1, const char* file2);
|
||||
int UTIL_isSameFileStat(const char* file1, const char* file2, const stat_t* file1Stat, const stat_t* file2Stat);
|
||||
int UTIL_isCompressedFile(const char* infilename, const char *extensionList[]);
|
||||
int UTIL_isLink(const char* infilename);
|
||||
int UTIL_isFIFO(const char* infilename);
|
||||
|
||||
/**
|
||||
* Returns with the given file descriptor is a console.
|
||||
* Allows faking whether stdin/stdout/stderr is a console
|
||||
* using UTIL_fake*IsConsole().
|
||||
*/
|
||||
int UTIL_isConsole(FILE* file);
|
||||
|
||||
/**
|
||||
* Pretends that stdin/stdout/stderr is a console for testing.
|
||||
*/
|
||||
void UTIL_fakeStdinIsConsole(void);
|
||||
void UTIL_fakeStdoutIsConsole(void);
|
||||
void UTIL_fakeStderrIsConsole(void);
|
||||
|
||||
/**
|
||||
* Emit traces for functions that read, or modify file metadata.
|
||||
*/
|
||||
void UTIL_traceFileStat(void);
|
||||
|
||||
#define UTIL_FILESIZE_UNKNOWN ((U64)(-1))
|
||||
U64 UTIL_getFileSize(const char* infilename);
|
||||
U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles);
|
||||
|
||||
/**
|
||||
* Take @size in bytes,
|
||||
* prepare the components to pretty-print it in a scaled way.
|
||||
* The components in the returned struct should be passed in
|
||||
* precision, value, suffix order to a "%.*f%s" format string.
|
||||
* Output policy is sensible to @g_utilDisplayLevel,
|
||||
* for verbose mode (@g_utilDisplayLevel >= 4),
|
||||
* does not scale down.
|
||||
*/
|
||||
typedef struct {
|
||||
double value;
|
||||
int precision;
|
||||
const char* suffix;
|
||||
} UTIL_HumanReadableSize_t;
|
||||
|
||||
UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size);
|
||||
|
||||
int UTIL_compareStr(const void *p1, const void *p2);
|
||||
const char* UTIL_getFileExtension(const char* infilename);
|
||||
void UTIL_mirrorSourceFilesDirectories(const char** fileNamesTable, unsigned int nbFiles, const char *outDirName);
|
||||
char* UTIL_createMirroredDestDirName(const char* srcFileName, const char* outDirRootName);
|
||||
|
||||
|
||||
|
||||
/*-****************************************
|
||||
* Lists of Filenames
|
||||
******************************************/
|
||||
|
||||
typedef struct
|
||||
{ const char** fileNames;
|
||||
char* buf; /* fileNames are stored in this buffer (or are read-only) */
|
||||
size_t tableSize; /* nb of fileNames */
|
||||
size_t tableCapacity;
|
||||
} FileNamesTable;
|
||||
|
||||
/*! UTIL_createFileNamesTable_fromFileName() :
|
||||
* read filenames from @inputFileName, and store them into returned object.
|
||||
* @return : a FileNamesTable*, or NULL in case of error (ex: @inputFileName doesn't exist).
|
||||
* Note: inputFileSize must be less than 50MB
|
||||
*/
|
||||
FileNamesTable*
|
||||
UTIL_createFileNamesTable_fromFileName(const char* inputFileName);
|
||||
|
||||
/*! UTIL_assembleFileNamesTable() :
|
||||
* This function takes ownership of its arguments, @filenames and @buf,
|
||||
* and store them inside the created object.
|
||||
* note : this function never fails,
|
||||
* it will rather exit() the program if internal allocation fails.
|
||||
* @return : resulting FileNamesTable* object.
|
||||
*/
|
||||
FileNamesTable*
|
||||
UTIL_assembleFileNamesTable(const char** filenames, size_t tableSize, char* buf);
|
||||
|
||||
/*! UTIL_freeFileNamesTable() :
|
||||
* This function is compatible with NULL argument and never fails.
|
||||
*/
|
||||
void UTIL_freeFileNamesTable(FileNamesTable* table);
|
||||
|
||||
/*! UTIL_mergeFileNamesTable():
|
||||
* @return : FileNamesTable*, concatenation of @table1 and @table2
|
||||
* note: @table1 and @table2 are consumed (freed) by this operation
|
||||
*/
|
||||
FileNamesTable*
|
||||
UTIL_mergeFileNamesTable(FileNamesTable* table1, FileNamesTable* table2);
|
||||
|
||||
|
||||
/*! UTIL_expandFNT() :
|
||||
* read names from @fnt, and expand those corresponding to directories
|
||||
* update @fnt, now containing only file names,
|
||||
* note : in case of error, @fnt[0] is NULL
|
||||
*/
|
||||
void UTIL_expandFNT(FileNamesTable** fnt, int followLinks);
|
||||
|
||||
/*! UTIL_createFNT_fromROTable() :
|
||||
* copy the @filenames pointer table inside the returned object.
|
||||
* The names themselves are still stored in their original buffer, which must outlive the object.
|
||||
* @return : a FileNamesTable* object,
|
||||
* or NULL in case of error
|
||||
*/
|
||||
FileNamesTable*
|
||||
UTIL_createFNT_fromROTable(const char** filenames, size_t nbFilenames);
|
||||
|
||||
/*! UTIL_allocateFileNamesTable() :
|
||||
* Allocates a table of const char*, to insert read-only names later on.
|
||||
* The created FileNamesTable* doesn't hold a buffer.
|
||||
* @return : FileNamesTable*, or NULL, if allocation fails.
|
||||
*/
|
||||
FileNamesTable* UTIL_allocateFileNamesTable(size_t tableSize);
|
||||
|
||||
/*! UTIL_searchFileNamesTable() :
|
||||
* Searched through entries in FileNamesTable for a specific name.
|
||||
* @return : index of entry if found or -1 if not found
|
||||
*/
|
||||
int UTIL_searchFileNamesTable(FileNamesTable* table, char const* name);
|
||||
|
||||
/*! UTIL_refFilename() :
|
||||
* Add a reference to read-only name into @fnt table.
|
||||
* As @filename is only referenced, its lifetime must outlive @fnt.
|
||||
* Internal table must be large enough to reference a new member,
|
||||
* otherwise its UB (protected by an `assert()`).
|
||||
*/
|
||||
void UTIL_refFilename(FileNamesTable* fnt, const char* filename);
|
||||
|
||||
|
||||
/* UTIL_createExpandedFNT() is only active if UTIL_HAS_CREATEFILELIST is defined.
|
||||
* Otherwise, UTIL_createExpandedFNT() is a shell function which does nothing
|
||||
* apart from displaying a warning message.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
# define UTIL_HAS_CREATEFILELIST
|
||||
#elif defined(__linux__) || (PLATFORM_POSIX_VERSION >= 200112L) /* opendir, readdir require POSIX.1-2001 */
|
||||
# define UTIL_HAS_CREATEFILELIST
|
||||
# define UTIL_HAS_MIRRORFILELIST
|
||||
#else
|
||||
/* do not define UTIL_HAS_CREATEFILELIST */
|
||||
#endif
|
||||
|
||||
/*! UTIL_createExpandedFNT() :
|
||||
* read names from @filenames, and expand those corresponding to directories.
|
||||
* links are followed or not depending on @followLinks directive.
|
||||
* @return : an expanded FileNamesTable*, where each name is a file
|
||||
* or NULL in case of error
|
||||
*/
|
||||
FileNamesTable*
|
||||
UTIL_createExpandedFNT(const char* const* filenames, size_t nbFilenames, int followLinks);
|
||||
|
||||
#if defined(_WIN32)
|
||||
DWORD CountSetBits(ULONG_PTR bitMask);
|
||||
#endif
|
||||
|
||||
/*-****************************************
|
||||
* System
|
||||
******************************************/
|
||||
|
||||
int UTIL_countCores(int logical);
|
||||
|
||||
int UTIL_countPhysicalCores(void);
|
||||
|
||||
int UTIL_countLogicalCores(void);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UTIL_H_MODULE */
|
17
build_amd64/_deps/zstd-src/programs/windres/verrsrc.h
Normal file
17
build_amd64/_deps/zstd-src/programs/windres/verrsrc.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
/* minimal set of defines required to generate zstd.res from zstd.rc */
|
||||
|
||||
#define VS_VERSION_INFO 1
|
||||
|
||||
#define VS_FFI_FILEFLAGSMASK 0x0000003FL
|
||||
#define VOS_NT_WINDOWS32 0x00040004L
|
||||
#define VFT_DLL 0x00000002L
|
||||
#define VFT2_UNKNOWN 0x00000000L
|
51
build_amd64/_deps/zstd-src/programs/windres/zstd.rc
Normal file
51
build_amd64/_deps/zstd-src/programs/windres/zstd.rc
Normal file
@@ -0,0 +1,51 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
|
||||
#include "zstd.h" /* ZSTD_VERSION_STRING */
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
#include "verrsrc.h"
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE 9, 1
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION ZSTD_VERSION_MAJOR,ZSTD_VERSION_MINOR,ZSTD_VERSION_RELEASE,0
|
||||
PRODUCTVERSION ZSTD_VERSION_MAJOR,ZSTD_VERSION_MINOR,ZSTD_VERSION_RELEASE,0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Meta Platforms, Inc."
|
||||
VALUE "FileDescription", "Zstandard - Fast and efficient compression algorithm"
|
||||
VALUE "FileVersion", ZSTD_VERSION_STRING
|
||||
VALUE "InternalName", "zstd.exe"
|
||||
VALUE "LegalCopyright", "Copyright (c) Meta Platforms, Inc. and affiliates."
|
||||
VALUE "OriginalFilename", "zstd.exe"
|
||||
VALUE "ProductName", "Zstandard"
|
||||
VALUE "ProductVersion", ZSTD_VERSION_STRING
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif
|
BIN
build_amd64/_deps/zstd-src/programs/windres/zstd32.res
Normal file
BIN
build_amd64/_deps/zstd-src/programs/windres/zstd32.res
Normal file
Binary file not shown.
BIN
build_amd64/_deps/zstd-src/programs/windres/zstd64.res
Normal file
BIN
build_amd64/_deps/zstd-src/programs/windres/zstd64.res
Normal file
Binary file not shown.
392
build_amd64/_deps/zstd-src/programs/zstd.1
Normal file
392
build_amd64/_deps/zstd-src/programs/zstd.1
Normal file
@@ -0,0 +1,392 @@
|
||||
.TH "ZSTD" "1" "October 2024" "zstd 1.5.6" "User Commands"
|
||||
.SH "NAME"
|
||||
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
|
||||
.SH "SYNOPSIS"
|
||||
.TS
|
||||
allbox;
|
||||
\fBzstd\fR [\fIOPTIONS\fR] [\- \fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR]
|
||||
.TE
|
||||
.P
|
||||
\fBzstdmt\fR is equivalent to \fBzstd \-T0\fR
|
||||
.P
|
||||
\fBunzstd\fR is equivalent to \fBzstd \-d\fR
|
||||
.P
|
||||
\fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR
|
||||
.SH "DESCRIPTION"
|
||||
\fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip\fR(1) and \fBxz\fR(1)\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, from fast modes at > 200 MB/s per core, to strong modes with excellent compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core, which remains roughly stable at all compression settings\.
|
||||
.P
|
||||
\fBzstd\fR command line syntax is generally similar to gzip, but features the following few differences:
|
||||
.IP "\(bu" 4
|
||||
Source files are preserved by default\. It's possible to remove them automatically by using the \fB\-\-rm\fR command\.
|
||||
.IP "\(bu" 4
|
||||
When compressing a single file, \fBzstd\fR displays progress notifications and result summary by default\. Use \fB\-q\fR to turn them off\.
|
||||
.IP "\(bu" 4
|
||||
\fBzstd\fR displays a short help page when command line is an error\. Use \fB\-q\fR to turn it off\.
|
||||
.IP "\(bu" 4
|
||||
\fBzstd\fR does not accept input from console, though it does accept \fBstdin\fR when it's not the console\.
|
||||
.IP "\(bu" 4
|
||||
\fBzstd\fR does not store the input's filename or attributes, only its contents\.
|
||||
.IP "" 0
|
||||
.P
|
||||
\fBzstd\fR processes each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal: it will display an error message and skip the file\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\.
|
||||
.P
|
||||
Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name:
|
||||
.IP "\(bu" 4
|
||||
When compressing, the suffix \fB\.zst\fR is appended to the source filename to get the target filename\.
|
||||
.IP "\(bu" 4
|
||||
When decompressing, the \fB\.zst\fR suffix is removed from the source filename to get the target filename
|
||||
.IP "" 0
|
||||
.SS "Concatenation with \.zst Files"
|
||||
It is possible to concatenate multiple \fB\.zst\fR files\. \fBzstd\fR will decompress such agglomerated file as if it was a single \fB\.zst\fR file\.
|
||||
.SH "OPTIONS"
|
||||
.SS "Integer Suffixes and Special Values"
|
||||
In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\.
|
||||
.TP
|
||||
\fBKiB\fR
|
||||
Multiply the integer by 1,024 (2\e^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\.
|
||||
.TP
|
||||
\fBMiB\fR
|
||||
Multiply the integer by 1,048,576 (2\e^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\.
|
||||
.SS "Operation Mode"
|
||||
If multiple operation mode options are given, the last one takes effect\.
|
||||
.TP
|
||||
\fB\-z\fR, \fB\-\-compress\fR
|
||||
Compress\. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, \fBunzstd\fR implies \fB\-\-decompress\fR)\.
|
||||
.TP
|
||||
\fB\-d\fR, \fB\-\-decompress\fR, \fB\-\-uncompress\fR
|
||||
Decompress\.
|
||||
.TP
|
||||
\fB\-t\fR, \fB\-\-test\fR
|
||||
Test the integrity of compressed \fIfiles\fR\. This option is equivalent to \fB\-\-decompress \-\-stdout > /dev/null\fR, decompressed data is discarded and checksummed for errors\. No files are created or removed\.
|
||||
.TP
|
||||
\fB\-b#\fR
|
||||
Benchmark file(s) using compression level \fI#\fR\. See \fIBENCHMARK\fR below for a description of this operation\.
|
||||
.TP
|
||||
\fB\-\-train FILES\fR
|
||||
Use \fIFILES\fR as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. See \fIDICTIONARY BUILDER\fR below for a description of this operation\.
|
||||
.TP
|
||||
\fB\-l\fR, \fB\-\-list\fR
|
||||
Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command's output can be augmented with the \fB\-v\fR modifier\.
|
||||
.SS "Operation Modifiers"
|
||||
.IP "\(bu" 4
|
||||
\fB\-#\fR: selects \fB#\fR compression level [1\-19] (default: 3)\. Higher compression levels \fIgenerally\fR produce higher compression ratio at the expense of speed and memory\. A rough rule of thumb is that compression speed is expected to be divided by 2 every 2 levels\. Technically, each level is mapped to a set of advanced parameters (that can also be modified individually, see below)\. Because the compressor's behavior highly depends on the content to compress, there's no guarantee of a smooth progression from one level to another\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\.
|
||||
.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\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-single\-thread\fR: Use a single thread for both I/O and compression\. As compression is serialized with I/O, this can be slightly slower\. Single\-thread mode features significantly lower memory usage, which can be useful for systems with limited amount of memory, such as 32\-bit systems\.
|
||||
.IP
|
||||
Note 1: this mode is the only available one when multithread support is disabled\.
|
||||
.IP
|
||||
Note 2: this mode is different from \fB\-T1\fR, which spawns 1 compression thread in parallel with I/O\. Final compressed result is also slightly different from \fB\-T1\fR\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-adapt[=min=#,max=#]\fR: \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MiB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\.
|
||||
.IP
|
||||
\fINote\fR: at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\.
|
||||
.IP
|
||||
Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s)
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd's diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that \fIwindowSize\fR > \fIsrcSize\fR\.
|
||||
.IP
|
||||
Note: cannot use both this and \fB\-D\fR together\.
|
||||
.IP
|
||||
Note: \fB\-\-long\fR mode will be automatically activated if \fIchainLog\fR < \fIfileLog\fR (\fIfileLog\fR being the \fIwindowLog\fR required to cover the whole file)\. You can also manually force it\.
|
||||
.IP
|
||||
Note: up to level 15, you can use \fB\-\-patch\-from\fR in \fB\-\-single\-thread\fR mode to improve compression ratio marginally at the cost of speed\. Using '\-\-single\-thread' above level 15 will lead to lower compression ratios\.
|
||||
.IP
|
||||
Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e\. 4096), and by setting a large \fB\-\-zstd=chainLog=\fR\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-rsyncable\fR: \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and a potential impact to compression speed, perceptible at higher speeds, for example when combining \fB\-\-rsyncable\fR with many parallel worker threads\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don't want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your mileage may vary\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled)
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \fB\-\-content\-size\fR (meaning that the original size will be placed in the header)\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won't be able to check if it's correct\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, \fBzstd\fR uses 128 MiB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (i\.e\. you can increase or decrease it)\.
|
||||
.IP
|
||||
This is also used during compression when using with \fB\-\-patch\-from=\fR\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MiB)\.
|
||||
.IP
|
||||
Additionally, this can be used to limit memory for dictionary training\. This parameter overrides the default limit of 2 GiB\. zstd will load training samples up to the memory limit and ignore the rest\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-stream\-size=#\fR: Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-target\-compressed\-block\-size=#\fR: Attempt to produce compressed blocks of approximately this size\. This will split larger blocks in order to approach this target\. This feature is notably useful for improved latency, when the receiver can leverage receiving early incomplete data\. This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller\. Enabling this feature can decrease compression speed by up to ~10% at level 1\. Higher levels will see smaller relative speed regression, becoming invisible at higher settings\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. During decompression and when the output destination is stdout, pass\-through unrecognized formats as\-is\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-c\fR, \fB\-\-stdout\fR: write to standard output (even if it is the console); keep original files (disable \fB\-\-rm\fR)\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-o FILE\fR: save result into \fBFILE\fR\. Note that this operation is in conflict with \fB\-c\fR\. If both operations are present on the command line, the last expressed one wins\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-[no\-]pass\-through\fR enable / disable passing through uncompressed files as\-is\. During decompression when pass\-through is enabled, unrecognized formats will be copied as\-is from the input to the output\. By default, pass\-through will occur when the output destination is stdout and the force (\fB\-f\fR) option is set\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. This command is silently ignored if output is \fBstdout\fR\. If used in combination with \fB\-o\fR, triggers a confirmation prompt (which can be silenced with \fB\-f\fR), as this is a destructive operation\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-r\fR: operate recursively on directories\. It selects all files in the named directory and all its subdirectories\. This can be useful both to reduce command line typing, and to circumvent shell expansion limitations, when there are a lot of files and naming breaks the maximum size of a command line\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-filelist FILE\fR read a list of files to process as content from \fBFILE\fR\. Format is compatible with \fBls\fR output, with one file per line\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-output\-dir\-flat DIR\fR: resulting files are stored into target \fBDIR\fR directory, instead of same directory as origin file\. Be aware that this command can introduce name collision issues, if multiple files, from different directories, end up having the same name\. Collision resolution ensures first file with a given name will be present in \fBDIR\fR, while in combination with \fB\-f\fR, the last file will be present instead\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-output\-dir\-mirror DIR\fR: similar to \fB\-\-output\-dir\-flat\fR, the output files are stored underneath target \fBDIR\fR directory, but this option will replicate input directory hierarchy into output \fBDIR\fR\.
|
||||
.IP
|
||||
If input directory contains "\.\.", the files in this directory will be ignored\. If input directory is an absolute directory (i\.e\. "/var/tmp/abc"), it will be stored into the "output\-dir/var/tmp/abc"\. If there are multiple input files or directories, name collision resolution will follow the same rules as \fB\-\-output\-dir\-flat\fR\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-format=FORMAT\fR: compress and decompress in other formats\. If compiled with support, zstd can compress to or decompress from other compression algorithm formats\. Possibly available options are \fBzstd\fR, \fBgzip\fR, \fBxz\fR, \fBlzma\fR, and \fBlz4\fR\. If no such format is provided, \fBzstd\fR is the default\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit
|
||||
.IP "\(bu" 4
|
||||
\fB\-V\fR, \fB\-\-version\fR: display version number and immediately exit\. note that, since it exits, flags specified after \fB\-V\fR are effectively ignored\. Advanced: \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-qV\fR will only display the version number, suitable for machine reading\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information
|
||||
.IP "\(bu" 4
|
||||
\fB\-q\fR, \fB\-\-quiet\fR: suppress warnings, interactivity, and notifications\. specify twice to suppress errors too\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-show\-default\-cparams\fR: shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size\. If the provided file is not a regular file (e\.g\. a pipe), this flag will output the parameters used for inputs of unknown size\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-exclude\-compressed\fR: only compress files that are not already compressed\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files
|
||||
.IP "" 0
|
||||
.SS "gzip Operation Modifiers"
|
||||
When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior:
|
||||
.TP
|
||||
\fB\-n\fR, \fB\-\-no\-name\fR
|
||||
do not store the original filename and timestamps when compressing a file\. This is the default behavior and hence a no\-op\.
|
||||
.TP
|
||||
\fB\-\-best\fR
|
||||
alias to the option \fB\-9\fR\.
|
||||
.SS "Environment Variables"
|
||||
Employing environment variables to set parameters has security implications\. Therefore, this avenue is intentionally limited\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the default compression level and number of threads to use during compression, respectively\.
|
||||
.P
|
||||
\fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\.
|
||||
.P
|
||||
\fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of (\fB1\fR), and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this variable to have any effect\.
|
||||
.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\.
|
||||
.SH "ADVANCED COMPRESSION OPTIONS"
|
||||
\fBzstd\fR provides 22 predefined regular compression levels plus the fast levels\. A compression level is translated internally into multiple advanced parameters that control the behavior of the compressor (one can observe the result of this translation with \fB\-\-show\-default\-cparams\fR)\. These advanced parameters can be overridden using advanced compression options\.
|
||||
.SS "\-\-zstd[=options]:"
|
||||
The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR:
|
||||
.TP
|
||||
\fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR
|
||||
Specify a strategy used by a match finder\.
|
||||
.IP
|
||||
There are 9 strategies numbered from 1 to 9, from fastest to strongest: 1=\fBZSTD_fast\fR, 2=\fBZSTD_dfast\fR, 3=\fBZSTD_greedy\fR, 4=\fBZSTD_lazy\fR, 5=\fBZSTD_lazy2\fR, 6=\fBZSTD_btlazy2\fR, 7=\fBZSTD_btopt\fR, 8=\fBZSTD_btultra\fR, 9=\fBZSTD_btultra2\fR\.
|
||||
.TP
|
||||
\fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR
|
||||
Specify the maximum number of bits for a match distance\.
|
||||
.IP
|
||||
The higher number of increases the chance to find a match which usually improves compression ratio\. It also increases memory requirements for the compressor and decompressor\. The minimum \fIwlog\fR is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32\-bit platforms and 31 (2 GiB) on 64\-bit platforms\.
|
||||
.IP
|
||||
Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\.
|
||||
.TP
|
||||
\fBhashLog\fR=\fIhlog\fR, \fBhlog\fR=\fIhlog\fR
|
||||
Specify the maximum number of bits for a hash table\.
|
||||
.IP
|
||||
Bigger hash tables cause fewer collisions which usually makes compression faster, but requires more memory during compression\.
|
||||
.IP
|
||||
The minimum \fIhlog\fR is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB)\.
|
||||
.TP
|
||||
\fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR
|
||||
Specify the maximum number of bits for the secondary search structure, whose form depends on the selected \fBstrategy\fR\.
|
||||
.IP
|
||||
Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the \fBZSTD_fast\fR \fBstrategy\fR, which only has the primary hash table\.
|
||||
.IP
|
||||
The minimum \fIclog\fR is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32\-bit platforms and 30 (1B entries / 4 GiB) on 64\-bit platforms\.
|
||||
.TP
|
||||
\fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR
|
||||
Specify the maximum number of searches in a hash chain or a binary tree using logarithmic scale\.
|
||||
.IP
|
||||
More searches increases the chance to find a match which usually increases compression ratio but decreases compression speed\.
|
||||
.IP
|
||||
The minimum \fIslog\fR is 1 and the maximum is 'windowLog' \- 1\.
|
||||
.TP
|
||||
\fBminMatch\fR=\fImml\fR, \fBmml\fR=\fImml\fR
|
||||
Specify the minimum searched length of a match in a hash table\.
|
||||
.IP
|
||||
Larger search lengths usually decrease compression ratio but improve decompression speed\.
|
||||
.IP
|
||||
The minimum \fImml\fR is 3 and the maximum is 7\.
|
||||
.TP
|
||||
\fBtargetLength\fR=\fItlen\fR, \fBtlen\fR=\fItlen\fR
|
||||
The impact of this field vary depending on selected strategy\.
|
||||
.IP
|
||||
For \fBZSTD_btopt\fR, \fBZSTD_btultra\fR and \fBZSTD_btultra2\fR, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\.
|
||||
.IP
|
||||
For \fBZSTD_fast\fR, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed: a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\.
|
||||
.IP
|
||||
For all other strategies, this field has no impact\.
|
||||
.IP
|
||||
The minimum \fItlen\fR is 0 and the maximum is 128 KiB\.
|
||||
.TP
|
||||
\fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR
|
||||
Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\.
|
||||
.IP
|
||||
The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default": \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\.
|
||||
.TP
|
||||
\fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR
|
||||
Specify the maximum size for a hash table used for long distance matching\.
|
||||
.IP
|
||||
This option is ignored unless long distance matching is enabled\.
|
||||
.IP
|
||||
Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\.
|
||||
.IP
|
||||
The minimum \fIlhlog\fR is 6 and the maximum is 30 (default: 20)\.
|
||||
.TP
|
||||
\fBldmMinMatch\fR=\fIlmml\fR, \fBlmml\fR=\fIlmml\fR
|
||||
Specify the minimum searched length of a match for long distance matching\.
|
||||
.IP
|
||||
This option is ignored unless long distance matching is enabled\.
|
||||
.IP
|
||||
Larger/very small values usually decrease compression ratio\.
|
||||
.IP
|
||||
The minimum \fIlmml\fR is 4 and the maximum is 4096 (default: 64)\.
|
||||
.TP
|
||||
\fBldmBucketSizeLog\fR=\fIlblog\fR, \fBlblog\fR=\fIlblog\fR
|
||||
Specify the size of each bucket for the hash table used for long distance matching\.
|
||||
.IP
|
||||
This option is ignored unless long distance matching is enabled\.
|
||||
.IP
|
||||
Larger bucket sizes improve collision resolution but decrease compression speed\.
|
||||
.IP
|
||||
The minimum \fIlblog\fR is 1 and the maximum is 8 (default: 3)\.
|
||||
.TP
|
||||
\fBldmHashRateLog\fR=\fIlhrlog\fR, \fBlhrlog\fR=\fIlhrlog\fR
|
||||
Specify the frequency of inserting entries into the long distance matching hash table\.
|
||||
.IP
|
||||
This option is ignored unless long distance matching is enabled\.
|
||||
.IP
|
||||
Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\.
|
||||
.IP
|
||||
The default value is \fBwlog \- lhlog\fR\.
|
||||
.SS "Example"
|
||||
The following parameters sets advanced compression options to something similar to predefined level 19 for files bigger than 256 KB:
|
||||
.P
|
||||
\fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6
|
||||
.SS "\-B#:"
|
||||
Specify the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to non\-identical compressed frames\.
|
||||
.SH "DICTIONARY BUILDER"
|
||||
\fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It's possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then, during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\.
|
||||
.TP
|
||||
\fB\-\-train FILEs\fR
|
||||
Use FILEs as training set to create a dictionary\. The training set should ideally contain a lot of samples (> 100), and weight typically 100x the target dictionary size (for example, ~10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\.
|
||||
.IP
|
||||
Since dictionary compression is mostly effective for small files, the expectation is that the training set will only contain small files\. In the case where some samples happen to be large, only the first 128 KiB of these samples will be used for training\.
|
||||
.IP
|
||||
\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional advanced parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default \fB\-\-train\fR is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\.
|
||||
.TP
|
||||
\fB\-o FILE\fR
|
||||
Dictionary saved into \fBFILE\fR (default name: dictionary)\.
|
||||
.TP
|
||||
\fB\-\-maxdict=#\fR
|
||||
Limit dictionary to specified size (default: 112640 bytes)\. As usual, quantities are expressed in bytes by default, and it's possible to employ suffixes (like \fBKB\fR or \fBMB\fR) to specify larger values\.
|
||||
.TP
|
||||
\fB\-#\fR
|
||||
Use \fB#\fR compression level during training (optional)\. Will generate statistics more tuned for selected compression level, resulting in a \fIsmall\fR compression ratio improvement for this level\.
|
||||
.TP
|
||||
\fB\-B#\fR
|
||||
Split input files into blocks of size # (default: no split)
|
||||
.TP
|
||||
\fB\-M#\fR, \fB\-\-memory=#\fR
|
||||
Limit the amount of sample data loaded for training (default: 2 GB)\. Note that the default (2 GB) is also the maximum\. This parameter can be useful in situations where the training set size is not well controlled and could be potentially very large\. Since speed of the training process is directly correlated to the size of the training sample set, a smaller sample set leads to faster training\.
|
||||
.IP
|
||||
In situations where the training set is larger than maximum memory, the CLI will randomly select samples among the available ones, up to the maximum allowed memory budget\. This is meant to improve dictionary relevance by mitigating the potential impact of clustering, such as selecting only files from the beginning of a list sorted by modification date, or sorted by alphabetical order\. The randomization process is deterministic, so training of the same list of files with the same parameters will lead to the creation of the same dictionary\.
|
||||
.TP
|
||||
\fB\-\-dictID=#\fR
|
||||
A dictionary ID is a locally unique ID\. The decoder will use this value to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It's possible to provide an explicit number ID instead\. It's up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. Note that short numbers have an advantage: an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\.
|
||||
.IP
|
||||
Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2\e^31, so they should not be used in public\.
|
||||
.TP
|
||||
\fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR
|
||||
Select parameters for the default dictionary builder algorithm named cover\. If \fId\fR is not specified, then it tries \fId\fR = 6 and \fId\fR = 8\. If \fIk\fR is not specified, then it tries \fIsteps\fR values in the range [50, 2000]\. If \fIsteps\fR is not specified, then the default value of 40 is used\. If \fIsplit\fR is not specified or split <= 0, then the default value of 100 is used\. Requires that \fId\fR <= \fIk\fR\. If \fIshrink\fR flag is not used, then the default value for \fIshrinkDict\fR of 0 is used\. If \fIshrink\fR is not specified, then the default value for \fIshrinkDictMaxRegression\fR of 1 is used\.
|
||||
.IP
|
||||
Selects segments of size \fIk\fR with highest score to put in the dictionary\. The score of a segment is computed by the sum of the frequencies of all the subsegments of size \fId\fR\. Generally \fId\fR should be in the range [6, 8], occasionally up to 16, but the algorithm will run faster with d <= \fI8\fR\. Good values for \fIk\fR vary widely based on the input data, but a safe range is [2 * \fId\fR, 2000]\. If \fIsplit\fR is 100, all input samples are used for both training and testing to find optimal \fId\fR and \fIk\fR to build dictionary\. Supports multithreading if \fBzstd\fR is compiled with threading support\. Having \fIshrink\fR enabled takes a truncated dictionary of minimum size and doubles in size until compression ratio of the truncated dictionary is at most \fIshrinkDictMaxRegression%\fR worse than the compression ratio of the largest dictionary\.
|
||||
.IP
|
||||
Examples:
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover=k=50,d=8 FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover=d=8,steps=500 FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover=k=50 FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover=k=50,split=60 FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover=shrink FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-cover=shrink=2 FILEs\fR
|
||||
.TP
|
||||
\fB\-\-train\-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]\fR
|
||||
Same as cover but with extra parameters \fIf\fR and \fIaccel\fR and different default value of split If \fIsplit\fR is not specified, then it tries \fIsplit\fR = 75\. If \fIf\fR is not specified, then it tries \fIf\fR = 20\. Requires that 0 < \fIf\fR < 32\. If \fIaccel\fR is not specified, then it tries \fIaccel\fR = 1\. Requires that 0 < \fIaccel\fR <= 10\. Requires that \fId\fR = 6 or \fId\fR = 8\.
|
||||
.IP
|
||||
\fIf\fR is log of size of array that keeps track of frequency of subsegments of size \fId\fR\. The subsegment is hashed to an index in the range [0,2^\fIf\fR \- 1]\. It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency\. Using a higher \fIf\fR reduces collision but takes longer\.
|
||||
.IP
|
||||
Examples:
|
||||
.IP
|
||||
\fBzstd \-\-train\-fastcover FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-fastcover=d=8,f=15,accel=2 FILEs\fR
|
||||
.TP
|
||||
\fB\-\-train\-legacy[=selectivity=#]\fR
|
||||
Use legacy dictionary builder algorithm with the given dictionary \fIselectivity\fR (default: 9)\. The smaller the \fIselectivity\fR value, the denser the dictionary, improving its efficiency but reducing its achievable maximum size\. \fB\-\-train\-legacy=s=#\fR is also accepted\.
|
||||
.IP
|
||||
Examples:
|
||||
.IP
|
||||
\fBzstd \-\-train\-legacy FILEs\fR
|
||||
.IP
|
||||
\fBzstd \-\-train\-legacy=selectivity=8 FILEs\fR
|
||||
.SH "BENCHMARK"
|
||||
The \fBzstd\fR CLI provides a benchmarking mode that can be used to easily find suitable compression parameters, or alternatively to benchmark a computer's performance\. \fBzstd \-b [FILE(s)]\fR will benchmark \fBzstd\fR for both compression and decompression using default compression level\. Note that results are very dependent on the content being compressed\. It's possible to pass multiple files to the benchmark, and even a directory with \fB\-r DIRECTORY\fR\. When no \fBFILE\fR is provided, the benchmark will use a procedurally generated \fBlorem ipsum\fR text\.
|
||||
.IP "\(bu" 4
|
||||
\fB\-b#\fR: benchmark file(s) using compression level #
|
||||
.IP "\(bu" 4
|
||||
\fB\-e#\fR: benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\fR (inclusive)
|
||||
.IP "\(bu" 4
|
||||
\fB\-d\fR: benchmark decompression speed only (requires providing a zstd\-compressed content)
|
||||
.IP "\(bu" 4
|
||||
\fB\-i#\fR: minimum evaluation time, in seconds (default: 3s), benchmark mode only
|
||||
.IP "\(bu" 4
|
||||
\fB\-B#\fR, \fB\-\-block\-size=#\fR: cut file(s) into independent chunks of size # (default: no chunking)
|
||||
.IP "\(bu" 4
|
||||
\fB\-S\fR: output one benchmark result per input file (default: consolidated result)
|
||||
.IP "\(bu" 4
|
||||
\fB\-D dictionary\fR benchmark using dictionary
|
||||
.IP "\(bu" 4
|
||||
\fB\-\-priority=rt\fR: set process priority to real\-time (Windows)
|
||||
.IP "" 0
|
||||
.P
|
||||
Beyond compression levels, benchmarking is also compatible with other parameters, such as number of threads (\fB\-T#\fR), advanced compression parameters (\fB\-\-zstd=###\fR), dictionary compression (\fB\-D dictionary\fR), or even disabling checksum verification for example\.
|
||||
.P
|
||||
\fBOutput Format:\fR CompressionLevel#Filename: InputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed
|
||||
.P
|
||||
\fBMethodology:\fR For speed measurement, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\.
|
||||
.SH "SEE ALSO"
|
||||
\fBzstdgrep\fR(1), \fBzstdless\fR(1), \fBgzip\fR(1), \fBxz\fR(1)
|
||||
.P
|
||||
The \fIzstandard\fR format is specified in Y\. Collet, "Zstandard Compression and the 'application/zstd' Media Type", https://www\.ietf\.org/rfc/rfc8878\.txt, Internet RFC 8878 (February 2021)\.
|
||||
.SH "BUGS"
|
||||
Report bugs at: https://github\.com/facebook/zstd/issues
|
||||
.SH "AUTHOR"
|
||||
Yann Collet
|
714
build_amd64/_deps/zstd-src/programs/zstd.1.md
Normal file
714
build_amd64/_deps/zstd-src/programs/zstd.1.md
Normal file
@@ -0,0 +1,714 @@
|
||||
zstd(1) -- zstd, zstdmt, unzstd, zstdcat - Compress or decompress .zst files
|
||||
============================================================================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
`zstd` [<OPTIONS>] [-|<INPUT-FILE>] [-o <OUTPUT-FILE>]
|
||||
|
||||
`zstdmt` is equivalent to `zstd -T0`
|
||||
|
||||
`unzstd` is equivalent to `zstd -d`
|
||||
|
||||
`zstdcat` is equivalent to `zstd -dcf`
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
`zstd` is a fast lossless compression algorithm and data compression tool,
|
||||
with command line syntax similar to `gzip`(1) and `xz`(1).
|
||||
It is based on the **LZ77** family, with further FSE & huff0 entropy stages.
|
||||
`zstd` offers highly configurable compression speed,
|
||||
from fast modes at > 200 MB/s per core,
|
||||
to strong modes with excellent compression ratios.
|
||||
It also features a very fast decoder, with speeds > 500 MB/s per core,
|
||||
which remains roughly stable at all compression settings.
|
||||
|
||||
`zstd` command line syntax is generally similar to gzip,
|
||||
but features the following few differences:
|
||||
|
||||
- Source files are preserved by default.
|
||||
It's possible to remove them automatically by using the `--rm` command.
|
||||
- When compressing a single file, `zstd` displays progress notifications
|
||||
and result summary by default.
|
||||
Use `-q` to turn them off.
|
||||
- `zstd` displays a short help page when command line is an error.
|
||||
Use `-q` to turn it off.
|
||||
- `zstd` does not accept input from console,
|
||||
though it does accept `stdin` when it's not the console.
|
||||
- `zstd` does not store the input's filename or attributes, only its contents.
|
||||
|
||||
`zstd` processes each _file_ according to the selected operation mode.
|
||||
If no _files_ are given or _file_ is `-`, `zstd` reads from standard input
|
||||
and writes the processed data to standard output.
|
||||
`zstd` will refuse to write compressed data to standard output
|
||||
if it is a terminal: it will display an error message and skip the file.
|
||||
Similarly, `zstd` will refuse to read compressed data from standard input
|
||||
if it is a terminal.
|
||||
|
||||
Unless `--stdout` or `-o` is specified, _files_ are written to a new file
|
||||
whose name is derived from the source _file_ name:
|
||||
|
||||
* When compressing, the suffix `.zst` is appended to the source filename to
|
||||
get the target filename.
|
||||
* When decompressing, the `.zst` suffix is removed from the source filename to
|
||||
get the target filename
|
||||
|
||||
### Concatenation with .zst Files
|
||||
It is possible to concatenate multiple `.zst` files. `zstd` will decompress
|
||||
such agglomerated file as if it was a single `.zst` file.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
|
||||
### Integer Suffixes and Special Values
|
||||
|
||||
In most places where an integer argument is expected,
|
||||
an optional suffix is supported to easily indicate large integers.
|
||||
There must be no space between the integer and the suffix.
|
||||
|
||||
* `KiB`:
|
||||
Multiply the integer by 1,024 (2\^10).
|
||||
`Ki`, `K`, and `KB` are accepted as synonyms for `KiB`.
|
||||
* `MiB`:
|
||||
Multiply the integer by 1,048,576 (2\^20).
|
||||
`Mi`, `M`, and `MB` are accepted as synonyms for `MiB`.
|
||||
|
||||
### Operation Mode
|
||||
|
||||
If multiple operation mode options are given,
|
||||
the last one takes effect.
|
||||
|
||||
* `-z`, `--compress`:
|
||||
Compress.
|
||||
This is the default operation mode when no operation mode option is specified
|
||||
and no other operation mode is implied from the command name
|
||||
(for example, `unzstd` implies `--decompress`).
|
||||
* `-d`, `--decompress`, `--uncompress`:
|
||||
Decompress.
|
||||
* `-t`, `--test`:
|
||||
Test the integrity of compressed _files_.
|
||||
This option is equivalent to `--decompress --stdout > /dev/null`,
|
||||
decompressed data is discarded and checksummed for errors.
|
||||
No files are created or removed.
|
||||
* `-b#`:
|
||||
Benchmark file(s) using compression level _#_.
|
||||
See _BENCHMARK_ below for a description of this operation.
|
||||
* `--train FILES`:
|
||||
Use _FILES_ as a training set to create a dictionary.
|
||||
The training set should contain a lot of small files (> 100).
|
||||
See _DICTIONARY BUILDER_ below for a description of this operation.
|
||||
* `-l`, `--list`:
|
||||
Display information related to a zstd compressed file, such as size, ratio, and checksum.
|
||||
Some of these fields may not be available.
|
||||
This command's output can be augmented with the `-v` modifier.
|
||||
|
||||
### Operation Modifiers
|
||||
|
||||
* `-#`:
|
||||
selects `#` compression level \[1-19\] (default: 3).
|
||||
Higher compression levels *generally* produce higher compression ratio at the expense of speed and memory.
|
||||
A rough rule of thumb is that compression speed is expected to be divided by 2 every 2 levels.
|
||||
Technically, each level is mapped to a set of advanced parameters (that can also be modified individually, see below).
|
||||
Because the compressor's behavior highly depends on the content to compress, there's no guarantee of a smooth progression from one level to another.
|
||||
* `--ultra`:
|
||||
unlocks high compression levels 20+ (maximum 22), using a lot more memory.
|
||||
Note that decompression will also require more memory when using these levels.
|
||||
* `--fast[=#]`:
|
||||
switch to ultra-fast compression levels.
|
||||
If `=#` is not present, it defaults to `1`.
|
||||
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 `--fast`, it overrides it.
|
||||
* `-T#`, `--threads=#`:
|
||||
Compress using `#` working threads (default: 1).
|
||||
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`,
|
||||
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.
|
||||
* `--single-thread`:
|
||||
Use a single thread for both I/O and compression.
|
||||
As compression is serialized with I/O, this can be slightly slower.
|
||||
Single-thread mode features significantly lower memory usage,
|
||||
which can be useful for systems with limited amount of memory, such as 32-bit systems.
|
||||
|
||||
Note 1: this mode is the only available one when multithread support is disabled.
|
||||
|
||||
Note 2: this mode is different from `-T1`, which spawns 1 compression thread in parallel with I/O.
|
||||
Final compressed result is also slightly different from `-T1`.
|
||||
* `--auto-threads={physical,logical} (default: physical)`:
|
||||
When using a default amount of threads via `-T0`, choose the default based on the number
|
||||
of detected physical or logical cores.
|
||||
* `--adapt[=min=#,max=#]`:
|
||||
`zstd` will dynamically adapt compression level to perceived I/O conditions.
|
||||
Compression level adaptation can be observed live by using command `-v`.
|
||||
Adaptation can be constrained between supplied `min` and `max` levels.
|
||||
The feature works when combined with multi-threading and `--long` mode.
|
||||
It does not work with `--single-thread`.
|
||||
It sets window size to 8 MiB by default (can be changed manually, see `wlog`).
|
||||
Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible.
|
||||
|
||||
_Note_: at the time of this writing, `--adapt` can remain stuck at low speed
|
||||
when combined with multiple worker threads (>=2).
|
||||
* `--long[=#]`:
|
||||
enables long distance matching with `#` `windowLog`, if `#` is not
|
||||
present it defaults to `27`.
|
||||
This increases the window size (`windowLog`) and memory usage for both the
|
||||
compressor and decompressor.
|
||||
This setting is designed to improve the compression ratio for files with
|
||||
long matches at a large distance.
|
||||
|
||||
Note: If `windowLog` is set to larger than 27, `--long=windowLog` or
|
||||
`--memory=windowSize` needs to be passed to the decompressor.
|
||||
* `--max`:
|
||||
set advanced parameters to maximum compression.
|
||||
warning: this setting is very slow and uses a lot of resources.
|
||||
It's inappropriate for 32-bit mode and therefore disabled in this mode.
|
||||
* `-D DICT`:
|
||||
use `DICT` as Dictionary to compress or decompress FILE(s)
|
||||
* `--patch-from FILE`:
|
||||
Specify the file to be used as a reference point for zstd's diff engine.
|
||||
This is effectively dictionary compression with some convenient parameter
|
||||
selection, namely that _windowSize_ > _srcSize_.
|
||||
|
||||
Note: cannot use both this and `-D` together.
|
||||
|
||||
Note: `--long` mode will be automatically activated if _chainLog_ < _fileLog_
|
||||
(_fileLog_ being the _windowLog_ required to cover the whole file). You
|
||||
can also manually force it.
|
||||
|
||||
Note: up to level 15, you can use `--patch-from` in `--single-thread` mode
|
||||
to improve compression ratio marginally at the cost of speed. Using
|
||||
'--single-thread' above level 15 will lead to lower compression
|
||||
ratios.
|
||||
|
||||
Note: for level 19, you can get increased compression ratio at the cost
|
||||
of speed by specifying `--zstd=targetLength=` to be something large
|
||||
(i.e. 4096), and by setting a large `--zstd=chainLog=`.
|
||||
* `--rsyncable`:
|
||||
`zstd` will periodically synchronize the compression state to make the
|
||||
compressed file more rsync-friendly.
|
||||
There is a negligible impact to compression ratio,
|
||||
and a potential impact to compression speed, perceptible at higher speeds,
|
||||
for example when combining `--rsyncable` with many parallel worker threads.
|
||||
This feature does not work with `--single-thread`. You probably don't want
|
||||
to use it with long range mode, since it will decrease the effectiveness of
|
||||
the synchronization points, but your mileage may vary.
|
||||
* `-C`, `--[no-]check`:
|
||||
add integrity check computed from uncompressed data (default: enabled)
|
||||
* `--[no-]content-size`:
|
||||
enable / disable whether or not the original size of the file is placed in
|
||||
the header of the compressed file. The default option is
|
||||
`--content-size` (meaning that the original size will be placed in the header).
|
||||
* `--no-dictID`:
|
||||
do not store dictionary ID within frame header (dictionary compression).
|
||||
The decoder will have to rely on implicit knowledge about which dictionary to use,
|
||||
it won't be able to check if it's correct.
|
||||
* `-M#`, `--memory=#`:
|
||||
Set a memory usage limit. By default, `zstd` uses 128 MiB for decompression
|
||||
as the maximum amount of memory the decompressor is allowed to use, but you can
|
||||
override this manually if need be in either direction (i.e. you can increase or
|
||||
decrease it).
|
||||
|
||||
This is also used during compression when using with `--patch-from=`. In this case,
|
||||
this parameter overrides that maximum size allowed for a dictionary. (128 MiB).
|
||||
|
||||
Additionally, this can be used to limit memory for dictionary training. This parameter
|
||||
overrides the default limit of 2 GiB. zstd will load training samples up to the memory limit
|
||||
and ignore the rest.
|
||||
* `--stream-size=#`:
|
||||
Sets the pledged source size of input coming from a stream. This value must be exact, as it
|
||||
will be included in the produced frame header. Incorrect stream sizes will cause an error.
|
||||
This information will be used to better optimize compression parameters, resulting in
|
||||
better and potentially faster compression, especially for smaller source sizes.
|
||||
* `--size-hint=#`:
|
||||
When handling input from a stream, `zstd` must guess how large the source size
|
||||
will be when optimizing compression parameters. If the stream size is relatively
|
||||
small, this guess may be a poor one, resulting in a higher compression ratio than
|
||||
expected. This feature allows for controlling the guess when needed.
|
||||
Exact guesses result in better compression ratios. Overestimates result in slightly
|
||||
degraded compression ratios, while underestimates may result in significant degradation.
|
||||
* `--target-compressed-block-size=#`:
|
||||
Attempt to produce compressed blocks of approximately this size.
|
||||
This will split larger blocks in order to approach this target.
|
||||
This feature is notably useful for improved latency, when the receiver can leverage receiving early incomplete data.
|
||||
This parameter defines a loose target: compressed blocks will target this size "on average", but individual blocks can still be larger or smaller.
|
||||
Enabling this feature can decrease compression speed by up to ~10% at level 1.
|
||||
Higher levels will see smaller relative speed regression, becoming invisible at higher settings.
|
||||
* `-f`, `--force`:
|
||||
disable input and output checks. Allows overwriting existing files, input
|
||||
from console, output to stdout, operating on links, block devices, etc.
|
||||
During decompression and when the output destination is stdout, pass-through
|
||||
unrecognized formats as-is.
|
||||
* `-c`, `--stdout`:
|
||||
write to standard output (even if it is the console); keep original files (disable `--rm`).
|
||||
* `-o FILE`:
|
||||
save result into `FILE`.
|
||||
Note that this operation is in conflict with `-c`.
|
||||
If both operations are present on the command line, the last expressed one wins.
|
||||
* `--[no-]sparse`:
|
||||
enable / disable sparse FS support,
|
||||
to make files with many zeroes smaller on disk.
|
||||
Creating sparse files may save disk space and speed up decompression by
|
||||
reducing the amount of disk I/O.
|
||||
default: enabled when output is into a file,
|
||||
and disabled when output is stdout.
|
||||
This setting overrides default and can force sparse mode over stdout.
|
||||
* `--[no-]pass-through`
|
||||
enable / disable passing through uncompressed files as-is. During
|
||||
decompression when pass-through is enabled, unrecognized formats will be
|
||||
copied as-is from the input to the output. By default, pass-through will
|
||||
occur when the output destination is stdout and the force (`-f`) option is
|
||||
set.
|
||||
* `--rm`:
|
||||
remove source file(s) after successful compression or decompression.
|
||||
This command is silently ignored if output is `stdout`.
|
||||
If used in combination with `-o`,
|
||||
triggers a confirmation prompt (which can be silenced with `-f`), as this is a destructive operation.
|
||||
* `-k`, `--keep`:
|
||||
keep source file(s) after successful compression or decompression.
|
||||
This is the default behavior.
|
||||
* `-r`:
|
||||
operate recursively on directories.
|
||||
It selects all files in the named directory and all its subdirectories.
|
||||
This can be useful both to reduce command line typing,
|
||||
and to circumvent shell expansion limitations,
|
||||
when there are a lot of files and naming breaks the maximum size of a command line.
|
||||
* `--filelist FILE`
|
||||
read a list of files to process as content from `FILE`.
|
||||
Format is compatible with `ls` output, with one file per line.
|
||||
* `--output-dir-flat DIR`:
|
||||
resulting files are stored into target `DIR` directory,
|
||||
instead of same directory as origin file.
|
||||
Be aware that this command can introduce name collision issues,
|
||||
if multiple files, from different directories, end up having the same name.
|
||||
Collision resolution ensures first file with a given name will be present in `DIR`,
|
||||
while in combination with `-f`, the last file will be present instead.
|
||||
* `--output-dir-mirror DIR`:
|
||||
similar to `--output-dir-flat`,
|
||||
the output files are stored underneath target `DIR` directory,
|
||||
but this option will replicate input directory hierarchy into output `DIR`.
|
||||
|
||||
If input directory contains "..", the files in this directory will be ignored.
|
||||
If input directory is an absolute directory (i.e. "/var/tmp/abc"),
|
||||
it will be stored into the "output-dir/var/tmp/abc".
|
||||
If there are multiple input files or directories,
|
||||
name collision resolution will follow the same rules as `--output-dir-flat`.
|
||||
* `--format=FORMAT`:
|
||||
compress and decompress in other formats. If compiled with
|
||||
support, zstd can compress to or decompress from other compression algorithm
|
||||
formats. Possibly available options are `zstd`, `gzip`, `xz`, `lzma`, and `lz4`.
|
||||
If no such format is provided, `zstd` is the default.
|
||||
* `-h`/`-H`, `--help`:
|
||||
display help/long help and exit
|
||||
* `-V`, `--version`:
|
||||
display version number and immediately exit.
|
||||
note that, since it exits, flags specified after `-V` are effectively ignored.
|
||||
Advanced: `-vV` also displays supported formats.
|
||||
`-vvV` also displays POSIX support.
|
||||
`-qV` will only display the version number, suitable for machine reading.
|
||||
* `-v`, `--verbose`:
|
||||
verbose mode, display more information
|
||||
* `-q`, `--quiet`:
|
||||
suppress warnings, interactivity, and notifications.
|
||||
specify twice to suppress errors too.
|
||||
* `--no-progress`:
|
||||
do not display the progress bar, but keep all other messages.
|
||||
* `--show-default-cparams`:
|
||||
shows the default compression parameters that will be used for a particular input file, based on the provided compression level and the input size.
|
||||
If the provided file is not a regular file (e.g. a pipe), this flag will output the parameters used for inputs of unknown size.
|
||||
* `--exclude-compressed`:
|
||||
only compress files that are not already compressed.
|
||||
* `--`:
|
||||
All arguments after `--` are treated as files
|
||||
|
||||
|
||||
### gzip Operation Modifiers
|
||||
When invoked via a `gzip` symlink, `zstd` will support further
|
||||
options that intend to mimic the `gzip` behavior:
|
||||
|
||||
* `-n`, `--no-name`:
|
||||
do not store the original filename and timestamps when compressing
|
||||
a file. This is the default behavior and hence a no-op.
|
||||
* `--best`:
|
||||
alias to the option `-9`.
|
||||
|
||||
|
||||
### Environment Variables
|
||||
Employing environment variables to set parameters has security implications.
|
||||
Therefore, this avenue is intentionally limited.
|
||||
Only `ZSTD_CLEVEL` and `ZSTD_NBTHREADS` are currently supported.
|
||||
They set the default compression level and number of threads to use during compression, respectively.
|
||||
|
||||
`ZSTD_CLEVEL` can be used to set the level between 1 and 19 (the "normal" range).
|
||||
If the value of `ZSTD_CLEVEL` is not a valid integer, it will be ignored with a warning message.
|
||||
`ZSTD_CLEVEL` just replaces the default compression level (`3`).
|
||||
|
||||
`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.
|
||||
`ZSTD_NBTHREADS` has a default value of `max(1, min(4, nbCores/4))`, and is capped at ZSTDMT_NBWORKERS_MAX==200.
|
||||
`zstd` must be compiled with multithread support for this variable to have any effect.
|
||||
|
||||
They can both be overridden by corresponding command line arguments:
|
||||
`-#` for compression level and `-T#` for number of compression threads.
|
||||
|
||||
|
||||
ADVANCED COMPRESSION OPTIONS
|
||||
----------------------------
|
||||
`zstd` provides 22 predefined regular compression levels plus the fast levels.
|
||||
A compression level is translated internally into multiple advanced parameters that control the behavior of the compressor
|
||||
(one can observe the result of this translation with `--show-default-cparams`).
|
||||
These advanced parameters can be overridden using advanced compression options.
|
||||
|
||||
### --zstd[=options]:
|
||||
The _options_ 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 _options_:
|
||||
|
||||
- `strategy`=_strat_, `strat`=_strat_:
|
||||
Specify a strategy used by a match finder.
|
||||
|
||||
There are 9 strategies numbered from 1 to 9, from fastest to strongest:
|
||||
1=`ZSTD_fast`, 2=`ZSTD_dfast`, 3=`ZSTD_greedy`,
|
||||
4=`ZSTD_lazy`, 5=`ZSTD_lazy2`, 6=`ZSTD_btlazy2`,
|
||||
7=`ZSTD_btopt`, 8=`ZSTD_btultra`, 9=`ZSTD_btultra2`.
|
||||
|
||||
- `windowLog`=_wlog_, `wlog`=_wlog_:
|
||||
Specify the maximum number of bits for a match distance.
|
||||
|
||||
The higher number of increases the chance to find a match which usually
|
||||
improves compression ratio.
|
||||
It also increases memory requirements for the compressor and decompressor.
|
||||
The minimum _wlog_ is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32-bit
|
||||
platforms and 31 (2 GiB) on 64-bit platforms.
|
||||
|
||||
Note: If `windowLog` is set to larger than 27, `--long=windowLog` or
|
||||
`--memory=windowSize` needs to be passed to the decompressor.
|
||||
|
||||
- `hashLog`=_hlog_, `hlog`=_hlog_:
|
||||
Specify the maximum number of bits for a hash table.
|
||||
|
||||
Bigger hash tables cause fewer collisions which usually makes compression
|
||||
faster, but requires more memory during compression.
|
||||
|
||||
The minimum _hlog_ is 6 (64 entries / 256 B) and the maximum is 30 (1B entries / 4 GiB).
|
||||
|
||||
- `chainLog`=_clog_, `clog`=_clog_:
|
||||
Specify the maximum number of bits for the secondary search structure,
|
||||
whose form depends on the selected `strategy`.
|
||||
|
||||
Higher numbers of bits increases the chance to find a match which usually
|
||||
improves compression ratio.
|
||||
It also slows down compression speed and increases memory requirements for
|
||||
compression.
|
||||
This option is ignored for the `ZSTD_fast` `strategy`, which only has the primary hash table.
|
||||
|
||||
The minimum _clog_ is 6 (64 entries / 256 B) and the maximum is 29 (512M entries / 2 GiB) on 32-bit platforms
|
||||
and 30 (1B entries / 4 GiB) on 64-bit platforms.
|
||||
|
||||
- `searchLog`=_slog_, `slog`=_slog_:
|
||||
Specify the maximum number of searches in a hash chain or a binary tree
|
||||
using logarithmic scale.
|
||||
|
||||
More searches increases the chance to find a match which usually increases
|
||||
compression ratio but decreases compression speed.
|
||||
|
||||
The minimum _slog_ is 1 and the maximum is 'windowLog' - 1.
|
||||
|
||||
- `minMatch`=_mml_, `mml`=_mml_:
|
||||
Specify the minimum searched length of a match in a hash table.
|
||||
|
||||
Larger search lengths usually decrease compression ratio but improve
|
||||
decompression speed.
|
||||
|
||||
The minimum _mml_ is 3 and the maximum is 7.
|
||||
|
||||
- `targetLength`=_tlen_, `tlen`=_tlen_:
|
||||
The impact of this field vary depending on selected strategy.
|
||||
|
||||
For `ZSTD_btopt`, `ZSTD_btultra` and `ZSTD_btultra2`, it specifies
|
||||
the minimum match length that causes match finder to stop searching.
|
||||
A larger `targetLength` usually improves compression ratio
|
||||
but decreases compression speed.
|
||||
|
||||
For `ZSTD_fast`, it triggers ultra-fast mode when > 0.
|
||||
The value represents the amount of data skipped between match sampling.
|
||||
Impact is reversed: a larger `targetLength` increases compression speed
|
||||
but decreases compression ratio.
|
||||
|
||||
For all other strategies, this field has no impact.
|
||||
|
||||
The minimum _tlen_ is 0 and the maximum is 128 KiB.
|
||||
|
||||
- `overlapLog`=_ovlog_, `ovlog`=_ovlog_:
|
||||
Determine `overlapSize`, amount of data reloaded from previous job.
|
||||
This parameter is only available when multithreading is enabled.
|
||||
Reloading more data improves compression ratio, but decreases speed.
|
||||
|
||||
The minimum _ovlog_ is 0, and the maximum is 9.
|
||||
1 means "no overlap", hence completely independent jobs.
|
||||
9 means "full overlap", meaning up to `windowSize` is reloaded from previous job.
|
||||
Reducing _ovlog_ by 1 reduces the reloaded amount by a factor 2.
|
||||
For example, 8 means "windowSize/2", and 6 means "windowSize/8".
|
||||
Value 0 is special and means "default": _ovlog_ is automatically determined by `zstd`.
|
||||
In which case, _ovlog_ will range from 6 to 9, depending on selected _strat_.
|
||||
|
||||
- `ldmHashRateLog`=_lhrlog_, `lhrlog`=_lhrlog_:
|
||||
Specify the frequency of inserting entries into the long distance matching
|
||||
hash table.
|
||||
|
||||
This option is ignored unless long distance matching is enabled.
|
||||
|
||||
Larger values will improve compression speed. Deviating far from the
|
||||
default value will likely result in a decrease in compression ratio.
|
||||
|
||||
The default value varies between 4 and 7, depending on `strategy`.
|
||||
|
||||
- `ldmHashLog`=_lhlog_, `lhlog`=_lhlog_:
|
||||
Specify the maximum size for a hash table used for long distance matching.
|
||||
|
||||
This option is ignored unless long distance matching is enabled.
|
||||
|
||||
Bigger hash tables usually improve compression ratio at the expense of more
|
||||
memory during compression and a decrease in compression speed.
|
||||
|
||||
The minimum _lhlog_ is 6 and the maximum is 30 (default: `windowLog - ldmHashRateLog`).
|
||||
|
||||
- `ldmMinMatch`=_lmml_, `lmml`=_lmml_:
|
||||
Specify the minimum searched length of a match for long distance matching.
|
||||
|
||||
This option is ignored unless long distance matching is enabled.
|
||||
|
||||
Larger/very small values usually decrease compression ratio.
|
||||
|
||||
The minimum _lmml_ is 4 and the maximum is 4096 (default: 32 to 64, depending on `strategy`).
|
||||
|
||||
- `ldmBucketSizeLog`=_lblog_, `lblog`=_lblog_:
|
||||
Specify the size of each bucket for the hash table used for long distance
|
||||
matching.
|
||||
|
||||
This option is ignored unless long distance matching is enabled.
|
||||
|
||||
Larger bucket sizes improve collision resolution but decrease compression
|
||||
speed.
|
||||
|
||||
The minimum _lblog_ is 1 and the maximum is 8 (default: 4 to 8, depending on `strategy`).
|
||||
|
||||
|
||||
### Example
|
||||
The following parameters sets advanced compression options to something
|
||||
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
|
||||
|
||||
### -B#:
|
||||
Specify the size of each compression job.
|
||||
This parameter is only available when multi-threading is enabled.
|
||||
Each compression job is run in parallel, so this value indirectly impacts the nb of active threads.
|
||||
Default job size varies depending on compression level (generally `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 non-identical compressed frames.
|
||||
|
||||
|
||||
DICTIONARY BUILDER
|
||||
------------------
|
||||
`zstd` offers _dictionary_ compression,
|
||||
which greatly improves efficiency on small files and messages.
|
||||
It's possible to train `zstd` with a set of samples,
|
||||
the result of which is saved into a file called a `dictionary`.
|
||||
Then, during compression and decompression, reference the same dictionary,
|
||||
using command `-D dictionaryFileName`.
|
||||
Compression of small files similar to the sample set will be greatly improved.
|
||||
|
||||
* `--train FILEs`:
|
||||
Use FILEs as training set to create a dictionary.
|
||||
The training set should ideally contain a lot of samples (> 100),
|
||||
and weight typically 100x the target dictionary size
|
||||
(for example, ~10 MB for a 100 KB dictionary).
|
||||
`--train` can be combined with `-r` to indicate a directory rather than listing all the files,
|
||||
which can be useful to circumvent shell expansion limits.
|
||||
|
||||
Since dictionary compression is mostly effective for small files,
|
||||
the expectation is that the training set will only contain small files.
|
||||
In the case where some samples happen to be large,
|
||||
only the first 128 KiB of these samples will be used for training.
|
||||
|
||||
`--train` supports multithreading if `zstd` is compiled with threading support (default).
|
||||
Additional advanced parameters can be specified with `--train-fastcover`.
|
||||
The legacy dictionary builder can be accessed with `--train-legacy`.
|
||||
The slower cover dictionary builder can be accessed with `--train-cover`.
|
||||
Default `--train` is equivalent to `--train-fastcover=d=8,steps=4`.
|
||||
|
||||
* `-o FILE`:
|
||||
Dictionary saved into `FILE` (default name: dictionary).
|
||||
* `--maxdict=#`:
|
||||
Limit dictionary to specified size (default: 112640 bytes).
|
||||
As usual, quantities are expressed in bytes by default,
|
||||
and it's possible to employ suffixes (like `KB` or `MB`)
|
||||
to specify larger values.
|
||||
* `-#`:
|
||||
Use `#` compression level during training (optional).
|
||||
Will generate statistics more tuned for selected compression level,
|
||||
resulting in a _small_ compression ratio improvement for this level.
|
||||
* `-B#`:
|
||||
Split input files into blocks of size # (default: no split)
|
||||
* `-M#`, `--memory=#`:
|
||||
Limit the amount of sample data loaded for training (default: 2 GB).
|
||||
Note that the default (2 GB) is also the maximum.
|
||||
This parameter can be useful in situations where the training set size
|
||||
is not well controlled and could be potentially very large.
|
||||
Since speed of the training process is directly correlated to
|
||||
the size of the training sample set,
|
||||
a smaller sample set leads to faster training.
|
||||
|
||||
In situations where the training set is larger than maximum memory,
|
||||
the CLI will randomly select samples among the available ones,
|
||||
up to the maximum allowed memory budget.
|
||||
This is meant to improve dictionary relevance
|
||||
by mitigating the potential impact of clustering,
|
||||
such as selecting only files from the beginning of a list
|
||||
sorted by modification date, or sorted by alphabetical order.
|
||||
The randomization process is deterministic, so
|
||||
training of the same list of files with the same parameters
|
||||
will lead to the creation of the same dictionary.
|
||||
|
||||
* `--dictID=#`:
|
||||
A dictionary ID is a locally unique ID.
|
||||
The decoder will use this value to verify it is using the right dictionary.
|
||||
By default, zstd will create a 4-bytes random number ID.
|
||||
It's possible to provide an explicit number ID instead.
|
||||
It's up to the dictionary manager to not assign twice the same ID to
|
||||
2 different dictionaries.
|
||||
Note that short numbers have an advantage:
|
||||
an ID < 256 will only need 1 byte in the compressed frame header,
|
||||
and an ID < 65536 will only need 2 bytes.
|
||||
This compares favorably to 4 bytes default.
|
||||
|
||||
Note that RFC8878 reserves IDs less than 32768 and greater than or equal to 2\^31, so they should not be used in public.
|
||||
|
||||
* `--train-cover[=k#,d=#,steps=#,split=#,shrink[=#]]`:
|
||||
Select parameters for the default dictionary builder algorithm named cover.
|
||||
If _d_ is not specified, then it tries _d_ = 6 and _d_ = 8.
|
||||
If _k_ is not specified, then it tries _steps_ values in the range [50, 2000].
|
||||
If _steps_ is not specified, then the default value of 40 is used.
|
||||
If _split_ is not specified or split <= 0, then the default value of 100 is used.
|
||||
Requires that _d_ <= _k_.
|
||||
If _shrink_ flag is not used, then the default value for _shrinkDict_ of 0 is used.
|
||||
If _shrink_ is not specified, then the default value for _shrinkDictMaxRegression_ of 1 is used.
|
||||
|
||||
Selects segments of size _k_ with highest score to put in the dictionary.
|
||||
The score of a segment is computed by the sum of the frequencies of all the
|
||||
subsegments of size _d_.
|
||||
Generally _d_ should be in the range [6, 8], occasionally up to 16, but the
|
||||
algorithm will run faster with d <= _8_.
|
||||
Good values for _k_ vary widely based on the input data, but a safe range is
|
||||
[2 * _d_, 2000].
|
||||
If _split_ is 100, all input samples are used for both training and testing
|
||||
to find optimal _d_ and _k_ to build dictionary.
|
||||
Supports multithreading if `zstd` is compiled with threading support.
|
||||
Having _shrink_ enabled takes a truncated dictionary of minimum size and doubles
|
||||
in size until compression ratio of the truncated dictionary is at most
|
||||
_shrinkDictMaxRegression%_ worse than the compression ratio of the largest dictionary.
|
||||
|
||||
Examples:
|
||||
|
||||
`zstd --train-cover FILEs`
|
||||
|
||||
`zstd --train-cover=k=50,d=8 FILEs`
|
||||
|
||||
`zstd --train-cover=d=8,steps=500 FILEs`
|
||||
|
||||
`zstd --train-cover=k=50 FILEs`
|
||||
|
||||
`zstd --train-cover=k=50,split=60 FILEs`
|
||||
|
||||
`zstd --train-cover=shrink FILEs`
|
||||
|
||||
`zstd --train-cover=shrink=2 FILEs`
|
||||
|
||||
* `--train-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]`:
|
||||
Same as cover but with extra parameters _f_ and _accel_ and different default value of split
|
||||
If _split_ is not specified, then it tries _split_ = 75.
|
||||
If _f_ is not specified, then it tries _f_ = 20.
|
||||
Requires that 0 < _f_ < 32.
|
||||
If _accel_ is not specified, then it tries _accel_ = 1.
|
||||
Requires that 0 < _accel_ <= 10.
|
||||
Requires that _d_ = 6 or _d_ = 8.
|
||||
|
||||
_f_ is log of size of array that keeps track of frequency of subsegments of size _d_.
|
||||
The subsegment is hashed to an index in the range [0,2^_f_ - 1].
|
||||
It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency.
|
||||
Using a higher _f_ reduces collision but takes longer.
|
||||
|
||||
Examples:
|
||||
|
||||
`zstd --train-fastcover FILEs`
|
||||
|
||||
`zstd --train-fastcover=d=8,f=15,accel=2 FILEs`
|
||||
|
||||
* `--train-legacy[=selectivity=#]`:
|
||||
Use legacy dictionary builder algorithm with the given dictionary
|
||||
_selectivity_ (default: 9).
|
||||
The smaller the _selectivity_ value, the denser the dictionary,
|
||||
improving its efficiency but reducing its achievable maximum size.
|
||||
`--train-legacy=s=#` is also accepted.
|
||||
|
||||
Examples:
|
||||
|
||||
`zstd --train-legacy FILEs`
|
||||
|
||||
`zstd --train-legacy=selectivity=8 FILEs`
|
||||
|
||||
|
||||
BENCHMARK
|
||||
---------
|
||||
The `zstd` CLI provides a benchmarking mode that can be used to easily find suitable compression parameters, or alternatively to benchmark a computer's performance.
|
||||
`zstd -b [FILE(s)]` will benchmark `zstd` for both compression and decompression using default compression level.
|
||||
Note that results are very dependent on the content being compressed.
|
||||
|
||||
It's possible to pass multiple files to the benchmark, and even a directory with `-r DIRECTORY`.
|
||||
When no `FILE` is provided, the benchmark will use a procedurally generated `lorem ipsum` text.
|
||||
|
||||
Benchmarking will employ `max(1, min(4, nbCores/4))` worker threads by default in order to match the behavior of the normal CLI I/O.
|
||||
|
||||
* `-b#`:
|
||||
benchmark file(s) using compression level #
|
||||
* `-e#`:
|
||||
benchmark file(s) using multiple compression levels, from `-b#` to `-e#` (inclusive)
|
||||
* `-d`:
|
||||
benchmark decompression speed only (requires providing a zstd-compressed content)
|
||||
* `-i#`:
|
||||
minimum evaluation time, in seconds (default: 3s), benchmark mode only
|
||||
* `-B#`, `--block-size=#`:
|
||||
cut file(s) into independent chunks of size # (default: no chunking)
|
||||
* `-S`:
|
||||
output one benchmark result per input file (default: consolidated result)
|
||||
* `-D dictionary`
|
||||
benchmark using dictionary
|
||||
* `--priority=rt`:
|
||||
set process priority to real-time (Windows)
|
||||
|
||||
Beyond compression levels, benchmarking is also compatible with other parameters, such as number of threads (`-T#`), advanced compression parameters (`--zstd=###`), dictionary compression (`-D dictionary`), or even disabling checksum verification for example.
|
||||
|
||||
**Output Format:** CompressionLevel#Filename: InputSize -> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed
|
||||
|
||||
**Methodology:** For speed measurement, the entire input is compressed/decompressed in-memory to measure speed. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
`zstdgrep`(1), `zstdless`(1), `gzip`(1), `xz`(1)
|
||||
|
||||
The <zstandard> format is specified in Y. Collet, "Zstandard Compression and the 'application/zstd' Media Type", https://www.ietf.org/rfc/rfc8878.txt, Internet RFC 8878 (February 2021).
|
||||
|
||||
BUGS
|
||||
----
|
||||
Report bugs at: https://github.com/facebook/zstd/issues
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
Yann Collet
|
1658
build_amd64/_deps/zstd-src/programs/zstdcli.c
Normal file
1658
build_amd64/_deps/zstd-src/programs/zstdcli.c
Normal file
File diff suppressed because it is too large
Load Diff
172
build_amd64/_deps/zstd-src/programs/zstdcli_trace.c
Normal file
172
build_amd64/_deps/zstd-src/programs/zstdcli_trace.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include "zstdcli_trace.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "timefn.h"
|
||||
#include "util.h"
|
||||
|
||||
#define ZSTD_STATIC_LINKING_ONLY
|
||||
#include "../lib/zstd.h"
|
||||
/* We depend on the trace header to avoid duplicating the ZSTD_trace struct.
|
||||
* But, we check the version so it is compatible with dynamic linking.
|
||||
*/
|
||||
#include "../lib/common/zstd_trace.h"
|
||||
/* We only use macros from threading.h so it is compatible with dynamic linking */
|
||||
#include "../lib/common/threading.h"
|
||||
|
||||
#if ZSTD_TRACE
|
||||
|
||||
static FILE* g_traceFile = NULL;
|
||||
static int g_mutexInit = 0;
|
||||
static ZSTD_pthread_mutex_t g_mutex;
|
||||
static UTIL_time_t g_enableTime = UTIL_TIME_INITIALIZER;
|
||||
|
||||
void TRACE_enable(char const* filename)
|
||||
{
|
||||
int const writeHeader = !UTIL_isRegularFile(filename);
|
||||
if (g_traceFile)
|
||||
fclose(g_traceFile);
|
||||
g_traceFile = fopen(filename, "a");
|
||||
if (g_traceFile && writeHeader) {
|
||||
/* Fields:
|
||||
* algorithm
|
||||
* version
|
||||
* method
|
||||
* streaming
|
||||
* level
|
||||
* workers
|
||||
* dictionary size
|
||||
* uncompressed size
|
||||
* compressed size
|
||||
* duration nanos
|
||||
* compression ratio
|
||||
* speed MB/s
|
||||
*/
|
||||
fprintf(g_traceFile, "Algorithm, Version, Method, Mode, Level, Workers, Dictionary Size, Uncompressed Size, Compressed Size, Duration Nanos, Compression Ratio, Speed MB/s\n");
|
||||
}
|
||||
g_enableTime = UTIL_getTime();
|
||||
if (!g_mutexInit) {
|
||||
if (!ZSTD_pthread_mutex_init(&g_mutex, NULL)) {
|
||||
g_mutexInit = 1;
|
||||
} else {
|
||||
TRACE_finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TRACE_finish(void)
|
||||
{
|
||||
if (g_traceFile) {
|
||||
fclose(g_traceFile);
|
||||
}
|
||||
g_traceFile = NULL;
|
||||
if (g_mutexInit) {
|
||||
ZSTD_pthread_mutex_destroy(&g_mutex);
|
||||
g_mutexInit = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void TRACE_log(char const* method, PTime duration, ZSTD_Trace const* trace)
|
||||
{
|
||||
int level = 0;
|
||||
int workers = 0;
|
||||
double const ratio = (double)trace->uncompressedSize / (double)trace->compressedSize;
|
||||
double const speed = ((double)trace->uncompressedSize * 1000) / (double)duration;
|
||||
if (trace->params) {
|
||||
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_compressionLevel, &level);
|
||||
ZSTD_CCtxParams_getParameter(trace->params, ZSTD_c_nbWorkers, &workers);
|
||||
}
|
||||
assert(g_traceFile != NULL);
|
||||
|
||||
ZSTD_pthread_mutex_lock(&g_mutex);
|
||||
/* Fields:
|
||||
* algorithm
|
||||
* version
|
||||
* method
|
||||
* streaming
|
||||
* level
|
||||
* workers
|
||||
* dictionary size
|
||||
* uncompressed size
|
||||
* compressed size
|
||||
* duration nanos
|
||||
* compression ratio
|
||||
* speed MB/s
|
||||
*/
|
||||
fprintf(g_traceFile,
|
||||
"zstd, %u, %s, %s, %d, %d, %llu, %llu, %llu, %llu, %.2f, %.2f\n",
|
||||
trace->version,
|
||||
method,
|
||||
trace->streaming ? "streaming" : "single-pass",
|
||||
level,
|
||||
workers,
|
||||
(unsigned long long)trace->dictionarySize,
|
||||
(unsigned long long)trace->uncompressedSize,
|
||||
(unsigned long long)trace->compressedSize,
|
||||
(unsigned long long)duration,
|
||||
ratio,
|
||||
speed);
|
||||
ZSTD_pthread_mutex_unlock(&g_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* These symbols override the weak symbols provided by the library.
|
||||
*/
|
||||
|
||||
ZSTD_TraceCtx ZSTD_trace_compress_begin(ZSTD_CCtx const* cctx)
|
||||
{
|
||||
(void)cctx;
|
||||
if (g_traceFile == NULL)
|
||||
return 0;
|
||||
return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
|
||||
}
|
||||
|
||||
void ZSTD_trace_compress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
|
||||
{
|
||||
PTime const beginNanos = (PTime)ctx;
|
||||
PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
|
||||
PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
|
||||
assert(g_traceFile != NULL);
|
||||
assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
|
||||
TRACE_log("compress", durationNanos, trace);
|
||||
}
|
||||
|
||||
ZSTD_TraceCtx ZSTD_trace_decompress_begin(ZSTD_DCtx const* dctx)
|
||||
{
|
||||
(void)dctx;
|
||||
if (g_traceFile == NULL)
|
||||
return 0;
|
||||
return (ZSTD_TraceCtx)UTIL_clockSpanNano(g_enableTime);
|
||||
}
|
||||
|
||||
void ZSTD_trace_decompress_end(ZSTD_TraceCtx ctx, ZSTD_Trace const* trace)
|
||||
{
|
||||
PTime const beginNanos = (PTime)ctx;
|
||||
PTime const endNanos = UTIL_clockSpanNano(g_enableTime);
|
||||
PTime const durationNanos = endNanos > beginNanos ? endNanos - beginNanos : 0;
|
||||
assert(g_traceFile != NULL);
|
||||
assert(trace->version == ZSTD_VERSION_NUMBER); /* CLI version must match. */
|
||||
TRACE_log("decompress", durationNanos, trace);
|
||||
}
|
||||
|
||||
#else /* ZSTD_TRACE */
|
||||
|
||||
void TRACE_enable(char const* filename)
|
||||
{
|
||||
(void)filename;
|
||||
}
|
||||
|
||||
void TRACE_finish(void) {}
|
||||
|
||||
#endif /* ZSTD_TRACE */
|
24
build_amd64/_deps/zstd-src/programs/zstdcli_trace.h
Normal file
24
build_amd64/_deps/zstd-src/programs/zstdcli_trace.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the BSD-style license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#ifndef ZSTDCLI_TRACE_H
|
||||
#define ZSTDCLI_TRACE_H
|
||||
|
||||
/**
|
||||
* Enable tracing - log to filename.
|
||||
*/
|
||||
void TRACE_enable(char const* filename);
|
||||
|
||||
/**
|
||||
* Shut down the tracing library.
|
||||
*/
|
||||
void TRACE_finish(void);
|
||||
|
||||
#endif /* ZSTDCLI_TRACE_H */
|
134
build_amd64/_deps/zstd-src/programs/zstdgrep
Executable file
134
build_amd64/_deps/zstd-src/programs/zstdgrep
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2003 Thomas Klausner.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
grep=${GREP:-grep}
|
||||
zcat=${ZCAT:-zstdcat}
|
||||
|
||||
endofopts=0
|
||||
pattern_found=0
|
||||
grep_args=""
|
||||
hyphen=0
|
||||
silent=0
|
||||
|
||||
prog=${0##*/}
|
||||
|
||||
# handle being called 'zegrep' or 'zfgrep'
|
||||
case $prog in
|
||||
*egrep*) prog=zegrep; grep_args='-E';;
|
||||
*fgrep*) prog=zfgrep; grep_args='-F';;
|
||||
*) prog=zstdgrep;;
|
||||
esac
|
||||
|
||||
# skip all options and pass them on to grep taking care of options
|
||||
# with arguments, and if -e was supplied
|
||||
|
||||
while [ "$#" -gt 0 ] && [ "${endofopts}" -eq 0 ]; do
|
||||
case "$1" in
|
||||
# from GNU grep-2.5.1 -- keep in sync!
|
||||
-[ABCDXdefm])
|
||||
if [ "$#" -lt 2 ]; then
|
||||
printf '%s: missing argument for %s flag\n' "${prog}" "$1" >&2
|
||||
exit 1
|
||||
fi
|
||||
case "$1" in
|
||||
-e)
|
||||
pattern="$2"
|
||||
pattern_found=1
|
||||
shift 2
|
||||
break
|
||||
;;
|
||||
-f)
|
||||
pattern_found=2
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
grep_args="${grep_args} $1 $2"
|
||||
shift 2
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
endofopts=1
|
||||
;;
|
||||
-)
|
||||
hyphen=1
|
||||
shift
|
||||
;;
|
||||
-h)
|
||||
silent=1
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
grep_args="${grep_args} $1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
# pattern to grep for
|
||||
endofopts=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# if no -e option was found, take next argument as grep-pattern
|
||||
if [ "${pattern_found}" -lt 1 ]; then
|
||||
if [ "$#" -ge 1 ]; then
|
||||
pattern="$1"
|
||||
shift
|
||||
elif [ "${hyphen}" -gt 0 ]; then
|
||||
pattern="-"
|
||||
else
|
||||
printf '%s: missing pattern\n' "${prog}" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
EXIT_CODE=0
|
||||
# call grep ...
|
||||
if [ "$#" -lt 1 ]; then
|
||||
# ... on stdin
|
||||
set -f # Disable file name generation (globbing).
|
||||
# shellcheck disable=SC2086
|
||||
"${zcat}" - | "${grep}" ${grep_args} -- "${pattern}" -
|
||||
EXIT_CODE=$?
|
||||
set +f
|
||||
else
|
||||
# ... on all files given on the command line
|
||||
if [ "${silent}" -lt 1 ] && [ "$#" -gt 1 ]; then
|
||||
grep_args="-H ${grep_args}"
|
||||
fi
|
||||
set -f
|
||||
while [ "$#" -gt 0 ]; do
|
||||
# shellcheck disable=SC2086
|
||||
if [ $pattern_found -eq 2 ]; then
|
||||
"${zcat}" -- "$1" | "${grep}" --label="${1}" ${grep_args} -- -
|
||||
else
|
||||
"${zcat}" -- "$1" | "${grep}" --label="${1}" ${grep_args} -- "${pattern}" -
|
||||
fi
|
||||
[ "$?" -ne 0 ] && EXIT_CODE=1
|
||||
shift
|
||||
done
|
||||
set +f
|
||||
fi
|
||||
|
||||
exit "${EXIT_CODE}"
|
26
build_amd64/_deps/zstd-src/programs/zstdgrep.1
Normal file
26
build_amd64/_deps/zstd-src/programs/zstdgrep.1
Normal file
@@ -0,0 +1,26 @@
|
||||
.
|
||||
.TH "ZSTDGREP" "1" "March 2024" "zstd 1.5.6" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files
|
||||
.
|
||||
.SH "SYNOPSIS"
|
||||
\fBzstdgrep\fR [\fIgrep\-flags\fR] [\-\-] \fIpattern\fR [\fIfiles\fR \.\.\.]
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
\fBzstdgrep\fR runs \fBgrep\fR(1) on files, or \fBstdin\fR if no files argument is given, after decompressing them with \fBzstdcat\fR(1)\.
|
||||
.
|
||||
.P
|
||||
The \fIgrep\-flags\fR and \fIpattern\fR arguments are passed on to \fBgrep\fR(1)\. If an \fB\-e\fR flag is found in the \fIgrep\-flags\fR, \fBzstdgrep\fR will not look for a \fIpattern\fR argument\.
|
||||
.
|
||||
.P
|
||||
Note that modern \fBgrep\fR alternatives such as \fBripgrep\fR (\fBrg\fR(1)) support \fBzstd\fR\-compressed files out of the box, and can prove better alternatives than \fBzstdgrep\fR notably for unsupported complex pattern searches\. Note though that such alternatives may also feature some minor command line differences\.
|
||||
.
|
||||
.SH "EXIT STATUS"
|
||||
In case of missing arguments or missing pattern, 1 will be returned, otherwise 0\.
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
\fBzstd\fR(1)
|
||||
.
|
||||
.SH "AUTHORS"
|
||||
Thomas Klausner \fIwiz@NetBSD\.org\fR
|
30
build_amd64/_deps/zstd-src/programs/zstdgrep.1.md
Normal file
30
build_amd64/_deps/zstd-src/programs/zstdgrep.1.md
Normal file
@@ -0,0 +1,30 @@
|
||||
zstdgrep(1) -- print lines matching a pattern in zstandard-compressed files
|
||||
============================================================================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
`zstdgrep` [<grep-flags>] [--] <pattern> [<files> ...]
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
`zstdgrep` runs `grep`(1) on files, or `stdin` if no files argument is given, after decompressing them with `zstdcat`(1).
|
||||
|
||||
The <grep-flags> and <pattern> arguments are passed on to `grep`(1). If an `-e` flag is found in the <grep-flags>, `zstdgrep` will not look for a <pattern> argument.
|
||||
|
||||
Note that modern `grep` alternatives such as `ripgrep` (`rg`(1)) support `zstd`-compressed files out of the box,
|
||||
and can prove better alternatives than `zstdgrep` notably for unsupported complex pattern searches.
|
||||
Note though that such alternatives may also feature some minor command line differences.
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
In case of missing arguments or missing pattern, 1 will be returned, otherwise 0.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
`zstd`(1)
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Thomas Klausner <wiz@NetBSD.org>
|
8
build_amd64/_deps/zstd-src/programs/zstdless
Executable file
8
build_amd64/_deps/zstd-src/programs/zstdless
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
zstd=${ZSTD:-zstd}
|
||||
|
||||
# TODO: Address quirks and bugs tied to old versions of less, provide a mechanism to pass flags directly to zstd
|
||||
|
||||
export LESSOPEN="|-${zstd} -cdfq %s"
|
||||
exec less "$@"
|
14
build_amd64/_deps/zstd-src/programs/zstdless.1
Normal file
14
build_amd64/_deps/zstd-src/programs/zstdless.1
Normal file
@@ -0,0 +1,14 @@
|
||||
.
|
||||
.TH "ZSTDLESS" "1" "March 2024" "zstd 1.5.6" "User Commands"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBzstdless\fR \- view zstandard\-compressed files
|
||||
.
|
||||
.SH "SYNOPSIS"
|
||||
\fBzstdless\fR [\fIflags\fR] [\fIfile\fR \.\.\.]
|
||||
.
|
||||
.SH "DESCRIPTION"
|
||||
\fBzstdless\fR runs \fBless\fR(1) on files or stdin, if no \fIfile\fR argument is given, after decompressing them with \fBzstdcat\fR(1)\.
|
||||
.
|
||||
.SH "SEE ALSO"
|
||||
\fBzstd\fR(1)
|
16
build_amd64/_deps/zstd-src/programs/zstdless.1.md
Normal file
16
build_amd64/_deps/zstd-src/programs/zstdless.1.md
Normal file
@@ -0,0 +1,16 @@
|
||||
zstdless(1) -- view zstandard-compressed files
|
||||
============================================================================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
`zstdless` [<flags>] [<file> ...]
|
||||
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
`zstdless` runs `less`(1) on files or stdin, if no <file> argument is given, after decompressing them with `zstdcat`(1).
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
`zstd`(1)
|
Reference in New Issue
Block a user