xxhash 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  /*
2
- xxHash - Fast Hash algorithm
2
+ xxHash - Extremely Fast Hash algorithm
3
3
  Header File
4
- Copyright (C) 2012-2013, Yann Collet.
4
+ Copyright (C) 2012-2014, Yann Collet.
5
5
  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
6
 
7
7
  Redistribution and use in source and binary forms, with or without
@@ -64,101 +64,93 @@ extern "C" {
64
64
  #endif
65
65
 
66
66
 
67
- //****************************
68
- // Type
69
- //****************************
67
+ /*****************************
68
+ Includes
69
+ *****************************/
70
+ #include <stddef.h> /* size_t */
71
+
72
+
73
+ /*****************************
74
+ Type
75
+ *****************************/
70
76
  typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
71
77
 
72
78
 
73
79
 
74
- //****************************
75
- // Simple Hash Functions
76
- //****************************
80
+ /*****************************
81
+ Simple Hash Functions
82
+ *****************************/
77
83
 
78
- unsigned int XXH32 (const void* input, int len, unsigned int seed);
84
+ unsigned int XXH32 (const void* input, size_t length, unsigned seed);
85
+ unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed);
79
86
 
80
87
  /*
81
88
  XXH32() :
82
- Calculate the 32-bits hash of sequence of length "len" stored at memory address "input".
83
- The memory between input & input+len must be valid (allocated and read-accessible).
89
+ Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
90
+ The memory between input & input+length must be valid (allocated and read-accessible).
84
91
  "seed" can be used to alter the result predictably.
85
92
  This function successfully passes all SMHasher tests.
86
93
  Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
87
- Note that "len" is type "int", which means it is limited to 2^31-1.
88
- If your data is larger, use the advanced functions below.
94
+ XXH64() :
95
+ Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
89
96
  */
90
97
 
91
98
 
92
99
 
93
- //****************************
94
- // Advanced Hash Functions
95
- //****************************
96
-
97
- void* XXH32_init (unsigned int seed);
98
- XXH_errorcode XXH32_update (void* state, const void* input, int len);
99
- unsigned int XXH32_digest (void* state);
100
+ /*****************************
101
+ Advanced Hash Functions
102
+ *****************************/
103
+ typedef struct { long long ll[ 6]; } XXH32_state_t;
104
+ typedef struct { long long ll[11]; } XXH64_state_t;
100
105
 
101
106
  /*
102
- These functions calculate the xxhash of an input provided in several small packets,
103
- as opposed to an input provided as a single block.
107
+ These structures allow static allocation of XXH states.
108
+ States must then be initialized using XXHnn_reset() before first use.
104
109
 
105
- It must be started with :
106
- void* XXH32_init()
107
- The function returns a pointer which holds the state of calculation.
108
-
109
- This pointer must be provided as "void* state" parameter for XXH32_update().
110
- XXH32_update() can be called as many times as necessary.
111
- The user must provide a valid (allocated) input.
112
- The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
113
- Note that "len" is type "int", which means it is limited to 2^31-1.
114
- If your data is larger, it is recommended to chunk your data into blocks
115
- of size for example 2^30 (1GB) to avoid any "int" overflow issue.
116
-
117
- Finally, you can end the calculation anytime, by using XXH32_digest().
118
- This function returns the final 32-bits hash.
119
- You must provide the same "void* state" parameter created by XXH32_init().
120
- Memory will be freed by XXH32_digest().
110
+ If you prefer dynamic allocation, please refer to functions below.
121
111
  */
122
112
 
113
+ XXH32_state_t* XXH32_createState(void);
114
+ XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
123
115
 
124
- int XXH32_sizeofState();
125
- XXH_errorcode XXH32_resetState(void* state, unsigned int seed);
116
+ XXH64_state_t* XXH64_createState(void);
117
+ XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
126
118
 
127
- #define XXH32_SIZEOFSTATE 48
128
- typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
129
119
  /*
130
- These functions allow user application to make its own allocation for state.
120
+ These functions create and release memory for XXH state.
121
+ States must then be initialized using XXHnn_reset() before first use.
122
+ */
131
123
 
132
- XXH32_sizeofState() is used to know how much space must be allocated for the xxHash 32-bits state.
133
- Note that the state must be aligned to access 'long long' fields. Memory must be allocated and referenced by a pointer.
134
- This pointer must then be provided as 'state' into XXH32_resetState(), which initializes the state.
135
124
 
136
- For static allocation purposes (such as allocation on stack, or freestanding systems without malloc()),
137
- use the structure XXH32_stateSpace_t, which will ensure that memory space is large enough and correctly aligned to access 'long long' fields.
138
- */
125
+ XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed);
126
+ XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
127
+ unsigned int XXH32_digest (const XXH32_state_t* statePtr);
139
128
 
129
+ XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
130
+ XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
131
+ unsigned long long XXH64_digest (const XXH64_state_t* statePtr);
140
132
 
141
- unsigned int XXH32_intermediateDigest (void* state);
142
133
  /*
143
- This function does the same as XXH32_digest(), generating a 32-bit hash,
144
- but preserve memory context.
145
- This way, it becomes possible to generate intermediate hashes, and then continue feeding data with XXH32_update().
146
- To free memory context, use XXH32_digest(), or free().
147
- */
134
+ These functions calculate the xxHash of an input provided in multiple smaller packets,
135
+ as opposed to an input provided as a single block.
148
136
 
137
+ XXH state space must first be allocated, using either static or dynamic method provided above.
149
138
 
139
+ Start a new hash by initializing state with a seed, using XXHnn_reset().
150
140
 
151
- //****************************
152
- // Deprecated function names
153
- //****************************
154
- // The following translations are provided to ease code transition
155
- // You are encouraged to no longer this function names
156
- #define XXH32_feed XXH32_update
157
- #define XXH32_result XXH32_digest
158
- #define XXH32_getIntermediateResult XXH32_intermediateDigest
141
+ Then, feed the hash state by calling XXHnn_update() as many times as necessary.
142
+ Obviously, input must be valid, meaning allocated and read accessible.
143
+ The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
159
144
 
145
+ Finally, you can produce a hash anytime, by using XXHnn_digest().
146
+ This function returns the final nn-bits hash.
147
+ You can nonetheless continue feeding the hash state with more input,
148
+ and therefore get some new hashes, by calling again XXHnn_digest().
149
+
150
+ When you are done, don't forget to free XXH state space, using typically XXHnn_freeState().
151
+ */
160
152
 
161
153
 
162
154
  #if defined (__cplusplus)
163
155
  }
164
- #endif
156
+ #endif
@@ -0,0 +1,109 @@
1
+ #include "xxhash.h"
2
+
3
+ VALUE xxhash_xxh32(VALUE mod, VALUE input, VALUE seed)
4
+ {
5
+ return ULL2NUM(XXH32(StringValuePtr(input), (size_t)RSTRING_LEN(input), (unsigned int)NUM2ULL(seed)));
6
+ }
7
+
8
+ void xxhash32_streaming_hash_free(XXH32_state_t* state)
9
+ {
10
+ // Digest frees the memory.
11
+ XXH32_freeState(state);
12
+ }
13
+
14
+ VALUE xxhash32_streaming_hash_new(VALUE klass, VALUE seed)
15
+ {
16
+ XXH32_state_t* state = XXH32_createState();
17
+ XXH_errorcode code = XXH32_reset(state, (unsigned int)NUM2ULL(seed));
18
+ if(code != XXH_OK) {
19
+ rb_raise(rb_eRuntimeError, "Error during reset.");
20
+ return Qnil;
21
+ }
22
+ return Data_Wrap_Struct(klass, 0, xxhash32_streaming_hash_free, state);
23
+ }
24
+
25
+ VALUE xxhash32_streaming_hash_update(VALUE self, VALUE data)
26
+ {
27
+ XXH32_state_t* state;
28
+ Data_Get_Struct(self, XXH32_state_t, state);
29
+
30
+ XXH_errorcode code = XXH32_update(state, StringValuePtr(data), (size_t)RSTRING_LEN(data));
31
+ if(code != XXH_OK) {
32
+ rb_raise(rb_eRuntimeError, "Error during update.");
33
+ }
34
+ return Qnil;
35
+ }
36
+
37
+ VALUE xxhash32_streaming_hash_digest(VALUE self)
38
+ {
39
+ XXH32_state_t* state;
40
+ Data_Get_Struct(self, XXH32_state_t, state);
41
+
42
+ // Do not free memory now.
43
+ return ULL2NUM(XXH32_digest(state));
44
+ }
45
+
46
+ VALUE xxhash_xxh64(VALUE mod, VALUE input, VALUE seed)
47
+ {
48
+ return ULL2NUM(XXH64(StringValuePtr(input), (size_t)RSTRING_LEN(input), (unsigned int)NUM2ULL(seed)));
49
+ }
50
+
51
+ void xxhash64_streaming_hash_free(XXH64_state_t* state)
52
+ {
53
+ // Digest frees the memory.
54
+ XXH64_freeState(state);
55
+ }
56
+
57
+ VALUE xxhash64_streaming_hash_new(VALUE klass, VALUE seed)
58
+ {
59
+ XXH64_state_t* state = XXH64_createState();
60
+ XXH_errorcode code = XXH64_reset(state, NUM2ULL(seed));
61
+ if(code != XXH_OK) {
62
+ rb_raise(rb_eRuntimeError, "Error during reset.");
63
+ return Qnil;
64
+ }
65
+ return Data_Wrap_Struct(klass, 0, xxhash64_streaming_hash_free, state);
66
+ }
67
+
68
+ VALUE xxhash64_streaming_hash_update(VALUE self, VALUE data)
69
+ {
70
+ XXH64_state_t* state;
71
+ Data_Get_Struct(self, XXH64_state_t, state);
72
+
73
+ XXH_errorcode code = XXH64_update(state, StringValuePtr(data), (size_t)RSTRING_LEN(data));
74
+ if(code != XXH_OK) {
75
+ rb_raise(rb_eRuntimeError, "Error during update.");
76
+ }
77
+ return Qnil;
78
+ }
79
+
80
+ VALUE xxhash64_streaming_hash_digest(VALUE self)
81
+ {
82
+ XXH64_state_t* state;
83
+ Data_Get_Struct(self, XXH64_state_t, state);
84
+
85
+ // Do not free memory now.
86
+ return ULL2NUM(XXH64_digest(state));
87
+ }
88
+
89
+
90
+ void Init_xxhash(void)
91
+ {
92
+ VALUE mXXhash = rb_define_module("XXhash");
93
+ VALUE mInternal = rb_define_module_under(mXXhash, "XXhashInternal");
94
+
95
+ rb_define_singleton_method(mInternal, "xxh32", (ruby_method*) &xxhash_xxh32, 2);
96
+ rb_define_singleton_method(mInternal, "xxh64", (ruby_method*) &xxhash_xxh64, 2);
97
+
98
+ VALUE cStreamingHash = rb_define_class_under(mInternal, "StreamingHash32", rb_cObject);
99
+
100
+ rb_define_singleton_method(cStreamingHash, "new", (ruby_method*) &xxhash32_streaming_hash_new, 1);
101
+ rb_define_method(cStreamingHash, "update", (ruby_method*) &xxhash32_streaming_hash_update, 1);
102
+ rb_define_method(cStreamingHash, "digest", (ruby_method*) &xxhash32_streaming_hash_digest, 0);
103
+
104
+ VALUE cStreamingHash64 = rb_define_class_under(mInternal, "StreamingHash64", rb_cObject);
105
+
106
+ rb_define_singleton_method(cStreamingHash64, "new", (ruby_method*) &xxhash64_streaming_hash_new, 1);
107
+ rb_define_method(cStreamingHash64, "update", (ruby_method*) &xxhash64_streaming_hash_update, 1);
108
+ rb_define_method(cStreamingHash64, "digest", (ruby_method*) &xxhash64_streaming_hash_digest, 0);
109
+ }
@@ -0,0 +1,18 @@
1
+ #include <ruby.h>
2
+ #include "libxxhash.h"
3
+
4
+ // Use this typedef to make the compiler happy when
5
+ // calling rb_define_method()
6
+ typedef VALUE (ruby_method)();
7
+
8
+ VALUE xxhash_xxh32(VALUE mod, VALUE input, VALUE seed);
9
+ void xxhash32_streaming_hash_free(XXH32_state_t* state);
10
+ VALUE xxhash32_streaming_hash_new(VALUE klass, VALUE seed);
11
+ VALUE xxhash32_streaming_hash_update(VALUE self, VALUE data);
12
+ VALUE xxhash32_streaming_hash_digest(VALUE self);
13
+ VALUE xxhash_xxh64(VALUE mod, VALUE input, VALUE seed);
14
+ void xxhash64_streaming_hash_free(XXH64_state_t* state);
15
+ VALUE xxhash64_streaming_hash_new(VALUE klass, VALUE seed);
16
+ VALUE xxhash64_streaming_hash_update(VALUE self, VALUE data);
17
+ VALUE xxhash64_streaming_hash_digest(VALUE self);
18
+ void Init_xxhash(void);
@@ -2,14 +2,30 @@ require 'xxhash/version'
2
2
  require 'xxhash/xxhash'
3
3
 
4
4
  module XXhash
5
- def self.xxh32(input, seed)
6
- Internal.xxh32(input, seed)
5
+ def self.xxh32(input, seed = 0)
6
+ XXhashInternal.xxh32(input, seed)
7
7
  end
8
8
 
9
- def self.xxh32_stream(io, seed, chunk_size = 32)
9
+ def self.xxh64(input, seed = 0)
10
+ XXhashInternal.xxh64(input, seed)
11
+ end
12
+
13
+ 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
+
16
+ hash = XXhashInternal::StreamingHash32.new(seed)
17
+
18
+ while chunk = io.read(chunk_size)
19
+ hash.update(chunk)
20
+ end
21
+
22
+ hash.digest
23
+ end
24
+
25
+ def self.xxh64_stream(io, seed = 0, chunk_size = 32)
10
26
  raise ArgumentError, 'first argument should be IO' if !io.is_a?(IO) && !io.is_a?(StringIO)
11
27
 
12
- hash = Internal::StreamingHash.new(seed)
28
+ hash = XXhashInternal::StreamingHash64.new(seed)
13
29
 
14
30
  while chunk = io.read(chunk_size)
15
31
  hash.update(chunk)
@@ -1,3 +1,3 @@
1
1
  module XXhash
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,13 +1,23 @@
1
- require 'test_helper'
1
+ require_relative 'test_helper'
2
2
  require 'stringio'
3
3
 
4
4
  describe XXhash do
5
- it 'returns hash' do
5
+ it 'returns 32-bit hash' do
6
6
  assert_equal 2758658570, XXhash.xxh32('test', 123)
7
7
  end
8
8
 
9
- describe 'StreamingHash' do
10
- it 'rises ArgumentError if forst argument is not IO object' do
9
+ it 'returns 64-bit hash' do
10
+ assert_equal 3134990500624303823, XXhash.xxh64('test', 123)
11
+ end
12
+
13
+ it 'uses 0 (default value) if seed is not specified' do
14
+ assert_equal 1042293711, XXhash.xxh32('test')
15
+ assert_equal 5754696928334414137, XXhash.xxh64('test')
16
+ end
17
+
18
+ describe 'StreamingHash32' do
19
+
20
+ it 'rises ArgumentError if first argument is not IO object' do
11
21
  assert_raises(ArgumentError) do
12
22
  XXhash.xxh32_stream('test', 123)
13
23
  end
@@ -23,4 +33,22 @@ describe XXhash do
23
33
  assert_equal h1, h2
24
34
  end
25
35
  end
36
+
37
+ describe 'StreamingHash64' do
38
+ it 'rises ArgumentError if first argument is not IO object' do
39
+ assert_raises(ArgumentError) do
40
+ XXhash.xxh64_stream('test', 123)
41
+ end
42
+ end
43
+
44
+ it 'returns the hash for streamed strings' do
45
+ assert_equal 3134990500624303823, XXhash.xxh64_stream(StringIO.new('test'), 123)
46
+ end
47
+
48
+ it 'returns the hash for streamed files' do
49
+ h1 = XXhash.xxh64(File.read(__FILE__), 123)
50
+ h2 = XXhash.xxh64_stream(File.open(__FILE__), 123)
51
+ assert_equal h1, h2
52
+ end
53
+ end
26
54
  end
@@ -11,7 +11,8 @@ Gem::Specification.new do |gem|
11
11
  gem.description = %q{Ruby wrapper for xxHash lib}
12
12
  gem.summary = %q{Ruby wrapper for xxHash lib}
13
13
  gem.homepage = "http://github.com/nashby/xxhash"
14
-
14
+ gem.license = 'MIT'
15
+
15
16
  gem.files = `git ls-files`.split($/)
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xxhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Vasiliy Ermolovich
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-04 00:00:00.000000000 Z
11
+ date: 2015-01-18 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: Ruby wrapper for xxHash lib
15
14
  email:
@@ -19,8 +18,8 @@ extensions:
19
18
  - ext/xxhash/extconf.rb
20
19
  extra_rdoc_files: []
21
20
  files:
22
- - .gitignore
23
- - .travis.yml
21
+ - ".gitignore"
22
+ - ".travis.yml"
24
23
  - CHANGELOG.md
25
24
  - Gemfile
26
25
  - LICENSE.txt
@@ -29,41 +28,36 @@ files:
29
28
  - ext/xxhash/extconf.rb
30
29
  - ext/xxhash/libxxhash.c
31
30
  - ext/xxhash/libxxhash.h
32
- - ext/xxhash/xxhash.cc
31
+ - ext/xxhash/xxhash.c
32
+ - ext/xxhash/xxhash.h
33
33
  - lib/xxhash.rb
34
34
  - lib/xxhash/version.rb
35
35
  - test/test_helper.rb
36
36
  - test/xxhash_test.rb
37
37
  - xxhash.gemspec
38
38
  homepage: http://github.com/nashby/xxhash
39
- licenses: []
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
40
42
  post_install_message:
41
43
  rdoc_options: []
42
44
  require_paths:
43
45
  - lib
44
46
  required_ruby_version: !ruby/object:Gem::Requirement
45
- none: false
46
47
  requirements:
47
- - - ! '>='
48
+ - - ">="
48
49
  - !ruby/object:Gem::Version
49
50
  version: '0'
50
- segments:
51
- - 0
52
- hash: -3728750430932162062
53
51
  required_rubygems_version: !ruby/object:Gem::Requirement
54
- none: false
55
52
  requirements:
56
- - - ! '>='
53
+ - - ">="
57
54
  - !ruby/object:Gem::Version
58
55
  version: '0'
59
- segments:
60
- - 0
61
- hash: -3728750430932162062
62
56
  requirements: []
63
57
  rubyforge_project:
64
- rubygems_version: 1.8.24
58
+ rubygems_version: 2.2.2
65
59
  signing_key:
66
- specification_version: 3
60
+ specification_version: 4
67
61
  summary: Ruby wrapper for xxHash lib
68
62
  test_files:
69
63
  - test/test_helper.rb