lz4-ruby 0.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|