digest-murmurhash 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83fe0d0927d2638319d39e938350a0a2211e0b8c
4
- data.tar.gz: 53c869f210dc4225fa7aa011d36bce3c1c63e519
3
+ metadata.gz: 3ae0e93d61ad1118ff16e6a8ee49e2624bfe93c6
4
+ data.tar.gz: 221199ad7ef8c94e0eba38d57ec6f0387652e051
5
5
  SHA512:
6
- metadata.gz: 59bd8b9afbcb440d8b21489c7c573f259bc73301eaa457e5f1f2cb16308d3ce615813d39ea33003c36434a04c7a4b756f0bbc5bbfbab6d0302f34c23de987726
7
- data.tar.gz: 1657035e9d32261c7d2677403e568a93bd52210a38c99436fb0bd4086d5e51be9d6715f9631c8e8f17ddd5f21065cfe578f023500bbab9a47b9dc2bb9cb9d8e9
6
+ metadata.gz: 1b4b91306a2c297fb8809037693c9ec30ca87352bc047dcad25b099513183e4534b0b260104133ea94054c129eccf5192604331b493e5076361b8c3e104ca610
7
+ data.tar.gz: 58bad31ff82316ca28e66a37dd0709f08bbb59e7df2839f78b80ca1dee00799ee925a3e8f25dab272d1c5d893708a017ae2d8d882db5029aca73b09f475e82fa
data/README.md CHANGED
@@ -10,6 +10,14 @@
10
10
 
11
11
  **Digest::MurmurHash2A** use algorithm MurmurHash2A(32-bit).
12
12
 
13
+ **Digest::MurmurHash64A** use algorithm MurmurHash64A(64-bit).
14
+
15
+ **Digest::MurmurHash64B** use algorithm MurmurHash64B(64-bit).
16
+
17
+ **Digest::MurmurHashNeutral2** use algorithm MurmurHashNeutral2(32-bit).
18
+
19
+ **Digest::MurmurHashAligned2** use algorithm MurmurHashAligned2(32-bit).
20
+
13
21
  (**Digest::MurmurHash** exist to write only version number)
14
22
 
15
23
  All classes compliance Digest API of Ruby.
@@ -40,6 +48,14 @@ p Digest::MurmurHash2.file("./LICENSE.txt").hexdigest #=> '78678326'
40
48
 
41
49
  **Digest::MurmurHash2A** < Digest::StringBuffer
42
50
 
51
+ **Digest::MurmurHash64A** < Digest::StringBuffer
52
+
53
+ **Digest::MurmurHash64B** < Digest::StringBuffer
54
+
55
+ **Digest::MurmurHashNeutral2** < Digest::StringBuffer
56
+
57
+ **Digest::MurmurHashAligned2** < Digest::StringBuffer
58
+
43
59
  ## Installation
44
60
 
45
61
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -17,5 +17,15 @@ Rake::ExtensionTask.new('murmurhash', spec) do |ext|
17
17
  ext.lib_dir = 'lib/digest/murmurhash'
18
18
  end
19
19
 
20
+ require 'digest/murmurhash/version'
21
+ desc "gem reinstall v#{Digest::MurmurHash::VERSION}"
22
+ task :reinstall do |t|
23
+ system "gem uninstall murmurhash"
24
+ system "rake clean"
25
+ system "bundle exec rake"
26
+ system "rake install"
27
+ system "irb -rdigest/murmurhash"
28
+ end
29
+
20
30
 
21
- task :default => [:spec]
31
+ task :default => [:spec, :build]
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Digest::MurmurHash::VERSION
9
9
  spec.author = "ksss"
10
10
  spec.email = "co000ri@gmail.com"
11
- spec.description = %q{Digest::MurmurHash1 is a class of use algorithm MurmurHash1(32-bit) desiged by Austin Appleby.}
12
- spec.summary = %q{Digest::MurmurHash1 is a class of use algorithm MurmurHash1(32-bit) desiged by Austin Appleby.}
11
+ spec.description = %q{Digest::MurmurHash is class collections of use algorithm MurmurHash desiged by Austin Appleby.}
12
+ spec.summary = %q{Digest::MurmurHash is class collections of use algorithm MurmurHash desiged by Austin Appleby.}
13
13
  spec.homepage = ""
14
14
  spec.license = "MIT"
15
15
 
@@ -23,5 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.3"
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "rspec", ['~> 2.11']
26
- spec.add_development_dependency "rake-compiler", ["~> 0.9.2"]
26
+ spec.add_development_dependency "rake-compiler", ["~> 0.8.3"]
27
27
  end
@@ -1,7 +1,6 @@
1
1
  require 'mkmf'
2
2
 
3
- have_header('ruby/digest.h')
4
-
5
3
  $preload = %w[digest]
4
+ $CFLAGS << " -Wall"
6
5
 
7
6
  create_makefile('digest/murmurhash/murmurhash')
@@ -0,0 +1,253 @@
1
+ #include "murmurhash.h"
2
+ #include "murmurhash1.h"
3
+ #include "murmurhash2.h"
4
+ #include "murmurhash2a.h"
5
+ #include "murmurhash64a.h"
6
+ #include "murmurhash64b.h"
7
+ #include "murmurhash_neutral2.h"
8
+ #include "murmurhash_aligned2.h"
9
+
10
+ VALUE cDigest_MurmurHash1,
11
+ cDigest_MurmurHash2,
12
+ cDigest_MurmurHash2A,
13
+ cDigest_MurmurHash64A,
14
+ cDigest_MurmurHash64B,
15
+ cDigest_MurmurHashNeutral2,
16
+ cDigest_MurmurHashAligned2;
17
+ ID id_seed,
18
+ id_DEFAULT_SEED;
19
+
20
+ VALUE
21
+ murmur_seed_get32(VALUE self)
22
+ {
23
+ if (!rb_ivar_defined(self, id_seed)) {
24
+ rb_ivar_set(self, id_seed, rb_usascii_str_new(DEFAULT_SEED, 4));
25
+ }
26
+ return rb_ivar_get(self, id_seed);
27
+ }
28
+
29
+ VALUE
30
+ murmur_seed_set32(VALUE self, VALUE obj)
31
+ {
32
+ StringValue(obj);
33
+ if (RSTRING_LEN(obj) != 4) {
34
+ rb_raise(rb_eArgError, "seed string should 64 bit chars");
35
+ }
36
+ return rb_ivar_set(self, id_seed, obj);
37
+ }
38
+
39
+ VALUE
40
+ murmur_seed_get64(VALUE self)
41
+ {
42
+ if (!rb_ivar_defined(self, id_seed)) {
43
+ rb_ivar_set(self, id_seed, rb_usascii_str_new(DEFAULT_SEED, 8));
44
+ }
45
+ return rb_ivar_get(self, id_seed);
46
+ }
47
+
48
+ VALUE
49
+ murmur_seed_set64(VALUE self, VALUE obj)
50
+ {
51
+ StringValue(obj);
52
+ if (RSTRING_LEN(obj) != 8) {
53
+ rb_raise(rb_eArgError, "seed string should 64 bit chars");
54
+ }
55
+ return rb_ivar_set(self, id_seed, obj);
56
+ }
57
+
58
+ uint32_t
59
+ _murmur_finish32(VALUE self, uint32_t (*process)(const char *, uint32_t, uint32_t))
60
+ {
61
+ const char *seed = RSTRING_PTR(murmur_seed_get32(self));
62
+ MURMURHASH(self, ptr);
63
+ return process(ptr->buffer, ptr->p - ptr->buffer, *(uint32_t*)seed);
64
+ }
65
+
66
+ uint64_t
67
+ _murmur_finish64(VALUE self, uint64_t (*process)(const char *, uint32_t, uint64_t))
68
+ {
69
+ const char *seed = RSTRING_PTR(murmur_seed_get64(self));
70
+ MURMURHASH(self, ptr);
71
+ return process(ptr->buffer, ptr->p - ptr->buffer, *(uint64_t*)seed);
72
+ }
73
+
74
+
75
+ uint32_t
76
+ _murmur_s_digest32(int argc, VALUE *argv, VALUE klass, uint32_t (*process)(const char *, uint32_t, uint32_t))
77
+ {
78
+ VALUE str;
79
+ const char *seed;
80
+
81
+ if (argc < 1)
82
+ rb_raise(rb_eArgError, "no data given");
83
+
84
+ str = *argv;
85
+
86
+ StringValue(str);
87
+
88
+ if (1 < argc) {
89
+ StringValue(argv[1]);
90
+ if (RSTRING_LEN(argv[1]) != 4) {
91
+ rb_raise(rb_eArgError, "seed string should 32 bit chars");
92
+ }
93
+ seed = RSTRING_PTR(argv[1]);
94
+ } else {
95
+ seed = RSTRING_PTR(rb_const_get(klass, id_DEFAULT_SEED));
96
+ }
97
+
98
+ return process(RSTRING_PTR(str), RSTRING_LEN(str), *(uint32_t*)seed);
99
+ }
100
+
101
+ uint64_t
102
+ _murmur_s_digest64(int argc, VALUE *argv, VALUE klass, uint64_t (*process)(const char *, uint32_t, uint64_t))
103
+ {
104
+ VALUE str;
105
+ const char *seed;
106
+
107
+ if (argc < 1)
108
+ rb_raise(rb_eArgError, "no data given");
109
+
110
+ str = *argv;
111
+
112
+ StringValue(str);
113
+
114
+ if (1 < argc) {
115
+ StringValue(argv[1]);
116
+ if (RSTRING_LEN(argv[1]) != 8) {
117
+ rb_raise(rb_eArgError, "seed string should 64 bit chars");
118
+ }
119
+ seed = RSTRING_PTR(argv[1]);
120
+ } else {
121
+ seed = RSTRING_PTR(rb_const_get(klass, id_DEFAULT_SEED));
122
+ }
123
+
124
+ return process(RSTRING_PTR(str), RSTRING_LEN(str), *(uint64_t*)seed);
125
+ }
126
+
127
+ /*
128
+ * from https://github.com/ruby/ruby/blob/trunk/ext/digest/digest.c
129
+ * Copyright (C) 1995-2001 Yukihiro Matsumoto
130
+ * Copyright (C) 2001-2006 Akinori MUSHA
131
+ */
132
+ VALUE
133
+ hexencode_str_new(VALUE str_digest)
134
+ {
135
+ char *digest;
136
+ size_t digest_len;
137
+ size_t i;
138
+ VALUE str;
139
+ char *p;
140
+ static const char hex[] = {
141
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
142
+ 'a', 'b', 'c', 'd', 'e', 'f'
143
+ };
144
+
145
+ StringValue(str_digest);
146
+ digest = RSTRING_PTR(str_digest);
147
+ digest_len = RSTRING_LEN(str_digest);
148
+
149
+ if (LONG_MAX / 2 < digest_len) {
150
+ rb_raise(rb_eRuntimeError, "digest string too long");
151
+ }
152
+
153
+ str = rb_usascii_str_new(0, digest_len * 2);
154
+
155
+ for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
156
+ unsigned char byte = digest[i];
157
+
158
+ p[i + i] = hex[byte >> 4];
159
+ p[i + i + 1] = hex[byte & 0x0f];
160
+ }
161
+
162
+ return str;
163
+ }
164
+
165
+ void
166
+ Init_murmurhash(void)
167
+ {
168
+ VALUE mDigest, cDigest_StringBuffer;
169
+
170
+ id_seed = rb_intern("seed");
171
+ id_DEFAULT_SEED = rb_intern("DEFAULT_SEED");
172
+
173
+ /* Digest::MurmurHash is require that Digest::StringBuffer */
174
+ mDigest = rb_path2class("Digest");
175
+ cDigest_StringBuffer = rb_path2class("Digest::StringBuffer");
176
+
177
+ /* class Digest::MurmurHash1 < Digest::StringBuffer */
178
+ cDigest_MurmurHash1 = rb_define_class_under(mDigest, "MurmurHash1", cDigest_StringBuffer);
179
+ rb_define_const(cDigest_MurmurHash1, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 4));
180
+ rb_define_singleton_method(cDigest_MurmurHash1, "digest", murmur1_s_digest, -1);
181
+ rb_define_singleton_method(cDigest_MurmurHash1, "hexdigest", murmur1_s_hexdigest, -1);
182
+ rb_define_singleton_method(cDigest_MurmurHash1, "rawdigest", murmur1_s_rawdigest, -1);
183
+ rb_define_private_method(cDigest_MurmurHash1, "finish", murmur1_finish, 0);
184
+ rb_define_method(cDigest_MurmurHash1, "to_i", murmur1_to_i, 0);
185
+ rb_define_method(cDigest_MurmurHash1, "seed", murmur_seed_get32, 0);
186
+ rb_define_method(cDigest_MurmurHash1, "seed=", murmur_seed_set32, 1);
187
+
188
+ /* class Digest::MurmurHash2 < Digest::StringBuffer */
189
+ cDigest_MurmurHash2 = rb_define_class_under(mDigest, "MurmurHash2", cDigest_StringBuffer);
190
+ rb_define_const(cDigest_MurmurHash2, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 4));
191
+ rb_define_singleton_method(cDigest_MurmurHash2, "digest", murmur2_s_digest, -1);
192
+ rb_define_singleton_method(cDigest_MurmurHash2, "hexdigest", murmur2_s_hexdigest, -1);
193
+ rb_define_singleton_method(cDigest_MurmurHash2, "rawdigest", murmur2_s_rawdigest, -1);
194
+ rb_define_private_method(cDigest_MurmurHash2, "finish", murmur2_finish, 0);
195
+ rb_define_method(cDigest_MurmurHash2, "to_i", murmur2_to_i, 0);
196
+ rb_define_method(cDigest_MurmurHash2, "seed", murmur_seed_get32, 0);
197
+ rb_define_method(cDigest_MurmurHash2, "seed=", murmur_seed_set32, 1);
198
+
199
+ /* class Digest::MurmurHash2A < Digest::StringBuffer */
200
+ cDigest_MurmurHash2A = rb_define_class_under(mDigest, "MurmurHash2A", cDigest_StringBuffer);
201
+ rb_define_const(cDigest_MurmurHash2A, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 4));
202
+ rb_define_singleton_method(cDigest_MurmurHash2A, "digest", murmur2a_s_digest, -1);
203
+ rb_define_singleton_method(cDigest_MurmurHash2A, "hexdigest", murmur2a_s_hexdigest, -1);
204
+ rb_define_singleton_method(cDigest_MurmurHash2A, "rawdigest", murmur2a_s_rawdigest, -1);
205
+ rb_define_private_method(cDigest_MurmurHash2A, "finish", murmur2a_finish, 0);
206
+ rb_define_method(cDigest_MurmurHash2A, "to_i", murmur2a_to_i, 0);
207
+ rb_define_method(cDigest_MurmurHash2A, "seed", murmur_seed_get32, 0);
208
+ rb_define_method(cDigest_MurmurHash2A, "seed=", murmur_seed_set32, 1);
209
+
210
+ /* class Digest::MurmurHash64A < Digest::StringBuffer */
211
+ cDigest_MurmurHash64A = rb_define_class_under(mDigest, "MurmurHash64A", cDigest_StringBuffer);
212
+ rb_define_const(cDigest_MurmurHash64A, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 8));
213
+ rb_define_singleton_method(cDigest_MurmurHash64A, "digest", murmur64a_s_digest, -1);
214
+ rb_define_singleton_method(cDigest_MurmurHash64A, "hexdigest", murmur64a_s_hexdigest, -1);
215
+ rb_define_singleton_method(cDigest_MurmurHash64A, "rawdigest", murmur64a_s_rawdigest, -1);
216
+ rb_define_private_method(cDigest_MurmurHash64A, "finish", murmur64a_finish, 0);
217
+ rb_define_method(cDigest_MurmurHash64A, "to_i", murmur64a_to_i, 0);
218
+ rb_define_method(cDigest_MurmurHash64A, "seed", murmur_seed_get64, 0);
219
+ rb_define_method(cDigest_MurmurHash64A, "seed=", murmur_seed_set64, 1);
220
+
221
+ /* class Digest::MurmurHash64B < Digest::StringBuffer */
222
+ cDigest_MurmurHash64B = rb_define_class_under(mDigest, "MurmurHash64B", cDigest_StringBuffer);
223
+ rb_define_const(cDigest_MurmurHash64B, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 8));
224
+ rb_define_singleton_method(cDigest_MurmurHash64B, "digest", murmur64b_s_digest, -1);
225
+ rb_define_singleton_method(cDigest_MurmurHash64B, "hexdigest", murmur64b_s_hexdigest, -1);
226
+ rb_define_singleton_method(cDigest_MurmurHash64B, "rawdigest", murmur64b_s_rawdigest, -1);
227
+ rb_define_private_method(cDigest_MurmurHash64B, "finish", murmur64b_finish, 0);
228
+ rb_define_method(cDigest_MurmurHash64B, "to_i", murmur64b_to_i, 0);
229
+ rb_define_method(cDigest_MurmurHash64B, "seed", murmur_seed_get64, 0);
230
+ rb_define_method(cDigest_MurmurHash64B, "seed=", murmur_seed_set64, 1);
231
+
232
+ /* class Digest::MurmurHashNeutral2 < Digest::StringBuffer */
233
+ cDigest_MurmurHashNeutral2 = rb_define_class_under(mDigest, "MurmurHashNeutral2", cDigest_StringBuffer);
234
+ rb_define_const(cDigest_MurmurHashNeutral2, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 4));
235
+ rb_define_singleton_method(cDigest_MurmurHashNeutral2, "digest", murmur_neutral2_s_digest, -1);
236
+ rb_define_singleton_method(cDigest_MurmurHashNeutral2, "hexdigest", murmur_neutral2_s_hexdigest, -1);
237
+ rb_define_singleton_method(cDigest_MurmurHashNeutral2, "rawdigest", murmur_neutral2_s_rawdigest, -1);
238
+ rb_define_private_method(cDigest_MurmurHashNeutral2, "finish", murmur_neutral2_finish, 0);
239
+ rb_define_method(cDigest_MurmurHashNeutral2, "to_i", murmur_neutral2_to_i, 0);
240
+ rb_define_method(cDigest_MurmurHashNeutral2, "seed", murmur_seed_get32, 0);
241
+ rb_define_method(cDigest_MurmurHashNeutral2, "seed=", murmur_seed_set32, 1);
242
+
243
+ /* class Digest::MurmurHashAligned2 < Digest::StringBuffer */
244
+ cDigest_MurmurHashAligned2 = rb_define_class_under(mDigest, "MurmurHashAligned2", cDigest_StringBuffer);
245
+ rb_define_const(cDigest_MurmurHashAligned2, "DEFAULT_SEED", rb_usascii_str_new(DEFAULT_SEED, 4));
246
+ rb_define_singleton_method(cDigest_MurmurHashAligned2, "digest", murmur_aligned2_s_digest, -1);
247
+ rb_define_singleton_method(cDigest_MurmurHashAligned2, "hexdigest", murmur_aligned2_s_hexdigest, -1);
248
+ rb_define_singleton_method(cDigest_MurmurHashAligned2, "rawdigest", murmur_aligned2_s_rawdigest, -1);
249
+ rb_define_private_method(cDigest_MurmurHashAligned2, "finish", murmur_aligned2_finish, 0);
250
+ rb_define_method(cDigest_MurmurHashAligned2, "to_i", murmur_aligned2_to_i, 0);
251
+ rb_define_method(cDigest_MurmurHashAligned2, "seed", murmur_seed_get32, 0);
252
+ rb_define_method(cDigest_MurmurHashAligned2, "seed=", murmur_seed_set32, 1);
253
+ }
@@ -3,7 +3,51 @@
3
3
 
4
4
  #include "ruby.h"
5
5
 
6
+ #if defined(_MSC_VER)
7
+ # define BIG_CONSTANT(x) (x)
8
+ // Other compilers
9
+ #else // defined(_MSC_VER)
10
+ # define BIG_CONSTANT(x) (x##LLU)
11
+ #endif // !defined(_MSC_VER)
12
+
13
+ #define DEFAULT_SEED "\x00\x00\x00\x00\x00\x00\x00\x00"
6
14
  #define MURMURHASH_MAGIC 0x5bd1e995
15
+ #define MURMURHASH_MAGIC64A BIG_CONSTANT(0xc6a4a7935bd1e995)
16
+ #if INTEGER_PACK_LITTLE_ENDIAN
17
+ # define ASSINE_BY_ENDIAN_32(digest, h) do { \
18
+ (digest)[3] = (h) >> 24; \
19
+ (digest)[2] = (h) >> 16; \
20
+ (digest)[1] = (h) >> 8; \
21
+ (digest)[0] = (h); \
22
+ } while (0)
23
+ # define ASSINE_BY_ENDIAN_64(digest, h) do { \
24
+ (digest)[7] = (h) >> 56; \
25
+ (digest)[6] = (h) >> 48; \
26
+ (digest)[5] = (h) >> 40; \
27
+ (digest)[4] = (h) >> 32; \
28
+ (digest)[3] = (h) >> 24; \
29
+ (digest)[2] = (h) >> 16; \
30
+ (digest)[1] = (h) >> 8; \
31
+ (digest)[0] = (h); \
32
+ } while (0)
33
+ #else
34
+ # define ASSINE_BY_ENDIAN_32(digest, h) do { \
35
+ (digest)[0] = (h) >> 24; \
36
+ (digest)[1] = (h) >> 16; \
37
+ (digest)[2] = (h) >> 8; \
38
+ (digest)[3] = (h); \
39
+ } while (0)
40
+ # define ASSINE_BY_ENDIAN_64(digest, h) do { \
41
+ (digest)[0] = (h) >> 56; \
42
+ (digest)[1] = (h) >> 48; \
43
+ (digest)[2] = (h) >> 40; \
44
+ (digest)[3] = (h) >> 32; \
45
+ (digest)[4] = (h) >> 24; \
46
+ (digest)[5] = (h) >> 16; \
47
+ (digest)[6] = (h) >> 8; \
48
+ (digest)[7] = (h); \
49
+ } while (0)
50
+ #endif
7
51
 
8
52
  /* should be same type structure to digest/stringbuffer */
9
53
  typedef struct {
@@ -19,43 +63,16 @@ typedef struct {
19
63
  rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be.'"); \
20
64
  }
21
65
 
22
- /*
23
- * from https://github.com/ruby/ruby/blob/trunk/ext/digest/digest.c
24
- * Copyright (C) 1995-2001 Yukihiro Matsumoto
25
- * Copyright (C) 2001-2006 Akinori MUSHA
26
- */
27
- static VALUE
28
- hexencode_str_new(VALUE str_digest)
29
- {
30
- char *digest;
31
- size_t digest_len;
32
- size_t i;
33
- VALUE str;
34
- char *p;
35
- static const char hex[] = {
36
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
37
- 'a', 'b', 'c', 'd', 'e', 'f'
38
- };
39
-
40
- StringValue(str_digest);
41
- digest = RSTRING_PTR(str_digest);
42
- digest_len = RSTRING_LEN(str_digest);
43
-
44
- if (LONG_MAX / 2 < digest_len) {
45
- rb_raise(rb_eRuntimeError, "digest string too long");
46
- }
47
-
48
- str = rb_usascii_str_new(0, digest_len * 2);
66
+ VALUE murmur_seed_get32(VALUE self);
67
+ VALUE murmur_seed_get64(VALUE self);
49
68
 
50
- for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) {
51
- unsigned char byte = digest[i];
52
-
53
- p[i + i] = hex[byte >> 4];
54
- p[i + i + 1] = hex[byte & 0x0f];
55
- }
69
+ extern ID id_seed, id_DEFAULT_SEED;
56
70
 
57
- return str;
58
- }
71
+ uint32_t _murmur_finish32(VALUE self, uint32_t (*process)(const char *, uint32_t, uint32_t));
72
+ uint64_t _murmur_finish64(VALUE self, uint64_t (*process)(const char *, uint32_t, uint64_t));
73
+ uint32_t _murmur_s_digest32(int argc, VALUE *argv, VALUE klass, uint32_t (*process)(const char *, uint32_t, uint32_t));
74
+ uint64_t _murmur_s_digest64(int argc, VALUE *argv, VALUE klass, uint64_t (*process)(const char *, uint32_t, uint64_t));
75
+ VALUE hexencode_str_new(VALUE str_digest);
59
76
 
60
77
  #endif /* ifndef MURMURHASH_INCLUDED */
61
78
 
@@ -4,27 +4,23 @@
4
4
 
5
5
  #include "murmurhash1.h"
6
6
 
7
- static inline size_t
8
- murmur1(uint32_t h, const uint8_t r)
9
- {
10
- const uint32_t m = MURMURHASH_MAGIC;
11
- h *= m;
12
- h ^= h >> r;
13
- return h;
14
- }
7
+ #define murmur1(r) do { \
8
+ h *= m; \
9
+ h ^= h >> r; \
10
+ } while(0)
15
11
 
16
12
  static uint32_t
17
- murmur_hash_process1(const char *data, uint32_t length)
13
+ murmur_hash_process1(const char *data, uint32_t length, uint32_t seed)
18
14
  {
19
15
  const uint32_t m = MURMURHASH_MAGIC;
20
16
  const uint8_t r = 16;
21
17
  uint32_t h;
22
18
 
23
- h = length * m;
19
+ h = seed ^ (length * m);
24
20
 
25
21
  while (4 <= length) {
26
22
  h += *(uint32_t*)data;
27
- h = murmur1(h, r);
23
+ murmur1(r);
28
24
  data += 4;
29
25
  length -= 4;
30
26
  }
@@ -36,11 +32,11 @@ murmur_hash_process1(const char *data, uint32_t length)
36
32
  h += data[1] << 8;
37
33
  case 1:
38
34
  h += data[0];
39
- h = murmur1(h, r);
35
+ murmur1(r);
40
36
  }
41
37
 
42
- h = murmur1(h, 10);
43
- h = murmur1(h, 17);
38
+ murmur1(10);
39
+ murmur1(17);
44
40
 
45
41
  return h;
46
42
  }
@@ -48,49 +44,27 @@ murmur_hash_process1(const char *data, uint32_t length)
48
44
  VALUE
49
45
  murmur1_finish(VALUE self)
50
46
  {
51
- uint32_t h;
52
47
  uint8_t digest[4];
53
- MURMURHASH(self, ptr);
54
-
55
- h = murmur_hash_process1(ptr->buffer, ptr->p - ptr->buffer);
56
-
57
- digest[0] = h >> 24;
58
- digest[1] = h >> 16;
59
- digest[2] = h >> 8;
60
- digest[3] = h;
48
+ uint64_t h;
61
49
 
50
+ h = _murmur_finish32(self, murmur_hash_process1);
51
+ ASSINE_BY_ENDIAN_32(digest, h);
62
52
  return rb_str_new((const char*) digest, 4);
63
53
  }
64
54
 
65
55
  VALUE
66
56
  murmur1_to_i(VALUE self)
67
57
  {
68
- MURMURHASH(self, ptr);
69
- return UINT2NUM(murmur_hash_process1(ptr->buffer, ptr->p - ptr->buffer));
58
+ return UINT2NUM(_murmur_finish32(self, murmur_hash_process1));
70
59
  }
71
60
 
72
61
  VALUE
73
62
  murmur1_s_digest(int argc, VALUE *argv, VALUE klass)
74
63
  {
75
- VALUE str;
76
- uint32_t h;
77
64
  uint8_t digest[4];
78
-
79
- if (argc < 1)
80
- rb_raise(rb_eArgError, "no data given");
81
-
82
- str = *argv++;
83
- argc--;
84
-
85
- StringValue(str);
86
-
87
- h = murmur_hash_process1(RSTRING_PTR(str), RSTRING_LEN(str));
88
-
89
- digest[0] = h >> 24;
90
- digest[1] = h >> 16;
91
- digest[2] = h >> 8;
92
- digest[3] = h;
93
-
65
+ uint32_t h;
66
+ h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process1);
67
+ ASSINE_BY_ENDIAN_32(digest, h);
94
68
  return rb_str_new((const char*) digest, 4);
95
69
  }
96
70
 
@@ -103,15 +77,5 @@ murmur1_s_hexdigest(int argc, VALUE *argv, VALUE klass)
103
77
  VALUE
104
78
  murmur1_s_rawdigest(int argc, VALUE *argv, VALUE klass)
105
79
  {
106
- VALUE str;
107
-
108
- if (argc < 1)
109
- rb_raise(rb_eArgError, "no data given");
110
-
111
- str = *argv++;
112
- argc--;
113
-
114
- StringValue(str);
115
-
116
- return UINT2NUM(murmur_hash_process1(RSTRING_PTR(str), RSTRING_LEN(str)));
80
+ return UINT2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process1));
117
81
  }