multi_compress 0.6.0 → 0.6.1
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 +10 -0
- data/GET_STARTED.md +1 -1
- data/README.md +1 -1
- data/THIRD_PARTY_NOTICES.md +1 -1
- data/ext/multi_compress/multi_compress.c +230 -77
- data/ext/multi_compress/vendor/.vendored +1 -1
- data/ext/multi_compress/vendor/brotli/c/common/version.h +2 -2
- data/ext/multi_compress/vendor/brotli/c/dec/decode.c +59 -30
- data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -3
- data/lib/multi_compress/active_record.rb +11 -5
- data/lib/multi_compress/codec.rb +164 -94
- data/lib/multi_compress/database/api.rb +42 -0
- data/lib/multi_compress/database/decoding.rb +42 -0
- data/lib/multi_compress/database/dictionary.rb +72 -0
- data/lib/multi_compress/database/encoding.rb +31 -0
- data/lib/multi_compress/database/header.rb +71 -0
- data/lib/multi_compress/database/operations.rb +73 -0
- data/lib/multi_compress/database/validation.rb +95 -0
- data/lib/multi_compress/database.rb +10 -282
- data/lib/multi_compress/db_deployment/bundle_archiver.rb +70 -0
- data/lib/multi_compress/db_deployment/bundle_metadata.rb +56 -0
- data/lib/multi_compress/db_deployment/bundle_stager.rb +62 -0
- data/lib/multi_compress/db_deployment/commands.rb +309 -0
- data/lib/multi_compress/db_deployment/deployment_bundle.rb +80 -0
- data/lib/multi_compress/db_deployment/deterministic_tar_writer.rb +76 -0
- data/lib/multi_compress/db_deployment/dictionary_registry.rb +244 -0
- data/lib/multi_compress/db_deployment/readable_view.rb +112 -0
- data/lib/multi_compress/db_deployment/readable_view_options.rb +51 -0
- data/lib/multi_compress/db_deployment/sql_identifiers.rb +45 -0
- data/lib/multi_compress/db_deployment.rb +10 -844
- data/lib/multi_compress/reader/buffer_operations.rb +57 -0
- data/lib/multi_compress/reader/read_operations.rb +67 -0
- data/lib/multi_compress/reader.rb +97 -0
- data/lib/multi_compress/stream_io.rb +13 -0
- data/lib/multi_compress/version.rb +1 -1
- data/lib/multi_compress/writer.rb +85 -0
- data/lib/multi_compress.rb +42 -333
- metadata +25 -6
data/lib/multi_compress.rb
CHANGED
|
@@ -5,11 +5,11 @@ require "multi_compress/version"
|
|
|
5
5
|
begin
|
|
6
6
|
require "multi_compress/multi_compress"
|
|
7
7
|
rescue LoadError
|
|
8
|
-
ext_dir = File.expand_path("
|
|
8
|
+
ext_dir = File.expand_path("multi_compress", __dir__)
|
|
9
9
|
|
|
10
10
|
so_path = %w[.bundle .so]
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
.map { |ext| File.join(ext_dir, "multi_compress#{ext}") }
|
|
12
|
+
.find { |path| File.exist?(path) }
|
|
13
13
|
|
|
14
14
|
raise LoadError, "Could not find compiled MultiCompress extension. Run: bundle exec rake compile" unless so_path
|
|
15
15
|
|
|
@@ -25,10 +25,10 @@ module MultiCompress
|
|
|
25
25
|
DEFAULT_STREAMING_MAX_OUTPUT_SIZE = 2 * 1024 * 1024 * 1024
|
|
26
26
|
|
|
27
27
|
EXTENSION_MAP = {
|
|
28
|
-
".zst"
|
|
28
|
+
".zst" => :zstd,
|
|
29
29
|
".zstd" => :zstd,
|
|
30
|
-
".lz4"
|
|
31
|
-
".br"
|
|
30
|
+
".lz4" => :lz4,
|
|
31
|
+
".br" => :brotli
|
|
32
32
|
}.freeze
|
|
33
33
|
|
|
34
34
|
private_constant :EXTENSION_MAP
|
|
@@ -91,361 +91,70 @@ module MultiCompress
|
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
unless private_method_defined?(:_c_decompress)
|
|
94
|
-
|
|
94
|
+
alias _c_decompress decompress
|
|
95
95
|
private :_c_decompress
|
|
96
96
|
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def self.zstd(data, level: nil)
|
|
100
|
-
compress(data, algo: :zstd, level: level)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def self.lz4(data, level: nil, format: nil)
|
|
104
|
-
if format
|
|
105
|
-
compress(data, algo: :lz4, level: level, format: format)
|
|
106
|
-
else
|
|
107
|
-
compress(data, algo: :lz4, level: level)
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def self.brotli(data, level: nil)
|
|
112
|
-
compress(data, algo: :brotli, level: level)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def self.decompress(data, **opts)
|
|
116
|
-
_c_decompress(data, **resolved_one_shot_options(opts))
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def self.zstd_decompress(data)
|
|
120
|
-
decompress(data, algo: :zstd)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def self.lz4_decompress(data, format: nil)
|
|
124
|
-
if format
|
|
125
|
-
decompress(data, algo: :lz4, format: format)
|
|
126
|
-
else
|
|
127
|
-
decompress(data, algo: :lz4)
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def self.brotli_decompress(data)
|
|
132
|
-
decompress(data, algo: :brotli)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def self.algo_from_ext(path)
|
|
136
|
-
EXTENSION_MAP[File.extname(path).downcase]
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def self.resolved_one_shot_options(opts)
|
|
140
|
-
return opts.merge(max_output_size: config.max_output_size) unless opts.key?(:max_output_size)
|
|
141
|
-
|
|
142
|
-
opts
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
private_class_method :resolved_one_shot_options
|
|
146
|
-
|
|
147
|
-
module InflaterDefaults
|
|
148
|
-
def initialize(*args, **opts)
|
|
149
|
-
resolved = opts.dup
|
|
150
|
-
resolved[:max_output_size] = MultiCompress.config.streaming_max_output_size unless resolved.key?(:max_output_size)
|
|
151
|
-
super(*args, **resolved)
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
Inflater.prepend(InflaterDefaults)
|
|
156
97
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def self.open(path_or_io, algo: nil, level: nil, dictionary: nil, &block)
|
|
161
|
-
io, algo, owned = resolve_io(path_or_io, algo, mode: "wb")
|
|
162
|
-
writer = new(io, algo: algo || :zstd, level: level, dictionary: dictionary)
|
|
163
|
-
writer.instance_variable_set(:@owned_io, owned)
|
|
164
|
-
|
|
165
|
-
return writer unless block
|
|
166
|
-
|
|
167
|
-
begin
|
|
168
|
-
yield writer
|
|
169
|
-
ensure
|
|
170
|
-
writer.close
|
|
171
|
-
end
|
|
98
|
+
def zstd(data, level: nil)
|
|
99
|
+
compress(data, algo: :zstd, level: level)
|
|
172
100
|
end
|
|
173
101
|
|
|
174
|
-
def
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
@closed = false
|
|
178
|
-
@owned_io = false
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def write(data)
|
|
182
|
-
ensure_open!
|
|
183
|
-
bytes = data.to_s
|
|
184
|
-
flush_compressed(@deflater.write(bytes))
|
|
185
|
-
bytes.bytesize
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def flush
|
|
189
|
-
ensure_open!
|
|
190
|
-
flush_compressed(@deflater.flush)
|
|
191
|
-
@io.flush if @io.respond_to?(:flush)
|
|
192
|
-
self
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def close
|
|
196
|
-
return if @closed
|
|
197
|
-
|
|
198
|
-
flush_compressed(@deflater.finish)
|
|
199
|
-
@deflater.close
|
|
200
|
-
@io.close if @owned_io && @io.respond_to?(:close)
|
|
201
|
-
@closed = true
|
|
202
|
-
nil
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
def closed?
|
|
206
|
-
@closed
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def <<(data)
|
|
210
|
-
write(data)
|
|
211
|
-
self
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def puts(*args)
|
|
215
|
-
args.flatten.each do |arg|
|
|
216
|
-
str = arg.to_s
|
|
217
|
-
write(str)
|
|
218
|
-
write("\n") unless str.end_with?("\n")
|
|
219
|
-
end
|
|
220
|
-
nil
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def print(*args)
|
|
224
|
-
args.each { |arg| write(arg.to_s) }
|
|
225
|
-
nil
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
private
|
|
229
|
-
|
|
230
|
-
def ensure_open!
|
|
231
|
-
raise StreamError, "writer is closed" if @closed
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def flush_compressed(compressed)
|
|
235
|
-
@io.write(compressed) if compressed && !compressed.empty?
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def self.resolve_io(path_or_io, algo, mode:)
|
|
239
|
-
if path_or_io.is_a?(String)
|
|
240
|
-
[File.open(path_or_io, mode), algo || MultiCompress.algo_from_ext(path_or_io), true]
|
|
102
|
+
def lz4(data, level: nil, format: nil)
|
|
103
|
+
if format
|
|
104
|
+
compress(data, algo: :lz4, level: level, format: format)
|
|
241
105
|
else
|
|
242
|
-
|
|
106
|
+
compress(data, algo: :lz4, level: level)
|
|
243
107
|
end
|
|
244
108
|
end
|
|
245
109
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
class Reader
|
|
250
|
-
CHUNK_SIZE = 8192
|
|
251
|
-
BUFFER_COMPACT_THRESHOLD = 64 * 1024
|
|
252
|
-
|
|
253
|
-
def self.open(path_or_io, algo: nil, dictionary: nil, **opts, &block)
|
|
254
|
-
io, algo, owned = resolve_io(path_or_io, algo, mode: "rb")
|
|
255
|
-
reader = new(io, algo: algo, dictionary: dictionary, **opts)
|
|
256
|
-
reader.instance_variable_set(:@owned_io, owned)
|
|
257
|
-
|
|
258
|
-
return reader unless block
|
|
259
|
-
|
|
260
|
-
begin
|
|
261
|
-
yield reader
|
|
262
|
-
ensure
|
|
263
|
-
reader.close
|
|
264
|
-
end
|
|
110
|
+
def brotli(data, level: nil)
|
|
111
|
+
compress(data, algo: :brotli, level: level)
|
|
265
112
|
end
|
|
266
113
|
|
|
267
|
-
def
|
|
268
|
-
|
|
269
|
-
@inflater = Inflater.new(algo: algo, dictionary: dictionary, **opts)
|
|
270
|
-
@closed = false
|
|
271
|
-
@owned_io = false
|
|
272
|
-
@buffer = +"".b
|
|
273
|
-
@buffer_pos = 0
|
|
274
|
-
@eof = false
|
|
114
|
+
def decompress(data, **opts)
|
|
115
|
+
_c_decompress(data, **resolved_one_shot_options(opts))
|
|
275
116
|
end
|
|
276
117
|
|
|
277
|
-
def
|
|
278
|
-
|
|
279
|
-
return read_all if length.nil?
|
|
280
|
-
|
|
281
|
-
read_exactly(length)
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def gets(separator = "\n")
|
|
285
|
-
ensure_open!
|
|
286
|
-
return nil if @eof && buffer_empty?
|
|
287
|
-
|
|
288
|
-
fill_buffer_until { buffer_includes?(separator) }
|
|
289
|
-
|
|
290
|
-
return extract_line(separator) if buffer_includes?(separator)
|
|
291
|
-
return consume_buffer unless buffer_empty?
|
|
292
|
-
|
|
293
|
-
nil
|
|
118
|
+
def zstd_decompress(data)
|
|
119
|
+
decompress(data, algo: :zstd)
|
|
294
120
|
end
|
|
295
121
|
|
|
296
|
-
def
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
@closed = true
|
|
302
|
-
nil
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
def closed?
|
|
306
|
-
@closed
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
def eof?
|
|
310
|
-
@eof && buffer_empty?
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
def each_line
|
|
314
|
-
return enum_for(:each_line) unless block_given?
|
|
315
|
-
|
|
316
|
-
while (line = gets)
|
|
317
|
-
yield line
|
|
122
|
+
def lz4_decompress(data, format: nil)
|
|
123
|
+
if format
|
|
124
|
+
decompress(data, algo: :lz4, format: format)
|
|
125
|
+
else
|
|
126
|
+
decompress(data, algo: :lz4)
|
|
318
127
|
end
|
|
319
128
|
end
|
|
320
129
|
|
|
321
|
-
def
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
while (chunk = read(size))
|
|
325
|
-
yield chunk
|
|
326
|
-
end
|
|
130
|
+
def brotli_decompress(data)
|
|
131
|
+
decompress(data, algo: :brotli)
|
|
327
132
|
end
|
|
328
133
|
|
|
329
|
-
def
|
|
330
|
-
|
|
134
|
+
def algo_from_ext(path)
|
|
135
|
+
EXTENSION_MAP[File.extname(path).downcase]
|
|
331
136
|
end
|
|
332
137
|
|
|
333
138
|
private
|
|
334
139
|
|
|
335
|
-
def
|
|
336
|
-
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
def buffer_size
|
|
340
|
-
@buffer.bytesize - @buffer_pos
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
def buffer_empty?
|
|
344
|
-
@buffer_pos >= @buffer.bytesize
|
|
345
|
-
end
|
|
346
|
-
|
|
347
|
-
def buffer_append(data)
|
|
348
|
-
compact_buffer_if_needed
|
|
349
|
-
@buffer << data
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
def compact_buffer_if_needed
|
|
353
|
-
return if @buffer_pos == 0
|
|
354
|
-
|
|
355
|
-
total = @buffer.bytesize
|
|
356
|
-
return unless @buffer_pos >= BUFFER_COMPACT_THRESHOLD && @buffer_pos * 2 >= total
|
|
140
|
+
def resolved_one_shot_options(opts)
|
|
141
|
+
return opts.merge(max_output_size: config.max_output_size) unless opts.key?(:max_output_size)
|
|
357
142
|
|
|
358
|
-
|
|
359
|
-
@buffer_pos = 0
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
def buffer_includes?(separator)
|
|
363
|
-
idx = @buffer.index(separator, @buffer_pos)
|
|
364
|
-
!idx.nil?
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
def read_all
|
|
368
|
-
return nil if @eof && buffer_empty?
|
|
369
|
-
|
|
370
|
-
result = if buffer_empty?
|
|
371
|
-
+"".b
|
|
372
|
-
else
|
|
373
|
-
@buffer.byteslice(@buffer_pos, @buffer.bytesize - @buffer_pos) || +"".b
|
|
374
|
-
end
|
|
375
|
-
@buffer.clear
|
|
376
|
-
@buffer_pos = 0
|
|
377
|
-
|
|
378
|
-
until @eof
|
|
379
|
-
chunk = read_compressed_chunk
|
|
380
|
-
break unless chunk && !chunk.empty?
|
|
381
|
-
|
|
382
|
-
decompressed = @inflater.write(chunk)
|
|
383
|
-
result << decompressed if decompressed
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
final = @inflater.finish
|
|
387
|
-
result << final if final && !final.empty?
|
|
388
|
-
|
|
389
|
-
result.empty? ? nil : result
|
|
390
|
-
end
|
|
391
|
-
|
|
392
|
-
def read_exactly(length)
|
|
393
|
-
return nil if @eof && buffer_empty?
|
|
394
|
-
|
|
395
|
-
fill_buffer_until { buffer_size >= length }
|
|
396
|
-
|
|
397
|
-
if buffer_size >= length
|
|
398
|
-
result = @buffer.byteslice(@buffer_pos, length)
|
|
399
|
-
@buffer_pos += length
|
|
400
|
-
compact_buffer_if_needed
|
|
401
|
-
result
|
|
402
|
-
elsif !buffer_empty?
|
|
403
|
-
consume_buffer
|
|
404
|
-
end
|
|
405
|
-
end
|
|
406
|
-
|
|
407
|
-
def fill_buffer_until
|
|
408
|
-
until yield || @eof
|
|
409
|
-
chunk = read_compressed_chunk
|
|
410
|
-
if chunk.nil? || chunk.empty?
|
|
411
|
-
@eof = true
|
|
412
|
-
break
|
|
413
|
-
end
|
|
414
|
-
decompressed = @inflater.write(chunk)
|
|
415
|
-
buffer_append(decompressed) if decompressed
|
|
416
|
-
end
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
def extract_line(separator)
|
|
420
|
-
idx = @buffer.index(separator, @buffer_pos)
|
|
421
|
-
end_pos = idx + separator.bytesize
|
|
422
|
-
result = @buffer.byteslice(@buffer_pos, end_pos - @buffer_pos)
|
|
423
|
-
@buffer_pos = end_pos
|
|
424
|
-
compact_buffer_if_needed
|
|
425
|
-
result
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
def consume_buffer
|
|
429
|
-
result = @buffer.byteslice(@buffer_pos, @buffer.bytesize - @buffer_pos) || +"".b
|
|
430
|
-
@buffer.clear
|
|
431
|
-
@buffer_pos = 0
|
|
432
|
-
result
|
|
143
|
+
opts
|
|
433
144
|
end
|
|
145
|
+
end
|
|
434
146
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
147
|
+
module InflaterDefaults
|
|
148
|
+
def initialize(*args, **opts)
|
|
149
|
+
resolved = opts.dup
|
|
150
|
+
resolved[:max_output_size] = MultiCompress.config.streaming_max_output_size unless resolved.key?(:max_output_size)
|
|
151
|
+
super(*args, **resolved)
|
|
439
152
|
end
|
|
153
|
+
end
|
|
440
154
|
|
|
441
|
-
|
|
442
|
-
if path_or_io.is_a?(String)
|
|
443
|
-
[File.open(path_or_io, mode), algo || MultiCompress.algo_from_ext(path_or_io), true]
|
|
444
|
-
else
|
|
445
|
-
[path_or_io, algo, false]
|
|
446
|
-
end
|
|
447
|
-
end
|
|
155
|
+
Inflater.prepend(InflaterDefaults)
|
|
448
156
|
|
|
449
|
-
|
|
450
|
-
|
|
157
|
+
require "multi_compress/stream_io"
|
|
158
|
+
require "multi_compress/writer"
|
|
159
|
+
require "multi_compress/reader"
|
|
451
160
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: multi_compress
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roman Haydarov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -348,8 +347,30 @@ files:
|
|
|
348
347
|
- lib/multi_compress/active_record.rb
|
|
349
348
|
- lib/multi_compress/codec.rb
|
|
350
349
|
- lib/multi_compress/database.rb
|
|
350
|
+
- lib/multi_compress/database/api.rb
|
|
351
|
+
- lib/multi_compress/database/decoding.rb
|
|
352
|
+
- lib/multi_compress/database/dictionary.rb
|
|
353
|
+
- lib/multi_compress/database/encoding.rb
|
|
354
|
+
- lib/multi_compress/database/header.rb
|
|
355
|
+
- lib/multi_compress/database/operations.rb
|
|
356
|
+
- lib/multi_compress/database/validation.rb
|
|
351
357
|
- lib/multi_compress/db_deployment.rb
|
|
358
|
+
- lib/multi_compress/db_deployment/bundle_archiver.rb
|
|
359
|
+
- lib/multi_compress/db_deployment/bundle_metadata.rb
|
|
360
|
+
- lib/multi_compress/db_deployment/bundle_stager.rb
|
|
361
|
+
- lib/multi_compress/db_deployment/commands.rb
|
|
362
|
+
- lib/multi_compress/db_deployment/deployment_bundle.rb
|
|
363
|
+
- lib/multi_compress/db_deployment/deterministic_tar_writer.rb
|
|
364
|
+
- lib/multi_compress/db_deployment/dictionary_registry.rb
|
|
365
|
+
- lib/multi_compress/db_deployment/readable_view.rb
|
|
366
|
+
- lib/multi_compress/db_deployment/readable_view_options.rb
|
|
367
|
+
- lib/multi_compress/db_deployment/sql_identifiers.rb
|
|
368
|
+
- lib/multi_compress/reader.rb
|
|
369
|
+
- lib/multi_compress/reader/buffer_operations.rb
|
|
370
|
+
- lib/multi_compress/reader/read_operations.rb
|
|
371
|
+
- lib/multi_compress/stream_io.rb
|
|
352
372
|
- lib/multi_compress/version.rb
|
|
373
|
+
- lib/multi_compress/writer.rb
|
|
353
374
|
- multi_compress.gemspec
|
|
354
375
|
- mysql_udf/Makefile
|
|
355
376
|
- mysql_udf/README.md
|
|
@@ -381,7 +402,6 @@ metadata:
|
|
|
381
402
|
homepage_uri: https://github.com/roman-haidarov/multi_compress
|
|
382
403
|
source_code_uri: https://github.com/roman-haidarov/multi_compress
|
|
383
404
|
changelog_uri: https://github.com/roman-haidarov/multi_compress/blob/main/CHANGELOG.md
|
|
384
|
-
post_install_message:
|
|
385
405
|
rdoc_options: []
|
|
386
406
|
require_paths:
|
|
387
407
|
- lib
|
|
@@ -396,8 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
396
416
|
- !ruby/object:Gem::Version
|
|
397
417
|
version: '0'
|
|
398
418
|
requirements: []
|
|
399
|
-
rubygems_version: 3.
|
|
400
|
-
signing_key:
|
|
419
|
+
rubygems_version: 3.6.7
|
|
401
420
|
specification_version: 4
|
|
402
421
|
summary: 'Modern fiber-friendly compression for Ruby: zstd, lz4, brotli in one gem'
|
|
403
422
|
test_files: []
|