zstd-ruby 1.5.6.6 → 1.5.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +37 -0
- data/ext/zstdruby/common.h +37 -11
- data/ext/zstdruby/main.c +4 -0
- data/ext/zstdruby/zstdruby.c +92 -0
- data/lib/zstd-ruby/stream_writer.rb +1 -1
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9acf1d7797f3431d0df130388295910e47c9bdaf36df29e1f116a55b993c130d
|
4
|
+
data.tar.gz: c58e20e6f0c2d270a21481b8ac2ba1c427d8cc6b1c2e52305e5b7540fcda41bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fad54c87b430ddbd437dd5e238b873c7572b2ed23e7b2a6409b817e1a823ab943bd49278c989abc1470a30c7fc8ad983fcf18a0b1dad84f8b99625fee2e6097
|
7
|
+
data.tar.gz: d8dd762266849d491ac971bd7eb764ea9bda42da6ef6fbd351bc91ab792e18009f1d52f8005734489776c049b4ef82bd25042020be8cb286c73f94af86b1a2c7
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -49,6 +49,22 @@ compressed_data = Zstd.compress(data, level: complession_level) # default compre
|
|
49
49
|
compressed_using_dict = Zstd.compress("", dict: File.read('dictionary_file'))
|
50
50
|
```
|
51
51
|
|
52
|
+
#### Compression with CDict
|
53
|
+
|
54
|
+
If you use the same dictionary repeatedly, you can speed up the setup by creating CDict in advance:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
cdict = Zstd::CDict.new(File.read('dictionary_file'))
|
58
|
+
compressed_using_dict = Zstd.compress("", dict: cdict)
|
59
|
+
```
|
60
|
+
|
61
|
+
The compression_level can be specified on creating CDict.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
cdict = Zstd::CDict.new(File.read('dictionary_file'), 5)
|
65
|
+
compressed_using_dict = Zstd.compress("", dict: cdict)
|
66
|
+
```
|
67
|
+
|
52
68
|
#### Streaming Compression
|
53
69
|
```ruby
|
54
70
|
stream = Zstd::StreamingCompress.new
|
@@ -86,6 +102,16 @@ stream << "ghi"
|
|
86
102
|
res << stream.finish
|
87
103
|
```
|
88
104
|
|
105
|
+
#### Streaming Compression with CDict of level 5
|
106
|
+
```ruby
|
107
|
+
cdict = Zstd::CDict.new(File.read('dictionary_file', 5)
|
108
|
+
stream = Zstd::StreamingCompress.new(dict: cdict)
|
109
|
+
stream << "abc" << "def"
|
110
|
+
res = stream.flush
|
111
|
+
stream << "ghi"
|
112
|
+
res << stream.finish
|
113
|
+
```
|
114
|
+
|
89
115
|
### Decompression
|
90
116
|
|
91
117
|
#### Simple Decompression
|
@@ -100,6 +126,15 @@ data = Zstd.decompress(compressed_data)
|
|
100
126
|
Zstd.decompress(compressed_using_dict, dict: File.read('dictionary_file'))
|
101
127
|
```
|
102
128
|
|
129
|
+
#### Decompression with DDict
|
130
|
+
|
131
|
+
If you use the same dictionary repeatedly, you can speed up the setup by creating DDict in advance:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
ddict = Zstd::Ddict.new(File.read('dictionary_file'))
|
135
|
+
data = Zstd.compress(compressed_using_dict, ddict)
|
136
|
+
```
|
137
|
+
|
103
138
|
#### Streaming Decompression
|
104
139
|
```ruby
|
105
140
|
cstr = "" # Compressed data
|
@@ -118,6 +153,8 @@ result << stream.decompress(cstr[0, 10])
|
|
118
153
|
result << stream.decompress(cstr[10..-1])
|
119
154
|
```
|
120
155
|
|
156
|
+
DDict can also be specified to `dict:`.
|
157
|
+
|
121
158
|
### Skippable frame
|
122
159
|
|
123
160
|
```ruby
|
data/ext/zstdruby/common.h
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
#ifndef ZSTD_RUBY_H
|
2
2
|
#define ZSTD_RUBY_H 1
|
3
3
|
|
4
|
+
#include <stdbool.h>
|
4
5
|
#include <ruby.h>
|
5
6
|
#ifdef HAVE_RUBY_THREAD_H
|
6
7
|
#include <ruby/thread.h>
|
7
8
|
#endif
|
8
|
-
#include <stdbool.h>
|
9
9
|
#include "./libzstd/zstd.h"
|
10
10
|
|
11
|
+
extern VALUE rb_cCDict, rb_cDDict;
|
12
|
+
|
11
13
|
static int convert_compression_level(VALUE compression_level_value)
|
12
14
|
{
|
13
15
|
if (NIL_P(compression_level_value)) {
|
@@ -34,12 +36,24 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VAL
|
|
34
36
|
ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
|
35
37
|
|
36
38
|
if (kwargs_values[1] != Qundef && kwargs_values[1] != Qnil) {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
if (CLASS_OF(kwargs_values[1]) == rb_cCDict) {
|
40
|
+
ZSTD_CDict* cdict = DATA_PTR(kwargs_values[1]);
|
41
|
+
size_t ref_dict_ret = ZSTD_CCtx_refCDict(ctx, cdict);
|
42
|
+
if (ZSTD_isError(ref_dict_ret)) {
|
43
|
+
ZSTD_freeCCtx(ctx);
|
44
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_refCDict failed");
|
45
|
+
}
|
46
|
+
} else if (TYPE(kwargs_values[1]) == T_STRING) {
|
47
|
+
char* dict_buffer = RSTRING_PTR(kwargs_values[1]);
|
48
|
+
size_t dict_size = RSTRING_LEN(kwargs_values[1]);
|
49
|
+
size_t load_dict_ret = ZSTD_CCtx_loadDictionary(ctx, dict_buffer, dict_size);
|
50
|
+
if (ZSTD_isError(load_dict_ret)) {
|
51
|
+
ZSTD_freeCCtx(ctx);
|
52
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
|
53
|
+
}
|
54
|
+
} else {
|
41
55
|
ZSTD_freeCCtx(ctx);
|
42
|
-
rb_raise(
|
56
|
+
rb_raise(rb_eArgError, "`dict:` must be a Zstd::CDict or a String");
|
43
57
|
}
|
44
58
|
}
|
45
59
|
}
|
@@ -113,12 +127,24 @@ static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
|
|
113
127
|
rb_get_kwargs(kwargs, kwargs_keys, 0, 1, kwargs_values);
|
114
128
|
|
115
129
|
if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
130
|
+
if (CLASS_OF(kwargs_values[0]) == rb_cDDict) {
|
131
|
+
ZSTD_DDict* ddict = DATA_PTR(kwargs_values[0]);
|
132
|
+
size_t ref_dict_ret = ZSTD_DCtx_refDDict(dctx, ddict);
|
133
|
+
if (ZSTD_isError(ref_dict_ret)) {
|
134
|
+
ZSTD_freeDCtx(dctx);
|
135
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_DCtx_refDDict failed");
|
136
|
+
}
|
137
|
+
} else if (TYPE(kwargs_values[0]) == T_STRING) {
|
138
|
+
char* dict_buffer = RSTRING_PTR(kwargs_values[0]);
|
139
|
+
size_t dict_size = RSTRING_LEN(kwargs_values[0]);
|
140
|
+
size_t load_dict_ret = ZSTD_DCtx_loadDictionary(dctx, dict_buffer, dict_size);
|
141
|
+
if (ZSTD_isError(load_dict_ret)) {
|
142
|
+
ZSTD_freeDCtx(dctx);
|
143
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
|
144
|
+
}
|
145
|
+
} else {
|
120
146
|
ZSTD_freeDCtx(dctx);
|
121
|
-
rb_raise(
|
147
|
+
rb_raise(rb_eArgError, "`dict:` must be a Zstd::DDict or a String");
|
122
148
|
}
|
123
149
|
}
|
124
150
|
}
|
data/ext/zstdruby/main.c
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#include "common.h"
|
2
2
|
|
3
3
|
VALUE rb_mZstd;
|
4
|
+
VALUE rb_cCDict;
|
5
|
+
VALUE rb_cDDict;
|
4
6
|
void zstd_ruby_init(void);
|
5
7
|
void zstd_ruby_skippable_frame_init(void);
|
6
8
|
void zstd_ruby_streaming_compress_init(void);
|
@@ -14,6 +16,8 @@ Init_zstdruby(void)
|
|
14
16
|
#endif
|
15
17
|
|
16
18
|
rb_mZstd = rb_define_module("Zstd");
|
19
|
+
rb_cCDict = rb_define_class_under(rb_mZstd, "CDict", rb_cObject);
|
20
|
+
rb_cDDict = rb_define_class_under(rb_mZstd, "DDict", rb_cObject);
|
17
21
|
zstd_ruby_init();
|
18
22
|
zstd_ruby_skippable_frame_init();
|
19
23
|
zstd_ruby_streaming_compress_init();
|
data/ext/zstdruby/zstdruby.c
CHANGED
@@ -195,6 +195,90 @@ static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
|
|
195
195
|
return output;
|
196
196
|
}
|
197
197
|
|
198
|
+
static void free_cdict(void *dict)
|
199
|
+
{
|
200
|
+
ZSTD_freeCDict(dict);
|
201
|
+
}
|
202
|
+
|
203
|
+
static size_t sizeof_cdict(const void *dict)
|
204
|
+
{
|
205
|
+
return ZSTD_sizeof_CDict(dict);
|
206
|
+
}
|
207
|
+
|
208
|
+
static void free_ddict(void *dict)
|
209
|
+
{
|
210
|
+
ZSTD_freeDDict(dict);
|
211
|
+
}
|
212
|
+
|
213
|
+
static size_t sizeof_ddict(const void *dict)
|
214
|
+
{
|
215
|
+
return ZSTD_sizeof_DDict(dict);
|
216
|
+
}
|
217
|
+
|
218
|
+
static const rb_data_type_t cdict_type = {
|
219
|
+
"Zstd::CDict",
|
220
|
+
{0, free_cdict, sizeof_cdict,},
|
221
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
222
|
+
};
|
223
|
+
|
224
|
+
static const rb_data_type_t ddict_type = {
|
225
|
+
"Zstd::DDict",
|
226
|
+
{0, free_ddict, sizeof_ddict,},
|
227
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
228
|
+
};
|
229
|
+
|
230
|
+
static VALUE rb_cdict_alloc(VALUE self)
|
231
|
+
{
|
232
|
+
ZSTD_CDict* cdict = NULL;
|
233
|
+
return TypedData_Wrap_Struct(self, &cdict_type, cdict);
|
234
|
+
}
|
235
|
+
|
236
|
+
static VALUE rb_cdict_initialize(int argc, VALUE *argv, VALUE self)
|
237
|
+
{
|
238
|
+
VALUE dict;
|
239
|
+
VALUE compression_level_value;
|
240
|
+
rb_scan_args(argc, argv, "11", &dict, &compression_level_value);
|
241
|
+
int compression_level = convert_compression_level(compression_level_value);
|
242
|
+
|
243
|
+
StringValue(dict);
|
244
|
+
char* dict_buffer = RSTRING_PTR(dict);
|
245
|
+
size_t dict_size = RSTRING_LEN(dict);
|
246
|
+
|
247
|
+
ZSTD_CDict* const cdict = ZSTD_createCDict(dict_buffer, dict_size, compression_level);
|
248
|
+
if (cdict == NULL) {
|
249
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCDict failed");
|
250
|
+
}
|
251
|
+
|
252
|
+
DATA_PTR(self) = cdict;
|
253
|
+
return self;
|
254
|
+
}
|
255
|
+
|
256
|
+
static VALUE rb_ddict_alloc(VALUE self)
|
257
|
+
{
|
258
|
+
ZSTD_CDict* ddict = NULL;
|
259
|
+
return TypedData_Wrap_Struct(self, &ddict_type, ddict);
|
260
|
+
}
|
261
|
+
|
262
|
+
static VALUE rb_ddict_initialize(VALUE self, VALUE dict)
|
263
|
+
{
|
264
|
+
StringValue(dict);
|
265
|
+
char* dict_buffer = RSTRING_PTR(dict);
|
266
|
+
size_t dict_size = RSTRING_LEN(dict);
|
267
|
+
|
268
|
+
ZSTD_DDict* const ddict = ZSTD_createDDict(dict_buffer, dict_size);
|
269
|
+
if (ddict == NULL) {
|
270
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDDict failed");
|
271
|
+
}
|
272
|
+
|
273
|
+
DATA_PTR(self) = ddict;
|
274
|
+
return self;
|
275
|
+
}
|
276
|
+
|
277
|
+
static VALUE rb_prohibit_copy(VALUE self, VALUE obj)
|
278
|
+
{
|
279
|
+
rb_raise(rb_eRuntimeError, "CDict cannot be duplicated");
|
280
|
+
}
|
281
|
+
|
198
282
|
void
|
199
283
|
zstd_ruby_init(void)
|
200
284
|
{
|
@@ -203,4 +287,12 @@ zstd_ruby_init(void)
|
|
203
287
|
rb_define_module_function(rb_mZstd, "compress_using_dict", rb_compress_using_dict, -1);
|
204
288
|
rb_define_module_function(rb_mZstd, "decompress", rb_decompress, -1);
|
205
289
|
rb_define_module_function(rb_mZstd, "decompress_using_dict", rb_decompress_using_dict, -1);
|
290
|
+
|
291
|
+
rb_define_alloc_func(rb_cCDict, rb_cdict_alloc);
|
292
|
+
rb_define_private_method(rb_cCDict, "initialize", rb_cdict_initialize, -1);
|
293
|
+
rb_define_method(rb_cCDict, "initialize_copy", rb_prohibit_copy, 1);
|
294
|
+
|
295
|
+
rb_define_alloc_func(rb_cDDict, rb_ddict_alloc);
|
296
|
+
rb_define_private_method(rb_cDDict, "initialize", rb_ddict_initialize, 1);
|
297
|
+
rb_define_method(rb_cDDict, "initialize_copy", rb_prohibit_copy, 1);
|
206
298
|
}
|
data/lib/zstd-ruby/version.rb
CHANGED
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.
|
4
|
+
version: 1.5.6.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SpringMT
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
200
|
- !ruby/object:Gem::Version
|
201
201
|
version: '0'
|
202
202
|
requirements: []
|
203
|
-
rubygems_version: 3.
|
203
|
+
rubygems_version: 3.4.19
|
204
204
|
signing_key:
|
205
205
|
specification_version: 4
|
206
206
|
summary: Ruby binding for zstd(Zstandard - Fast real-time compression algorithm)
|