From a69595b3249cfb811b25777a41d7b0a20feaa777 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 18 Dec 2024 20:51:01 +0000 Subject: [PATCH] add zstd test --- CMakeLists.txt | 6 ++-- cmake/FindZSTD.cmake | 21 +++++++++++ src/create.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 cmake/FindZSTD.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f5cd61..7295dc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,9 @@ project(ec3) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +set(Bluelib_STATIC 1) find_package(Bluelib REQUIRED) -find_package(LibLZMA REQUIRED) +find_package(ZSTD REQUIRED) file(GLOB ec3_sources src/*.c @@ -16,5 +17,6 @@ target_link_libraries(ec3 Bluelib::Object Bluelib::Term Bluelib::Cmd - LibLZMA::LibLZMA) + ${ZSTD_LIBRARY}) +target_include_directories(ec3 PRIVATE ${ZSTD_INCLUDE_DIR}) \ No newline at end of file diff --git a/cmake/FindZSTD.cmake b/cmake/FindZSTD.cmake new file mode 100644 index 0000000..d821e46 --- /dev/null +++ b/cmake/FindZSTD.cmake @@ -0,0 +1,21 @@ +# taken from: https://github.com/facebook/folly/blob/master/CMake/FindZstd.cmake +# SPDX-FileCopyrightText: Facebook, Inc. and its affiliates. +# SPDX-License-Identifier: Apache-2.0 +# +# - Try to find Facebook zstd library +# This will define +# ZSTD_FOUND +# ZSTD_INCLUDE_DIR +# ZSTD_LIBRARY +# + +find_path(ZSTD_INCLUDE_DIR NAMES zstd.h) +find_library(ZSTD_LIBRARY NAMES zstd) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS( + ZSTD DEFAULT_MSG + ZSTD_LIBRARY ZSTD_INCLUDE_DIR +) + +mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY) diff --git a/src/create.c b/src/create.c index a8e6b73..07db466 100644 --- a/src/create.c +++ b/src/create.c @@ -1,8 +1,12 @@ #include "commands.h" #include +#include +#include +#include enum { + ARG_INPATH, OPT_OUTPATH, OPT_OUTPATH_PATH, }; @@ -12,6 +16,75 @@ static int create( const b_arglist *opt, const b_array *args) { + const char *in_path = NULL, *out_path = NULL; + + b_arglist_get_string(opt, B_COMMAND_INVALID_ID, ARG_INPATH, 0, &in_path); + b_arglist_get_string(opt, OPT_OUTPATH, OPT_OUTPATH_PATH, 0, &out_path); + + printf("in path: %s\n", in_path); + printf("out path: %s\n", out_path); + + size_t in_bufsz = ZSTD_CStreamInSize(); + size_t out_bufsz = ZSTD_CStreamOutSize(); + + printf("in buffer: %zu\n", in_bufsz); + printf("out buffer: %zu\n", out_bufsz); + + FILE *in = fopen(in_path, "rb"); + if (!in) { + return -1; + } + + FILE *out = fopen(out_path, "wb"); + if (!out) { + return -1; + } + + ZSTD_CCtx *zstd = ZSTD_createCCtx(); + ZSTD_CCtx_setParameter(zstd, ZSTD_c_compressionLevel, 22); + ZSTD_CCtx_setParameter(zstd, ZSTD_c_checksumFlag, 1); + + void *in_buf = malloc(in_bufsz); + void *out_buf = malloc(out_bufsz); + + size_t total = 0; + + while (1) { + size_t r = fread(in_buf, 1, in_bufsz, in); + if (r == 0) { + break; + } + + if ((total % 0x1000000) == 0) { + printf("read %zu MB bytes\n", total / 1000000); + } + total += r; + + bool last_chunk = r < in_bufsz; + ZSTD_EndDirective mode = last_chunk ? ZSTD_e_end : ZSTD_e_continue; + + ZSTD_inBuffer input = { in_buf, r, 0 }; + int finished; + do { + ZSTD_outBuffer output = { out_buf, out_bufsz, 0 }; + size_t remaining = ZSTD_compressStream2(zstd, &output, &input, mode); + + fwrite(out_buf, 1, output.pos, out); + + finished = last_chunk ? (remaining == 0) : (input.pos == input.size); + } while (!finished); + + if (last_chunk) { + break; + } + } + + ZSTD_freeCCtx(zstd); + fclose(out); + fclose(in); + free(in_buf); + free(out_buf); + return 0; } @@ -37,4 +110,14 @@ B_COMMAND(CMD_CREATE, CMD_ROOT) B_ARG_NR_VALUES(1); } } + + B_COMMAND_ARG(ARG_INPATH) { + B_ARG_NAME("input file"); + B_ARG_NR_VALUES(1); + } + + B_COMMAND_USAGE() { + B_COMMAND_USAGE_ARG(ARG_INPATH); + B_COMMAND_USAGE_OPT(OPT_OUTPATH); + } }