zrip 0.1.2 → 0.2.0
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/CHANGELOG.md +12 -0
- data/Cargo.lock +5 -41
- data/README.md +13 -40
- data/ext/zrip/Cargo.toml +2 -2
- data/ext/zrip/build.rs +23 -0
- data/ext/zrip/src/lib.rs +697 -300
- data/ext/zrip/src/rb.rs +615 -0
- data/lib/zrip/block_codec.rb +49 -0
- data/lib/zrip/dict_trainer.rb +32 -0
- data/lib/zrip/dictionary.rb +10 -0
- data/lib/zrip/frame_codec.rb +58 -0
- data/lib/zrip/version.rb +1 -1
- data/lib/zrip.rb +14 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 50caa1679bd74290e01032b2564ab2ac083633f00ad7070f2e3e597572ffe22b
|
|
4
|
+
data.tar.gz: d89a94b7221aba11a0084f8ffeab771428f682ddf19908a647c2bce862b43ffe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 74bc8d13edae353144da41a66e80d41440157dc11c9555726c2c01659d88a02c8ffd0a7410b0157fb011a45677c54448a808ed463a1f9b1d99bd9a2769e42926
|
|
7
|
+
data.tar.gz: 91c282a2f5275e2e0cd72a9a2cf089a0582e47d256acce3c9bf67be6f494ab89a046bfece175d23f9543e7162b90b8bf66cc0dd97e5ebd5c9a695c3462e23d01
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.2.0] - 2026-08-07
|
|
6
|
+
|
|
7
|
+
- Release the Ruby GVL around large frame/block compression and frame
|
|
8
|
+
decompression calls.
|
|
9
|
+
- Update the `zrip` crate dependency to 0.8.5.
|
|
10
|
+
- Replace Magnus with direct `rb-sys` bindings, add TruffleRuby build support,
|
|
11
|
+
and lower the Ruby requirement to 3.4.
|
|
12
|
+
- Apply `max_output_size:` to the total decompressed output of concatenated
|
|
13
|
+
Zstandard frames.
|
|
14
|
+
- Add RubyDoc metadata and move API reference details from `README.md` into
|
|
15
|
+
YARD comments.
|
|
16
|
+
|
|
5
17
|
## [0.1.2] - 2026-08-05
|
|
6
18
|
|
|
7
19
|
- Update `zrip` crate dependency from 0.8.3 to 0.8.4.
|
data/Cargo.lock
CHANGED
|
@@ -110,29 +110,6 @@ dependencies = [
|
|
|
110
110
|
"windows-link",
|
|
111
111
|
]
|
|
112
112
|
|
|
113
|
-
[[package]]
|
|
114
|
-
name = "magnus"
|
|
115
|
-
version = "0.8.2"
|
|
116
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
117
|
-
checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
|
|
118
|
-
dependencies = [
|
|
119
|
-
"magnus-macros",
|
|
120
|
-
"rb-sys",
|
|
121
|
-
"rb-sys-env",
|
|
122
|
-
"seq-macro",
|
|
123
|
-
]
|
|
124
|
-
|
|
125
|
-
[[package]]
|
|
126
|
-
name = "magnus-macros"
|
|
127
|
-
version = "0.8.0"
|
|
128
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
129
|
-
checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
|
|
130
|
-
dependencies = [
|
|
131
|
-
"proc-macro2",
|
|
132
|
-
"quote",
|
|
133
|
-
"syn",
|
|
134
|
-
]
|
|
135
|
-
|
|
136
113
|
[[package]]
|
|
137
114
|
name = "memchr"
|
|
138
115
|
version = "2.8.3"
|
|
@@ -197,12 +174,6 @@ dependencies = [
|
|
|
197
174
|
"syn",
|
|
198
175
|
]
|
|
199
176
|
|
|
200
|
-
[[package]]
|
|
201
|
-
name = "rb-sys-env"
|
|
202
|
-
version = "0.2.3"
|
|
203
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
204
|
-
checksum = "cca7ad6a7e21e72151d56fe2495a259b5670e204c3adac41ee7ef676ea08117a"
|
|
205
|
-
|
|
206
177
|
[[package]]
|
|
207
178
|
name = "regex"
|
|
208
179
|
version = "1.13.1"
|
|
@@ -238,12 +209,6 @@ version = "2.1.3"
|
|
|
238
209
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
239
210
|
checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
|
|
240
211
|
|
|
241
|
-
[[package]]
|
|
242
|
-
name = "seq-macro"
|
|
243
|
-
version = "0.3.6"
|
|
244
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
245
|
-
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
|
246
|
-
|
|
247
212
|
[[package]]
|
|
248
213
|
name = "shell-words"
|
|
249
214
|
version = "1.1.1"
|
|
@@ -283,16 +248,15 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
|
|
283
248
|
name = "zrip"
|
|
284
249
|
version = "0.1.2"
|
|
285
250
|
dependencies = [
|
|
286
|
-
"magnus",
|
|
287
251
|
"rb-sys",
|
|
288
|
-
"zrip 0.8.
|
|
252
|
+
"zrip 0.8.5",
|
|
289
253
|
]
|
|
290
254
|
|
|
291
255
|
[[package]]
|
|
292
256
|
name = "zrip"
|
|
293
|
-
version = "0.8.
|
|
257
|
+
version = "0.8.5"
|
|
294
258
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
295
|
-
checksum = "
|
|
259
|
+
checksum = "fa05c09787b3aaaaa57870dca9fd9f3b4934018cbb5dde1b112017e2e70ec491"
|
|
296
260
|
dependencies = [
|
|
297
261
|
"zrip-core",
|
|
298
262
|
"zrip-decode",
|
|
@@ -307,9 +271,9 @@ checksum = "9335acd94c1f09f729178fc339f9d49790254c1e98ba076f88df3a3f534c4e7d"
|
|
|
307
271
|
|
|
308
272
|
[[package]]
|
|
309
273
|
name = "zrip-decode"
|
|
310
|
-
version = "0.8.
|
|
274
|
+
version = "0.8.5"
|
|
311
275
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
312
|
-
checksum = "
|
|
276
|
+
checksum = "1801cd8b5d374e2bc31cd8a231182dd47e621492fa0bf68ca7d3033e001cd06b"
|
|
313
277
|
dependencies = [
|
|
314
278
|
"fearless_simd",
|
|
315
279
|
"zrip-core",
|
data/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# zrip
|
|
1
|
+
# zrip: Ractor-safe Zstandard for Ruby
|
|
2
2
|
|
|
3
3
|
[](https://github.com/paddor/zrip-rb/actions/workflows/ci.yml)
|
|
4
4
|
[](https://rubygems.org/gems/zrip)
|
|
5
5
|
[](LICENSE)
|
|
6
|
-
[](https://www.ruby-lang.org)
|
|
7
7
|
|
|
8
8
|
Ruby bindings for [zrip](https://crates.io/crates/zrip), a pure-Rust Zstandard
|
|
9
|
-
implementation. Built
|
|
10
|
-
|
|
9
|
+
implementation. Built as an `rb-sys` native extension and declared Ractor-safe
|
|
10
|
+
so you can compress from any Ractor without a global lock.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
@@ -22,7 +22,7 @@ declared Ractor-safe so you can compress from any Ractor without a global lock.
|
|
|
22
22
|
|
|
23
23
|
## Install
|
|
24
24
|
|
|
25
|
-
Requires Ruby >= 4
|
|
25
|
+
Requires Ruby >= 3.4 and a Rust toolchain (for building the native extension):
|
|
26
26
|
|
|
27
27
|
```sh
|
|
28
28
|
gem install zrip
|
|
@@ -66,8 +66,8 @@ strong = Zrip::FrameCodec.new(level: 19) # higher = smaller output
|
|
|
66
66
|
```ruby
|
|
67
67
|
codec = Zrip::FrameCodec.new
|
|
68
68
|
|
|
69
|
-
# Limit output size to 1 MiB
|
|
70
|
-
codec.decompress(compressed, max_output_size:
|
|
69
|
+
# Limit total output size to 1 MiB
|
|
70
|
+
codec.decompress(compressed, max_output_size: 1024 * 1024)
|
|
71
71
|
|
|
72
72
|
# Read frame content size from header (without decompressing)
|
|
73
73
|
Zrip::FrameCodec.get_frame_content_size(compressed) #=> 12000
|
|
@@ -96,6 +96,9 @@ codec = Zrip::FrameCodec.new(dict: dict)
|
|
|
96
96
|
|
|
97
97
|
### Ractor safety
|
|
98
98
|
|
|
99
|
+
On Ruby VMs without Ractor support, the codecs still work normally; the
|
|
100
|
+
Ractor-specific guarantees and examples do not apply.
|
|
101
|
+
|
|
99
102
|
```ruby
|
|
100
103
|
codec = Zrip::FrameCodec.new
|
|
101
104
|
|
|
@@ -111,39 +114,9 @@ end
|
|
|
111
114
|
ractors.each { |r| p r.value } # => :ok, :ok, :ok, :ok
|
|
112
115
|
```
|
|
113
116
|
|
|
114
|
-
##
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|---|---|---|
|
|
118
|
-
| `Zrip::FrameCodec` | `.new(dict: nil, level: 1)` | Create a frame codec, optionally with a `Dictionary`, raw `String` dict, or compression level |
|
|
119
|
-
| | `.get_frame_content_size(string)` | Read Frame_Content_Size from a Zstd frame header |
|
|
120
|
-
| | `#compress(string)` | Compress to Zstd frame |
|
|
121
|
-
| | `#decompress(string, max_output_size: nil)` | Decompress a Zstd frame, optionally bounded |
|
|
122
|
-
| | `#has_dict?` | Whether a dictionary is loaded |
|
|
123
|
-
| | `#id` | Dictionary ID (nil without dict) |
|
|
124
|
-
| | `#size` | Dictionary size in bytes (0 without dict) |
|
|
125
|
-
| | `#level` | Compression level |
|
|
126
|
-
| `Zrip::BlockCodec` | `.new(dict: nil, level: 1)` | Create a block codec, optionally with a dict |
|
|
127
|
-
| | `#compress(string)` | Compress to Zstd block |
|
|
128
|
-
| | `#decompress(string, max_output_size: nil)` | Decompress a Zstd block, optionally bounded |
|
|
129
|
-
| | `#has_dict?` | Whether a dictionary is loaded |
|
|
130
|
-
| | `#size` | Dictionary size in bytes (0 without dict) |
|
|
131
|
-
| | `#level` | Compression level |
|
|
132
|
-
| `Zrip::Dictionary` | `.new(bytes:, id: nil)` | Immutable dictionary value object (`Data.define`) |
|
|
133
|
-
| | `#bytes` | Frozen binary dict bytes |
|
|
134
|
-
| | `#id` | 32-bit dictionary ID (auto-detected from ZDICT header or SHA-256) |
|
|
135
|
-
| | `#size` | Dictionary size in bytes |
|
|
136
|
-
| `Zrip::DictTrainer` | `.new(max_dict_size)` | Create a trainer |
|
|
137
|
-
| | `#add_sample(string)` | Feed a training sample (skips < 4 bytes) |
|
|
138
|
-
| | `#train` | Consume the trainer, return dict bytes |
|
|
139
|
-
| | `#sample_count` | Number of accepted samples |
|
|
140
|
-
| | `#total_bytes` | Total bytes of accepted samples |
|
|
141
|
-
| | `#trained?` | Whether `#train` has been called |
|
|
142
|
-
| | `#max_dict_size` | Configured max dict size |
|
|
143
|
-
| `Zrip::DecompressError` | | Raised on decompression failure |
|
|
144
|
-
| `Zrip::CompressError` | | Raised on compression failure |
|
|
145
|
-
| `Zrip::MissingContentSizeError` | | Raised when Frame_Content_Size is absent (subclass of `DecompressError`) |
|
|
146
|
-
| `Zrip::OutputSizeLimitError` | | Raised when declared content size exceeds limit (subclass of `DecompressError`) |
|
|
117
|
+
## Documentation
|
|
118
|
+
|
|
119
|
+
Reference: <https://rubydoc.info/gems/zrip>
|
|
147
120
|
|
|
148
121
|
## License
|
|
149
122
|
|
data/ext/zrip/Cargo.toml
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
name = "zrip"
|
|
3
3
|
version = "0.1.2"
|
|
4
4
|
edition = "2021"
|
|
5
|
+
build = "build.rs"
|
|
5
6
|
|
|
6
7
|
[lib]
|
|
7
8
|
name = "zrip"
|
|
8
9
|
crate-type = ["cdylib", "rlib"]
|
|
9
10
|
|
|
10
11
|
[dependencies]
|
|
11
|
-
zstd = { version = "0.8.
|
|
12
|
-
magnus = "0.8"
|
|
12
|
+
zstd = { version = "0.8.5", package = "zrip", features = ["frame", "dict_builder"] }
|
|
13
13
|
rb-sys = "0.9"
|
|
14
14
|
|
|
15
15
|
[build-dependencies]
|
data/ext/zrip/build.rs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
use std::process::Command;
|
|
2
|
+
|
|
3
|
+
fn main() {
|
|
4
|
+
println!("cargo:rerun-if-env-changed=RUBY");
|
|
5
|
+
println!("cargo:rustc-check-cfg=cfg(ruby_engine, values(\"mri\", \"truffleruby\"))");
|
|
6
|
+
|
|
7
|
+
let ruby = std::env::var("RUBY").unwrap_or_else(|_| "ruby".to_string());
|
|
8
|
+
let output = Command::new(&ruby)
|
|
9
|
+
.arg("-rrbconfig")
|
|
10
|
+
.arg("-e")
|
|
11
|
+
.arg("print RbConfig::CONFIG.fetch('ruby_install_name')")
|
|
12
|
+
.output()
|
|
13
|
+
.unwrap_or_else(|err| panic!("failed to run {ruby}: {err}"));
|
|
14
|
+
|
|
15
|
+
if !output.status.success() {
|
|
16
|
+
panic!("failed to query Ruby engine with {ruby}");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
match String::from_utf8_lossy(&output.stdout).trim() {
|
|
20
|
+
"truffleruby" => println!("cargo:rustc-cfg=ruby_engine=\"truffleruby\""),
|
|
21
|
+
_ => println!("cargo:rustc-cfg=ruby_engine=\"mri\""),
|
|
22
|
+
}
|
|
23
|
+
}
|