lz4-ruby 0.2.0-java
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 +7 -0
- data/.document +5 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +81 -0
- data/Rakefile +104 -0
- data/VERSION +1 -0
- data/benchmarking/bench.rb +137 -0
- data/benchmarking/bench_all.sh +5 -0
- data/benchmarking/compressor.rb +71 -0
- data/benchmarking/compressor_lz4.rb +25 -0
- data/benchmarking/compressor_lzo.rb +25 -0
- data/benchmarking/compressor_snappy.rb +25 -0
- data/ext/lz4ruby/extconf.rb +6 -0
- data/ext/lz4ruby/lz4.c +861 -0
- data/ext/lz4ruby/lz4.h +117 -0
- data/ext/lz4ruby/lz4hc.c +671 -0
- data/ext/lz4ruby/lz4hc.h +60 -0
- data/ext/lz4ruby/lz4ruby.c +92 -0
- data/lib/lz4-jruby.rb +3 -0
- data/lib/lz4-ruby.rb +74 -0
- data/lib/lz4ruby.jar +0 -0
- data/pom.xml +71 -0
- data/spec/helper.rb +33 -0
- data/spec/lz4_compressHC_spec.rb +50 -0
- data/spec/lz4_compress_spec.rb +50 -0
- data/src/main/java/com/headius/jruby/lz4/LZ4Internal.java +64 -0
- data/src/main/java/com/headius/jruby/lz4/LZ4Library.java +18 -0
- metadata +142 -0
data/ext/lz4ruby/lz4hc.h
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
/*
|
2
|
+
LZ4 HC - High Compression Mode of LZ4
|
3
|
+
Header File
|
4
|
+
Copyright (C) 2011-2012, Yann Collet.
|
5
|
+
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are
|
9
|
+
met:
|
10
|
+
|
11
|
+
* Redistributions of source code must retain the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer.
|
13
|
+
* Redistributions in binary form must reproduce the above
|
14
|
+
copyright notice, this list of conditions and the following disclaimer
|
15
|
+
in the documentation and/or other materials provided with the
|
16
|
+
distribution.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
You can contact the author at :
|
31
|
+
- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
|
32
|
+
- LZ4 source repository : http://code.google.com/p/lz4/
|
33
|
+
*/
|
34
|
+
#pragma once
|
35
|
+
|
36
|
+
|
37
|
+
#if defined (__cplusplus)
|
38
|
+
extern "C" {
|
39
|
+
#endif
|
40
|
+
|
41
|
+
|
42
|
+
int LZ4_compressHC (const char* source, char* dest, int isize);
|
43
|
+
|
44
|
+
/*
|
45
|
+
LZ4_compressHC :
|
46
|
+
return : the number of bytes in compressed buffer dest
|
47
|
+
note : destination buffer must be already allocated.
|
48
|
+
To avoid any problem, size it to handle worst cases situations (input data not compressible)
|
49
|
+
Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
|
50
|
+
*/
|
51
|
+
|
52
|
+
|
53
|
+
/* Note :
|
54
|
+
Decompression functions are provided within regular LZ4 source code (see "lz4.h") (BSD license)
|
55
|
+
*/
|
56
|
+
|
57
|
+
|
58
|
+
#if defined (__cplusplus)
|
59
|
+
}
|
60
|
+
#endif
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "lz4.h"
|
3
|
+
#include "lz4hc.h"
|
4
|
+
|
5
|
+
typedef int (*CompressFunc)(const char *source, char *dest, int isize);
|
6
|
+
|
7
|
+
static VALUE lz4internal;
|
8
|
+
static VALUE lz4_error;
|
9
|
+
|
10
|
+
/**
|
11
|
+
* LZ4Internal functions.
|
12
|
+
*/
|
13
|
+
static VALUE compress_internal(CompressFunc compressor, VALUE header, VALUE input, VALUE in_size) {
|
14
|
+
const char *src_p;
|
15
|
+
int src_size;
|
16
|
+
|
17
|
+
const char *header_p;
|
18
|
+
int header_size;
|
19
|
+
|
20
|
+
VALUE result;
|
21
|
+
char *buf;
|
22
|
+
int buf_size;
|
23
|
+
|
24
|
+
int comp_size;
|
25
|
+
|
26
|
+
Check_Type(input, T_STRING);
|
27
|
+
src_p = RSTRING_PTR(input);
|
28
|
+
src_size = NUM2INT(in_size);
|
29
|
+
buf_size = LZ4_compressBound(src_size);
|
30
|
+
|
31
|
+
Check_Type(header, T_STRING);
|
32
|
+
header_p = RSTRING_PTR(header);
|
33
|
+
header_size = RSTRING_LEN(header);
|
34
|
+
|
35
|
+
result = rb_str_new(NULL, buf_size + header_size);
|
36
|
+
buf = RSTRING_PTR(result);
|
37
|
+
|
38
|
+
memcpy(buf, header_p, header_size);
|
39
|
+
|
40
|
+
comp_size = compressor(src_p, buf + header_size, src_size);
|
41
|
+
rb_str_resize(result, comp_size + header_size);
|
42
|
+
|
43
|
+
return result;
|
44
|
+
}
|
45
|
+
|
46
|
+
static VALUE lz4internal_compress(VALUE self, VALUE header, VALUE input, VALUE in_size) {
|
47
|
+
return compress_internal(LZ4_compress, header, input, in_size);
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE lz4internal_compressHC(VALUE self, VALUE header, VALUE input, VALUE in_size) {
|
51
|
+
return compress_internal(LZ4_compressHC, header, input, in_size);
|
52
|
+
}
|
53
|
+
|
54
|
+
static VALUE lz4internal_uncompress(VALUE self, VALUE input, VALUE in_size, VALUE offset, VALUE out_size) {
|
55
|
+
const char *src_p;
|
56
|
+
int src_size;
|
57
|
+
|
58
|
+
int header_size;
|
59
|
+
|
60
|
+
VALUE result;
|
61
|
+
char *buf;
|
62
|
+
int buf_size;
|
63
|
+
|
64
|
+
int read_bytes;
|
65
|
+
|
66
|
+
Check_Type(input, T_STRING);
|
67
|
+
src_p = RSTRING_PTR(input);
|
68
|
+
src_size = NUM2INT(in_size);
|
69
|
+
|
70
|
+
header_size = NUM2INT(offset);
|
71
|
+
buf_size = NUM2INT(out_size);
|
72
|
+
|
73
|
+
result = rb_str_new(NULL, buf_size);
|
74
|
+
buf = RSTRING_PTR(result);
|
75
|
+
|
76
|
+
read_bytes = LZ4_uncompress_unknownOutputSize(src_p + header_size, buf, src_size - header_size, buf_size);
|
77
|
+
if (read_bytes < 0) {
|
78
|
+
rb_raise(lz4_error, "Compressed data is maybe corrupted.");
|
79
|
+
}
|
80
|
+
|
81
|
+
return result;
|
82
|
+
}
|
83
|
+
|
84
|
+
void Init_lz4ruby(void) {
|
85
|
+
lz4internal = rb_define_module("LZ4Internal");
|
86
|
+
|
87
|
+
rb_define_module_function(lz4internal, "compress", lz4internal_compress, 3);
|
88
|
+
rb_define_module_function(lz4internal, "compressHC", lz4internal_compressHC, 3);
|
89
|
+
rb_define_module_function(lz4internal, "uncompress", lz4internal_uncompress, 4);
|
90
|
+
|
91
|
+
lz4_error = rb_define_class_under(lz4internal, "Error", rb_eStandardError);
|
92
|
+
}
|
data/lib/lz4-jruby.rb
ADDED
data/lib/lz4-ruby.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
if /(mswin|mingw)/ =~ RUBY_PLATFORM
|
2
|
+
/(\d+\.\d+)/ =~ RUBY_VERSION
|
3
|
+
ver = $1
|
4
|
+
require "#{ver}/lz4ruby.so"
|
5
|
+
elsif RUBY_PLATFORM == 'java'
|
6
|
+
require 'lz4-jruby'
|
7
|
+
else
|
8
|
+
require 'lz4ruby'
|
9
|
+
end
|
10
|
+
|
11
|
+
class LZ4
|
12
|
+
def self.compress(input, in_size = nil)
|
13
|
+
return _compress(input, in_size, false)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.compressHC(input, in_size = nil)
|
17
|
+
return _compress(input, in_size, true)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self._compress(input, in_size, high_compression)
|
21
|
+
in_size = input.length if in_size == nil
|
22
|
+
header = encode_varbyte(in_size)
|
23
|
+
|
24
|
+
if high_compression
|
25
|
+
return LZ4Internal.compressHC(header, input, in_size)
|
26
|
+
else
|
27
|
+
return LZ4Internal.compress(header, input, in_size)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.uncompress(input, in_size = nil)
|
32
|
+
in_size = input.length if in_size == nil
|
33
|
+
out_size, varbyte_len = decode_varbyte(input)
|
34
|
+
|
35
|
+
if out_size < 0 || varbyte_len < 0
|
36
|
+
raise "Compressed data is maybe corrupted"
|
37
|
+
end
|
38
|
+
|
39
|
+
return LZ4Internal::uncompress(input, in_size, varbyte_len, out_size)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.encode_varbyte(val)
|
43
|
+
varbytes = []
|
44
|
+
|
45
|
+
loop do
|
46
|
+
byte = val & 0x7f
|
47
|
+
val >>= 7
|
48
|
+
|
49
|
+
if val == 0
|
50
|
+
varbytes.push(byte)
|
51
|
+
break
|
52
|
+
else
|
53
|
+
varbytes.push(byte | 0x80)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
return varbytes.pack("C*")
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.decode_varbyte(text)
|
61
|
+
len = [text.length, 5].min
|
62
|
+
bytes = text[0, len].unpack("C*")
|
63
|
+
|
64
|
+
varbyte_len = 0
|
65
|
+
val = 0
|
66
|
+
bytes.each do |b|
|
67
|
+
val |= (b & 0x7f) << (7 * varbyte_len)
|
68
|
+
varbyte_len += 1
|
69
|
+
return val, varbyte_len if b & 0x80 == 0
|
70
|
+
end
|
71
|
+
|
72
|
+
return -1, -1
|
73
|
+
end
|
74
|
+
end
|
data/lib/lz4ruby.jar
ADDED
Binary file
|
data/pom.xml
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
2
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
3
|
+
<modelVersion>4.0.0</modelVersion>
|
4
|
+
|
5
|
+
<groupId>com.headius.jruby.lz4</groupId>
|
6
|
+
<artifactId>lz4ruby</artifactId>
|
7
|
+
<version>0.2.0</version>
|
8
|
+
<packaging>jar</packaging>
|
9
|
+
|
10
|
+
<name>lz4ruby</name>
|
11
|
+
<url>http://maven.apache.org</url>
|
12
|
+
|
13
|
+
<properties>
|
14
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
15
|
+
</properties>
|
16
|
+
|
17
|
+
<dependencies>
|
18
|
+
<dependency>
|
19
|
+
<groupId>junit</groupId>
|
20
|
+
<artifactId>junit</artifactId>
|
21
|
+
<version>3.8.1</version>
|
22
|
+
<scope>test</scope>
|
23
|
+
</dependency>
|
24
|
+
<dependency>
|
25
|
+
<groupId>net.jpountz.lz4</groupId>
|
26
|
+
<artifactId>lz4</artifactId>
|
27
|
+
<version>1.1.1</version>
|
28
|
+
</dependency>
|
29
|
+
<dependency>
|
30
|
+
<groupId>org.jruby</groupId>
|
31
|
+
<artifactId>jruby</artifactId>
|
32
|
+
<version>1.7.0</version>
|
33
|
+
<scope>provided</scope>
|
34
|
+
</dependency>
|
35
|
+
</dependencies>
|
36
|
+
|
37
|
+
<build>
|
38
|
+
<plugins>
|
39
|
+
<plugin>
|
40
|
+
<artifactId>maven-compiler-plugin</artifactId>
|
41
|
+
<version>3.1</version>
|
42
|
+
<configuration>
|
43
|
+
<source>1.6</source>
|
44
|
+
<target>1.6</target>
|
45
|
+
</configuration>
|
46
|
+
</plugin>
|
47
|
+
<plugin>
|
48
|
+
<groupId>org.apache.maven.plugins</groupId>
|
49
|
+
<artifactId>maven-shade-plugin</artifactId>
|
50
|
+
<version>2.0</version>
|
51
|
+
<configuration>
|
52
|
+
<relocations>
|
53
|
+
<relocation>
|
54
|
+
<pattern>net.jpountz</pattern>
|
55
|
+
<shadedPattern>com.headius.jruby.lz4.vendor.net.jpountz</shadedPattern>
|
56
|
+
</relocation>
|
57
|
+
</relocations>
|
58
|
+
<outputFile>${basedir}/lib/lz4ruby.jar</outputFile>
|
59
|
+
</configuration>
|
60
|
+
<executions>
|
61
|
+
<execution>
|
62
|
+
<phase>package</phase>
|
63
|
+
<goals>
|
64
|
+
<goal>shade</goal>
|
65
|
+
</goals>
|
66
|
+
</execution>
|
67
|
+
</executions>
|
68
|
+
</plugin>
|
69
|
+
</plugins>
|
70
|
+
</build>
|
71
|
+
</project>
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'ext/lz4ruby'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
|
16
|
+
build_native = <<EOS
|
17
|
+
cd ext/lz4ruby
|
18
|
+
ruby extconf.rb
|
19
|
+
make clean
|
20
|
+
make
|
21
|
+
EOS
|
22
|
+
`#{build_native}`
|
23
|
+
|
24
|
+
require 'lz4-ruby'
|
25
|
+
|
26
|
+
def generate_random_bytes(len)
|
27
|
+
result = []
|
28
|
+
len.times do |t|
|
29
|
+
result << rand(256)
|
30
|
+
end
|
31
|
+
return result.pack("C*")
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
|
3
|
+
describe "LZ4::compress" do
|
4
|
+
LOOP_COUNT = 257
|
5
|
+
|
6
|
+
context "give empty text" do
|
7
|
+
compressed = LZ4.compressHC("")
|
8
|
+
uncompressed = LZ4.uncompress(compressed)
|
9
|
+
|
10
|
+
it "should be able to uncompress" do
|
11
|
+
expect(uncompressed).to eql("")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "give long text" do
|
16
|
+
text = "a" * 131073
|
17
|
+
compressed = LZ4.compressHC(text)
|
18
|
+
uncompressed = LZ4.uncompress(compressed)
|
19
|
+
|
20
|
+
it "should be able to uncompress" do
|
21
|
+
expect(uncompressed).to eql(text)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
LOOP_COUNT.times do |t|
|
26
|
+
len = t + 1
|
27
|
+
text = "a" * len
|
28
|
+
|
29
|
+
context "give text of #{len} \"a\"'s" do
|
30
|
+
compressed = LZ4.compressHC(text)
|
31
|
+
uncompressed = LZ4.uncompress(compressed)
|
32
|
+
it "should be able to uncompress" do
|
33
|
+
expect(uncompressed).to eql(text)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
LOOP_COUNT.times do |t|
|
39
|
+
len = t + 1
|
40
|
+
text = generate_random_bytes(len)
|
41
|
+
|
42
|
+
context "give text of #{len} bytes" do
|
43
|
+
compressed = LZ4.compressHC(text)
|
44
|
+
uncompressed = LZ4.uncompress(compressed)
|
45
|
+
it "should be able to uncompress" do
|
46
|
+
expect(uncompressed).to eql(text)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require './spec/helper'
|
2
|
+
|
3
|
+
describe "LZ4::compress" do
|
4
|
+
LOOP_COUNT = 257
|
5
|
+
|
6
|
+
context "give empty text" do
|
7
|
+
compressed = LZ4.compress("")
|
8
|
+
uncompressed = LZ4.uncompress(compressed)
|
9
|
+
|
10
|
+
it "should be able to uncompress" do
|
11
|
+
expect(uncompressed).to eql("")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "give long text" do
|
16
|
+
text = "a" * 131073
|
17
|
+
compressed = LZ4.compress(text)
|
18
|
+
uncompressed = LZ4.uncompress(compressed)
|
19
|
+
|
20
|
+
it "should be able to uncompress" do
|
21
|
+
expect(uncompressed).to eql(text)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
LOOP_COUNT.times do |t|
|
26
|
+
len = t + 1
|
27
|
+
text = "a" * len
|
28
|
+
|
29
|
+
context "give text of #{len} \"a\"'s" do
|
30
|
+
compressed = LZ4.compress(text)
|
31
|
+
uncompressed = LZ4.uncompress(compressed)
|
32
|
+
it "should be able to uncompress" do
|
33
|
+
expect(uncompressed).to eql(text)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
LOOP_COUNT.times do |t|
|
39
|
+
len = t + 1
|
40
|
+
text = generate_random_bytes(len)
|
41
|
+
|
42
|
+
context "give text of #{len} bytes" do
|
43
|
+
compressed = LZ4.compress(text)
|
44
|
+
uncompressed = LZ4.uncompress(compressed)
|
45
|
+
it "should be able to uncompress" do
|
46
|
+
expect(uncompressed).to eql(text)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|