omnizip 0.3.22 → 0.3.23
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 +40 -0
- data/lib/omnizip/algorithms/zstandard/match_finder.rb +25 -8
- data/lib/omnizip/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 61cf26f9e324600f286b236ab80e02d720059f32bca2fa3c71640ba3abc4355a
|
|
4
|
+
data.tar.gz: fa189e081e402ecb4d084490e7874402faacf231a296cd009a15f218fcd9453e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 308660d6095a909d72c528bdfb5e828e76d320172b979a53ef7401aa2c1c12a560a0afd57f49991eb5190f87deca1c15cd798e8abae89bd3341ed3bb43c39b3d
|
|
7
|
+
data.tar.gz: 29ac9066539f2d8cef3973a2eb9cfe15a549a5efead04a1f5c88f28587fb6a2d23ac28c401c1c4187f5c226bfe4b531e3565523400dcd183adc83c842cd2d5dc
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.23] - 2026-08-26
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Zstd encoder hot paths use allocation-free integer reads instead of
|
|
14
|
+
`String#byteslice` + `unpack1` comparisons (profiling showed GC at
|
|
15
|
+
52% of encoder time): default-level compression is ~3.4x faster and
|
|
16
|
+
level 22 ~1.9x on the benchmark corpus, with byte-identical output.
|
|
17
|
+
|
|
18
|
+
## [0.3.22] - 2026-08-25
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- Zstandard dictionary compression (`Dictionary.from_raw` /
|
|
22
|
+
`serialize` / `deserialize`, `compress_with_dict`,
|
|
23
|
+
`decompress_with_dict`): the dictionary content primes the match
|
|
24
|
+
finder as shared history and the frame header carries the
|
|
25
|
+
Dictionary_ID, which the decoder verifies (Phase-1 scope, as in the
|
|
26
|
+
Rust reference; entropy-table preloading is future work).
|
|
27
|
+
|
|
28
|
+
## [0.3.21] - 2026-08-25
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- 7-Zip encoder dictionary is now capped at the size announced in the
|
|
32
|
+
coder properties (prevents matches reading outside the decoder
|
|
33
|
+
window for inputs above the announced size).
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- Zstd lazy levels (6+) gained the rep0 fast-path and backward
|
|
37
|
+
extension: levels 6-12 improve 0.180 -> 0.154 and levels 19-22
|
|
38
|
+
0.146 -> 0.126 on the benchmark corpus; the level scale is now
|
|
39
|
+
monotonic.
|
|
40
|
+
- Zstd adaptive block splitting: heterogeneous chunks of 32 KiB or
|
|
41
|
+
more split into 16 KiB sub-blocks so entropy tables fit each
|
|
42
|
+
content regime.
|
|
43
|
+
|
|
44
|
+
## [0.3.20] - 2026-08-25
|
|
45
|
+
|
|
46
|
+
### Removed
|
|
47
|
+
- Dead `SevenZipLZMA2`/`XZLZMA2` algorithm wrappers (never
|
|
48
|
+
autoloaded; one referenced a nonexistent decoder constant).
|
|
49
|
+
|
|
10
50
|
## [0.3.19] - 2026-08-25
|
|
11
51
|
|
|
12
52
|
### Fixed
|
|
@@ -131,11 +131,29 @@ module Omnizip
|
|
|
131
131
|
min_match: MIN_MATCH_ECONOMICAL }
|
|
132
132
|
end
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
# Allocation-free little-endian reads; the hot loops call
|
|
135
|
+
# these millions of times, and String#byteslice + unpack1
|
|
136
|
+
# showed up as half the encoder's time via GC pressure.
|
|
137
|
+
def read4(src, pos)
|
|
138
|
+
src.getbyte(pos) |
|
|
136
139
|
(src.getbyte(pos + 1) << 8) |
|
|
137
140
|
(src.getbyte(pos + 2) << 16) |
|
|
138
141
|
(src.getbyte(pos + 3) << 24)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def read8(src, pos)
|
|
145
|
+
src.getbyte(pos) |
|
|
146
|
+
(src.getbyte(pos + 1) << 8) |
|
|
147
|
+
(src.getbyte(pos + 2) << 16) |
|
|
148
|
+
(src.getbyte(pos + 3) << 24) |
|
|
149
|
+
(src.getbyte(pos + 4) << 32) |
|
|
150
|
+
(src.getbyte(pos + 5) << 40) |
|
|
151
|
+
(src.getbyte(pos + 6) << 48) |
|
|
152
|
+
(src.getbyte(pos + 7) << 56)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def hash4(src, pos, h_bits)
|
|
156
|
+
v = read4(src, pos)
|
|
139
157
|
# 32-bit wrapping multiply (C/uint32_t), then the high bits.
|
|
140
158
|
((v * PRIME4_BYTES) & 0xFFFFFFFF) >> (32 - h_bits)
|
|
141
159
|
end
|
|
@@ -148,8 +166,8 @@ module Omnizip
|
|
|
148
166
|
b_size = b.bytesize
|
|
149
167
|
while len + 8 <= limit && a_pos + len + 8 <= a_size &&
|
|
150
168
|
b_pos + len + 8 <= b_size
|
|
151
|
-
wa = a
|
|
152
|
-
wb = b
|
|
169
|
+
wa = read8(a, a_pos + len)
|
|
170
|
+
wb = read8(b, b_pos + len)
|
|
153
171
|
if wa == wb
|
|
154
172
|
len += 8
|
|
155
173
|
else
|
|
@@ -289,8 +307,7 @@ module Omnizip
|
|
|
289
307
|
# rubocop:disable-next Metrics/AbcSize
|
|
290
308
|
def rep0_match(src, ip, rep0, min_match, limit, anchor)
|
|
291
309
|
return nil if rep0 <= 0 || ip <= rep0
|
|
292
|
-
return nil if src
|
|
293
|
-
src.byteslice(ip - rep0, MIN_MATCH)
|
|
310
|
+
return nil if read4(src, ip) != read4(src, ip - rep0)
|
|
294
311
|
|
|
295
312
|
m_len = MIN_MATCH + count_match(
|
|
296
313
|
src, ip + MIN_MATCH, src, ip + MIN_MATCH - rep0,
|
|
@@ -346,7 +363,7 @@ module Omnizip
|
|
|
346
363
|
break if dist >= max_distance
|
|
347
364
|
break if candidate + MIN_MATCH > size
|
|
348
365
|
|
|
349
|
-
if src
|
|
366
|
+
if read4(src, ip) == read4(src, candidate)
|
|
350
367
|
m_len = MIN_MATCH + count_match(src, ip + MIN_MATCH,
|
|
351
368
|
src, candidate + MIN_MATCH,
|
|
352
369
|
[max_extend - MIN_MATCH, 0].max)
|
|
@@ -397,7 +414,7 @@ module Omnizip
|
|
|
397
414
|
if candidate.positive? && candidate < ip
|
|
398
415
|
dist = ip - candidate
|
|
399
416
|
if dist < max_distance && candidate + MIN_MATCH <= size &&
|
|
400
|
-
src
|
|
417
|
+
read4(src, ip) == read4(src, candidate)
|
|
401
418
|
best_len = MIN_MATCH + count_match(
|
|
402
419
|
src, ip + MIN_MATCH, src, candidate + MIN_MATCH,
|
|
403
420
|
[limit + MIN_MATCH_ECONOMICAL - ip - MIN_MATCH, 0].max
|
data/lib/omnizip/version.rb
CHANGED