digest-murmurhash 0.2.3 → 0.3.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: 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
  }