xxhash 0.2.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,8 @@
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-2016, Yann Collet.
5
+
5
6
  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7
 
7
8
  Redistribution and use in source and binary forms, with or without
@@ -28,7 +29,7 @@
28
29
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
 
30
31
  You can contact the author at :
31
- - xxHash source repository : http://code.google.com/p/xxhash/
32
+ - xxHash source repository : https://github.com/Cyan4973/xxHash
32
33
  */
33
34
 
34
35
  /* Notice extracted from xxHash homepage :
@@ -55,110 +56,246 @@ SHA1-32 0.28 GB/s 10
55
56
  Q.Score is a measure of quality of the hash function.
56
57
  It depends on successfully passing SMHasher test set.
57
58
  10 is a perfect score.
59
+
60
+ A 64-bits version, named XXH64, is available since r35.
61
+ It offers much better speed, but for 64-bits applications only.
62
+ Name Speed on 64 bits Speed on 32 bits
63
+ XXH64 13.8 GB/s 1.9 GB/s
64
+ XXH32 6.8 GB/s 6.0 GB/s
58
65
  */
59
66
 
60
- #pragma once
67
+ #ifndef XXHASH_H_5627135585666179
68
+ #define XXHASH_H_5627135585666179 1
61
69
 
62
70
  #if defined (__cplusplus)
63
71
  extern "C" {
64
72
  #endif
65
73
 
66
74
 
67
- //****************************
68
- // Type
69
- //****************************
75
+ /* ****************************
76
+ * Compiler specifics
77
+ ******************************/
78
+ #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */
79
+ # define restrict /* disable restrict */
80
+ #endif
81
+
82
+
83
+ /* ****************************
84
+ * Definitions
85
+ ******************************/
86
+ #include <stddef.h> /* size_t */
70
87
  typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
71
88
 
72
89
 
90
+ /* ****************************
91
+ * API modifier
92
+ ******************************/
93
+ /** XXH_PRIVATE_API
94
+ * This is useful to include xxhash functions in `static` mode
95
+ * in order to inline them, and remove their symbol from the public list.
96
+ * Methodology :
97
+ * #define XXH_PRIVATE_API
98
+ * #include "xxhash.h"
99
+ * `xxhash.c` is automatically included.
100
+ * It's not useful to compile and link it as a separate module.
101
+ */
102
+ #ifdef XXH_PRIVATE_API
103
+ # ifndef XXH_STATIC_LINKING_ONLY
104
+ # define XXH_STATIC_LINKING_ONLY
105
+ # endif
106
+ # if defined(__GNUC__)
107
+ # define XXH_PUBLIC_API static __inline __attribute__((unused))
108
+ # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
109
+ # define XXH_PUBLIC_API static inline
110
+ # elif defined(_MSC_VER)
111
+ # define XXH_PUBLIC_API static __inline
112
+ # else
113
+ # define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */
114
+ # endif
115
+ #else
116
+ # define XXH_PUBLIC_API /* do nothing */
117
+ #endif /* XXH_PRIVATE_API */
118
+
119
+ /*!XXH_NAMESPACE, aka Namespace Emulation :
120
+
121
+ If you want to include _and expose_ xxHash functions from within your own library,
122
+ but also want to avoid symbol collisions with other libraries which may also include xxHash,
123
+
124
+ you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
125
+ with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values).
126
+
127
+ Note that no change is required within the calling program as long as it includes `xxhash.h` :
128
+ regular symbol name will be automatically translated by this header.
129
+ */
130
+ #ifdef XXH_NAMESPACE
131
+ # define XXH_CAT(A,B) A##B
132
+ # define XXH_NAME2(A,B) XXH_CAT(A,B)
133
+ # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
134
+ # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
135
+ # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
136
+ # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
137
+ # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
138
+ # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
139
+ # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
140
+ # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
141
+ # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
142
+ # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
143
+ # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
144
+ # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
145
+ # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
146
+ # define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
147
+ # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
148
+ # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
149
+ # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
150
+ # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
151
+ # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
152
+ #endif
73
153
 
74
- //****************************
75
- // Simple Hash Functions
76
- //****************************
77
154
 
78
- unsigned int XXH32 (const void* input, int len, unsigned int seed);
155
+ /* *************************************
156
+ * Version
157
+ ***************************************/
158
+ #define XXH_VERSION_MAJOR 0
159
+ #define XXH_VERSION_MINOR 6
160
+ #define XXH_VERSION_RELEASE 2
161
+ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
162
+ XXH_PUBLIC_API unsigned XXH_versionNumber (void);
79
163
 
80
- /*
81
- 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).
84
- "seed" can be used to alter the result predictably.
85
- This function successfully passes all SMHasher tests.
86
- 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.
89
- */
90
164
 
165
+ /*-**********************************************************************
166
+ * 32-bits hash
167
+ ************************************************************************/
168
+ typedef unsigned int XXH32_hash_t;
91
169
 
170
+ /*! XXH32() :
171
+ Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
172
+ The memory between input & input+length must be valid (allocated and read-accessible).
173
+ "seed" can be used to alter the result predictably.
174
+ Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */
175
+ XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
92
176
 
93
- //****************************
94
- // Advanced Hash Functions
95
- //****************************
177
+ /*====== Streaming ======*/
178
+ typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
179
+ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
180
+ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
181
+ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state);
96
182
 
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);
183
+ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
184
+ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
185
+ XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
100
186
 
101
187
  /*
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.
188
+ These functions generate the xxHash of an input provided in multiple segments.
189
+ Note that, for small input, they are slower than single-call functions, due to state management.
190
+ For small input, prefer `XXH32()` and `XXH64()` .
104
191
 
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().
121
- */
192
+ XXH state must first be allocated, using XXH*_createState() .
122
193
 
194
+ Start a new hash by initializing state with a seed, using XXH*_reset().
123
195
 
124
- int XXH32_sizeofState();
125
- XXH_errorcode XXH32_resetState(void* state, unsigned int seed);
196
+ Then, feed the hash state by calling XXH*_update() as many times as necessary.
197
+ Obviously, input must be allocated and read accessible.
198
+ The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
126
199
 
127
- #define XXH32_SIZEOFSTATE 48
128
- typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t;
129
- /*
130
- These functions allow user application to make its own allocation for state.
200
+ Finally, a hash value can be produced anytime, by using XXH*_digest().
201
+ This function returns the nn-bits hash as an int or long long.
131
202
 
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.
203
+ It's still possible to continue inserting input into the hash state after a digest,
204
+ and generate some new hashes later on, by calling again XXH*_digest().
135
205
 
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.
206
+ When done, free XXH state space if it was allocated dynamically.
138
207
  */
139
208
 
209
+ /*====== Canonical representation ======*/
140
210
 
141
- unsigned int XXH32_intermediateDigest (void* state);
142
- /*
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().
211
+ typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
212
+ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
213
+ XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
214
+
215
+ /* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
216
+ * The canonical representation uses human-readable write convention, aka big-endian (large digits first).
217
+ * These functions allow transformation of hash result into and from its canonical format.
218
+ * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
147
219
  */
148
220
 
149
221
 
222
+ #ifndef XXH_NO_LONG_LONG
223
+ /*-**********************************************************************
224
+ * 64-bits hash
225
+ ************************************************************************/
226
+ typedef unsigned long long XXH64_hash_t;
227
+
228
+ /*! XXH64() :
229
+ Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
230
+ "seed" can be used to alter the result predictably.
231
+ This function runs faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
232
+ */
233
+ XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
234
+
235
+ /*====== Streaming ======*/
236
+ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
237
+ XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
238
+ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
239
+ XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state);
240
+
241
+ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
242
+ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
243
+ XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
244
+
245
+ /*====== Canonical representation ======*/
246
+ typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
247
+ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
248
+ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
249
+ #endif /* XXH_NO_LONG_LONG */
250
+
251
+
252
+ #ifdef XXH_STATIC_LINKING_ONLY
253
+
254
+ /* ================================================================================================
255
+ This section contains definitions which are not guaranteed to remain stable.
256
+ They may change in future versions, becoming incompatible with a different version of the library.
257
+ They shall only be used with static linking.
258
+ Never use these definitions in association with dynamic linking !
259
+ =================================================================================================== */
260
+
261
+ /* These definitions are only meant to allow allocation of XXH state
262
+ statically, on stack, or in a struct for example.
263
+ Do not use members directly. */
264
+
265
+ struct XXH32_state_s {
266
+ unsigned total_len_32;
267
+ unsigned large_len;
268
+ unsigned v1;
269
+ unsigned v2;
270
+ unsigned v3;
271
+ unsigned v4;
272
+ unsigned mem32[4]; /* buffer defined as U32 for alignment */
273
+ unsigned memsize;
274
+ unsigned reserved; /* never read nor write, will be removed in a future version */
275
+ }; /* typedef'd to XXH32_state_t */
276
+
277
+ #ifndef XXH_NO_LONG_LONG
278
+ struct XXH64_state_s {
279
+ unsigned long long total_len;
280
+ unsigned long long v1;
281
+ unsigned long long v2;
282
+ unsigned long long v3;
283
+ unsigned long long v4;
284
+ unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
285
+ unsigned memsize;
286
+ unsigned reserved[2]; /* never read nor write, will be removed in a future version */
287
+ }; /* typedef'd to XXH64_state_t */
288
+ #endif
150
289
 
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
290
+ # ifdef XXH_PRIVATE_API
291
+ # include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */
292
+ # endif
159
293
 
294
+ #endif /* XXH_STATIC_LINKING_ONLY */
160
295
 
161
296
 
162
297
  #if defined (__cplusplus)
163
298
  }
164
299
  #endif
300
+
301
+ #endif /* XXHASH_H_5627135585666179 */
@@ -0,0 +1,224 @@
1
+ #include "xxhash.h"
2
+
3
+ VALUE xxhash_xxh32_file(VALUE mod, VALUE filename, VALUE seed)
4
+ {
5
+ StringValue(filename);
6
+
7
+ XXH32_state_t* state = XXH32_createState();
8
+ if (state == NULL) {
9
+ rb_raise(rb_eRuntimeError, "%s", "Cannot create state, out of memory");
10
+ }
11
+
12
+ XXH32_reset(state, NUM2INT(seed));
13
+
14
+ char buffer[16384];
15
+ size_t count;
16
+ FILE *fp = fopen(RSTRING_PTR(filename), "rb");
17
+ if (fp == NULL) {
18
+ XXH32_freeState(state);
19
+ VALUE error = INT2FIX(errno);
20
+ rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
21
+ }
22
+
23
+ while ((count = fread(buffer, 1, sizeof(buffer), fp)) != 0) {
24
+ XXH32_update(state, buffer, count);
25
+ }
26
+ fclose(fp);
27
+
28
+ XXH32_hash_t result = XXH32_digest(state);
29
+
30
+ XXH32_freeState(state);
31
+ return ULL2NUM(result);
32
+ }
33
+
34
+ VALUE xxhash_xxh64_file(VALUE mod, VALUE filename, VALUE seed)
35
+ {
36
+ StringValue(filename);
37
+
38
+ XXH64_state_t* state = XXH64_createState();
39
+ if (state == NULL) {
40
+ rb_raise(rb_eRuntimeError, "%s", "Cannot create state, out of memory");
41
+ }
42
+
43
+ XXH64_reset(state, NUM2INT(seed));
44
+
45
+ char buffer[16384];
46
+ size_t count;
47
+ FILE *fp = fopen(RSTRING_PTR(filename), "rb");
48
+ if (fp == NULL) {
49
+ XXH64_freeState(state);
50
+ VALUE error = INT2FIX(errno);
51
+ rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
52
+ }
53
+
54
+ while ((count = fread(buffer, 1, sizeof(buffer), fp)) != 0) {
55
+ XXH64_update(state, buffer, count);
56
+ }
57
+ fclose(fp);
58
+
59
+ XXH64_hash_t result = XXH64_digest(state);
60
+
61
+ XXH64_freeState(state);
62
+ return ULL2NUM(result);
63
+ }
64
+
65
+ VALUE xxhash_xxh32(VALUE mod, VALUE input, VALUE seed)
66
+ {
67
+ return ULL2NUM(XXH32(StringValuePtr(input), (size_t)RSTRING_LEN(input), (unsigned int)NUM2ULL(seed)));
68
+ }
69
+
70
+ void xxhash32_streaming_hash_free(xxhash_xxh32_t* storage)
71
+ {
72
+ // Digest frees the memory.
73
+ XXH32_freeState(storage->state);
74
+ xfree(storage);
75
+ }
76
+
77
+ VALUE xxhash32_streaming_hash_new(VALUE klass, VALUE seed)
78
+ {
79
+ XXH_errorcode code;
80
+ xxhash_xxh32_t* storage;
81
+ storage = ALLOC(xxhash_xxh32_t);
82
+ storage->state = XXH32_createState();
83
+ storage->seed = (unsigned int)NUM2ULL(seed);
84
+ code = XXH32_reset(storage->state, storage->seed);
85
+ if(code != XXH_OK) {
86
+ rb_raise(rb_eRuntimeError, "Error during reset.");
87
+ return Qnil;
88
+ }
89
+ return Data_Wrap_Struct(klass, 0, xxhash32_streaming_hash_free, storage);
90
+ }
91
+
92
+ VALUE xxhash32_streaming_hash_reset(VALUE self)
93
+ {
94
+ XXH_errorcode code;
95
+ xxhash_xxh32_t* storage;
96
+ Data_Get_Struct(self, xxhash_xxh32_t, storage);
97
+
98
+ code = XXH32_reset(storage->state, storage->seed);
99
+ if(code != XXH_OK) {
100
+ rb_raise(rb_eRuntimeError, "Error during reset.");
101
+ }
102
+ return Qnil;
103
+ }
104
+
105
+
106
+ VALUE xxhash32_streaming_hash_update(VALUE self, VALUE data)
107
+ {
108
+ XXH_errorcode code;
109
+ xxhash_xxh32_t* storage;
110
+ Data_Get_Struct(self, xxhash_xxh32_t, storage);
111
+
112
+ code = XXH32_update(storage->state, StringValuePtr(data), (size_t)RSTRING_LEN(data));
113
+ if(code != XXH_OK) {
114
+ rb_raise(rb_eRuntimeError, "Error during update.");
115
+ }
116
+ return Qnil;
117
+ }
118
+
119
+ VALUE xxhash32_streaming_hash_digest(VALUE self)
120
+ {
121
+ xxhash_xxh32_t* storage;
122
+ Data_Get_Struct(self, xxhash_xxh32_t, storage);
123
+
124
+ // Do not free memory now.
125
+ return ULL2NUM(XXH32_digest(storage->state));
126
+ }
127
+
128
+ VALUE xxhash_xxh64(VALUE mod, VALUE input, VALUE seed)
129
+ {
130
+ return ULL2NUM(XXH64(StringValuePtr(input), (size_t)RSTRING_LEN(input), (unsigned int)NUM2ULL(seed)));
131
+ }
132
+
133
+ void xxhash64_streaming_hash_free(xxhash_xxh64_t* storage)
134
+ {
135
+ // Digest frees the memory.
136
+ XXH64_freeState(storage->state);
137
+ xfree(storage);
138
+ }
139
+
140
+ VALUE xxhash64_streaming_hash_new(VALUE klass, VALUE seed)
141
+ {
142
+ XXH_errorcode code;
143
+ xxhash_xxh64_t* storage;
144
+ storage = ALLOC(xxhash_xxh64_t);
145
+ storage->state = XXH64_createState();
146
+ storage->seed = (unsigned int)NUM2ULL(seed);
147
+
148
+ code = XXH64_reset(storage->state, storage->seed);
149
+ if(code != XXH_OK) {
150
+ rb_raise(rb_eRuntimeError, "Error during reset.");
151
+ return Qnil;
152
+ }
153
+ return Data_Wrap_Struct(klass, 0, xxhash64_streaming_hash_free, storage);
154
+ }
155
+
156
+ VALUE xxhash64_streaming_hash_reset(VALUE self)
157
+ {
158
+ XXH_errorcode code;
159
+ xxhash_xxh64_t* storage;
160
+ Data_Get_Struct(self, xxhash_xxh64_t, storage);
161
+
162
+ code = XXH64_reset(storage->state, storage->seed);
163
+ if(code != XXH_OK) {
164
+ rb_raise(rb_eRuntimeError, "Error during reset.");
165
+ }
166
+ return Qnil;
167
+ }
168
+
169
+ VALUE xxhash64_streaming_hash_update(VALUE self, VALUE data)
170
+ {
171
+ XXH_errorcode code;
172
+ xxhash_xxh64_t* storage;
173
+ Data_Get_Struct(self, xxhash_xxh64_t, storage);
174
+
175
+ code = XXH64_update(storage->state, StringValuePtr(data), (size_t)RSTRING_LEN(data));
176
+ if(code != XXH_OK) {
177
+ rb_raise(rb_eRuntimeError, "Error during update.");
178
+ }
179
+ return Qnil;
180
+ }
181
+
182
+ VALUE xxhash64_streaming_hash_digest(VALUE self)
183
+ {
184
+ xxhash_xxh64_t* storage;
185
+ Data_Get_Struct(self, xxhash_xxh64_t, storage);
186
+
187
+ // Do not free memory now.
188
+ return ULL2NUM(XXH64_digest(storage->state));
189
+ }
190
+
191
+
192
+ void Init_xxhash(void)
193
+ {
194
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
195
+ rb_ext_ractor_safe(true);
196
+ #endif
197
+
198
+ VALUE cStreamingHash;
199
+ VALUE cStreamingHash64;
200
+ VALUE mXXhash;
201
+ VALUE mInternal;
202
+
203
+ mXXhash = rb_define_module("XXhash");
204
+ mInternal = rb_define_module_under(mXXhash, "XXhashInternal");
205
+
206
+ rb_define_singleton_method(mInternal, "xxh32", (ruby_method*) &xxhash_xxh32, 2);
207
+ rb_define_singleton_method(mInternal, "xxh32_file", (ruby_method*) &xxhash_xxh32_file, 2);
208
+ rb_define_singleton_method(mInternal, "xxh64", (ruby_method*) &xxhash_xxh64, 2);
209
+ rb_define_singleton_method(mInternal, "xxh64_file", (ruby_method*) &xxhash_xxh64_file, 2);
210
+
211
+ cStreamingHash = rb_define_class_under(mInternal, "StreamingHash32", rb_cObject);
212
+
213
+ rb_define_singleton_method(cStreamingHash, "new", (ruby_method*) &xxhash32_streaming_hash_new, 1);
214
+ rb_define_method(cStreamingHash, "update", (ruby_method*) &xxhash32_streaming_hash_update, 1);
215
+ rb_define_method(cStreamingHash, "digest", (ruby_method*) &xxhash32_streaming_hash_digest, 0);
216
+ rb_define_method(cStreamingHash, "reset", (ruby_method*) &xxhash32_streaming_hash_reset, 0);
217
+
218
+ cStreamingHash64 = rb_define_class_under(mInternal, "StreamingHash64", rb_cObject);
219
+
220
+ rb_define_singleton_method(cStreamingHash64, "new", (ruby_method*) &xxhash64_streaming_hash_new, 1);
221
+ rb_define_method(cStreamingHash64, "update", (ruby_method*) &xxhash64_streaming_hash_update, 1);
222
+ rb_define_method(cStreamingHash64, "digest", (ruby_method*) &xxhash64_streaming_hash_digest, 0);
223
+ rb_define_method(cStreamingHash64, "reset", (ruby_method*) &xxhash64_streaming_hash_reset, 0);
224
+ }
@@ -0,0 +1,34 @@
1
+ #include <stdlib.h>
2
+ #include <errno.h>
3
+ #include <ruby.h>
4
+ #include "libxxhash.h"
5
+
6
+ typedef struct {
7
+ XXH32_state_t* state;
8
+ unsigned int seed;
9
+ } xxhash_xxh32_t;
10
+
11
+ typedef struct {
12
+ XXH64_state_t* state;
13
+ unsigned int seed;
14
+ } xxhash_xxh64_t;
15
+
16
+ // Use this typedef to make the compiler happy when
17
+ // calling rb_define_method()
18
+ typedef VALUE (ruby_method)();
19
+
20
+ VALUE xxhash_xxh32(VALUE mod, VALUE input, VALUE seed);
21
+ VALUE xxhash_xxh32_file(VALUE mod, VALUE filename, VALUE seed);
22
+ void xxhash32_streaming_hash_free(xxhash_xxh32_t* state);
23
+ VALUE xxhash32_streaming_hash_new(VALUE klass, VALUE seed);
24
+ VALUE xxhash32_streaming_hash_update(VALUE self, VALUE data);
25
+ VALUE xxhash32_streaming_hash_reset(VALUE self);
26
+ VALUE xxhash32_streaming_hash_digest(VALUE self);
27
+ VALUE xxhash_xxh64(VALUE mod, VALUE input, VALUE seed);
28
+ VALUE xxhash_xxh64_file(VALUE mod, VALUE filename, VALUE seed);
29
+ void xxhash64_streaming_hash_free(xxhash_xxh64_t* state);
30
+ VALUE xxhash64_streaming_hash_new(VALUE klass, VALUE seed);
31
+ VALUE xxhash64_streaming_hash_update(VALUE self, VALUE data);
32
+ VALUE xxhash64_streaming_hash_reset(VALUE self);
33
+ VALUE xxhash64_streaming_hash_digest(VALUE self);
34
+ void Init_xxhash(void);
@@ -1,3 +1,3 @@
1
1
  module XXhash
2
- VERSION = "0.2.0"
2
+ VERSION = "0.5.0"
3
3
  end