digest-murmurhash 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +66 -26
  3. data/Rakefile +2 -2
  4. data/digest-murmurhash.gemspec +6 -7
  5. data/ext/digest/murmurhash/{murmurhash1.c → 1.c} +1 -1
  6. data/ext/digest/murmurhash/{murmurhash2.c → 2.c} +1 -1
  7. data/ext/digest/murmurhash/{murmurhash2a.c → 2a.c} +1 -1
  8. data/ext/digest/murmurhash/3_x64_128.c +117 -0
  9. data/ext/digest/murmurhash/3_x86_128.c +141 -0
  10. data/ext/digest/murmurhash/3_x86_32.c +88 -0
  11. data/ext/digest/murmurhash/{murmurhash64a.c → 64a.c} +1 -1
  12. data/ext/digest/murmurhash/{murmurhash64b.c → 64b.c} +2 -2
  13. data/ext/digest/murmurhash/aligned2.c +163 -0
  14. data/ext/digest/murmurhash/extconf.rb +1 -1
  15. data/ext/digest/murmurhash/{murmurhash.c → init.c} +136 -22
  16. data/ext/digest/murmurhash/init.h +94 -0
  17. data/ext/digest/murmurhash/{murmurhash_neutral2.c → neutral2.c} +3 -3
  18. data/lib/digest/murmurhash.rb +3 -73
  19. data/lib/digest/murmurhash/base.rb +58 -0
  20. data/spec/bench.rb +18 -12
  21. data/spec/digest_spec.rb +41 -29
  22. data/spec/exception_spec.rb +17 -12
  23. data/spec/mem_spec.rb +1 -1
  24. data/spec/spec_helper.rb +6 -8
  25. metadata +20 -36
  26. data/ext/digest/murmurhash/murmurhash.h +0 -46
  27. data/ext/digest/murmurhash/murmurhash1.h +0 -11
  28. data/ext/digest/murmurhash/murmurhash2.h +0 -11
  29. data/ext/digest/murmurhash/murmurhash2a.h +0 -11
  30. data/ext/digest/murmurhash/murmurhash64a.h +0 -10
  31. data/ext/digest/murmurhash/murmurhash64b.h +0 -11
  32. data/ext/digest/murmurhash/murmurhash_aligned2.c +0 -75
  33. data/ext/digest/murmurhash/murmurhash_aligned2.h +0 -11
  34. data/ext/digest/murmurhash/murmurhash_neutral2.h +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4bb19a065230c4cf479bbc3e5d30a3ecacaab7e
4
- data.tar.gz: 8b6b55cb5d5d3c398e9ac006b5b84359272c034d
3
+ metadata.gz: cd9a5f608b1cac914b791b811bc75eba224ca841
4
+ data.tar.gz: ed6533e449b132c385c3457708c52d556d47114d
5
5
  SHA512:
6
- metadata.gz: 09aa8502b047d0487b5727846236e91c33d06e7db3bfdc89f74ddc71f935d7f672232d3c6e27fc5c588fe6c90fb8d151e7611c356e2c168e216e20822862d07a
7
- data.tar.gz: 1b6a03328a0428b3cc5455ca306fcc4d5bab0c5a8609300e9b7dbc774a499b8921d9f5b96b653ec3c72b8fa4d59cec5fcffe09447eac5d84f1c1b5ef4dc92771
6
+ metadata.gz: 54555dc73a82614b6fe9ba109662e96d4dad18b8e9ed30a073d9cde49d611b256158381d9c61280a9dbe7783e8db4967ccc8de2af9a2a507c71bdca87c99730b
7
+ data.tar.gz: 4b47b42486c884ddb3edee9b7c4f1ec11529657baf471492e45c113abc6e7dba622a5e7e7cc664480c9790b139fe49942e091c3257f0134635316075f8ce3791
data/README.md CHANGED
@@ -4,57 +4,97 @@
4
4
 
5
5
  **MurmurHash** is a algorithm desiged by Austin Appleby.
6
6
 
7
- **Digest::MurmurHash1** use algorithm MurmurHash1(32-bit).
7
+ This library have some classes for MurmurHash algorithm.
8
8
 
9
- **Digest::MurmurHash2** use algorithm MurmurHash2(32-bit).
9
+ - **Digest::MurmurHash1** use algorithm MurmurHash1(32-bit).
10
10
 
11
- **Digest::MurmurHash2A** use algorithm MurmurHash2A(32-bit).
11
+ - **Digest::MurmurHash2** use algorithm MurmurHash2(32-bit).
12
12
 
13
- **Digest::MurmurHash64A** use algorithm MurmurHash64A(64-bit).
13
+ - **Digest::MurmurHash2A** use algorithm MurmurHash2A(32-bit).
14
14
 
15
- **Digest::MurmurHash64B** use algorithm MurmurHash64B(64-bit).
15
+ - **Digest::MurmurHash64A** use algorithm MurmurHash64A(64-bit).
16
16
 
17
- **Digest::MurmurHashNeutral2** use algorithm MurmurHashNeutral2(32-bit).
17
+ - **Digest::MurmurHash64B** use algorithm MurmurHash64B(64-bit).
18
18
 
19
- **Digest::MurmurHashAligned2** use algorithm MurmurHashAligned2(32-bit).
19
+ - **Digest::MurmurHashNeutral2** use algorithm MurmurHashNeutral2(32-bit).
20
20
 
21
- (**Digest::MurmurHash** exist to write only version number)
21
+ - **Digest::MurmurHashAligned2** use algorithm MurmurHashAligned2(32-bit).
22
+
23
+ - **Digest::MurmurHash3\_x86\_32** use algorithm MurmurHash3 for 32-bit platform (32-bit).
24
+
25
+ - **Digest::MurmurHash3\_x86\_128** use algorithm MurmurHash3 for 32-bit platform (128-bit).
26
+
27
+ - **Digest::MurmurHash3\_x64\_128** use algorithm MurmurHash3 for 64-bit platform (128-bit).
28
+
29
+ (**Digest::MurmurHash** class was nothing)
22
30
 
23
31
  All classes compliance Digest API of Ruby.
24
32
 
25
33
  ## Usage
26
34
 
27
- You can use same interface built-in Digest::XXX classes.
28
-
29
35
  ```ruby
30
36
  require 'digest/murmurhash'
31
37
 
32
38
  # MurmurHash1 can use like same than Digest::XXX.
33
39
 
34
- p Digest::MurmurHash1.hexdigest('murmurhash') #=> 'c709abd5'
35
- p Digest::MurmurHash1.file("./LICENSE.txt").hexdigest #=> '712e9641'
36
-
37
- # and MurmurHash2 too. but return another value because using another algorithm.
40
+ p Digest::MurmurHash1.hexdigest('murmurhash') #=> d5ab09c7
41
+ p Digest::MurmurHash1.digest('murmurhash') #=> \xD5\xAB\x09\xC7
42
+ p Digest::MurmurHash1.rawdigest('murmurhash') #=> 3339299797
43
+ p Digest::MurmurHash1.file("./LICENSE.txt").hexdigest #=> "41962e71"
38
44
 
39
- p Digest::MurmurHash2.hexdigest('murmurhash') #=> '33f67c7e'
40
- p Digest::MurmurHash2.file("./LICENSE.txt").hexdigest #=> '78678326'
41
45
  ```
42
46
 
43
- ## Class tree
44
-
45
- **Digest::MurmurHash1** < Digest::StringBuffer
47
+ ## Feature
46
48
 
47
- **Digest::MurmurHash2** < Digest::StringBuffer
49
+ - Very fast because hash algorithm is written by C extention
50
+ - You can try *all* Hurmurhash algorithms
51
+ - You can use same interface built-in Digest::{MD5,SH1,...} classes.
48
52
 
49
- **Digest::MurmurHash2A** < Digest::StringBuffer
53
+ ## Simple benchmark
50
54
 
51
- **Digest::MurmurHash64A** < Digest::StringBuffer
52
-
53
- **Digest::MurmurHash64B** < Digest::StringBuffer
55
+ ```ruby
56
+ #! /usr/bin/env ruby
54
57
 
55
- **Digest::MurmurHashNeutral2** < Digest::StringBuffer
58
+ require 'benchmark'
59
+ require 'digest/md5'
60
+ require 'digest/sha1'
61
+ require 'digest/murmurhash'
62
+ require 'digest/siphash'
63
+
64
+ include Digest
65
+
66
+ n = 1000
67
+ str = "teststrings" * 1024 * 10
68
+
69
+ Benchmark.bm do |f|
70
+ [MurmurHash1, MurmurHash2, MurmurHash2A, MurmurHash64A, MurmurHash64B, MurmurHashNeutral2, MurmurHashAligned2, MurmurHash3_x86_32, MurmurHash3_x86_128, MurmurHash3_x64_128, SipHash, MD5, SHA1].each do |klass|
71
+ f.report(klass.to_s) {
72
+ i = 0
73
+ while i < n
74
+ klass.digest(str)
75
+ i += 1
76
+ end
77
+ }
78
+ end
79
+ end
80
+ ```
56
81
 
57
- **Digest::MurmurHashAligned2** < Digest::StringBuffer
82
+ ```
83
+ user system total real
84
+ Digest::MurmurHash1 0.050000 0.010000 0.060000 ( 0.047889)
85
+ Digest::MurmurHash2 0.030000 0.000000 0.030000 ( 0.034564)
86
+ Digest::MurmurHash2A 0.030000 0.010000 0.040000 ( 0.031808)
87
+ Digest::MurmurHash64A 0.010000 0.000000 0.010000 ( 0.018400)
88
+ Digest::MurmurHash64B 0.030000 0.000000 0.030000 ( 0.027818)
89
+ Digest::MurmurHashNeutral2 0.040000 0.000000 0.040000 ( 0.041021)
90
+ Digest::MurmurHashAligned2 0.020000 0.010000 0.030000 ( 0.030409)
91
+ Digest::MurmurHash3_x86_32 0.130000 0.010000 0.140000 ( 0.139622)
92
+ Digest::MurmurHash3_x86_128 0.120000 0.020000 0.140000 ( 0.143768)
93
+ Digest::MurmurHash3_x64_128 0.070000 0.010000 0.080000 ( 0.072687)
94
+ Digest::SipHash 0.060000 0.010000 0.070000 ( 0.068243)
95
+ Digest::MD5 0.130000 0.010000 0.140000 ( 0.153793)
96
+ Digest::SHA1 0.130000 0.020000 0.150000 ( 0.137686)
97
+ ```
58
98
 
59
99
  ## Installation
60
100
 
data/Rakefile CHANGED
@@ -12,14 +12,14 @@ task :spec => :compile
12
12
 
13
13
  require 'rake/extensiontask'
14
14
  spec = Bundler::GemHelper.gemspec
15
- Rake::ExtensionTask.new('murmurhash', spec) do |ext|
15
+ Rake::ExtensionTask.new('ext', spec) do |ext|
16
16
  ext.ext_dir = 'ext/digest/murmurhash'
17
17
  ext.lib_dir = 'lib/digest/murmurhash'
18
18
  end
19
19
 
20
20
  desc "gem reinstall"
21
21
  task :reinstall do |t|
22
- system "gem uninstall murmurhash"
22
+ system "gem uninstall digest-murmurhash"
23
23
  system "rake clean"
24
24
  system "bundle exec rake"
25
25
  system "rake install"
@@ -2,12 +2,12 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "digest-murmurhash"
5
- spec.version = "1.0.0"
6
- spec.author = "ksss"
7
- spec.email = "co000ri@gmail.com"
8
- spec.description = %q{Digest::MurmurHash is class collections of use algorithm MurmurHash desiged by Austin Appleby.}
9
- spec.summary = %q{Digest::MurmurHash is class collections of use algorithm MurmurHash desiged by Austin Appleby.}
10
- spec.homepage = ""
5
+ spec.version = "1.1.0"
6
+ spec.authors = ["ksss"]
7
+ spec.email = ["co000ri@gmail.com"]
8
+ spec.description = %q{digest-murmurhash is class collections of use algorithm MurmurHash desiged by Austin Appleby.}
9
+ spec.summary = %q{digest-murmurhash is class collections of use algorithm MurmurHash desiged by Austin Appleby.}
10
+ spec.homepage = "https://github.com/ksss/digest-murmurhash"
11
11
  spec.license = "MIT"
12
12
 
13
13
  spec.files = `git ls-files`.split($/)
@@ -16,7 +16,6 @@ Gem::Specification.new do |spec|
16
16
  spec.require_paths = ["lib"]
17
17
  spec.extensions = ["ext/digest/murmurhash/extconf.rb"]
18
18
 
19
- spec.add_runtime_dependency "digest-simple"
20
19
  spec.add_development_dependency "bundler"
21
20
  spec.add_development_dependency "rake"
22
21
  spec.add_development_dependency "rspec"
@@ -2,7 +2,7 @@
2
2
  * MurmurHash1 (C) Austin Appleby
3
3
  */
4
4
 
5
- #include "murmurhash1.h"
5
+ #include "init.h"
6
6
 
7
7
  #define murmur1(r) do { \
8
8
  h *= m; \
@@ -2,7 +2,7 @@
2
2
  * MurmurHash2 (C) Austin Appleby
3
3
  */
4
4
 
5
- #include "murmurhash2.h"
5
+ #include "init.h"
6
6
 
7
7
  static uint32_t
8
8
  murmur_hash_process2(const char *data, uint32_t length, uint32_t seed)
@@ -2,7 +2,7 @@
2
2
  * MurmurHash2A (C) Austin Appleby
3
3
  */
4
4
 
5
- #include "murmurhash2a.h"
5
+ #include "init.h"
6
6
 
7
7
  #define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
8
8
 
@@ -0,0 +1,117 @@
1
+ /*
2
+ * MurmurHash3_x64_128 (C) Austin Appleby
3
+ */
4
+
5
+ #include "init.h"
6
+
7
+ void
8
+ murmur_hash_process3_x64_128(const char * key, uint32_t len, uint32_t seed, void *out)
9
+ {
10
+ const uint8_t * data = (const uint8_t*)key;
11
+ const int nblocks = len / 16;
12
+
13
+ uint64_t h1 = seed;
14
+ uint64_t h2 = seed;
15
+
16
+ const uint64_t c1 = (uint64_t)BIG_CONSTANT(0x87c37b91114253d5);
17
+ const uint64_t c2 = (uint64_t)BIG_CONSTANT(0x4cf5ad432745937f);
18
+
19
+ //----------
20
+ // body
21
+
22
+ const uint64_t * blocks = (const uint64_t *)(data);
23
+
24
+ int i;
25
+
26
+ for(i = 0; i < nblocks; i++)
27
+ {
28
+ uint64_t k1 = getblock64(blocks,i*2+0);
29
+ uint64_t k2 = getblock64(blocks,i*2+1);
30
+
31
+ k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
32
+
33
+ h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
34
+
35
+ k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
36
+
37
+ h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
38
+ }
39
+
40
+ //----------
41
+ // tail
42
+
43
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
44
+
45
+ uint64_t k1 = 0;
46
+ uint64_t k2 = 0;
47
+
48
+ switch(len & 15)
49
+ {
50
+ case 15: k2 ^= ((uint64_t)tail[14]) << 48;
51
+ case 14: k2 ^= ((uint64_t)tail[13]) << 40;
52
+ case 13: k2 ^= ((uint64_t)tail[12]) << 32;
53
+ case 12: k2 ^= ((uint64_t)tail[11]) << 24;
54
+ case 11: k2 ^= ((uint64_t)tail[10]) << 16;
55
+ case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
56
+ case 9: k2 ^= ((uint64_t)tail[ 8]) << 0;
57
+ k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
58
+
59
+ case 8: k1 ^= ((uint64_t)tail[ 7]) << 56;
60
+ case 7: k1 ^= ((uint64_t)tail[ 6]) << 48;
61
+ case 6: k1 ^= ((uint64_t)tail[ 5]) << 40;
62
+ case 5: k1 ^= ((uint64_t)tail[ 4]) << 32;
63
+ case 4: k1 ^= ((uint64_t)tail[ 3]) << 24;
64
+ case 3: k1 ^= ((uint64_t)tail[ 2]) << 16;
65
+ case 2: k1 ^= ((uint64_t)tail[ 1]) << 8;
66
+ case 1: k1 ^= ((uint64_t)tail[ 0]) << 0;
67
+ k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
68
+ };
69
+
70
+ //----------
71
+ // finalization
72
+
73
+ h1 ^= len; h2 ^= len;
74
+
75
+ h1 += h2;
76
+ h2 += h1;
77
+
78
+ h1 = fmix64(h1);
79
+ h2 = fmix64(h2);
80
+
81
+ h1 += h2;
82
+ h2 += h1;
83
+
84
+ ((uint64_t*)out)[0] = h1;
85
+ ((uint64_t*)out)[1] = h2;
86
+ }
87
+
88
+ VALUE
89
+ murmur3_x64_128_finish(VALUE self)
90
+ {
91
+ uint8_t digest[16];
92
+ uint64_t out[2];
93
+
94
+ _murmur_finish128(self, out, murmur_hash_process3_x64_128);
95
+ assign_by_endian_128(digest, out);
96
+ return rb_str_new((const char*) digest, 16);
97
+ }
98
+
99
+ VALUE
100
+ murmur3_x64_128_s_digest(int argc, VALUE *argv, VALUE klass)
101
+ {
102
+ uint8_t digest[16];
103
+ uint64_t out[2];
104
+
105
+ _murmur_s_digest128(argc, argv, klass, (void*)out, murmur_hash_process3_x64_128);
106
+ assign_by_endian_128(digest, out);
107
+ return rb_str_new((const char*) digest, 16);
108
+ }
109
+
110
+ VALUE
111
+ murmur3_x64_128_s_rawdigest(int argc, VALUE *argv, VALUE klass)
112
+ {
113
+ uint64_t out[2];
114
+
115
+ _murmur_s_digest128(argc, argv, klass, (void*)out, murmur_hash_process3_x64_128);
116
+ return rb_assoc_new(ULL2NUM(out[0]), ULL2NUM(out[1]));
117
+ }
@@ -0,0 +1,141 @@
1
+ /*
2
+ * MurmurHash3_x86_128 (C) Austin Appleby
3
+ */
4
+
5
+ #include "init.h"
6
+
7
+ void
8
+ murmur_hash_process3_x86_128(const char * key, uint32_t len, uint32_t seed, void *out)
9
+ {
10
+ const uint8_t * data = (const uint8_t*)key;
11
+ const int nblocks = len / 16;
12
+
13
+ uint32_t h1 = seed;
14
+ uint32_t h2 = seed;
15
+ uint32_t h3 = seed;
16
+ uint32_t h4 = seed;
17
+
18
+ const uint32_t c1 = 0x239b961b;
19
+ const uint32_t c2 = 0xab0e9789;
20
+ const uint32_t c3 = 0x38b34ae5;
21
+ const uint32_t c4 = 0xa1e38b93;
22
+
23
+ int i;
24
+
25
+ //----------
26
+ // body
27
+
28
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
29
+
30
+ for(i = -nblocks; i; i++)
31
+ {
32
+ uint32_t k1 = getblock32(blocks,i*4+0);
33
+ uint32_t k2 = getblock32(blocks,i*4+1);
34
+ uint32_t k3 = getblock32(blocks,i*4+2);
35
+ uint32_t k4 = getblock32(blocks,i*4+3);
36
+
37
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
38
+
39
+ h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
40
+
41
+ k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
42
+
43
+ h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
44
+
45
+ k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
46
+
47
+ h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
48
+
49
+ k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
50
+
51
+ h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
52
+ }
53
+
54
+ //----------
55
+ // tail
56
+
57
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
58
+
59
+ uint32_t k1 = 0;
60
+ uint32_t k2 = 0;
61
+ uint32_t k3 = 0;
62
+ uint32_t k4 = 0;
63
+
64
+ switch(len & 15)
65
+ {
66
+ case 15: k4 ^= tail[14] << 16;
67
+ case 14: k4 ^= tail[13] << 8;
68
+ case 13: k4 ^= tail[12] << 0;
69
+ k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
70
+
71
+ case 12: k3 ^= tail[11] << 24;
72
+ case 11: k3 ^= tail[10] << 16;
73
+ case 10: k3 ^= tail[ 9] << 8;
74
+ case 9: k3 ^= tail[ 8] << 0;
75
+ k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
76
+
77
+ case 8: k2 ^= tail[ 7] << 24;
78
+ case 7: k2 ^= tail[ 6] << 16;
79
+ case 6: k2 ^= tail[ 5] << 8;
80
+ case 5: k2 ^= tail[ 4] << 0;
81
+ k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
82
+
83
+ case 4: k1 ^= tail[ 3] << 24;
84
+ case 3: k1 ^= tail[ 2] << 16;
85
+ case 2: k1 ^= tail[ 1] << 8;
86
+ case 1: k1 ^= tail[ 0] << 0;
87
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
88
+ }
89
+
90
+ //----------
91
+ // finalization
92
+
93
+ h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
94
+
95
+ h1 += h2; h1 += h3; h1 += h4;
96
+ h2 += h1; h3 += h1; h4 += h1;
97
+
98
+ h1 = fmix32(h1);
99
+ h2 = fmix32(h2);
100
+ h3 = fmix32(h3);
101
+ h4 = fmix32(h4);
102
+
103
+ h1 += h2; h1 += h3; h1 += h4;
104
+ h2 += h1; h3 += h1; h4 += h1;
105
+
106
+ ((uint32_t*)out)[0] = h1;
107
+ ((uint32_t*)out)[1] = h2;
108
+ ((uint32_t*)out)[2] = h3;
109
+ ((uint32_t*)out)[3] = h4;
110
+ }
111
+
112
+ VALUE
113
+ murmur3_x86_128_finish(VALUE self)
114
+ {
115
+ uint8_t digest[16];
116
+ uint32_t out[4];
117
+
118
+ _murmur_finish128(self, out, murmur_hash_process3_x86_128);
119
+ assign_by_endian_128(digest, out);
120
+ return rb_str_new((const char*) digest, 16);
121
+ }
122
+
123
+ VALUE
124
+ murmur3_x86_128_s_digest(int argc, VALUE *argv, VALUE klass)
125
+ {
126
+ uint8_t digest[16];
127
+ uint32_t out[4];
128
+
129
+ _murmur_s_digest128(argc, argv, klass, out, murmur_hash_process3_x86_128);
130
+ assign_by_endian_128(digest, out);
131
+ return rb_str_new((const char*) digest, 16);
132
+ }
133
+
134
+ VALUE
135
+ murmur3_x86_128_s_rawdigest(int argc, VALUE *argv, VALUE klass)
136
+ {
137
+ uint64_t out[2];
138
+
139
+ _murmur_s_digest128(argc, argv, klass, (void*)out, murmur_hash_process3_x86_128);
140
+ return rb_assoc_new(ULL2NUM(out[0]), ULL2NUM(out[1]));
141
+ }