From 36a70f90de1f39e64d603afcba725f13d8387085 Mon Sep 17 00:00:00 2001 From: Ricardo Azpeitia Pimentel Date: Wed, 18 Jun 2025 08:39:04 -0500 Subject: [PATCH] Add enable long matching distance --- c_src/zstd_nif.c | 10 +++++++++- src/zstd.erl | 9 +++++++-- test/zstd_tests.erl | 10 +++++++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/c_src/zstd_nif.c b/c_src/zstd_nif.c index 7efaf03..894395e 100644 --- a/c_src/zstd_nif.c +++ b/c_src/zstd_nif.c @@ -112,6 +112,7 @@ static ERL_NIF_TERM zstd_nif_new_decompression_stream(ErlNifEnv* env, int argc, static ERL_NIF_TERM zstd_nif_init_compression_stream(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int level = ZSTD_CLEVEL_DEFAULT; int window_log = 0; + int enable_long_distance_matching = 0; size_t ret; ZSTD_CStream **pzcs; @@ -124,7 +125,11 @@ static ERL_NIF_TERM zstd_nif_init_compression_stream(ErlNifEnv* env, int argc, c return enif_make_badarg(env); /* extract the window log if any */ - if ((argc == 3) && !(enif_get_int(env, argv[2], &window_log))) + if ((argc >= 3) && !(enif_get_int(env, argv[2], &window_log))) + return enif_make_badarg(env); + + /* extract the enable long distance matching if any */ + if ((argc == 4) && !(enif_get_int(env, argv[3], &enable_long_distance_matching))) return enif_make_badarg(env); /* initialize the stream */ @@ -132,6 +137,8 @@ static ERL_NIF_TERM zstd_nif_init_compression_stream(ErlNifEnv* env, int argc, c return enif_make_tuple2(env, zstd_atom_error, enif_make_string(env, ZSTD_getErrorName(ret), ERL_NIF_LATIN1)); if (ZSTD_isError(ret = ZSTD_CCtx_setParameter(*pzcs, ZSTD_c_windowLog, window_log))) return enif_make_tuple2(env, zstd_atom_error, enif_make_string(env, ZSTD_getErrorName(ret), ERL_NIF_LATIN1)); + if (ZSTD_isError(ret = ZSTD_CCtx_setParameter(*pzcs, ZSTD_c_enableLongDistanceMatching, enable_long_distance_matching))) + return enif_make_tuple2(env, zstd_atom_error, enif_make_string(env, ZSTD_getErrorName(ret), ERL_NIF_LATIN1)); if (ZSTD_isError(ret = ZSTD_CCtx_setParameter(*pzcs, ZSTD_c_checksumFlag, 1))) return enif_make_tuple2(env, zstd_atom_error, enif_make_string(env, ZSTD_getErrorName(ret), ERL_NIF_LATIN1)); @@ -423,6 +430,7 @@ static ErlNifFunc nif_funcs[] = { { "compression_stream_init" , 1, zstd_nif_init_compression_stream , ERL_DIRTY_JOB_CPU_BOUND }, { "compression_stream_init" , 2, zstd_nif_init_compression_stream , ERL_DIRTY_JOB_CPU_BOUND }, { "compression_stream_init" , 3, zstd_nif_init_compression_stream , ERL_DIRTY_JOB_CPU_BOUND }, + { "compression_stream_init" , 4, zstd_nif_init_compression_stream , ERL_DIRTY_JOB_CPU_BOUND }, { "decompression_stream_init" , 1, zstd_nif_init_decompression_stream , ERL_DIRTY_JOB_CPU_BOUND }, { "compression_stream_reset" , 2, zstd_nif_reset_compression_stream }, diff --git a/src/zstd.erl b/src/zstd.erl index b8f924b..44e968f 100644 --- a/src/zstd.erl +++ b/src/zstd.erl @@ -3,8 +3,8 @@ -export([compress/1, compress/2]). -export([decompress/1]). -export([new_compression_stream/0, compression_stream_init/1, compression_stream_init/2, - compression_stream_init/3, compression_stream_reset/1, compression_stream_reset/2, - stream_compress/2, stream_flush/1, new_decompression_stream/0, + compression_stream_init/3, compression_stream_init/4, compression_stream_reset/1, + compression_stream_reset/2, stream_compress/2, stream_flush/1, new_decompression_stream/0, decompression_stream_init/1, decompression_stream_reset/1, stream_decompress/2]). -on_load init/0. @@ -46,6 +46,11 @@ compression_stream_init(_Ref, _Level) -> compression_stream_init(_Ref, _Level, _WindowLog) -> erlang:nif_error(?LINE). +-spec compression_stream_init(reference(), 0..22, integer(), integer()) -> + ok | {error, invalid | string()}. +compression_stream_init(_Ref, _Level, _WindowLog, _EnableLongDistanceMatching) -> + erlang:nif_error(?LINE). + -spec decompression_stream_init(reference()) -> ok | {error, invalid | string()}. decompression_stream_init(_Ref) -> erlang:nif_error(?LINE). diff --git a/test/zstd_tests.erl b/test/zstd_tests.erl index d413b02..51b78b8 100644 --- a/test/zstd_tests.erl +++ b/test/zstd_tests.erl @@ -1,5 +1,9 @@ -module(zstd_tests). +-define(COMPRESSION_LEVEL, 5). +-define(WINDOW_LOG, 23). +-define(ENABLE_LONG_DISTANCE_MATCHING, 1). + -include_lib("eunit/include/eunit.hrl"). zstd_test() -> @@ -11,7 +15,11 @@ zstd_test() -> zstd_stream_test() -> Bin = << <<"A">> || _ <- lists:seq(1, 1024 * 1024) >>, CStream = zstd:new_compression_stream(), - ok = zstd:compression_stream_init(CStream, 5, 23), + ok = + zstd:compression_stream_init(CStream, + ?COMPRESSION_LEVEL, + ?WINDOW_LOG, + ?ENABLE_LONG_DISTANCE_MATCHING), {ok, CompressionBin} = zstd:stream_compress(CStream, Bin), {ok, FlushBin} = zstd:stream_flush(CStream),