From 4e528538e29de0fa5f9891e6ec6d9e6d09450b42 Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Mon, 10 Aug 2020 11:31:21 -0300 Subject: [PATCH 1/2] Reuse a thread-specific zstd decompress context Simple, never deallocate, don't support reload, etc. --- c_src/zstd_nif.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/c_src/zstd_nif.c b/c_src/zstd_nif.c index 26ed8c0..473940c 100644 --- a/c_src/zstd_nif.c +++ b/c_src/zstd_nif.c @@ -3,6 +3,8 @@ #include #include +ErlNifTSDKey zstdDecompressContextKey; + static ERL_NIF_TERM zstd_nif_compress(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin, ret_bin; size_t buff_size, compressed_size; @@ -34,6 +36,12 @@ static ERL_NIF_TERM zstd_nif_decompress(ErlNifEnv* env, int argc, const ERL_NIF_ ErlNifBinary bin; unsigned long long uncompressed_size; + ZSTD_DCtx* ctx = (ZSTD_DCtx*)enif_tsd_get(zstdDecompressContextKey); + if (!ctx) { + ctx = ZSTD_createDCtx(); + enif_tsd_set(zstdDecompressContextKey, ctx); + } + if(!enif_inspect_binary(env, argv[0], &bin)) return enif_make_badarg(env); @@ -41,7 +49,7 @@ static ERL_NIF_TERM zstd_nif_decompress(ErlNifEnv* env, int argc, const ERL_NIF_ outp = enif_make_new_binary(env, uncompressed_size, &out); - if(ZSTD_decompress(outp, uncompressed_size, bin.data, bin.size) != uncompressed_size) + if(ZSTD_decompressDCtx(ctx, outp, uncompressed_size, bin.data, bin.size) != uncompressed_size) return enif_make_atom(env, "error"); return out; @@ -52,4 +60,10 @@ static ErlNifFunc nif_funcs[] = { {"decompress", 1, zstd_nif_decompress} }; -ERL_NIF_INIT(zstd, nif_funcs, NULL, NULL, NULL, NULL); +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) + { + enif_tsd_key_create("zstd_decompress_context_key", &zstdDecompressContextKey); + return 0; + } + +ERL_NIF_INIT(zstd, nif_funcs, load, NULL, NULL, NULL); From ebfce21077c9a18d5a30d685ae1cb95a1145c4ad Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Mon, 10 Aug 2020 12:28:08 -0300 Subject: [PATCH 2/2] Same for compression ctx --- c_src/zstd_nif.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/c_src/zstd_nif.c b/c_src/zstd_nif.c index 473940c..f0345f2 100644 --- a/c_src/zstd_nif.c +++ b/c_src/zstd_nif.c @@ -4,12 +4,19 @@ #include ErlNifTSDKey zstdDecompressContextKey; +ErlNifTSDKey zstdCompressContextKey; static ERL_NIF_TERM zstd_nif_compress(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin, ret_bin; size_t buff_size, compressed_size; unsigned int compression_level; + ZSTD_CCtx* ctx = (ZSTD_CCtx*)enif_tsd_get(zstdCompressContextKey); + if (!ctx) { + ctx = ZSTD_createCCtx(); + enif_tsd_set(zstdCompressContextKey, ctx); + } + if(!enif_inspect_binary(env, argv[0], &bin) || !enif_get_uint(env, argv[1], &compression_level) || compression_level > ZSTD_maxCLevel()) @@ -20,7 +27,7 @@ static ERL_NIF_TERM zstd_nif_compress(ErlNifEnv* env, int argc, const ERL_NIF_TE if(!enif_alloc_binary(buff_size, &ret_bin)) return enif_make_atom(env, "error"); - compressed_size = ZSTD_compress(ret_bin.data, buff_size, bin.data, bin.size, compression_level); + compressed_size = ZSTD_compressCCtx(ctx, ret_bin.data, buff_size, bin.data, bin.size, compression_level); if(ZSTD_isError(compressed_size)) return enif_make_atom(env, "error"); @@ -63,6 +70,7 @@ static ErlNifFunc nif_funcs[] = { static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) { enif_tsd_key_create("zstd_decompress_context_key", &zstdDecompressContextKey); + enif_tsd_key_create("zstd_compress_context_key", &zstdCompressContextKey); return 0; }