xxhash 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,31 @@
1
+ #include <stdlib.h>
1
2
  #include <ruby.h>
2
3
  #include "libxxhash.h"
3
4
 
5
+ typedef struct {
6
+ XXH32_state_t* state;
7
+ unsigned int seed;
8
+ } xxhash_xxh32_t;
9
+
10
+ typedef struct {
11
+ XXH64_state_t* state;
12
+ unsigned int seed;
13
+ } xxhash_xxh64_t;
14
+
4
15
  // Use this typedef to make the compiler happy when
5
16
  // calling rb_define_method()
6
17
  typedef VALUE (ruby_method)();
7
18
 
8
19
  VALUE xxhash_xxh32(VALUE mod, VALUE input, VALUE seed);
9
- void xxhash32_streaming_hash_free(XXH32_state_t* state);
20
+ void xxhash32_streaming_hash_free(xxhash_xxh32_t* state);
10
21
  VALUE xxhash32_streaming_hash_new(VALUE klass, VALUE seed);
11
22
  VALUE xxhash32_streaming_hash_update(VALUE self, VALUE data);
23
+ VALUE xxhash32_streaming_hash_reset(VALUE self);
12
24
  VALUE xxhash32_streaming_hash_digest(VALUE self);
13
25
  VALUE xxhash_xxh64(VALUE mod, VALUE input, VALUE seed);
14
- void xxhash64_streaming_hash_free(XXH64_state_t* state);
26
+ void xxhash64_streaming_hash_free(xxhash_xxh64_t* state);
15
27
  VALUE xxhash64_streaming_hash_new(VALUE klass, VALUE seed);
16
28
  VALUE xxhash64_streaming_hash_update(VALUE self, VALUE data);
29
+ VALUE xxhash64_streaming_hash_reset(VALUE self);
17
30
  VALUE xxhash64_streaming_hash_digest(VALUE self);
18
31
  void Init_xxhash(void);
@@ -1,36 +1,96 @@
1
1
  require 'xxhash/version'
2
2
  require 'xxhash/xxhash'
3
+ require 'digest'
3
4
 
4
5
  module XXhash
5
6
  def self.xxh32(input, seed = 0)
6
- XXhashInternal.xxh32(input, seed)
7
+ XXhashInternal.xxh32(input.to_s, seed.to_i)
7
8
  end
8
9
 
9
10
  def self.xxh64(input, seed = 0)
10
- XXhashInternal.xxh64(input, seed)
11
+ XXhashInternal.xxh64(input.to_s, seed.to_i)
11
12
  end
12
13
 
13
14
  def self.xxh32_stream(io, seed = 0, chunk_size = 32)
14
- raise ArgumentError, 'first argument should be IO' if !io.is_a?(IO) && !io.is_a?(StringIO)
15
+ seed = seed.to_i
16
+ chunk_size = chunk_size.to_i
17
+ raise ArgumentError, 'first argument should be IO' if !io.respond_to?(:read)
15
18
 
16
19
  hash = XXhashInternal::StreamingHash32.new(seed)
17
20
 
18
21
  while chunk = io.read(chunk_size)
19
- hash.update(chunk)
22
+ hash.update(chunk.to_s)
20
23
  end
21
24
 
22
25
  hash.digest
23
26
  end
24
27
 
25
28
  def self.xxh64_stream(io, seed = 0, chunk_size = 32)
26
- raise ArgumentError, 'first argument should be IO' if !io.is_a?(IO) && !io.is_a?(StringIO)
29
+ seed = seed.to_i
30
+ chunk_size = chunk_size.to_i
31
+ raise ArgumentError, 'first argument should be IO' if !io.respond_to?(:read)
27
32
 
28
33
  hash = XXhashInternal::StreamingHash64.new(seed)
29
34
 
30
35
  while chunk = io.read(chunk_size)
31
- hash.update(chunk)
36
+ hash.update(chunk.to_s)
32
37
  end
33
38
 
34
39
  hash.digest
35
40
  end
41
+
42
+ end
43
+
44
+ module Digest
45
+ class XXHash < Digest::Class
46
+ attr_reader :digest_length
47
+
48
+ def initialize(bitlen, seed = 0)
49
+ bitlen = bitlen.to_i
50
+ seed = seed.to_i
51
+ @hash = case bitlen
52
+ when 32
53
+ XXhash::XXhashInternal::StreamingHash32.new(seed)
54
+ when 64
55
+ XXhash::XXhashInternal::StreamingHash64.new(seed)
56
+ else
57
+ raise ArgumentError, "Unsupported bit length: %s" % bitlen.inspect
58
+ end
59
+
60
+ @digest_length = bitlen
61
+ end
62
+
63
+ def update(chunk)
64
+ @hash.update(chunk.to_s)
65
+ end
66
+
67
+ def digest(val = nil)
68
+ @hash.update(val) if val
69
+
70
+ @hash.digest
71
+ end
72
+
73
+ def digest!(val = nil)
74
+ result = digest(val)
75
+ @hash.reset
76
+
77
+ result
78
+ end
79
+
80
+ def reset
81
+ @hash.reset
82
+ end
83
+ end
84
+
85
+ class XXHash32 < Digest::XXHash
86
+ def initialize(seed = 0)
87
+ super(32, seed.to_i)
88
+ end
89
+ end
90
+
91
+ class XXHash64 < Digest::XXHash
92
+ def initialize(seed = 0)
93
+ super(64, seed.to_i)
94
+ end
95
+ end
36
96
  end
@@ -1,3 +1,3 @@
1
1
  module XXhash
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -15,7 +15,7 @@ describe XXhash do
15
15
  assert_equal 5754696928334414137, XXhash.xxh64('test')
16
16
  end
17
17
 
18
- describe 'StreamingHash32' do
18
+ describe 'XXhashInternal::StreamingHash32' do
19
19
 
20
20
  it 'rises ArgumentError if first argument is not IO object' do
21
21
  assert_raises(ArgumentError) do
@@ -34,7 +34,7 @@ describe XXhash do
34
34
  end
35
35
  end
36
36
 
37
- describe 'StreamingHash64' do
37
+ describe 'XXhashInternal::StreamingHash64' do
38
38
  it 'rises ArgumentError if first argument is not IO object' do
39
39
  assert_raises(ArgumentError) do
40
40
  XXhash.xxh64_stream('test', 123)
@@ -50,5 +50,81 @@ describe XXhash do
50
50
  h2 = XXhash.xxh64_stream(File.open(__FILE__), 123)
51
51
  assert_equal h1, h2
52
52
  end
53
+
54
+ it 'exception (not segfault) on nil' do
55
+ begin
56
+ XXhash.xxh64(nil)
57
+ fail
58
+ rescue
59
+ end
60
+ end
53
61
  end
62
+
63
+ def use_external_hash hash, io, chunk_size=1024
64
+ while chunk=io.read(chunk_size)
65
+ hash.update(chunk)
66
+ end
67
+ hash.digest
68
+ end
69
+
70
+ describe 'Digest::XXhash32' do
71
+
72
+ it 'returns the hash for streamed strings' do
73
+ StringIO.open('test') do |io|
74
+ xxhash = Digest::XXHash32.new(123)
75
+ result = use_external_hash xxhash, io
76
+ assert_equal 2758658570, result
77
+ end
78
+ end
79
+
80
+ it 'returns the hash for streamed files' do
81
+ h1 = XXhash.xxh32(File.read(__FILE__), 123)
82
+ xxhash = Digest::XXHash32.new(123)
83
+ result = use_external_hash xxhash, File.open(__FILE__)
84
+ assert_equal h1, result
85
+ end
86
+
87
+ it 'returns correct hash after a reset' do
88
+ h1 = XXhash.xxh32(File.read(__FILE__), 123)
89
+ xxhash = Digest::XXHash32.new(123)
90
+ assert_equal 2758658570, xxhash.digest('test')
91
+ xxhash.reset
92
+ result = use_external_hash xxhash, File.open(__FILE__)
93
+ assert_equal h1, result
94
+ end
95
+
96
+ it 'exception (not segfault) on nil' do
97
+ begin
98
+ XXhash.xxh32(nil)
99
+ rescue
100
+ end
101
+ end
102
+ end
103
+
104
+ describe 'Digest::XXhash64' do
105
+ it 'returns the hash for streamed strings' do
106
+ StringIO.open('test') do |io|
107
+ xxhash = Digest::XXHash64.new(123)
108
+ result = use_external_hash xxhash, io
109
+ assert_equal 3134990500624303823, result
110
+ end
111
+ end
112
+
113
+ it 'returns the hash for streamed files' do
114
+ h1 = XXhash.xxh64(File.read(__FILE__), 123)
115
+ xxhash = Digest::XXHash64.new(123)
116
+ result = use_external_hash xxhash, File.open(__FILE__)
117
+ assert_equal h1, result
118
+ end
119
+
120
+ it 'returns correct hash after reset' do
121
+ h1 = XXhash.xxh64(File.read(__FILE__), 123)
122
+ xxhash = Digest::XXHash64.new(123)
123
+ assert_equal 3134990500624303823, xxhash.digest('test')
124
+ xxhash.reset
125
+ result = use_external_hash xxhash, File.open(__FILE__)
126
+ assert_equal h1, result
127
+ end
128
+ end
129
+
54
130
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xxhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasiliy Ermolovich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-18 00:00:00.000000000 Z
11
+ date: 2016-12-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby wrapper for xxHash lib
14
14
  email:
@@ -55,7 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
55
  version: '0'
56
56
  requirements: []
57
57
  rubyforge_project:
58
- rubygems_version: 2.2.2
58
+ rubygems_version: 2.5.1
59
59
  signing_key:
60
60
  specification_version: 4
61
61
  summary: Ruby wrapper for xxHash lib