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 +4 -4
- data/README.md +16 -0
- data/Rakefile +11 -1
- data/digest-murmurhash.gemspec +3 -3
- data/ext/digest/murmurhash/extconf.rb +1 -2
- data/ext/digest/murmurhash/murmurhash.c +253 -0
- data/ext/digest/murmurhash/murmurhash.h +52 -35
- data/ext/digest/murmurhash/murmurhash1.c +18 -54
- data/ext/digest/murmurhash/murmurhash2.c +17 -56
- data/ext/digest/murmurhash/murmurhash2a.c +18 -42
- data/ext/digest/murmurhash/murmurhash64a.c +87 -0
- data/ext/digest/murmurhash/murmurhash64a.h +13 -0
- data/ext/digest/murmurhash/murmurhash64b.c +93 -0
- data/ext/digest/murmurhash/murmurhash64b.h +13 -0
- data/ext/digest/murmurhash/murmurhash_aligned2.c +87 -0
- data/ext/digest/murmurhash/murmurhash_aligned2.h +13 -0
- data/ext/digest/murmurhash/murmurhash_neutral2.c +87 -0
- data/ext/digest/murmurhash/murmurhash_neutral2.h +13 -0
- data/lib/digest/murmurhash/version.rb +1 -1
- data/spec/bench.rb +21 -31
- data/spec/digest_spec.rb +54 -34
- data/spec/exception_spec.rb +19 -4
- data/spec/mem_spec.rb +3 -6
- data/spec/spec_helper.rb +21 -0
- metadata +15 -7
- data/ext/digest/murmurhash/init.c +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ae0e93d61ad1118ff16e6a8ee49e2624bfe93c6
|
4
|
+
data.tar.gz: 221199ad7ef8c94e0eba38d57ec6f0387652e051
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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]
|
data/digest-murmurhash.gemspec
CHANGED
@@ -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::
|
12
|
-
spec.summary = %q{Digest::
|
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.
|
26
|
+
spec.add_development_dependency "rake-compiler", ["~> 0.8.3"]
|
27
27
|
end
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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
|
-
|
35
|
+
murmur1(r);
|
40
36
|
}
|
41
37
|
|
42
|
-
|
43
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
80
|
-
|
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
|
-
|
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
|
}
|