Skip to content

Commit 4ad9fc7

Browse files
authored
Merge pull request #77 from SpringMT/feature/dictionary-standardized
Feature/dictionary standardized
2 parents cf9b448 + 1060b32 commit 4ad9fc7

21 files changed

+294
-112
lines changed

README.md

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,22 @@ Or install it yourself as:
3434
require 'zstd-ruby'
3535
```
3636

37-
### Simple Compression
37+
### Compression
38+
39+
#### Simple Compression
3840

3941
```ruby
4042
compressed_data = Zstd.compress(data)
41-
compressed_data = Zstd.compress(data, complession_level) # default compression_level is 0
43+
compressed_data = Zstd.compress(data, level: complession_level) # default compression_level is 3
4244
```
4345

44-
### Compression using Dictionary
46+
#### Compression with Dictionary
4547
```ruby
4648
# dictionary is supposed to have been created using `zstd --train`
47-
compressed_using_dict = Zstd.compress_using_dict("", IO.read('dictionary_file'))
49+
compressed_using_dict = Zstd.compress("", dict: IO.read('dictionary_file'))
4850
```
4951

50-
### Streaming Compression
52+
#### Streaming Compression
5153
```ruby
5254
stream = Zstd::StreamingCompress.new
5355
stream << "abc" << "def"
@@ -66,7 +68,7 @@ res << stream.compress("def")
6668
res << stream.finish
6769
```
6870

69-
### Streaming Compression using Dictionary
71+
#### Streaming Compression with Dictionary
7072
```ruby
7173
stream = Zstd::StreamingCompress.new(dict: IO.read('dictionary_file'))
7274
stream << "abc" << "def"
@@ -75,19 +77,30 @@ stream << "ghi"
7577
res << stream.finish
7678
```
7779

78-
### Simple Decompression
80+
#### Streaming Compression with level and Dictionary
81+
```ruby
82+
stream = Zstd::StreamingCompress.new(level: 5, dict: IO.read('dictionary_file'))
83+
stream << "abc" << "def"
84+
res = stream.flush
85+
stream << "ghi"
86+
res << stream.finish
87+
```
88+
89+
### Decompression
90+
91+
#### Simple Decompression
7992

8093
```ruby
8194
data = Zstd.decompress(compressed_data)
8295
```
8396

84-
### Decomporession using Dictionary
97+
#### Decompression with Dictionary
8598
```ruby
8699
# dictionary is supposed to have been created using `zstd --train`
87-
Zstd.decompress_using_dict(compressed_using_dict, IO.read('dictionary_file'))
100+
Zstd.decompress(compressed_using_dict, dict: IO.read('dictionary_file'))
88101
```
89102

90-
### Streaming Decompression
103+
#### Streaming Decompression
91104
```ruby
92105
cstr = "" # Compressed data
93106
stream = Zstd::StreamingDecompress.new
@@ -96,7 +109,7 @@ result << stream.decompress(cstr[0, 10])
96109
result << stream.decompress(cstr[10..-1])
97110
```
98111

99-
### Streaming Decompression using dictionary
112+
#### Streaming Decompression with dictionary
100113
```ruby
101114
cstr = "" # Compressed data
102115
stream = Zstd::StreamingDecompress.new(dict: IO.read('dictionary_file'))

benchmarks/results/city.json.gzip

0 Bytes
Binary file not shown.

benchmarks/zstd_compress_memory.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
json_string = json_data.to_json
1515

1616
i = 0
17-
17+
start_time = Time.now
1818
while true do
1919
Zstd.compress(json_string)
2020
if ((i % 1000) == 0 )
21-
puts "count:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
21+
puts "sec:#{Time.now - start_time}\tcount:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
2222
end
2323
i += 1
2424
end

benchmarks/zstd_decompress_memory.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
while true do
1717
Zstd.decompress IO.read("./results/#{sample_file_name}.zstd")
1818
if ((i % 1000) == 0 )
19-
puts "count:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
19+
puts "sec:#{Time.now - start_time}\tcount:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
2020
end
2121
i += 1
2222
end

benchmarks/zstd_streaming_compress_memory.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
json_string = IO.read("./samples/#{sample_file_name}")
1414

1515
i = 0
16+
start_time = Time.now
1617
while true do
1718
stream = Zstd::StreamingCompress.new
1819
stream << json_string[0, 5]
@@ -21,7 +22,7 @@
2122
res << stream.finish
2223
if ((i % 1000) == 0 )
2324
GC.start
24-
puts "count:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
25+
puts "sec:#{Time.now - start_time}\tcount:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
2526
end
2627
i += 1
2728
end

benchmarks/zstd_streaming_decompress_memory.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
cstr = IO.read("./results/#{sample_file_name}.zstd")
1414
i = 0
15+
start_time = Time.now
1516
while true do
1617
stream = Zstd::StreamingDecompress.new
1718
result = ''
@@ -20,7 +21,7 @@
2021

2122
if ((i % 1000) == 0 )
2223
GC.start
23-
puts "count:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
24+
puts "sec:#{Time.now - start_time}\tcount:#{i}\truby_memory:#{ObjectSpace.memsize_of_all/1000}\tobject_count:#{ObjectSpace.count_objects}\trss:#{`ps -o rss= -p #{Process.pid}`.to_i}"
2425
end
2526
i += 1
2627
end

examples/sinatra/Gemfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "sinatra"
4+
gem "rackup"
5+
gem "zstd-ruby", path: "../../"

examples/sinatra/Gemfile.lock

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
PATH
2+
remote: ../..
3+
specs:
4+
zstd-ruby (1.5.6.1)
5+
6+
GEM
7+
remote: https://rubygems.org/
8+
specs:
9+
base64 (0.2.0)
10+
mustermann (3.0.0)
11+
ruby2_keywords (~> 0.0.1)
12+
rack (3.0.10)
13+
rack-protection (4.0.0)
14+
base64 (>= 0.1.0)
15+
rack (>= 3.0.0, < 4)
16+
rack-session (2.0.0)
17+
rack (>= 3.0.0)
18+
rackup (2.1.0)
19+
rack (>= 3)
20+
webrick (~> 1.8)
21+
ruby2_keywords (0.0.5)
22+
sinatra (4.0.0)
23+
mustermann (~> 3.0)
24+
rack (>= 3.0.0, < 4)
25+
rack-protection (= 4.0.0)
26+
rack-session (>= 2.0.0, < 3)
27+
tilt (~> 2.0)
28+
tilt (2.3.0)
29+
webrick (1.8.1)
30+
31+
PLATFORMS
32+
arm64-darwin-21
33+
ruby
34+
35+
DEPENDENCIES
36+
rackup
37+
sinatra
38+
zstd-ruby!
39+
40+
BUNDLED WITH
41+
2.5.7

examples/sinatra/app.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require 'sinatra'
2+
require 'zstd-ruby'
3+
4+
get '/' do
5+
headers["Content-Encoding"] = "zstd"
6+
Zstd.compress('Hello world!')
7+
end

ext/zstdruby/common.h

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef ZSTD_RUBY_H
22
#define ZSTD_RUBY_H 1
33

4-
#include "ruby.h"
4+
#include <ruby.h>
55
#include "./libzstd/zstd.h"
66

77
static int convert_compression_level(VALUE compression_level_value)
@@ -12,4 +12,55 @@ static int convert_compression_level(VALUE compression_level_value)
1212
return NUM2INT(compression_level_value);
1313
}
1414

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+
static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VALUE kwargs)
21+
{
22+
ID kwargs_keys[2];
23+
kwargs_keys[0] = rb_intern("level");
24+
kwargs_keys[1] = rb_intern("dict");
25+
VALUE kwargs_values[2];
26+
rb_get_kwargs(kwargs, kwargs_keys, 0, 2, kwargs_values);
27+
28+
int compression_level = ZSTD_CLEVEL_DEFAULT;
29+
if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
30+
compression_level = convert_compression_level(kwargs_values[0]);
31+
} else if (!NIL_P(level_from_args)) {
32+
rb_warn("`level` in args is deprecated; use keyword args `level:` instead.");
33+
compression_level = convert_compression_level(level_from_args);
34+
}
35+
ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
36+
37+
if (kwargs_values[1] != Qundef && kwargs_values[1] != Qnil) {
38+
char* dict_buffer = RSTRING_PTR(kwargs_values[1]);
39+
size_t dict_size = RSTRING_LEN(kwargs_values[1]);
40+
size_t load_dict_ret = ZSTD_CCtx_loadDictionary(ctx, dict_buffer, dict_size);
41+
if (ZSTD_isError(load_dict_ret)) {
42+
ZSTD_freeCCtx(ctx);
43+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
44+
}
45+
}
46+
}
47+
48+
static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
49+
{
50+
ID kwargs_keys[1];
51+
kwargs_keys[0] = rb_intern("dict");
52+
VALUE kwargs_values[1];
53+
rb_get_kwargs(kwargs, kwargs_keys, 0, 1, kwargs_values);
54+
55+
if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
56+
char* dict_buffer = RSTRING_PTR(kwargs_values[0]);
57+
size_t dict_size = RSTRING_LEN(kwargs_values[0]);
58+
size_t load_dict_ret = ZSTD_DCtx_loadDictionary(dctx, dict_buffer, dict_size);
59+
if (ZSTD_isError(load_dict_ret)) {
60+
ZSTD_freeDCtx(dctx);
61+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
62+
}
63+
}
64+
}
65+
1566
#endif /* ZSTD_RUBY_H */

0 commit comments

Comments
 (0)