murmur_redux 0.0.1 → 1.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f86efa1d0a92c333ab5119703d1be96f108cd342
4
- data.tar.gz: c775a8a518c9d285a4919ef30843fc9b69116e7d
3
+ metadata.gz: 925117d747be38f53fff1621f2b2a5c50ff81843
4
+ data.tar.gz: 2f56e116c367da28c0d039fcfb43ce6a082ce84b
5
5
  SHA512:
6
- metadata.gz: 5da0aff8b1c40090d1d96144c53cf50347c3307753db3849c78f1a05b2498ab5bb86723e79a15b1b4f31cb6cbb05490c49ac88f160200795eb75f51fdc5a7199
7
- data.tar.gz: 603bcefa464c6e311839c8365443ca2c13a29414c7c79c3515b892318980fc6bc2b098b8f3c79f76ae5b894f0599974d3162bbffdefb46379ad8aa4614ea5c5e
6
+ metadata.gz: af1fffda69050fd8a3d9290622c6a1fa2024fd0d0097e273ca9409aebbfb116f48f11e1bd45295098aad07ee850f1c0598e062ec28f2c8e3502eca65eff24d1c
7
+ data.tar.gz: 6acbb6e828d76d3f2bdef8dd9b25180d32145426c2d2d009af4ca8ab25f31d67437290aad20a9f2dfcf8996ed4313fe3a1f8ade0cbe74791dbbd72a2fd0933be
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  *.gem
2
2
  *.swp
3
3
  *.lock
4
+ *.so
4
5
  tmp/*
data/.rspec CHANGED
File without changes
data/.ruby-gemset CHANGED
File without changes
data/.ruby-version CHANGED
File without changes
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :test do
6
+ gem 'rake-compiler'
6
7
  gem 'rspec'
7
8
  gem 'guard-rspec'
8
9
  end
data/Guardfile CHANGED
File without changes
data/README.md CHANGED
@@ -1,10 +1,8 @@
1
- # Search redux
1
+ # Murmur redux
2
2
 
3
3
  A simpler wrapper around [murmurhash3](https://github.com/funny-falcon/murmurhash3-ruby) gem with a nicer API.
4
4
 
5
- ## Requirements
6
-
7
- Murmur redux requires at least Ruby >= 1.9.2
5
+ It defaults to `MurmurHash3_x86_128` which is a nice combination of low latency and with good collision resistence.
8
6
 
9
7
  ## Installation
10
8
 
@@ -19,12 +17,33 @@ gem 'murmur_redux'
19
17
  By default it uses MurmurHash3_x86_128 which is a nice combination of low latency and with good collision resistence.
20
18
 
21
19
  ```ruby
22
- class MyClass
23
- hex_string = MurmurRedux::Hash.digest('test')
24
- end
20
+ hex_string = MurmurRedux::Hash.digest('test')
21
+
22
+ # => '9de1bd74cc287dac824dbdf93182129a'
25
23
  ```
26
24
 
27
- ## License (MIT)
25
+ ### FAQ
26
+
27
+ ##### What is MurmurHash ?
28
+
29
+ From its Wikipedia page[0] :
30
+
31
+ >MurmurHash is a non-cryptographic hash function suitable for general hash-based lookup. It was created by Austin Appleby in 2008, and exists in a number of variants, all of which have been released into the public domain. When compared to other popular hash functions, MurmurHash performed well in a random distribution of regular keys.
32
+
33
+ ##### How fast is it ?
34
+
35
+ Is one of the fastest hashing algorithms with with good to great collision resistence[1].
36
+
37
+ - [0] - [wiki article](http://en.wikipedia.org/wiki/MurmurHash)
38
+ - [1] - [performance](http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed)
39
+
40
+ ### Credits
41
+
42
+ - [MurmurHash3](https://code.google.com/p/smhasher/wiki/MurmurHash3)
43
+ - [murmurhash3-ruby gem](https://github.com/funny-falcon/murmurhash3-ruby)
44
+ - [Byte Friendly article on MurmurHash 3](http://tech.tulentsev.com/2012/10/ruby-gem-for-murmurhash-3)
45
+
46
+ ### License (MIT)
28
47
 
29
48
  Copyright (c) 2013 Marian Posaceanu
30
49
 
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+ require 'rake/extensiontask'
6
+
7
+ Rake::ExtensionTask.new 'murmur_native' do |ext|
8
+ ext.lib_dir = 'lib/murmur_redux'
9
+ end
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('murmur_native')
@@ -0,0 +1,467 @@
1
+ #include <ruby.h>
2
+ /*-----------------------------------------------------------------------------
3
+ * MurmurHash3 was written by Austin Appleby, and is placed in the public
4
+ * domain. The author hereby disclaims copyright to this source code.
5
+
6
+ * Note - The x86 and x64 versions do _not_ produce the same results, as the
7
+ * algorithms are optimized for their respective platforms. You can still
8
+ * compile and run any of them on any platform, but your performance with the
9
+ * non-native version will be less than optimal.
10
+ */
11
+
12
+ typedef unsigned char uint8_t;
13
+ typedef unsigned int uint32_t;
14
+ #ifndef HAVE_STDINT_H
15
+ #if SIZEOF_LONG == 8
16
+ typedef unsigned long uint64_t;
17
+ #else
18
+ typedef unsigned long long uint64_t;
19
+ #endif
20
+ #endif
21
+
22
+ /*-----------------------------------------------------------------------------
23
+ * Platform-specific functions and macros
24
+ */
25
+
26
+ #ifdef __GNUC__
27
+ #define FORCE_INLINE __attribute__((always_inline))
28
+ #elif defined(_MSC_VER)
29
+ #define FORCE_INLINE __forceinline
30
+ #else
31
+ #define FORCE_INLINE
32
+ #endif
33
+
34
+ #if defined(_MSC_VER)
35
+
36
+ #define ROTL32(x,y) _rotl(x,y)
37
+ #define ROTL64(x,y) _rotl64(x,y)
38
+
39
+ #define BIG_CONSTANT(x) (x)
40
+
41
+ #else
42
+
43
+ static inline FORCE_INLINE uint32_t
44
+ rotl32 ( uint32_t x, int8_t r )
45
+ {
46
+ return (x << r) | (x >> (32 - r));
47
+ }
48
+
49
+ static inline FORCE_INLINE uint64_t
50
+ rotl64 ( uint64_t x, int8_t r )
51
+ {
52
+ return (x << r) | (x >> (64 - r));
53
+ }
54
+
55
+ #define ROTL32(x,y) rotl32(x,y)
56
+ #define ROTL64(x,y) rotl64(x,y)
57
+
58
+ #define BIG_CONSTANT(x) (x##LLU)
59
+ #endif
60
+
61
+ /* end platform specific */
62
+
63
+ /* Block read - if your platform needs to do endian-swapping or can only
64
+ * handle aligned reads, do the conversion here */
65
+ #ifdef WORDS_BIGENDIAN
66
+ #define GCC_VERSION_SINCE(major, minor, patchlevel) \
67
+ (defined(__GNUC__) && !defined(__INTEL_COMPILER) && \
68
+ ((__GNUC__ > (major)) || \
69
+ (__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \
70
+ (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))))
71
+ #if GCC_VERSION_SINCE(4,3,0)
72
+ # define swap32(x) __builtin_bswap32(x)
73
+ # define swap64(x) __builtin_bswap64(x)
74
+ #endif
75
+
76
+ #ifndef swap32
77
+ # define swap32(x) ((((x)&0xFF)<<24) \
78
+ |(((x)>>24)&0xFF) \
79
+ |(((x)&0x0000FF00)<<8) \
80
+ |(((x)&0x00FF0000)>>8) )
81
+ #endif
82
+
83
+ #ifndef swap64
84
+ # ifdef HAVE_INT64_T
85
+ static inline FORCE_INLINE uint64_t
86
+ swap64(uint64_t x) {
87
+ x = (x>>32) | (x << 32);
88
+ x = ((x & BIG_CONSTANT(0xFFFF0000FFFF0000)) >> 16) |
89
+ ((x & BIG_CONSTANT(0x0000FFFF0000FFFF)) << 16);
90
+ return ((x & BIG_CONSTANT(0xFF00FF00FF00FF00)) >> 8) |
91
+ ((x & BIG_CONSTANT(0x00FF00FF00FF00FF)) << 8);
92
+ }
93
+ # endif
94
+
95
+ #endif
96
+ static inline FORCE_INLINE uint32_t
97
+ getblock32(const uint32_t * p, int i)
98
+ {
99
+ return swap32(p[i]);
100
+ }
101
+
102
+ static inline FORCE_INLINE uint64_t
103
+ getblock64(const uint64_t * p, int i)
104
+ {
105
+ return swap64(p[i]);
106
+ }
107
+ #else
108
+ #define getblock32(p, i) (p[i])
109
+ #define getblock64(p, i) (p[i])
110
+ #endif
111
+
112
+ /* Finalization mix - force all bits of a hash block to avalanche */
113
+
114
+ static inline FORCE_INLINE uint32_t
115
+ fmix32 ( uint32_t h )
116
+ {
117
+ h ^= h >> 16;
118
+ h *= 0x85ebca6b;
119
+ h ^= h >> 13;
120
+ h *= 0xc2b2ae35;
121
+ h ^= h >> 16;
122
+
123
+ return h;
124
+ }
125
+
126
+ static inline FORCE_INLINE uint64_t
127
+ fmix64 ( uint64_t k )
128
+ {
129
+ k ^= k >> 33;
130
+ k *= BIG_CONSTANT(0xff51afd7ed558ccd);
131
+ k ^= k >> 33;
132
+ k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
133
+ k ^= k >> 33;
134
+
135
+ return k;
136
+ }
137
+
138
+ static inline FORCE_INLINE uint32_t
139
+ mmix32(uint32_t k1)
140
+ {
141
+ k1 *= 0xcc9e2d51;
142
+ k1 = ROTL32(k1, 15);
143
+ return k1 * 0x1b873593;
144
+ }
145
+
146
+ static uint32_t
147
+ MurmurHash3_x86_32 ( const void * key, long len, uint32_t seed)
148
+ {
149
+ const uint8_t * data = (const uint8_t*)key;
150
+ const int nblocks = (int)(len / 4);
151
+ int i;
152
+
153
+ uint32_t h1 = seed;
154
+ uint32_t k1 = 0;
155
+
156
+
157
+ /* body */
158
+
159
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
160
+
161
+ for(i = -nblocks; i; i++)
162
+ {
163
+ h1 ^= mmix32(getblock32(blocks, i));
164
+ h1 = ROTL32(h1,13);
165
+ h1 = h1*5+0xe6546b64;
166
+ }
167
+
168
+ /* tail */
169
+
170
+ data += nblocks*4;
171
+
172
+ switch(len & 3)
173
+ {
174
+ case 3: k1 ^= data[2] << 16;
175
+ case 2: k1 ^= data[1] << 8;
176
+ case 1: k1 ^= data[0];
177
+ h1 ^= mmix32(k1);
178
+ };
179
+
180
+ /* finalization */
181
+
182
+ h1 ^= len;
183
+
184
+ h1 = fmix32(h1);
185
+
186
+ return h1;
187
+ }
188
+
189
+ #define C1_128 BIG_CONSTANT(0x87c37b91114253d5)
190
+ #define C2_128 BIG_CONSTANT(0x4cf5ad432745937f)
191
+
192
+ static inline FORCE_INLINE uint64_t
193
+ mmix128_1(uint64_t k1)
194
+ {
195
+ k1 *= C1_128;
196
+ k1 = ROTL64(k1, 31);
197
+ return k1 * C2_128;
198
+ }
199
+
200
+ static inline FORCE_INLINE uint64_t
201
+ mmix128_2(uint64_t k2)
202
+ {
203
+ k2 *= C2_128;
204
+ k2 = ROTL64(k2, 33);
205
+ return k2 * C1_128;
206
+ }
207
+
208
+ static void MurmurHash3_x64_128 ( const void * key, const long len,
209
+ const uint32_t seed, void * out )
210
+ {
211
+ const uint8_t * data = (const uint8_t*)key;
212
+ const int nblocks = (int)(len / 16);
213
+ int i;
214
+
215
+ uint64_t h1 = seed;
216
+ uint64_t h2 = seed;
217
+ uint64_t k1 = 0, k2 = 0;
218
+
219
+ /* body */
220
+
221
+ const uint64_t * blocks = (const uint64_t *)(data);
222
+
223
+ for(i = 0; i < nblocks; i++)
224
+ {
225
+ k1 = getblock64(blocks, i*2+0);
226
+ k2 = getblock64(blocks, i*2+1);
227
+
228
+ h1 ^= mmix128_1(k1);
229
+ h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
230
+
231
+ h2 ^= mmix128_2(k2);
232
+ h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
233
+ }
234
+
235
+ /* tail */
236
+
237
+ data += nblocks*16;
238
+ k1 = k2 = 0;
239
+
240
+ switch(len & 15)
241
+ {
242
+ case 15: k2 ^= (uint64_t)(data[14]) << 48;
243
+ case 14: k2 ^= (uint64_t)(data[13]) << 40;
244
+ case 13: k2 ^= (uint64_t)(data[12]) << 32;
245
+ case 12: k2 ^= (uint64_t)(data[11]) << 24;
246
+ case 11: k2 ^= (uint64_t)(data[10]) << 16;
247
+ case 10: k2 ^= (uint64_t)(data[ 9]) << 8;
248
+ case 9: k2 ^= (uint64_t)(data[ 8]) << 0;
249
+ h2 ^= mmix128_2(k2);
250
+
251
+ case 8: k1 ^= (uint64_t)(data[ 7]) << 56;
252
+ case 7: k1 ^= (uint64_t)(data[ 6]) << 48;
253
+ case 6: k1 ^= (uint64_t)(data[ 5]) << 40;
254
+ case 5: k1 ^= (uint64_t)(data[ 4]) << 32;
255
+ case 4: k1 ^= (uint64_t)(data[ 3]) << 24;
256
+ case 3: k1 ^= (uint64_t)(data[ 2]) << 16;
257
+ case 2: k1 ^= (uint64_t)(data[ 1]) << 8;
258
+ case 1: k1 ^= (uint64_t)(data[ 0]) << 0;
259
+ h1 ^= mmix128_1(k1);
260
+ };
261
+
262
+ /* finalization */
263
+
264
+ h1 ^= len; h2 ^= len;
265
+
266
+ h1 += h2;
267
+ h2 += h1;
268
+
269
+ h1 = fmix64(h1);
270
+ h2 = fmix64(h2);
271
+
272
+ h1 += h2;
273
+ h2 += h1;
274
+
275
+ ((uint64_t*)out)[0] = h1;
276
+ ((uint64_t*)out)[1] = h2;
277
+ }
278
+
279
+ /* end of MurmurHash3 algorithm */
280
+
281
+ static VALUE
282
+ rb_fmix32(VALUE self, VALUE integer)
283
+ {
284
+ uint32_t _int = NUM2UINT(integer);
285
+ return UINT2NUM(fmix32(_int));
286
+ }
287
+
288
+ static VALUE
289
+ rb_fmix64(VALUE self, VALUE integer)
290
+ {
291
+ #if SIZEOF_LONG == 8
292
+ uint64_t _int = NUM2ULONG(integer);
293
+ return ULONG2NUM(fmix64(_int));
294
+ #else
295
+ uint64_t _int = NUM2ULL(integer);
296
+ return ULL2NUM(fmix64(_int));
297
+ #endif
298
+ }
299
+
300
+ static VALUE
301
+ rb_murmur3_32_str_hash(int argc, VALUE* argv, VALUE self)
302
+ {
303
+ VALUE rstr;
304
+ uint32_t result;
305
+
306
+ if (argc == 0 || argc > 2) {
307
+ rb_raise(rb_eArgError, "accept 1 or 2 arguments: (string[, seed])");
308
+ }
309
+ rstr = argv[0];
310
+ StringValue(rstr);
311
+
312
+ result = MurmurHash3_x86_32(RSTRING_PTR(rstr), RSTRING_LEN(rstr), argc == 1 ? 0 : NUM2UINT(argv[1]));
313
+
314
+ return UINT2NUM(result);
315
+ }
316
+
317
+ static VALUE
318
+ rb_murmur3_32_int32_hash(int argc, VALUE* argv, VALUE self)
319
+ {
320
+ /* VALUE rint; */
321
+ uint32_t _int;
322
+ uint32_t result;
323
+
324
+ if (argc == 0 || argc > 2) {
325
+ rb_raise(rb_eArgError, "accept 1 or 2 arguments: (int32[, seed])");
326
+ }
327
+ _int = NUM2UINT(argv[0]);
328
+
329
+ result = MurmurHash3_x86_32(&_int, 4, argc == 1 ? 0 : NUM2UINT(argv[1]));
330
+
331
+ return UINT2NUM(result);
332
+ }
333
+
334
+ static VALUE
335
+ rb_murmur3_32_int64_hash(int argc, VALUE* argv, VALUE self)
336
+ {
337
+ /* VALUE rint; */
338
+ uint64_t _int;
339
+ uint32_t result;
340
+
341
+ if (argc == 0 || argc > 2) {
342
+ rb_raise(rb_eArgError, "accept 1 or 2 arguments: (int64[, seed])");
343
+ }
344
+ #if SIZEOF_LONG == 8
345
+ _int = NUM2ULONG(argv[0]);
346
+ #else
347
+ _int = NUM2ULL(argv[0]);
348
+ #endif
349
+
350
+ result = MurmurHash3_x86_32(&_int, 8, argc == 1 ? 0 : NUM2UINT(argv[1]));
351
+
352
+ return UINT2NUM(result);
353
+ }
354
+
355
+ #define PREPARE_128_BIT() \
356
+ VALUE rstr, rseed, ar_result; \
357
+ uint32_t result[4]; \
358
+
359
+ #define SWAP_128_BIT() do { \
360
+ uint32_t tmp; \
361
+ tmp = result[0]; \
362
+ result[0] = result[1]; \
363
+ result[1] = tmp; \
364
+ tmp = result[2]; \
365
+ result[2] = result[3]; \
366
+ result[3] = tmp; \
367
+ } while (0)
368
+
369
+ #define RETURN_128_BIT() \
370
+ ar_result = rb_ary_new2(4); \
371
+ rb_ary_push(ar_result, UINT2NUM(result[0])); \
372
+ rb_ary_push(ar_result, UINT2NUM(result[1])); \
373
+ rb_ary_push(ar_result, UINT2NUM(result[2])); \
374
+ rb_ary_push(ar_result, UINT2NUM(result[3])); \
375
+ return ar_result
376
+
377
+ static VALUE
378
+ rb_murmur3_128_str_hash(int argc, VALUE* argv, VALUE self)
379
+ {
380
+ VALUE rstr, ar_result;
381
+ uint32_t result[4];
382
+
383
+ if (argc == 0 || argc > 2) {
384
+ rb_raise(rb_eArgError, "accept 1 or 2 arguments: (string[, seed])");
385
+ }
386
+ rstr = argv[0];
387
+ StringValue(rstr);
388
+
389
+ MurmurHash3_x64_128(RSTRING_PTR(rstr), RSTRING_LEN(rstr), argc == 1 ? 0 : NUM2UINT(argv[1]), result);
390
+ #if WORDS_BIGENDIAN
391
+ SWAP_128_BIT();
392
+ #endif
393
+ RETURN_128_BIT();
394
+ }
395
+
396
+ static VALUE
397
+ rb_murmur3_128_int32_hash(int argc, VALUE* argv, VALUE self)
398
+ {
399
+ VALUE ar_result;
400
+ uint32_t result[4], _int;
401
+
402
+ if (argc == 0 || argc > 2) {
403
+ rb_raise(rb_eArgError, "accept 1 or 2 arguments: (int32[, seed])");
404
+ }
405
+ _int = NUM2UINT(argv[0]);
406
+ MurmurHash3_x64_128(&_int, 4, argc == 1 ? 0 : NUM2UINT(argv[1]), result);
407
+ #if WORDS_BIGENDIAN
408
+ SWAP_128_BIT();
409
+ #endif
410
+ RETURN_128_BIT();
411
+ }
412
+
413
+ static VALUE
414
+ rb_murmur3_128_int64_hash(int argc, VALUE* argv, VALUE self)
415
+ {
416
+ VALUE ar_result;
417
+ uint32_t result[4];
418
+ uint64_t _int;
419
+
420
+ if (argc == 0 || argc > 2) {
421
+ rb_raise(rb_eArgError, "accept 1 or 2 arguments: (int64[, seed])");
422
+ }
423
+ #if SIZEOF_LONG == 8
424
+ _int = NUM2ULONG(argv[0]);
425
+ #else
426
+ _int = NUM2ULL(argv[0]);
427
+ #endif
428
+ MurmurHash3_x64_128(&_int, 8, argc == 1 ? 0 : NUM2UINT(argv[1]), result);
429
+ #if WORDS_BIGENDIAN
430
+ SWAP_128_BIT();
431
+ #endif
432
+ RETURN_128_BIT();
433
+ }
434
+
435
+ void
436
+ Init_murmur_native() {
437
+ VALUE singleton;
438
+ VALUE mod_murmur = rb_define_module("MurmurRedux");
439
+ VALUE mod_murmur32 = rb_define_module_under(mod_murmur, "Native32");
440
+ VALUE mod_murmur128 = rb_define_module_under(mod_murmur, "Native128");
441
+
442
+ rb_define_method(mod_murmur32, "murmur3_32_fmix", rb_fmix32, 1);
443
+ rb_define_method(mod_murmur32, "murmur3_32_str_hash", rb_murmur3_32_str_hash, -1);
444
+ rb_define_method(mod_murmur32, "murmur3_32_int32_hash", rb_murmur3_32_int32_hash, -1);
445
+ rb_define_method(mod_murmur32, "murmur3_32_int64_hash", rb_murmur3_32_int64_hash, -1);
446
+
447
+ rb_extend_object(mod_murmur32, mod_murmur32);
448
+ singleton = rb_singleton_class(mod_murmur32);
449
+ rb_define_alias(singleton, "fmix", "murmur3_32_fmix");
450
+ rb_define_alias(singleton, "str_hash", "murmur3_32_str_hash");
451
+ rb_define_alias(singleton, "int32_hash", "murmur3_32_int32_hash");
452
+ rb_define_alias(singleton, "int64_hash", "murmur3_32_int64_hash");
453
+
454
+
455
+ rb_define_method(mod_murmur128, "murmur3_128_fmix", rb_fmix64, 1);
456
+ rb_define_method(mod_murmur128, "murmur3_128_str_hash", rb_murmur3_128_str_hash, -1);
457
+ rb_define_method(mod_murmur128, "murmur3_128_int32_hash", rb_murmur3_128_int32_hash, -1);
458
+ rb_define_method(mod_murmur128, "murmur3_128_int64_hash", rb_murmur3_128_int64_hash, -1);
459
+
460
+ rb_extend_object(mod_murmur128, mod_murmur128);
461
+ singleton = rb_singleton_class(mod_murmur128);
462
+ rb_define_alias(singleton, "fmix", "murmur3_128_fmix");
463
+ rb_define_alias(singleton, "str_hash", "murmur3_128_str_hash");
464
+ rb_define_alias(singleton, "int32_hash", "murmur3_128_int32_hash");
465
+ rb_define_alias(singleton, "int64_hash", "murmur3_128_int64_hash");
466
+
467
+ }
File without changes
@@ -2,14 +2,14 @@ module MurmurRedux
2
2
  class Hash
3
3
  class << self
4
4
  def digest(string)
5
- ints = MurmurHash3::V128.str_hash(string)
5
+ ints = MurmurRedux::V128.str_hash(string)
6
6
 
7
- gen_hex_string(ints)
7
+ generate_hex_string(ints)
8
8
  end
9
9
 
10
10
  private
11
11
 
12
- def gen_hex_string(ints)
12
+ def generate_hex_string(ints)
13
13
  ints.pack('L*').unpack('H*').first
14
14
  end
15
15
  end
@@ -1,3 +1,3 @@
1
1
  module MurmurRedux
2
- VERSION = '0.0.1' unless defined? MurmurRedux::VERSION
2
+ VERSION = '1.0.0' unless defined? MurmurRedux::VERSION
3
3
  end
data/lib/murmur_redux.rb CHANGED
@@ -1,6 +1,9 @@
1
- require 'murmurhash3'
1
+ module MurmurRedux
2
+ require 'murmur_redux/murmur_native'
3
+ V32 = Native32
4
+ V128 = Native128
5
+ end
2
6
 
3
7
  require 'murmur_redux/version'
4
8
  require 'murmur_redux/errors'
5
9
  require 'murmur_redux/hash'
6
-
data/murmur_redux.gemspec CHANGED
@@ -1,20 +1,21 @@
1
- $LOAD_PATH.push File.expand_path("../lib", __FILE__)
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+ require 'rake'
2
3
  require 'murmur_redux/version'
3
4
 
4
- Gem::Specification.new do |s|
5
- s.name = 'murmur_redux'
6
- s.version = MurmurRedux::VERSION
7
- s.platform = Gem::Platform::RUBY
8
- s.summary = 'A simple wrapper around murmurhash3 gem with a nicer API.'
9
- s.description = 'A simple wrapper around murmurhash3 gem with a nicer API : MurmurRedux::Hash.digest(string)'
10
- s.author = 'Marian Posaceanu'
11
- s.email = 'contact@marianposaceanu.com'
12
- s.files = `git ls-files`.split("\n")
13
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
- s.require_paths = ['lib']
15
- s.homepage = 'https://github.com/dakull/murmur_redux'
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'murmur_redux'
7
+ gem.version = MurmurRedux::VERSION
8
+ gem.platform = Gem::Platform::RUBY
9
+ gem.summary = 'A simple wrapper around murmurhash3 C extension.'
10
+ gem.description = 'A simple wrapper around murmurhash3 C extension originally based on https://github.com/funny-falcon/murmurhash3-ruby'
11
+ gem.author = 'Marian Posaceanu'
12
+ gem.email = 'contact@marianposaceanu.com'
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ gem.require_paths = ['lib', 'ext']
16
+ gem.homepage = 'https://github.com/dakull/murmur_redux'
17
+ gem.extensions = FileList["ext/**/extconf.rb"]
18
+ gem.license = 'MIT'
16
19
 
17
- s.required_ruby_version = '>= 1.9.2'
18
-
19
- s.add_dependency('murmurhash3', '~> 0.1.3')
20
+ gem.required_ruby_version = '>= 1.9.2'
20
21
  end
@@ -0,0 +1,55 @@
1
+ shared_examples_128 = proc do
2
+ it 'should make correct hash for string' do
3
+ murmur.str_hash('asdfqwer', 0).should eq([0xd6d7d367, 0xcb41f064, 0x8973cd72, 0xc345e72e])
4
+ murmur.str_hash('asdfqwerzxcvyui', 0).should eq([0x007b2172f, 0x64ecae1b, 0x1813b5a5, 0x9c674ee6])
5
+ murmur.str_hash('asdfqwerzxcvyuio', 0).should eq([0xf508df57, 0xbb38f3fd, 0xf48c9d98, 0xb65c36cd])
6
+ murmur.str_hash('asdfqwerzxcvyuio!', 0).should eq([0x8a011755, 0xb13d463f, 0x8386d32a, 0x0df8884c])
7
+ end
8
+
9
+ it 'should make correct hash for 32bit integer' do
10
+ murmur.int32_hash(1717859169).should eq([0x20b48108, 0x10369ceb, 0x3ad523cc, 0xdacb587f])
11
+ murmur.int32_hash(1717859169).should eq(murmur.str_hash('asdf'))
12
+ end
13
+
14
+ it 'should make correct hash for 64bit integer' do
15
+ murmur.int64_hash(0x12345678).should eq(murmur.str_hash("\x78\x56\x34\x12\x00\x00\x00\x00"))
16
+ murmur.int64_hash(0x1234567812345678).should eq(murmur.str_hash("\x78\x56\x34\x12\x78\x56\x34\x12"))
17
+ end
18
+
19
+ it 'should make correct fmix for 64bit integer' do
20
+ murmur.fmix(1717859169).should eq(0xbefb9076a3712207)
21
+ murmur.fmix(12345678912345678).should eq(0x197ef59146f5221c)
22
+ end
23
+ end
24
+
25
+ shared_examples_32 = proc do
26
+ it 'should make correct hash for string' do
27
+ murmur.str_hash('asdfqwer', 0).should eq(0xa46b5209)
28
+ murmur.str_hash('asdfqwerty', 0).should eq(0xa3cfe04b)
29
+ murmur.str_hash('asd', 0).should eq(0x14570c6f)
30
+ end
31
+
32
+ it 'should make correct hash for 32bit integer' do
33
+ murmur.int32_hash(1717859169).should eq(0x1b20e026)
34
+ murmur.int32_hash(1717859169).should eq(murmur.str_hash('asdf'))
35
+ end
36
+
37
+ it 'should make correct hash for 64bit integer' do
38
+ murmur.int64_hash(0x12345678).should eq(murmur.str_hash("\x78\x56\x34\x12\x00\x00\x00\x00"))
39
+ murmur.int64_hash(0x1234567812345678).should eq(murmur.str_hash("\x78\x56\x34\x12\x78\x56\x34\x12"))
40
+ end
41
+
42
+ it 'should make correct fmix for 32bit integer' do
43
+ murmur.fmix(1717859169).should eq(0x17561734)
44
+ end
45
+ end
46
+
47
+ describe "Native 32" do
48
+ let(:murmur) { MurmurRedux::Native32 }
49
+ class_exec &shared_examples_32
50
+ end
51
+
52
+ describe "Native 128" do
53
+ let(:murmur) { MurmurRedux::Native128 }
54
+ class_exec &shared_examples_128
55
+ end
@@ -6,6 +6,6 @@ describe MurmurRedux::Hash do
6
6
  it 'digests an argument supplied string into a hexadecimal representation' do
7
7
  digested_string = MurmurRedux::Hash.digest(string_to_digest)
8
8
 
9
- expect(digested_string).should eq('df65d6d2d12d51f164c5f3a85066322c')
9
+ expect(digested_string).to eq('df65d6d2d12d51f164c5f3a85066322c')
10
10
  end
11
11
  end
data/spec/spec_helper.rb CHANGED
File without changes
metadata CHANGED
@@ -1,33 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: murmur_redux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marian Posaceanu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-08 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: murmurhash3
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: 0.1.3
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 0.1.3
27
- description: 'A simple wrapper around murmurhash3 gem with a nicer API : MurmurRedux::Hash.digest(string)'
11
+ date: 2013-09-21 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A simple wrapper around murmurhash3 C extension originally based on https://github.com/funny-falcon/murmurhash3-ruby
28
14
  email: contact@marianposaceanu.com
29
15
  executables: []
30
- extensions: []
16
+ extensions:
17
+ - ext/murmur_native/extconf.rb
31
18
  extra_rdoc_files: []
32
19
  files:
33
20
  - .gitignore
@@ -37,20 +24,26 @@ files:
37
24
  - Gemfile
38
25
  - Guardfile
39
26
  - README.md
27
+ - Rakefile
28
+ - ext/murmur_native/extconf.rb
29
+ - ext/murmur_native/murmur_native.c
40
30
  - lib/murmur_redux.rb
41
31
  - lib/murmur_redux/errors.rb
42
32
  - lib/murmur_redux/hash.rb
43
33
  - lib/murmur_redux/version.rb
44
34
  - murmur_redux.gemspec
35
+ - spec/murmur_native_spec.rb
45
36
  - spec/murmur_redux/hash_spec.rb
46
37
  - spec/spec_helper.rb
47
38
  homepage: https://github.com/dakull/murmur_redux
48
- licenses: []
39
+ licenses:
40
+ - MIT
49
41
  metadata: {}
50
42
  post_install_message:
51
43
  rdoc_options: []
52
44
  require_paths:
53
45
  - lib
46
+ - ext
54
47
  required_ruby_version: !ruby/object:Gem::Requirement
55
48
  requirements:
56
49
  - - '>='
@@ -63,8 +56,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
56
  version: '0'
64
57
  requirements: []
65
58
  rubyforge_project:
66
- rubygems_version: 2.0.0
59
+ rubygems_version: 2.0.3
67
60
  signing_key:
68
61
  specification_version: 4
69
- summary: A simple wrapper around murmurhash3 gem with a nicer API.
62
+ summary: A simple wrapper around murmurhash3 C extension.
70
63
  test_files: []