zstd-ruby 1.5.6.2 → 1.5.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5c50aade1eb5c3a36dfaba5dc325c1bc416ceaa3558539ae5b389bb4378f6c37
4
- data.tar.gz: 490b1268c79f5e481969fb1cf2fe2adb9bba5a51ab0e0197fd0338913a228611
3
+ metadata.gz: 729474c9a3f3196fe69a06dfdd280c5879bc368b1884b8d508b75164aa7e1dcd
4
+ data.tar.gz: 1cdf1b0554dd89aa1f7b6450be8eb183773a0f3b895024715ae7b3243cec598b
5
5
  SHA512:
6
- metadata.gz: 14db577b5e10bc3a92df632d391dfdb55802da3768e5b829c9b849f440b0b5234be8d924a6b0c5d237cab7befdd540d1535de0ba56dafd30fbfe13c2e635e229
7
- data.tar.gz: e6959f0da13aaa2a609fec024a3f293e4366760e3efd7626fc545c29ad5a1b0290119bc088cf60cb6665c1f2a5d93f0faf72152be3cf470ce5cf43657695a588
6
+ metadata.gz: d69bc35190b5dbc8ce36f9e5acf6ef26a2c85a899ddd409f8eee4a83b005166b20d22e2659cae1b101fb1b97f6a7bf12cf4066e3da94b2a1991d41bf255cd1ce
7
+ data.tar.gz: 2ee85e56a8ae268da1e4b69bf35a016a5d9bc677f240435725e082b5c5279e60d7f8be32dbe57283e618b7cf59b3937b57aa859f6cbb0aafa64458a903747fa2
@@ -2,6 +2,10 @@
2
2
  #define ZSTD_RUBY_H 1
3
3
 
4
4
  #include <ruby.h>
5
+ #ifdef HAVE_RUBY_THREAD_H
6
+ #include <ruby/thread.h>
7
+ #endif
8
+ #include <stdbool.h>
5
9
  #include "./libzstd/zstd.h"
6
10
 
7
11
  static int convert_compression_level(VALUE compression_level_value)
@@ -12,11 +16,6 @@ static int convert_compression_level(VALUE compression_level_value)
12
16
  return NUM2INT(compression_level_value);
13
17
  }
14
18
 
15
- static size_t zstd_compress(ZSTD_CCtx* const ctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input, ZSTD_EndDirective endOp)
16
- {
17
- return ZSTD_compressStream2(ctx, output, input, endOp);
18
- }
19
-
20
19
  static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VALUE kwargs)
21
20
  {
22
21
  ID kwargs_keys[2];
@@ -45,6 +44,36 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VAL
45
44
  }
46
45
  }
47
46
 
47
+ struct compress_params {
48
+ ZSTD_CCtx* ctx;
49
+ ZSTD_outBuffer* output;
50
+ ZSTD_inBuffer* input;
51
+ ZSTD_EndDirective endOp;
52
+ size_t ret;
53
+ };
54
+
55
+ static void* compress_wrapper(void* args)
56
+ {
57
+ struct compress_params* params = args;
58
+ params->ret = ZSTD_compressStream2(params->ctx, params->output, params->input, params->endOp);
59
+ return NULL;
60
+ }
61
+
62
+ static size_t zstd_compress(ZSTD_CCtx* const ctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input, ZSTD_EndDirective endOp, bool gvl)
63
+ {
64
+ #ifdef HAVE_RUBY_THREAD_H
65
+ if (gvl) {
66
+ return ZSTD_compressStream2(ctx, output, input, endOp);
67
+ } else {
68
+ struct compress_params params = { ctx, output, input, endOp };
69
+ rb_thread_call_without_gvl(compress_wrapper, &params, NULL, NULL);
70
+ return params.ret;
71
+ }
72
+ #else
73
+ return ZSTD_compressStream2(ctx, output, input, endOp);
74
+ #endif
75
+ }
76
+
48
77
  static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
49
78
  {
50
79
  ID kwargs_keys[1];
@@ -63,4 +92,33 @@ static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
63
92
  }
64
93
  }
65
94
 
95
+ struct decompress_params {
96
+ ZSTD_DCtx* dctx;
97
+ ZSTD_outBuffer* output;
98
+ ZSTD_inBuffer* input;
99
+ size_t ret;
100
+ };
101
+
102
+ static void* decompress_wrapper(void* args)
103
+ {
104
+ struct decompress_params* params = args;
105
+ params->ret = ZSTD_decompressStream(params->dctx, params->output, params->input);
106
+ return NULL;
107
+ }
108
+
109
+ static size_t zstd_decompress(ZSTD_DCtx* const dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input, bool gvl)
110
+ {
111
+ #ifdef HAVE_RUBY_THREAD_H
112
+ if (gvl) {
113
+ return ZSTD_decompressStream(dctx, output, input);
114
+ } else {
115
+ struct decompress_params params = { dctx, output, input };
116
+ rb_thread_call_without_gvl(decompress_wrapper, &params, NULL, NULL);
117
+ return params.ret;
118
+ }
119
+ #else
120
+ return ZSTD_decompressStream(dctx, output, input);
121
+ #endif
122
+ }
123
+
66
124
  #endif /* ZSTD_RUBY_H */
@@ -2,7 +2,7 @@ require "mkmf"
2
2
 
3
3
  have_func('rb_gc_mark_movable')
4
4
 
5
- $CFLAGS = '-I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY'
5
+ $CFLAGS = '-I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY -DZSTD_MULTITHREAD -pthread -DDEBUGLEVEL=0'
6
6
  $CPPFLAGS += " -fdeclspec" if CONFIG['CXX'] =~ /clang/
7
7
 
8
8
  Dir.chdir File.expand_path('..', __FILE__) do
@@ -106,7 +106,7 @@ no_compress(struct streaming_compress_t* sc, ZSTD_EndDirective endOp)
106
106
  do {
107
107
  ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
108
108
 
109
- size_t const ret = zstd_compress(sc->ctx, &output, &input, endOp);
109
+ size_t const ret = zstd_compress(sc->ctx, &output, &input, endOp, false);
110
110
  if (ZSTD_isError(ret)) {
111
111
  rb_raise(rb_eRuntimeError, "flush error error code: %s", ZSTD_getErrorName(ret));
112
112
  }
@@ -130,7 +130,7 @@ rb_streaming_compress_compress(VALUE obj, VALUE src)
130
130
  VALUE result = rb_str_new(0, 0);
131
131
  while (input.pos < input.size) {
132
132
  ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
133
- size_t const ret = zstd_compress(sc->ctx, &output, &input, ZSTD_e_continue);
133
+ size_t const ret = zstd_compress(sc->ctx, &output, &input, ZSTD_e_continue, false);
134
134
  if (ZSTD_isError(ret)) {
135
135
  rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
136
136
  }
@@ -157,7 +157,7 @@ rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
157
157
 
158
158
  while (input.pos < input.size) {
159
159
  ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
160
- size_t const ret = zstd_compress(sc->ctx, &output, &input, ZSTD_e_continue);
160
+ size_t const ret = zstd_compress(sc->ctx, &output, &input, ZSTD_e_continue, false);
161
161
  if (ZSTD_isError(ret)) {
162
162
  rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
163
163
  }
@@ -104,7 +104,7 @@ rb_streaming_decompress_decompress(VALUE obj, VALUE src)
104
104
  VALUE result = rb_str_new(0, 0);
105
105
  while (input.pos < input.size) {
106
106
  ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
107
- size_t const ret = ZSTD_decompressStream(sd->dctx, &output, &input);
107
+ size_t const ret = zstd_decompress(sd->dctx, &output, &input, false);
108
108
  if (ZSTD_isError(ret)) {
109
109
  rb_raise(rb_eRuntimeError, "decompress error error code: %s", ZSTD_getErrorName(ret));
110
110
  }
@@ -26,12 +26,13 @@ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
26
26
  char* input_data = RSTRING_PTR(input_value);
27
27
  size_t input_size = RSTRING_LEN(input_value);
28
28
  ZSTD_inBuffer input = { input_data, input_size, 0 };
29
+ // ZSTD_compressBound causes SEGV under multi-thread
29
30
  size_t max_compressed_size = ZSTD_compressBound(input_size);
30
31
  VALUE buf = rb_str_new(NULL, max_compressed_size);
31
32
  char* output_data = RSTRING_PTR(buf);
32
33
  ZSTD_outBuffer output = { (void*)output_data, max_compressed_size, 0 };
33
34
 
34
- size_t const ret = zstd_compress(ctx, &output, &input, ZSTD_e_end);
35
+ size_t const ret = zstd_compress(ctx, &output, &input, ZSTD_e_end, true);
35
36
  if (ZSTD_isError(ret)) {
36
37
  ZSTD_freeCCtx(ctx);
37
38
  rb_raise(rb_eRuntimeError, "%s: %s", "compress failed", ZSTD_getErrorName(ret));
@@ -87,19 +88,8 @@ static VALUE rb_compress_using_dict(int argc, VALUE *argv, VALUE self)
87
88
  }
88
89
 
89
90
 
90
- static VALUE decompress_buffered(const char* input_data, size_t input_size)
91
+ static VALUE decompress_buffered(ZSTD_DCtx* dctx, const char* input_data, size_t input_size)
91
92
  {
92
- ZSTD_DStream* const dstream = ZSTD_createDStream();
93
- if (dstream == NULL) {
94
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDStream failed");
95
- }
96
-
97
- size_t initResult = ZSTD_initDStream(dstream);
98
- if (ZSTD_isError(initResult)) {
99
- ZSTD_freeDStream(dstream);
100
- rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_initDStream failed", ZSTD_getErrorName(initResult));
101
- }
102
-
103
93
  VALUE output_string = rb_str_new(NULL, 0);
104
94
  ZSTD_outBuffer output = { NULL, 0, 0 };
105
95
 
@@ -109,15 +99,14 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
109
99
  rb_str_resize(output_string, output.size);
110
100
  output.dst = RSTRING_PTR(output_string);
111
101
 
112
- size_t readHint = ZSTD_decompressStream(dstream, &output, &input);
113
- if (ZSTD_isError(readHint)) {
114
- ZSTD_freeDStream(dstream);
115
- rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_decompressStream failed", ZSTD_getErrorName(readHint));
102
+ size_t ret = zstd_decompress(dctx, &output, &input, true);
103
+ if (ZSTD_isError(ret)) {
104
+ ZSTD_freeDCtx(dctx);
105
+ rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_decompressStream failed", ZSTD_getErrorName(ret));
116
106
  }
117
107
  }
118
-
119
- ZSTD_freeDStream(dstream);
120
108
  rb_str_resize(output_string, output.pos);
109
+ ZSTD_freeDCtx(dctx);
121
110
  return output_string;
122
111
  }
123
112
 
@@ -129,6 +118,11 @@ static VALUE rb_decompress(int argc, VALUE *argv, VALUE self)
129
118
  StringValue(input_value);
130
119
  char* input_data = RSTRING_PTR(input_value);
131
120
  size_t input_size = RSTRING_LEN(input_value);
121
+ ZSTD_DCtx* const dctx = ZSTD_createDCtx();
122
+ if (dctx == NULL) {
123
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
124
+ }
125
+ set_decompress_params(dctx, kwargs);
132
126
 
133
127
  unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
134
128
  if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
@@ -137,15 +131,9 @@ static VALUE rb_decompress(int argc, VALUE *argv, VALUE self)
137
131
  // ZSTD_decompressStream may be called multiple times when ZSTD_CONTENTSIZE_UNKNOWN, causing slowness.
138
132
  // Therefore, we will not standardize on ZSTD_decompressStream
139
133
  if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
140
- return decompress_buffered(input_data, input_size);
134
+ return decompress_buffered(dctx, input_data, input_size);
141
135
  }
142
136
 
143
- ZSTD_DCtx* const dctx = ZSTD_createDCtx();
144
- if (dctx == NULL) {
145
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
146
- }
147
- set_decompress_params(dctx, kwargs);
148
-
149
137
  VALUE output = rb_str_new(NULL, uncompressed_size);
150
138
  char* output_data = RSTRING_PTR(output);
151
139
 
@@ -167,15 +155,6 @@ static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
167
155
  StringValue(input_value);
168
156
  char* input_data = RSTRING_PTR(input_value);
169
157
  size_t input_size = RSTRING_LEN(input_value);
170
- unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
171
- if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
172
- rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
173
- }
174
- if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
175
- return decompress_buffered(input_data, input_size);
176
- }
177
- VALUE output = rb_str_new(NULL, uncompressed_size);
178
- char* output_data = RSTRING_PTR(output);
179
158
 
180
159
  char* dict_buffer = RSTRING_PTR(dict);
181
160
  size_t dict_size = RSTRING_LEN(dict);
@@ -183,12 +162,11 @@ static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
183
162
  if (ddict == NULL) {
184
163
  rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDDict failed");
185
164
  }
186
-
187
165
  unsigned const expected_dict_id = ZSTD_getDictID_fromDDict(ddict);
188
166
  unsigned const actual_dict_id = ZSTD_getDictID_fromFrame(input_data, input_size);
189
167
  if (expected_dict_id != actual_dict_id) {
190
168
  ZSTD_freeDDict(ddict);
191
- rb_raise(rb_eRuntimeError, "%s: %s", "DictID mismatch", ZSTD_getErrorName(uncompressed_size));
169
+ rb_raise(rb_eRuntimeError, "DictID mismatch");
192
170
  }
193
171
 
194
172
  ZSTD_DCtx* const ctx = ZSTD_createDCtx();
@@ -196,6 +174,19 @@ static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
196
174
  ZSTD_freeDDict(ddict);
197
175
  rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
198
176
  }
177
+
178
+ unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
179
+ if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
180
+ ZSTD_freeDDict(ddict);
181
+ ZSTD_freeDCtx(ctx);
182
+ rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
183
+ }
184
+ if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
185
+ return decompress_buffered(ctx, input_data, input_size);
186
+ }
187
+
188
+ VALUE output = rb_str_new(NULL, uncompressed_size);
189
+ char* output_data = RSTRING_PTR(output);
199
190
  size_t const decompress_size = ZSTD_decompress_usingDDict(ctx, output_data, uncompressed_size, input_data, input_size, ddict);
200
191
  if (ZSTD_isError(decompress_size)) {
201
192
  ZSTD_freeDDict(ddict);
@@ -1,3 +1,3 @@
1
1
  module Zstd
2
- VERSION = "1.5.6.2"
2
+ VERSION = "1.5.6.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zstd-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.6.2
4
+ version: 1.5.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - SpringMT
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-11 00:00:00.000000000 Z
11
+ date: 2024-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler