Internal changes
PiperOrigin-RevId: 621907514
This commit is contained in:
committed by
Danila Kutenin
parent
0212163f6e
commit
e1e7329dc7
2
.bazelrc
2
.bazelrc
@@ -1,4 +1,2 @@
|
|||||||
# googletest requires C++14 or above
|
# googletest requires C++14 or above
|
||||||
build --cxxopt='-std=c++17'
|
build --cxxopt='-std=c++17'
|
||||||
# Enable Bzlmod for every Bazel command
|
|
||||||
common --enable_bzlmod
|
|
||||||
|
|||||||
43
.github/workflows/riscv64-qemu-test.yaml
vendored
43
.github/workflows/riscv64-qemu-test.yaml
vendored
@@ -1,43 +0,0 @@
|
|||||||
name: riscv64-qemu-test
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
RISCV_CROSSCOMPILE: "ON"
|
|
||||||
riscv_gnu_toolchain_download_path: https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2025.07.03/riscv64-glibc-ubuntu-24.04-gcc-nightly-2025.07.03-nightly.tar.xz
|
|
||||||
RISCV_PATH: /opt/riscv
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y --no-install-recommends \
|
|
||||||
qemu-user qemu-user-static \
|
|
||||||
build-essential \
|
|
||||||
cmake \
|
|
||||||
git
|
|
||||||
sudo mkdir -p $RISCV_PATH
|
|
||||||
wget ${riscv_gnu_toolchain_download_path} -O riscv-toolchain.tar.xz
|
|
||||||
sudo tar -xvf riscv-toolchain.tar.xz -C $RISCV_PATH --strip-components=1
|
|
||||||
sudo sed -i "s|libdir='/mnt/riscv/riscv64-unknown-linux-gnu/lib'|libdir='$RISCV_PATH/riscv64-unknown-linux-gnu/lib'|g" $RISCV_PATH/riscv64-unknown-linux-gnu/lib/libatomic.la
|
|
||||||
|
|
||||||
- name: Build and Run Unit Tests
|
|
||||||
run: |
|
|
||||||
export PATH=$RISCV_PATH/bin:$PATH
|
|
||||||
export LD_LIBRARY_PATH="/opt/riscv/lib:$LD_LIBRARY_PATH"
|
|
||||||
export QEMU_LD_PREFIX=$RISCV_PATH/sysroot
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release ../
|
|
||||||
make -j$(nproc)
|
|
||||||
make test
|
|
||||||
|
|
||||||
- name: Run Benchmark
|
|
||||||
run: ./build/snappy_benchmark
|
|
||||||
working-directory: ./
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,5 +6,4 @@
|
|||||||
# Build directory.
|
# Build directory.
|
||||||
build/
|
build/
|
||||||
/bazel-*
|
/bazel-*
|
||||||
MODULE.bazel.lock
|
|
||||||
out/
|
out/
|
||||||
|
|||||||
63
BUILD.bazel
63
BUILD.bazel
@@ -26,21 +26,11 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
|
||||||
load("@bazel_skylib//rules:write_file.bzl", "write_file")
|
|
||||||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
|
||||||
load("@rules_cc//cc:cc_test.bzl", "cc_test")
|
|
||||||
|
|
||||||
package(default_visibility = ["//visibility:public"])
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|
||||||
exports_files([
|
SNAPPY_VERSION = (1, 1, 10)
|
||||||
"COPYING",
|
|
||||||
"COPYING.notestdata",
|
|
||||||
])
|
|
||||||
|
|
||||||
SNAPPY_VERSION = (1, 2, 2)
|
|
||||||
|
|
||||||
config_setting(
|
config_setting(
|
||||||
name = "windows",
|
name = "windows",
|
||||||
@@ -50,7 +40,7 @@ config_setting(
|
|||||||
cc_library(
|
cc_library(
|
||||||
name = "config",
|
name = "config",
|
||||||
hdrs = ["config.h"],
|
hdrs = ["config.h"],
|
||||||
defines = ["HAVE_CONFIG_H"],
|
defines = ["HAVE_CONFIG_H"]
|
||||||
)
|
)
|
||||||
|
|
||||||
cc_library(
|
cc_library(
|
||||||
@@ -62,10 +52,8 @@ cc_library(
|
|||||||
name = "snappy-stubs-internal",
|
name = "snappy-stubs-internal",
|
||||||
srcs = ["snappy-stubs-internal.cc"],
|
srcs = ["snappy-stubs-internal.cc"],
|
||||||
hdrs = ["snappy-stubs-internal.h"],
|
hdrs = ["snappy-stubs-internal.h"],
|
||||||
implementation_deps = [
|
|
||||||
":config",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":snappy-stubs-public",
|
":snappy-stubs-public",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -82,15 +70,12 @@ cc_library(
|
|||||||
"snappy-sinksource.h",
|
"snappy-sinksource.h",
|
||||||
],
|
],
|
||||||
copts = select({
|
copts = select({
|
||||||
":windows": [],
|
":windows": [],
|
||||||
"//conditions:default": [
|
"//conditions:default": [
|
||||||
"-Wno-sign-compare",
|
"-Wno-sign-compare",
|
||||||
],
|
]}),
|
||||||
}),
|
|
||||||
implementation_deps = [
|
|
||||||
":config",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
|
":config",
|
||||||
":snappy-stubs-internal",
|
":snappy-stubs-internal",
|
||||||
":snappy-stubs-public",
|
":snappy-stubs-public",
|
||||||
],
|
],
|
||||||
@@ -129,7 +114,7 @@ cc_test(
|
|||||||
deps = [
|
deps = [
|
||||||
":snappy",
|
":snappy",
|
||||||
":snappy-test",
|
":snappy-test",
|
||||||
"@com_google_benchmark//:benchmark_main",
|
"//third_party/benchmark:benchmark_main",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -142,15 +127,15 @@ cc_test(
|
|||||||
deps = [
|
deps = [
|
||||||
":snappy",
|
":snappy",
|
||||||
":snappy-test",
|
":snappy-test",
|
||||||
"@com_google_googletest//:gtest_main",
|
"//third_party/googletest:gtest_main",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Generate a config.h similar to what cmake would produce.
|
# Generate a config.h similar to what cmake would produce.
|
||||||
write_file(
|
genrule(
|
||||||
name = "config_h",
|
name = "config_h",
|
||||||
out = "config.h",
|
outs = ["config.h"],
|
||||||
content = """\
|
cmd = """cat <<EOF >$@
|
||||||
#define HAVE_STDDEF_H 1
|
#define HAVE_STDDEF_H 1
|
||||||
#define HAVE_STDINT_H 1
|
#define HAVE_STDINT_H 1
|
||||||
#ifdef __has_builtin
|
#ifdef __has_builtin
|
||||||
@@ -207,17 +192,19 @@ write_file(
|
|||||||
# define SNAPPY_IS_BIG_ENDIAN 1
|
# define SNAPPY_IS_BIG_ENDIAN 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
""".splitlines(),
|
EOF
|
||||||
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
expand_template(
|
genrule(
|
||||||
name = "snappy_stubs_public_h",
|
name = "snappy_stubs_public_h",
|
||||||
out = "snappy-stubs-public.h",
|
srcs = ["snappy-stubs-public.h.in"],
|
||||||
substitutions = {
|
outs = ["snappy-stubs-public.h"],
|
||||||
"${HAVE_SYS_UIO_H_01}": "!_WIN32",
|
# Assume sys/uio.h is available on non-Windows.
|
||||||
"${PROJECT_VERSION_MAJOR}": str(SNAPPY_VERSION[0]),
|
# Set the version numbers.
|
||||||
"${PROJECT_VERSION_MINOR}": str(SNAPPY_VERSION[1]),
|
cmd = ("""sed -e 's/$${HAVE_SYS_UIO_H_01}/!_WIN32/g' \
|
||||||
"${PROJECT_VERSION_PATCH}": str(SNAPPY_VERSION[2]),
|
-e 's/$${PROJECT_VERSION_MAJOR}/%d/g' \
|
||||||
},
|
-e 's/$${PROJECT_VERSION_MINOR}/%d/g' \
|
||||||
template = "snappy-stubs-public.h.in",
|
-e 's/$${PROJECT_VERSION_PATCH}/%d/g' \
|
||||||
|
$< >$@""" % SNAPPY_VERSION),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.1)
|
||||||
project(Snappy VERSION 1.2.2 LANGUAGES C CXX)
|
project(Snappy VERSION 1.1.10 LANGUAGES C CXX)
|
||||||
|
|
||||||
# C++ standard can be overridden when this is used as a sub-project.
|
# C++ standard can be overridden when this is used as a sub-project.
|
||||||
if(NOT CMAKE_CXX_STANDARD)
|
if(NOT CMAKE_CXX_STANDARD)
|
||||||
@@ -38,7 +38,7 @@ if(NOT CMAKE_CXX_STANDARD)
|
|||||||
endif(NOT CMAKE_CXX_STANDARD)
|
endif(NOT CMAKE_CXX_STANDARD)
|
||||||
|
|
||||||
# https://github.com/izenecloud/cmake/blob/master/SetCompilerWarningAll.cmake
|
# https://github.com/izenecloud/cmake/blob/master/SetCompilerWarningAll.cmake
|
||||||
if(MSVC)
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
# Use the highest warning level for Visual Studio.
|
# Use the highest warning level for Visual Studio.
|
||||||
set(CMAKE_CXX_WARNING_LEVEL 4)
|
set(CMAKE_CXX_WARNING_LEVEL 4)
|
||||||
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
@@ -55,7 +55,7 @@ if(MSVC)
|
|||||||
# Disable RTTI.
|
# Disable RTTI.
|
||||||
string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
|
||||||
else(MSVC)
|
else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
# Use -Wall for clang and gcc.
|
# Use -Wall for clang and gcc.
|
||||||
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall")
|
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wall")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
@@ -85,7 +85,7 @@ else(MSVC)
|
|||||||
# Disable RTTI.
|
# Disable RTTI.
|
||||||
string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
||||||
endif(MSVC)
|
endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
|
||||||
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
|
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
|
||||||
# it prominent in the GUI.
|
# it prominent in the GUI.
|
||||||
@@ -155,20 +155,10 @@ int main() {
|
|||||||
return __builtin_expect(0, 1);
|
return __builtin_expect(0, 1);
|
||||||
}" HAVE_BUILTIN_EXPECT)
|
}" HAVE_BUILTIN_EXPECT)
|
||||||
|
|
||||||
# Check if the built-in __builtin_ctz (count trailing zeros) is available.
|
|
||||||
# Require either a non-RISC-V target, or a RISC-V core that implements
|
|
||||||
# the Zbb bit-manipulation extension where ctz is guaranteed.
|
|
||||||
check_cxx_source_compiles("
|
check_cxx_source_compiles("
|
||||||
#ifdef __riscv
|
int main() {
|
||||||
#ifdef __riscv_zbb
|
return __builtin_ctzll(0);
|
||||||
int main() { return __builtin_ctzll(0); }
|
}" HAVE_BUILTIN_CTZ)
|
||||||
#else
|
|
||||||
#error \"ZBB not enabled in current config\"
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
int main() { return __builtin_ctzll(0); }
|
|
||||||
#endif
|
|
||||||
" HAVE_BUILTIN_CTZ)
|
|
||||||
|
|
||||||
check_cxx_source_compiles("
|
check_cxx_source_compiles("
|
||||||
int main() {
|
int main() {
|
||||||
@@ -216,41 +206,13 @@ int main() {
|
|||||||
|
|
||||||
check_cxx_source_compiles("
|
check_cxx_source_compiles("
|
||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#include <stdint.h>
|
|
||||||
int main() {
|
int main() {
|
||||||
uint8_t val = 3, dup[8];
|
uint8_t val = 3, dup[8];
|
||||||
uint8x16_t v1 = vld1q_dup_u8(&val);
|
uint8x16_t v = vld1q_dup_u8(&val);
|
||||||
uint8x16_t v2 = vqtbl1q_u8(v1, v1);
|
vst1q_u8(dup, v);
|
||||||
vst1q_u8(dup, v1);
|
|
||||||
vst1q_u8(dup, v2);
|
|
||||||
return 0;
|
return 0;
|
||||||
}" SNAPPY_HAVE_NEON)
|
}" SNAPPY_HAVE_NEON)
|
||||||
|
|
||||||
#check RVV 1.0 need __riscv_ prefix
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <riscv_vector.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
int main() {
|
|
||||||
uint8_t val = 3, dup[8];
|
|
||||||
size_t vl = __riscv_vsetvl_e8m1(8);
|
|
||||||
vuint8m1_t v = __riscv_vmv_v_x_u8m1(val, vl);
|
|
||||||
return 0;
|
|
||||||
}" SNAPPY_RVV_1)
|
|
||||||
|
|
||||||
|
|
||||||
#check RVV 0.7.1 not __riscv_ prefix
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <riscv_vector.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
int main() {
|
|
||||||
uint8_t val = 3, dup[8];
|
|
||||||
size_t vl = vsetvl_e8m1(8);
|
|
||||||
vuint8m1_t v = vmv_v_x_u8m1(val, vl);
|
|
||||||
return 0;
|
|
||||||
}" SNAPPY_RVV_0_7)
|
|
||||||
|
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
check_symbol_exists("mmap" "sys/mman.h" HAVE_FUNC_MMAP)
|
check_symbol_exists("mmap" "sys/mman.h" HAVE_FUNC_MMAP)
|
||||||
check_symbol_exists("sysconf" "unistd.h" HAVE_FUNC_SYSCONF)
|
check_symbol_exists("sysconf" "unistd.h" HAVE_FUNC_SYSCONF)
|
||||||
@@ -296,7 +258,9 @@ target_sources(snappy
|
|||||||
"snappy-stubs-internal.cc"
|
"snappy-stubs-internal.cc"
|
||||||
"snappy.cc"
|
"snappy.cc"
|
||||||
"${PROJECT_BINARY_DIR}/config.h"
|
"${PROJECT_BINARY_DIR}/config.h"
|
||||||
PUBLIC
|
|
||||||
|
# Only CMake 3.3+ supports PUBLIC sources in targets exported by "install".
|
||||||
|
$<$<VERSION_GREATER:CMAKE_VERSION,3.2>:PUBLIC>
|
||||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/snappy-c.h>
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/snappy-c.h>
|
||||||
$<INSTALL_INTERFACE:include/snappy-c.h>
|
$<INSTALL_INTERFACE:include/snappy-c.h>
|
||||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/snappy-sinksource.h>
|
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/snappy-sinksource.h>
|
||||||
@@ -333,9 +297,6 @@ if(SNAPPY_BUILD_TESTS OR SNAPPY_BUILD_BENCHMARKS)
|
|||||||
|
|
||||||
# Test files include snappy-test.h, HAVE_CONFIG_H must be defined.
|
# Test files include snappy-test.h, HAVE_CONFIG_H must be defined.
|
||||||
target_compile_definitions(snappy_test_support PUBLIC -DHAVE_CONFIG_H)
|
target_compile_definitions(snappy_test_support PUBLIC -DHAVE_CONFIG_H)
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
set_target_properties(snappy_test_support PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
|
||||||
endif(BUILD_SHARED_LIBS)
|
|
||||||
|
|
||||||
target_link_libraries(snappy_test_support snappy)
|
target_link_libraries(snappy_test_support snappy)
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
Copyright 2011, Google Inc.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* 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.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"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 COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS 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.
|
|
||||||
26
MODULE.bazel
26
MODULE.bazel
@@ -1,26 +0,0 @@
|
|||||||
module(
|
|
||||||
name = "snappy",
|
|
||||||
version = "1.2.2",
|
|
||||||
compatibility_level = 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
bazel_dep(name = "rules_cc", version = "0.2.4")
|
|
||||||
bazel_dep(name = "bazel_skylib", version = "1.8.2")
|
|
||||||
|
|
||||||
bazel_dep(
|
|
||||||
name = "googletest",
|
|
||||||
version = "1.17.0.bcr.2",
|
|
||||||
dev_dependency = True,
|
|
||||||
repo_name = "com_google_googletest",
|
|
||||||
)
|
|
||||||
bazel_dep(
|
|
||||||
name = "google_benchmark",
|
|
||||||
version = "1.9.5",
|
|
||||||
dev_dependency = True,
|
|
||||||
repo_name = "com_google_benchmark",
|
|
||||||
)
|
|
||||||
|
|
||||||
bazel_dep(
|
|
||||||
name = "platforms",
|
|
||||||
version = "1.0.0",
|
|
||||||
)
|
|
||||||
15
NEWS
15
NEWS
@@ -1,18 +1,3 @@
|
|||||||
Snappy v1.2.2, Mar 26th 2025:
|
|
||||||
|
|
||||||
* We added a new compression level in v1.2.1 which compresses a bit
|
|
||||||
denser but slower. Decompression speed should be even faster with it.
|
|
||||||
|
|
||||||
* We fixed a very old issue of data corruption when compressed size
|
|
||||||
exceeds 4GB. This can happen when you compress data close to 4GB
|
|
||||||
and it's incompressible, for example, random data.
|
|
||||||
|
|
||||||
* Started to use minimum CMake 3.10 because older ones are not
|
|
||||||
planned to be supported.
|
|
||||||
|
|
||||||
* Various other small fixes and performance improvements (especially
|
|
||||||
for clang).
|
|
||||||
|
|
||||||
Snappy v1.1.10, Mar 8th 2023:
|
Snappy v1.1.10, Mar 8th 2023:
|
||||||
|
|
||||||
* Performance improvements
|
* Performance improvements
|
||||||
|
|||||||
@@ -140,10 +140,10 @@ explicitly supports the following:
|
|||||||
1. C++11
|
1. C++11
|
||||||
2. Clang (gcc and MSVC are best-effort).
|
2. Clang (gcc and MSVC are best-effort).
|
||||||
3. Low level optimizations (e.g. assembly or equivalent intrinsics) for:
|
3. Low level optimizations (e.g. assembly or equivalent intrinsics) for:
|
||||||
- [x86](https://en.wikipedia.org/wiki/X86)
|
1. [x86](https://en.wikipedia.org/wiki/X86)
|
||||||
- [x86-64](https://en.wikipedia.org/wiki/X86-64)
|
2. [x86-64](https://en.wikipedia.org/wiki/X86-64)
|
||||||
- ARMv7 (32-bit)
|
3. ARMv7 (32-bit)
|
||||||
- ARMv8 (AArch64)
|
4. ARMv8 (AArch64)
|
||||||
4. Supports only the Snappy compression scheme as described in
|
4. Supports only the Snappy compression scheme as described in
|
||||||
[format_description.txt](format_description.txt).
|
[format_description.txt](format_description.txt).
|
||||||
5. CMake for building
|
5. CMake for building
|
||||||
|
|||||||
@@ -58,12 +58,6 @@
|
|||||||
/* Define to 1 if you target processors with NEON and have <arm_neon.h>. */
|
/* Define to 1 if you target processors with NEON and have <arm_neon.h>. */
|
||||||
#cmakedefine01 SNAPPY_HAVE_NEON
|
#cmakedefine01 SNAPPY_HAVE_NEON
|
||||||
|
|
||||||
/* Define to 1 if you target processors with RVV1.0 and have <riscv_vector.h>. */
|
|
||||||
#cmakedefine01 SNAPPY_RVV_1
|
|
||||||
|
|
||||||
/* Define to 1 if you target processors with RVV0.7 and have <riscv_vector.h>. */
|
|
||||||
#cmakedefine01 SNAPPY_RVV_0_7
|
|
||||||
|
|
||||||
/* Define to 1 if you have <arm_neon.h> and <arm_acle.h> and want to optimize
|
/* Define to 1 if you have <arm_neon.h> and <arm_acle.h> and want to optimize
|
||||||
compression speed by using __crc32cw from <arm_acle.h>. */
|
compression speed by using __crc32cw from <arm_acle.h>. */
|
||||||
#cmakedefine01 SNAPPY_HAVE_NEON_CRC32
|
#cmakedefine01 SNAPPY_HAVE_NEON_CRC32
|
||||||
|
|||||||
@@ -46,24 +46,7 @@
|
|||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SNAPPY_RVV_1 || SNAPPY_RVV_0_7
|
#if SNAPPY_HAVE_SSSE3 || SNAPPY_HAVE_NEON
|
||||||
#define SNAPPY_HAVE_RVV 1
|
|
||||||
#include <riscv_vector.h>
|
|
||||||
#else
|
|
||||||
#define SNAPPY_HAVE_RVV 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SNAPPY_RVV_1
|
|
||||||
#define VSETVL_E8M2 __riscv_vsetvl_e8m2
|
|
||||||
#define VLE8_V_U8M2 __riscv_vle8_v_u8m2
|
|
||||||
#define VSE8_V_U8M2 __riscv_vse8_v_u8m2
|
|
||||||
#elif SNAPPY_RVV_0_7
|
|
||||||
#define VSETVL_E8M2 vsetvl_e8m2
|
|
||||||
#define VLE8_V_U8M2 vle8_v_u8m2
|
|
||||||
#define VSE8_V_U8M2 vse8_v_u8m2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SNAPPY_HAVE_SSSE3 || SNAPPY_HAVE_NEON
|
|
||||||
#define SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE 1
|
#define SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE 1
|
||||||
#else
|
#else
|
||||||
#define SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE 0
|
#define SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE 0
|
||||||
@@ -78,7 +61,7 @@ using V128 = __m128i;
|
|||||||
#elif SNAPPY_HAVE_NEON
|
#elif SNAPPY_HAVE_NEON
|
||||||
using V128 = uint8x16_t;
|
using V128 = uint8x16_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load 128 bits of integer data. `src` must be 16-byte aligned.
|
// Load 128 bits of integer data. `src` must be 16-byte aligned.
|
||||||
inline V128 V128_Load(const V128* src);
|
inline V128 V128_Load(const V128* src);
|
||||||
|
|
||||||
@@ -127,8 +110,6 @@ inline V128 V128_Shuffle(V128 input, V128 shuffle_mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline V128 V128_DupChar(char c) { return vdupq_n_u8(c); }
|
inline V128 V128_DupChar(char c) { return vdupq_n_u8(c); }
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif // SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
|
#endif // SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
|
||||||
|
|
||||||
@@ -191,10 +172,9 @@ char* CompressFragment(const char* input,
|
|||||||
// loading from s2 + n.
|
// loading from s2 + n.
|
||||||
//
|
//
|
||||||
// Separate implementation for 64-bit, little-endian cpus.
|
// Separate implementation for 64-bit, little-endian cpus.
|
||||||
// riscv and little-endian cpu choose this routinue can be done faster too.
|
|
||||||
#if !SNAPPY_IS_BIG_ENDIAN && \
|
#if !SNAPPY_IS_BIG_ENDIAN && \
|
||||||
(defined(__x86_64__) || defined(_M_X64) || defined(ARCH_PPC) || \
|
(defined(__x86_64__) || defined(_M_X64) || defined(ARCH_PPC) || \
|
||||||
defined(ARCH_ARM) || (defined(__riscv) && (__riscv_xlen == 64)))
|
defined(ARCH_ARM))
|
||||||
static inline std::pair<size_t, bool> FindMatchLength(const char* s1,
|
static inline std::pair<size_t, bool> FindMatchLength(const char* s1,
|
||||||
const char* s2,
|
const char* s2,
|
||||||
const char* s2_limit,
|
const char* s2_limit,
|
||||||
|
|||||||
@@ -304,8 +304,8 @@ class Bits {
|
|||||||
void operator=(const Bits&);
|
void operator=(const Bits&);
|
||||||
};
|
};
|
||||||
|
|
||||||
// In RISC-V, CLZ is supported by instructions from the ZBB bit-manipulation extension.
|
|
||||||
#if HAVE_BUILTIN_CTZ
|
#if HAVE_BUILTIN_CTZ
|
||||||
|
|
||||||
inline int Bits::Log2FloorNonZero(uint32_t n) {
|
inline int Bits::Log2FloorNonZero(uint32_t n) {
|
||||||
assert(n != 0);
|
assert(n != 0);
|
||||||
// (31 ^ x) is equivalent to (31 - x) for x in [0, 31]. An easy proof
|
// (31 ^ x) is equivalent to (31 - x) for x in [0, 31]. An easy proof
|
||||||
@@ -393,7 +393,6 @@ inline int Bits::FindLSBSetNonZero(uint32_t n) {
|
|||||||
|
|
||||||
#endif // End portable versions.
|
#endif // End portable versions.
|
||||||
|
|
||||||
// In RISC-V, CLZ is supported by instructions from the ZBB bit-manipulation extension.
|
|
||||||
#if HAVE_BUILTIN_CTZ
|
#if HAVE_BUILTIN_CTZ
|
||||||
|
|
||||||
inline int Bits::FindLSBSetNonZero64(uint64_t n) {
|
inline int Bits::FindLSBSetNonZero64(uint64_t n) {
|
||||||
|
|||||||
117
snappy.cc
117
snappy.cc
@@ -74,7 +74,6 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -281,8 +280,6 @@ inline char* IncrementalCopySlow(const char* src, char* op,
|
|||||||
// 4, 5, 0, 1, 2, 3, 4, 5, 0, 1}. These byte index sequences are generated by
|
// 4, 5, 0, 1, 2, 3, 4, 5, 0, 1}. These byte index sequences are generated by
|
||||||
// calling MakePatternMaskBytes(0, 6, index_sequence<16>()) and
|
// calling MakePatternMaskBytes(0, 6, index_sequence<16>()) and
|
||||||
// MakePatternMaskBytes(16, 6, index_sequence<16>()) respectively.
|
// MakePatternMaskBytes(16, 6, index_sequence<16>()) respectively.
|
||||||
|
|
||||||
|
|
||||||
template <size_t... indexes>
|
template <size_t... indexes>
|
||||||
inline constexpr std::array<char, sizeof...(indexes)> MakePatternMaskBytes(
|
inline constexpr std::array<char, sizeof...(indexes)> MakePatternMaskBytes(
|
||||||
int index_offset, int pattern_size, index_sequence<indexes...>) {
|
int index_offset, int pattern_size, index_sequence<indexes...>) {
|
||||||
@@ -300,6 +297,7 @@ MakePatternMaskBytesTable(int index_offset,
|
|||||||
MakePatternMaskBytes(index_offset, pattern_sizes_minus_one + 1,
|
MakePatternMaskBytes(index_offset, pattern_sizes_minus_one + 1,
|
||||||
make_index_sequence</*indexes=*/sizeof(V128)>())...};
|
make_index_sequence</*indexes=*/sizeof(V128)>())...};
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an array of shuffle control masks that can be used as the source
|
// This is an array of shuffle control masks that can be used as the source
|
||||||
// operand for PSHUFB to permute the contents of the destination XMM register
|
// operand for PSHUFB to permute the contents of the destination XMM register
|
||||||
// into a repeating byte pattern.
|
// into a repeating byte pattern.
|
||||||
@@ -330,6 +328,7 @@ static inline V128 LoadPattern(const char* src, const size_t pattern_size) {
|
|||||||
return V128_Shuffle(V128_LoadU(reinterpret_cast<const V128*>(src)),
|
return V128_Shuffle(V128_LoadU(reinterpret_cast<const V128*>(src)),
|
||||||
generation_mask);
|
generation_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNAPPY_ATTRIBUTE_ALWAYS_INLINE
|
SNAPPY_ATTRIBUTE_ALWAYS_INLINE
|
||||||
static inline std::pair<V128 /* pattern */, V128 /* reshuffle_mask */>
|
static inline std::pair<V128 /* pattern */, V128 /* reshuffle_mask */>
|
||||||
LoadPatternAndReshuffleMask(const char* src, const size_t pattern_size) {
|
LoadPatternAndReshuffleMask(const char* src, const size_t pattern_size) {
|
||||||
@@ -345,6 +344,7 @@ LoadPatternAndReshuffleMask(const char* src, const size_t pattern_size) {
|
|||||||
pattern_reshuffle_masks[pattern_size - 1].data()));
|
pattern_reshuffle_masks[pattern_size - 1].data()));
|
||||||
return {pattern, reshuffle_mask};
|
return {pattern, reshuffle_mask};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
|
#endif // SNAPPY_HAVE_VECTOR_BYTE_SHUFFLE
|
||||||
|
|
||||||
// Fallback for when we need to copy while extending the pattern, for example
|
// Fallback for when we need to copy while extending the pattern, for example
|
||||||
@@ -493,6 +493,7 @@ inline char* IncrementalCopy(const char* src, char* op, char* const op_limit,
|
|||||||
LoadPatternAndReshuffleMask(src, pattern_size);
|
LoadPatternAndReshuffleMask(src, pattern_size);
|
||||||
V128 pattern = pattern_and_reshuffle_mask.first;
|
V128 pattern = pattern_and_reshuffle_mask.first;
|
||||||
V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
|
V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
|
||||||
|
|
||||||
// There is at least one, and at most four 16-byte blocks. Writing four
|
// There is at least one, and at most four 16-byte blocks. Writing four
|
||||||
// conditionals instead of a loop allows FDO to layout the code with
|
// conditionals instead of a loop allows FDO to layout the code with
|
||||||
// respect to the actual probabilities of each length.
|
// respect to the actual probabilities of each length.
|
||||||
@@ -519,6 +520,7 @@ inline char* IncrementalCopy(const char* src, char* op, char* const op_limit,
|
|||||||
LoadPatternAndReshuffleMask(src, pattern_size);
|
LoadPatternAndReshuffleMask(src, pattern_size);
|
||||||
V128 pattern = pattern_and_reshuffle_mask.first;
|
V128 pattern = pattern_and_reshuffle_mask.first;
|
||||||
V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
|
V128 reshuffle_mask = pattern_and_reshuffle_mask.second;
|
||||||
|
|
||||||
// This code path is relatively cold however so we save code size
|
// This code path is relatively cold however so we save code size
|
||||||
// by avoiding unrolling and vectorizing.
|
// by avoiding unrolling and vectorizing.
|
||||||
//
|
//
|
||||||
@@ -957,8 +959,6 @@ emit_remainder:
|
|||||||
char* CompressFragmentDoubleHash(const char* input, size_t input_size, char* op,
|
char* CompressFragmentDoubleHash(const char* input, size_t input_size, char* op,
|
||||||
uint16_t* table, const int table_size,
|
uint16_t* table, const int table_size,
|
||||||
uint16_t* table2, const int table_size2) {
|
uint16_t* table2, const int table_size2) {
|
||||||
(void)table_size2;
|
|
||||||
assert(table_size == table_size2);
|
|
||||||
// "ip" is the input pointer, and "op" is the output pointer.
|
// "ip" is the input pointer, and "op" is the output pointer.
|
||||||
const char* ip = input;
|
const char* ip = input;
|
||||||
assert(input_size <= kBlockSize);
|
assert(input_size <= kBlockSize);
|
||||||
@@ -1224,7 +1224,7 @@ inline bool Copy64BytesWithPatternExtension(ptrdiff_t dst, size_t offset) {
|
|||||||
void MemCopy64(char* dst, const void* src, size_t size) {
|
void MemCopy64(char* dst, const void* src, size_t size) {
|
||||||
// Always copy this many bytes. If that's below size then copy the full 64.
|
// Always copy this many bytes. If that's below size then copy the full 64.
|
||||||
constexpr int kShortMemCopy = 32;
|
constexpr int kShortMemCopy = 32;
|
||||||
(void)kShortMemCopy;
|
|
||||||
assert(size <= 64);
|
assert(size <= 64);
|
||||||
assert(std::less_equal<const void*>()(static_cast<const char*>(src) + size,
|
assert(std::less_equal<const void*>()(static_cast<const char*>(src) + size,
|
||||||
dst) ||
|
dst) ||
|
||||||
@@ -1243,27 +1243,6 @@ void MemCopy64(char* dst, const void* src, size_t size) {
|
|||||||
data = _mm256_lddqu_si256(static_cast<const __m256i *>(src) + 1);
|
data = _mm256_lddqu_si256(static_cast<const __m256i *>(src) + 1);
|
||||||
_mm256_storeu_si256(reinterpret_cast<__m256i *>(dst) + 1, data);
|
_mm256_storeu_si256(reinterpret_cast<__m256i *>(dst) + 1, data);
|
||||||
}
|
}
|
||||||
// RVV acceleration available on RISC-V when compiled with -march=rv64gcv
|
|
||||||
#elif defined(__riscv) && SNAPPY_HAVE_RVV
|
|
||||||
// Cast pointers to the type we will operate on.
|
|
||||||
unsigned char* dst_ptr = reinterpret_cast<unsigned char*>(dst);
|
|
||||||
const unsigned char* src_ptr = reinterpret_cast<const unsigned char*>(src);
|
|
||||||
size_t remaining_bytes = size;
|
|
||||||
// Loop as long as there are bytes remaining to be copied.
|
|
||||||
while (remaining_bytes > 0) {
|
|
||||||
// Set vector configuration: e8 (8-bit elements), m2 (LMUL=2).
|
|
||||||
// Use e8m2 configuration to maximize throughput.
|
|
||||||
size_t vl = VSETVL_E8M2(remaining_bytes);
|
|
||||||
// Load data from the current source pointer.
|
|
||||||
vuint8m2_t vec = VLE8_V_U8M2(src_ptr, vl);
|
|
||||||
// Store data to the current destination pointer.
|
|
||||||
VSE8_V_U8M2(dst_ptr, vec, vl);
|
|
||||||
// Update pointers and the remaining count.
|
|
||||||
src_ptr += vl;
|
|
||||||
dst_ptr += vl;
|
|
||||||
remaining_bytes -= vl;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
std::memmove(dst, src, kShortMemCopy);
|
std::memmove(dst, src, kShortMemCopy);
|
||||||
// Profiling shows that nearly all copies are short.
|
// Profiling shows that nearly all copies are short.
|
||||||
@@ -1363,32 +1342,6 @@ inline size_t AdvanceToNextTagX86Optimized(const uint8_t** ip_p, size_t* tag) {
|
|||||||
return tag_type;
|
return tag_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNAPPY_ATTRIBUTE_ALWAYS_INLINE
|
|
||||||
inline size_t AdvanceToNextTagRVOptimized(const uint8_t** ip_p, size_t* tag) {
|
|
||||||
const uint8_t*& ip = *ip_p;
|
|
||||||
// This section is crucial for the throughput of the decompression loop.
|
|
||||||
// The latency of an iteration is fundamentally constrained by the data chain on ip:
|
|
||||||
// ip -> c = *tag -> literal_len = c >> 2, tag_type = c & 3
|
|
||||||
// -> literal_advance = literal_len + 2, copy_advance = tag_type + 1
|
|
||||||
// -> next_ip = ip + literal_advance OR ip + copy_advance (literal vs copy)
|
|
||||||
// -> *tag = byte at (next_ip - 1); ip = next_ip
|
|
||||||
//
|
|
||||||
// Base RISC-V has no x86-style cmov and no AArch64 csinc on the same shape; this
|
|
||||||
// computes both candidate advances and both load offsets, then selects with
|
|
||||||
// (is_literal ? ... : ...). With the Zicond extension (czero.eqz / czero.nez), those
|
|
||||||
// selections typically lower to branchless conditional-zero ops instead of a
|
|
||||||
// hard-to-predict literal/copy branch, which is why this form tends to win there.
|
|
||||||
const size_t literal_len = *tag >> 2;
|
|
||||||
const size_t tag_type = *tag & 3;
|
|
||||||
const bool is_literal = (tag_type == 0);
|
|
||||||
const size_t copy_advance = tag_type + 1;
|
|
||||||
const size_t literal_advance = literal_len + 2;
|
|
||||||
const uint8_t* next_ip = is_literal ? (ip + literal_advance) : (ip + copy_advance);
|
|
||||||
*tag = is_literal ? ip[literal_advance - 1] : ip[copy_advance - 1];
|
|
||||||
ip = next_ip;
|
|
||||||
return tag_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the offset for copy-1 and copy-2 returns 0 for literals or copy-4.
|
// Extract the offset for copy-1 and copy-2 returns 0 for literals or copy-4.
|
||||||
inline uint32_t ExtractOffset(uint32_t val, size_t tag_type) {
|
inline uint32_t ExtractOffset(uint32_t val, size_t tag_type) {
|
||||||
// For x86 non-static storage works better. For ARM static storage is better.
|
// For x86 non-static storage works better. For ARM static storage is better.
|
||||||
@@ -1401,13 +1354,7 @@ inline uint32_t ExtractOffset(uint32_t val, size_t tag_type) {
|
|||||||
reinterpret_cast<const char*>(&kExtractMasksCombined) + 2 * tag_type,
|
reinterpret_cast<const char*>(&kExtractMasksCombined) + 2 * tag_type,
|
||||||
sizeof(result));
|
sizeof(result));
|
||||||
return val & result;
|
return val & result;
|
||||||
// For AArch64 and RISC-V, use a bit-twiddling trick to extract the mask from a
|
#elif defined(__aarch64__)
|
||||||
// single combined constant instead of a lookup table. The constant packs multiple
|
|
||||||
// 16-bit masks based on tag_type (see implementation below). The code calculates
|
|
||||||
// the shift amount from tag_type, right-shifts the constant to move the desired
|
|
||||||
// mask to the LSB position, then extracts it with & 0xFFFF. This branchless
|
|
||||||
// approach is often more performant on modern CPUs.
|
|
||||||
#elif defined(__aarch64__) || (defined(__riscv) && (__riscv_xlen == 64))
|
|
||||||
constexpr uint64_t kExtractMasksCombined = 0x0000FFFF00FF0000ull;
|
constexpr uint64_t kExtractMasksCombined = 0x0000FFFF00FF0000ull;
|
||||||
return val & static_cast<uint32_t>(
|
return val & static_cast<uint32_t>(
|
||||||
(kExtractMasksCombined >> (tag_type * 16)) & 0xFFFF);
|
(kExtractMasksCombined >> (tag_type * 16)) & 0xFFFF);
|
||||||
@@ -1471,11 +1418,6 @@ std::pair<const uint8_t*, ptrdiff_t> DecompressBranchless(
|
|||||||
// We never need more than 16 bits. Doing a Load16 allows the compiler
|
// We never need more than 16 bits. Doing a Load16 allows the compiler
|
||||||
// to elide the masking operation in ExtractOffset.
|
// to elide the masking operation in ExtractOffset.
|
||||||
next = LittleEndian::Load16(old_ip);
|
next = LittleEndian::Load16(old_ip);
|
||||||
#elif defined(__riscv)
|
|
||||||
size_t tag_type = AdvanceToNextTagRVOptimized(&ip, &tag);
|
|
||||||
// We never need more than 16 bits. Doing a Load16 allows the compiler
|
|
||||||
// to elide the masking operation in ExtractOffset.
|
|
||||||
next = LittleEndian::Load16(old_ip);
|
|
||||||
#else
|
#else
|
||||||
size_t tag_type = AdvanceToNextTagX86Optimized(&ip, &tag);
|
size_t tag_type = AdvanceToNextTagX86Optimized(&ip, &tag);
|
||||||
next = LittleEndian::Load32(old_ip);
|
next = LittleEndian::Load32(old_ip);
|
||||||
@@ -1554,7 +1496,7 @@ class SnappyDecompressor {
|
|||||||
// If ip < ip_limit_min_maxtaglen_ it's safe to read kMaxTagLength from
|
// If ip < ip_limit_min_maxtaglen_ it's safe to read kMaxTagLength from
|
||||||
// buffer.
|
// buffer.
|
||||||
const char* ip_limit_min_maxtaglen_;
|
const char* ip_limit_min_maxtaglen_;
|
||||||
uint64_t peeked_; // Bytes peeked from reader (need to skip)
|
uint32_t peeked_; // Bytes peeked from reader (need to skip)
|
||||||
bool eof_; // Hit end of input without an error?
|
bool eof_; // Hit end of input without an error?
|
||||||
char scratch_[kMaximumTagLength]; // See RefillTag().
|
char scratch_[kMaximumTagLength]; // See RefillTag().
|
||||||
|
|
||||||
@@ -1745,8 +1687,7 @@ constexpr uint32_t CalculateNeeded(uint8_t tag) {
|
|||||||
#if __cplusplus >= 201402L
|
#if __cplusplus >= 201402L
|
||||||
constexpr bool VerifyCalculateNeeded() {
|
constexpr bool VerifyCalculateNeeded() {
|
||||||
for (int i = 0; i < 1; i++) {
|
for (int i = 0; i < 1; i++) {
|
||||||
if (CalculateNeeded(i) != static_cast<uint32_t>((char_table[i] >> 11)) + 1)
|
if (CalculateNeeded(i) != (char_table[i] >> 11) + 1) return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1782,7 +1723,7 @@ bool SnappyDecompressor::RefillTag() {
|
|||||||
assert(needed <= sizeof(scratch_));
|
assert(needed <= sizeof(scratch_));
|
||||||
|
|
||||||
// Read more bytes from reader if needed
|
// Read more bytes from reader if needed
|
||||||
uint64_t nbuf = ip_limit_ - ip;
|
uint32_t nbuf = ip_limit_ - ip;
|
||||||
if (nbuf < needed) {
|
if (nbuf < needed) {
|
||||||
// Stitch together bytes from ip and reader to form the word
|
// Stitch together bytes from ip and reader to form the word
|
||||||
// contents. We store the needed bytes in "scratch_". They
|
// contents. We store the needed bytes in "scratch_". They
|
||||||
@@ -1795,7 +1736,7 @@ bool SnappyDecompressor::RefillTag() {
|
|||||||
size_t length;
|
size_t length;
|
||||||
const char* src = reader_->Peek(&length);
|
const char* src = reader_->Peek(&length);
|
||||||
if (length == 0) return false;
|
if (length == 0) return false;
|
||||||
uint64_t to_add = std::min<uint64_t>(needed - nbuf, length);
|
uint32_t to_add = std::min<uint32_t>(needed - nbuf, length);
|
||||||
std::memcpy(scratch_ + nbuf, src, to_add);
|
std::memcpy(scratch_ + nbuf, src, to_add);
|
||||||
nbuf += to_add;
|
nbuf += to_add;
|
||||||
reader_->Skip(to_add);
|
reader_->Skip(to_add);
|
||||||
@@ -1849,16 +1790,11 @@ bool GetUncompressedLength(Source* source, uint32_t* result) {
|
|||||||
return decompressor.ReadUncompressedLength(result);
|
return decompressor.ReadUncompressedLength(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Compress(Source* reader, Sink* writer) {
|
|
||||||
return Compress(reader, writer, CompressionOptions{});
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Compress(Source* reader, Sink* writer, CompressionOptions options) {
|
size_t Compress(Source* reader, Sink* writer, CompressionOptions options) {
|
||||||
assert(options.level == 1 || options.level == 2);
|
assert(options.level == 1 || options.level == 2);
|
||||||
int token = 0;
|
int token = 0;
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
size_t N = reader->Available();
|
size_t N = reader->Available();
|
||||||
assert(N <= 0xFFFFFFFFu);
|
|
||||||
const size_t uncompressed_size = N;
|
const size_t uncompressed_size = N;
|
||||||
char ulength[Varint::kMax32];
|
char ulength[Varint::kMax32];
|
||||||
char* p = Varint::Encode32(ulength, N);
|
char* p = Varint::Encode32(ulength, N);
|
||||||
@@ -1950,16 +1886,16 @@ class SnappyIOVecReader : public Source {
|
|||||||
if (total_size > 0 && curr_size_remaining_ == 0) Advance();
|
if (total_size > 0 && curr_size_remaining_ == 0) Advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
~SnappyIOVecReader() override = default;
|
~SnappyIOVecReader() = default;
|
||||||
|
|
||||||
size_t Available() const override { return total_size_remaining_; }
|
size_t Available() const { return total_size_remaining_; }
|
||||||
|
|
||||||
const char* Peek(size_t* len) override {
|
const char* Peek(size_t* len) {
|
||||||
*len = curr_size_remaining_;
|
*len = curr_size_remaining_;
|
||||||
return curr_pos_;
|
return curr_pos_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skip(size_t n) override {
|
void Skip(size_t n) {
|
||||||
while (n >= curr_size_remaining_ && n > 0) {
|
while (n >= curr_size_remaining_ && n > 0) {
|
||||||
n -= curr_size_remaining_;
|
n -= curr_size_remaining_;
|
||||||
Advance();
|
Advance();
|
||||||
@@ -2360,12 +2296,6 @@ bool IsValidCompressed(Source* compressed) {
|
|||||||
return InternalUncompress(compressed, &writer);
|
return InternalUncompress(compressed, &writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawCompress(const char* input, size_t input_length, char* compressed,
|
|
||||||
size_t* compressed_length) {
|
|
||||||
RawCompress(input, input_length, compressed, compressed_length,
|
|
||||||
CompressionOptions{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RawCompress(const char* input, size_t input_length, char* compressed,
|
void RawCompress(const char* input, size_t input_length, char* compressed,
|
||||||
size_t* compressed_length, CompressionOptions options) {
|
size_t* compressed_length, CompressionOptions options) {
|
||||||
ByteArraySource reader(input, input_length);
|
ByteArraySource reader(input, input_length);
|
||||||
@@ -2376,12 +2306,6 @@ void RawCompress(const char* input, size_t input_length, char* compressed,
|
|||||||
*compressed_length = (writer.CurrentDestination() - compressed);
|
*compressed_length = (writer.CurrentDestination() - compressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
|
||||||
char* compressed, size_t* compressed_length) {
|
|
||||||
RawCompressFromIOVec(iov, uncompressed_length, compressed, compressed_length,
|
|
||||||
CompressionOptions{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
||||||
char* compressed, size_t* compressed_length,
|
char* compressed, size_t* compressed_length,
|
||||||
CompressionOptions options) {
|
CompressionOptions options) {
|
||||||
@@ -2393,11 +2317,6 @@ void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
|||||||
*compressed_length = writer.CurrentDestination() - compressed;
|
*compressed_length = writer.CurrentDestination() - compressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Compress(const char* input, size_t input_length,
|
|
||||||
std::string* compressed) {
|
|
||||||
return Compress(input, input_length, compressed, CompressionOptions{});
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Compress(const char* input, size_t input_length, std::string* compressed,
|
size_t Compress(const char* input, size_t input_length, std::string* compressed,
|
||||||
CompressionOptions options) {
|
CompressionOptions options) {
|
||||||
// Pre-grow the buffer to the max length of the compressed output
|
// Pre-grow the buffer to the max length of the compressed output
|
||||||
@@ -2410,11 +2329,6 @@ size_t Compress(const char* input, size_t input_length, std::string* compressed,
|
|||||||
return compressed_length;
|
return compressed_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt,
|
|
||||||
std::string* compressed) {
|
|
||||||
return CompressFromIOVec(iov, iov_cnt, compressed, CompressionOptions{});
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt,
|
size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt,
|
||||||
std::string* compressed, CompressionOptions options) {
|
std::string* compressed, CompressionOptions options) {
|
||||||
// Compute the number of bytes to be compressed.
|
// Compute the number of bytes to be compressed.
|
||||||
@@ -2619,6 +2533,7 @@ bool SnappyScatteredWriter<Allocator>::SlowAppendFromSelf(size_t offset,
|
|||||||
class SnappySinkAllocator {
|
class SnappySinkAllocator {
|
||||||
public:
|
public:
|
||||||
explicit SnappySinkAllocator(Sink* dest) : dest_(dest) {}
|
explicit SnappySinkAllocator(Sink* dest) : dest_(dest) {}
|
||||||
|
~SnappySinkAllocator() {}
|
||||||
|
|
||||||
char* Allocate(int size) {
|
char* Allocate(int size) {
|
||||||
Datablock block(new char[size], size);
|
Datablock block(new char[size], size);
|
||||||
|
|||||||
25
snappy.h
25
snappy.h
@@ -64,9 +64,6 @@ namespace snappy {
|
|||||||
// faster decompression speeds than snappy:1 and zstd:-3.
|
// faster decompression speeds than snappy:1 and zstd:-3.
|
||||||
int level = DefaultCompressionLevel();
|
int level = DefaultCompressionLevel();
|
||||||
|
|
||||||
constexpr CompressionOptions() = default;
|
|
||||||
constexpr CompressionOptions(int compression_level)
|
|
||||||
: level(compression_level) {}
|
|
||||||
static constexpr int MinCompressionLevel() { return 1; }
|
static constexpr int MinCompressionLevel() { return 1; }
|
||||||
static constexpr int MaxCompressionLevel() { return 2; }
|
static constexpr int MaxCompressionLevel() { return 2; }
|
||||||
static constexpr int DefaultCompressionLevel() { return 1; }
|
static constexpr int DefaultCompressionLevel() { return 1; }
|
||||||
@@ -78,10 +75,8 @@ namespace snappy {
|
|||||||
|
|
||||||
// Compress the bytes read from "*reader" and append to "*writer". Return the
|
// Compress the bytes read from "*reader" and append to "*writer". Return the
|
||||||
// number of bytes written.
|
// number of bytes written.
|
||||||
// First version is to preserve ABI.
|
|
||||||
size_t Compress(Source* reader, Sink* writer);
|
|
||||||
size_t Compress(Source* reader, Sink* writer,
|
size_t Compress(Source* reader, Sink* writer,
|
||||||
CompressionOptions options);
|
CompressionOptions options = {});
|
||||||
|
|
||||||
// Find the uncompressed length of the given stream, as given by the header.
|
// Find the uncompressed length of the given stream, as given by the header.
|
||||||
// Note that the true length could deviate from this; the stream could e.g.
|
// Note that the true length could deviate from this; the stream could e.g.
|
||||||
@@ -100,22 +95,16 @@ namespace snappy {
|
|||||||
// Original contents of *compressed are lost.
|
// Original contents of *compressed are lost.
|
||||||
//
|
//
|
||||||
// REQUIRES: "input[]" is not an alias of "*compressed".
|
// REQUIRES: "input[]" is not an alias of "*compressed".
|
||||||
// First version is to preserve ABI.
|
|
||||||
size_t Compress(const char* input, size_t input_length,
|
size_t Compress(const char* input, size_t input_length,
|
||||||
std::string* compressed);
|
std::string* compressed, CompressionOptions options = {});
|
||||||
size_t Compress(const char* input, size_t input_length,
|
|
||||||
std::string* compressed, CompressionOptions options);
|
|
||||||
|
|
||||||
// Same as `Compress` above but taking an `iovec` array as input. Note that
|
// Same as `Compress` above but taking an `iovec` array as input. Note that
|
||||||
// this function preprocesses the inputs to compute the sum of
|
// this function preprocesses the inputs to compute the sum of
|
||||||
// `iov[0..iov_cnt-1].iov_len` before reading. To avoid this, use
|
// `iov[0..iov_cnt-1].iov_len` before reading. To avoid this, use
|
||||||
// `RawCompressFromIOVec` below.
|
// `RawCompressFromIOVec` below.
|
||||||
// First version is to preserve ABI.
|
|
||||||
size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt,
|
|
||||||
std::string* compressed);
|
|
||||||
size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt,
|
size_t CompressFromIOVec(const struct iovec* iov, size_t iov_cnt,
|
||||||
std::string* compressed,
|
std::string* compressed,
|
||||||
CompressionOptions options);
|
CompressionOptions options = {});
|
||||||
|
|
||||||
// Decompresses "compressed[0..compressed_length-1]" to "*uncompressed".
|
// Decompresses "compressed[0..compressed_length-1]" to "*uncompressed".
|
||||||
// Original contents of "*uncompressed" are lost.
|
// Original contents of "*uncompressed" are lost.
|
||||||
@@ -159,18 +148,14 @@ namespace snappy {
|
|||||||
// ... Process(output, output_length) ...
|
// ... Process(output, output_length) ...
|
||||||
// delete [] output;
|
// delete [] output;
|
||||||
void RawCompress(const char* input, size_t input_length, char* compressed,
|
void RawCompress(const char* input, size_t input_length, char* compressed,
|
||||||
size_t* compressed_length);
|
size_t* compressed_length, CompressionOptions options = {});
|
||||||
void RawCompress(const char* input, size_t input_length, char* compressed,
|
|
||||||
size_t* compressed_length, CompressionOptions options);
|
|
||||||
|
|
||||||
// Same as `RawCompress` above but taking an `iovec` array as input. Note that
|
// Same as `RawCompress` above but taking an `iovec` array as input. Note that
|
||||||
// `uncompressed_length` is the total number of bytes to be read from the
|
// `uncompressed_length` is the total number of bytes to be read from the
|
||||||
// elements of `iov` (_not_ the number of elements in `iov`).
|
// elements of `iov` (_not_ the number of elements in `iov`).
|
||||||
void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
|
||||||
char* compressed, size_t* compressed_length);
|
|
||||||
void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
void RawCompressFromIOVec(const struct iovec* iov, size_t uncompressed_length,
|
||||||
char* compressed, size_t* compressed_length,
|
char* compressed, size_t* compressed_length,
|
||||||
CompressionOptions options);
|
CompressionOptions options = {});
|
||||||
|
|
||||||
// Given data in "compressed[0..compressed_length-1]" generated by
|
// Given data in "compressed[0..compressed_length-1]" generated by
|
||||||
// calling the Snappy::Compress routine, this routine
|
// calling the Snappy::Compress routine, this routine
|
||||||
|
|||||||
@@ -31,10 +31,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "snappy-test.h"
|
||||||
|
|
||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
|
|
||||||
#include "snappy-internal.h"
|
#include "snappy-internal.h"
|
||||||
#include "snappy-sinksource.h"
|
#include "snappy-sinksource.h"
|
||||||
#include "snappy-test.h"
|
|
||||||
#include "snappy.h"
|
#include "snappy.h"
|
||||||
#include "snappy_test_data.h"
|
#include "snappy_test_data.h"
|
||||||
|
|
||||||
@@ -42,7 +44,7 @@ namespace snappy {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void FilesAndLevels(benchmark::internal::Benchmark* benchmark) {
|
void FilesAndLevels(::testing::Benchmark* benchmark) {
|
||||||
for (int i = 0; i < ARRAYSIZE(kTestDataFiles); ++i) {
|
for (int i = 0; i < ARRAYSIZE(kTestDataFiles); ++i) {
|
||||||
for (int level = snappy::CompressionOptions::MinCompressionLevel();
|
for (int level = snappy::CompressionOptions::MinCompressionLevel();
|
||||||
level <= snappy::CompressionOptions::MaxCompressionLevel(); ++level) {
|
level <= snappy::CompressionOptions::MaxCompressionLevel(); ++level) {
|
||||||
@@ -62,9 +64,8 @@ void BM_UFlat(benchmark::State& state) {
|
|||||||
kTestDataFiles[file_index].size_limit);
|
kTestDataFiles[file_index].size_limit);
|
||||||
|
|
||||||
std::string zcontents;
|
std::string zcontents;
|
||||||
snappy::Compress(
|
snappy::Compress(contents.data(), contents.size(), &zcontents,
|
||||||
contents.data(), contents.size(), &zcontents,
|
snappy::CompressionOptions{.level = state.range(1)});
|
||||||
snappy::CompressionOptions{/*level=*/static_cast<int>(state.range(1))});
|
|
||||||
char* dst = new char[contents.size()];
|
char* dst = new char[contents.size()];
|
||||||
|
|
||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
@@ -128,9 +129,8 @@ void BM_UValidate(benchmark::State& state) {
|
|||||||
kTestDataFiles[file_index].size_limit);
|
kTestDataFiles[file_index].size_limit);
|
||||||
|
|
||||||
std::string zcontents;
|
std::string zcontents;
|
||||||
snappy::Compress(
|
snappy::Compress(contents.data(), contents.size(), &zcontents,
|
||||||
contents.data(), contents.size(), &zcontents,
|
snappy::CompressionOptions{.level = state.range(1)});
|
||||||
snappy::CompressionOptions{/*level=*/static_cast<int>(state.range(1))});
|
|
||||||
|
|
||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
CHECK(snappy::IsValidCompressedBuffer(zcontents.data(), zcontents.size()));
|
CHECK(snappy::IsValidCompressedBuffer(zcontents.data(), zcontents.size()));
|
||||||
@@ -193,7 +193,7 @@ void BM_UIOVecSource(benchmark::State& state) {
|
|||||||
size_t zsize = 0;
|
size_t zsize = 0;
|
||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
snappy::RawCompressFromIOVec(iov, contents.size(), dst, &zsize,
|
snappy::RawCompressFromIOVec(iov, contents.size(), dst, &zsize,
|
||||||
snappy::CompressionOptions{/*level=*/level});
|
snappy::CompressionOptions{.level = level});
|
||||||
benchmark::DoNotOptimize(iov);
|
benchmark::DoNotOptimize(iov);
|
||||||
}
|
}
|
||||||
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
|
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
|
||||||
@@ -226,7 +226,7 @@ void BM_UIOVecSink(benchmark::State& state) {
|
|||||||
// Uncompress into an iovec containing ten entries.
|
// Uncompress into an iovec containing ten entries.
|
||||||
const int kNumEntries = 10;
|
const int kNumEntries = 10;
|
||||||
struct iovec iov[kNumEntries];
|
struct iovec iov[kNumEntries];
|
||||||
char* dst = new char[contents.size()];
|
char *dst = new char[contents.size()];
|
||||||
size_t used_so_far = 0;
|
size_t used_so_far = 0;
|
||||||
for (int i = 0; i < kNumEntries; ++i) {
|
for (int i = 0; i < kNumEntries; ++i) {
|
||||||
iov[i].iov_base = dst + used_so_far;
|
iov[i].iov_base = dst + used_so_far;
|
||||||
@@ -267,9 +267,8 @@ void BM_UFlatSink(benchmark::State& state) {
|
|||||||
kTestDataFiles[file_index].size_limit);
|
kTestDataFiles[file_index].size_limit);
|
||||||
|
|
||||||
std::string zcontents;
|
std::string zcontents;
|
||||||
snappy::Compress(
|
snappy::Compress(contents.data(), contents.size(), &zcontents,
|
||||||
contents.data(), contents.size(), &zcontents,
|
snappy::CompressionOptions{.level = state.range(1)});
|
||||||
snappy::CompressionOptions{/*level=*/static_cast<int>(state.range(1))});
|
|
||||||
char* dst = new char[contents.size()];
|
char* dst = new char[contents.size()];
|
||||||
|
|
||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
@@ -305,7 +304,7 @@ void BM_ZFlat(benchmark::State& state) {
|
|||||||
size_t zsize = 0;
|
size_t zsize = 0;
|
||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
snappy::RawCompress(contents.data(), contents.size(), dst, &zsize,
|
snappy::RawCompress(contents.data(), contents.size(), dst, &zsize,
|
||||||
snappy::CompressionOptions{/*level=*/level});
|
snappy::CompressionOptions{.level = level});
|
||||||
benchmark::DoNotOptimize(dst);
|
benchmark::DoNotOptimize(dst);
|
||||||
}
|
}
|
||||||
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
|
state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
|
||||||
@@ -341,7 +340,7 @@ void BM_ZFlatAll(benchmark::State& state) {
|
|||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
for (int i = 0; i < num_files; ++i) {
|
for (int i = 0; i < num_files; ++i) {
|
||||||
snappy::RawCompress(contents[i].data(), contents[i].size(), dst[i],
|
snappy::RawCompress(contents[i].data(), contents[i].size(), dst[i],
|
||||||
&zsize, snappy::CompressionOptions{/*level=*/level});
|
&zsize, snappy::CompressionOptions{.level = level});
|
||||||
benchmark::DoNotOptimize(dst);
|
benchmark::DoNotOptimize(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -378,7 +377,7 @@ void BM_ZFlatIncreasingTableSize(benchmark::State& state) {
|
|||||||
for (auto s : state) {
|
for (auto s : state) {
|
||||||
for (size_t i = 0; i < contents.size(); ++i) {
|
for (size_t i = 0; i < contents.size(); ++i) {
|
||||||
snappy::RawCompress(contents[i].data(), contents[i].size(), dst[i],
|
snappy::RawCompress(contents[i].data(), contents[i].size(), dst[i],
|
||||||
&zsize, snappy::CompressionOptions{/*level=*/level});
|
&zsize, snappy::CompressionOptions{.level = level});
|
||||||
benchmark::DoNotOptimize(dst);
|
benchmark::DoNotOptimize(dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|||||||
std::string compressed;
|
std::string compressed;
|
||||||
size_t compressed_size =
|
size_t compressed_size =
|
||||||
snappy::Compress(input.data(), input.size(), &compressed,
|
snappy::Compress(input.data(), input.size(), &compressed,
|
||||||
snappy::CompressionOptions{/*level=*/level});
|
snappy::CompressionOptions{.level = level});
|
||||||
|
|
||||||
(void)compressed_size; // Variable only used in debug builds.
|
(void)compressed_size; // Variable only used in debug builds.
|
||||||
assert(compressed_size == compressed.size());
|
assert(compressed_size == compressed.size());
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cinttypes>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <random>
|
#include <random>
|
||||||
@@ -485,18 +484,6 @@ TEST(Snappy, MaxBlowup) {
|
|||||||
Verify(input);
|
Verify(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue #201, when output is more than 4GB, we had a data corruption bug.
|
|
||||||
// We cannot run this test always because of CI constraints.
|
|
||||||
TEST(Snappy, DISABLED_MoreThan4GB) {
|
|
||||||
std::mt19937 rng;
|
|
||||||
std::uniform_int_distribution<int> uniform_byte(0, 255);
|
|
||||||
std::string input;
|
|
||||||
input.resize((1ull << 32) - 1);
|
|
||||||
for (uint64_t i = 0; i < ((1ull << 32) - 1); ++i)
|
|
||||||
input[i] = static_cast<char>(uniform_byte(rng));
|
|
||||||
Verify(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Snappy, RandomData) {
|
TEST(Snappy, RandomData) {
|
||||||
std::minstd_rand0 rng(snappy::GetFlag(FLAGS_test_random_seed));
|
std::minstd_rand0 rng(snappy::GetFlag(FLAGS_test_random_seed));
|
||||||
std::uniform_int_distribution<int> uniform_0_to_3(0, 3);
|
std::uniform_int_distribution<int> uniform_0_to_3(0, 3);
|
||||||
|
|||||||
Reference in New Issue
Block a user