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.
@@ -4,31 +4,24 @@
4
4
 
5
5
  #include "murmurhash2.h"
6
6
 
7
- static inline size_t
8
- murmur2(uint32_t h, uint32_t k, const uint8_t r)
9
- {
10
- const uint32_t m = MURMURHASH_MAGIC;
11
- k *= m;
12
- k ^= k >> r;
13
- k *= m;
14
-
15
- h *= m;
16
- h ^= k;
17
- return h;
18
- }
19
-
20
7
  static uint32_t
21
- murmur_hash_process2(const char *data, uint32_t length)
8
+ murmur_hash_process2(const char *data, uint32_t length, uint32_t seed)
22
9
  {
23
10
  const uint32_t m = MURMURHASH_MAGIC;
24
11
  const uint8_t r = 24;
25
12
  uint32_t h, k;
26
13
 
27
- h = length * m;
14
+ h = seed ^ length;
28
15
 
29
16
  while (4 <= length) {
30
17
  k = *(uint32_t*)data;
31
- h = murmur2(h, k, r);
18
+ k *= m;
19
+ k ^= k >> r;
20
+ k *= m;
21
+
22
+ h *= m;
23
+ h ^= k;
24
+
32
25
  data += 4;
33
26
  length -= 4;
34
27
  }
@@ -50,49 +43,27 @@ murmur_hash_process2(const char *data, uint32_t length)
50
43
  VALUE
51
44
  murmur2_finish(VALUE self)
52
45
  {
53
- uint32_t h;
54
46
  uint8_t digest[4];
55
- MURMURHASH(self, ptr);
56
-
57
- h = murmur_hash_process2(ptr->buffer, ptr->p - ptr->buffer);
58
-
59
- digest[0] = h >> 24;
60
- digest[1] = h >> 16;
61
- digest[2] = h >> 8;
62
- digest[3] = h;
47
+ uint64_t h;
63
48
 
49
+ h = _murmur_finish32(self, murmur_hash_process2);
50
+ ASSINE_BY_ENDIAN_32(digest, h);
64
51
  return rb_str_new((const char*) digest, 4);
65
52
  }
66
53
 
67
54
  VALUE
68
55
  murmur2_to_i(VALUE self)
69
56
  {
70
- MURMURHASH(self, ptr);
71
- return UINT2NUM(murmur_hash_process2(ptr->buffer, ptr->p - ptr->buffer));
57
+ return ULONG2NUM(_murmur_finish32(self, murmur_hash_process2));
72
58
  }
73
59
 
74
60
  VALUE
75
61
  murmur2_s_digest(int argc, VALUE *argv, VALUE klass)
76
62
  {
77
- VALUE str;
78
- uint32_t h;
79
63
  uint8_t digest[4];
80
-
81
- if (argc < 1)
82
- rb_raise(rb_eArgError, "no data given");
83
-
84
- str = *argv++;
85
- argc--;
86
-
87
- StringValue(str);
88
-
89
- h = murmur_hash_process2(RSTRING_PTR(str), RSTRING_LEN(str));
90
-
91
- digest[0] = h >> 24;
92
- digest[1] = h >> 16;
93
- digest[2] = h >> 8;
94
- digest[3] = h;
95
-
64
+ uint32_t h;
65
+ h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process2);
66
+ ASSINE_BY_ENDIAN_32(digest, h);
96
67
  return rb_str_new((const char*) digest, 4);
97
68
  }
98
69
 
@@ -105,16 +76,6 @@ murmur2_s_hexdigest(int argc, VALUE *argv, VALUE klass)
105
76
  VALUE
106
77
  murmur2_s_rawdigest(int argc, VALUE *argv, VALUE klass)
107
78
  {
108
- VALUE str;
109
-
110
- if (argc < 1)
111
- rb_raise(rb_eArgError, "no data given");
112
-
113
- str = *argv++;
114
- argc--;
115
-
116
- StringValue(str);
117
-
118
- return UINT2NUM(murmur_hash_process2(RSTRING_PTR(str), RSTRING_LEN(str)));
79
+ return ULONG2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process2));
119
80
  }
120
81
 
@@ -7,7 +7,7 @@
7
7
  #define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
8
8
 
9
9
  static uint32_t
10
- murmur_hash_process2a(const void *key, uint32_t length)
10
+ murmur_hash_process2a(const char *key, uint32_t length, uint32_t seed)
11
11
  {
12
12
  const uint32_t m = MURMURHASH_MAGIC;
13
13
  const uint8_t r = 24;
@@ -15,7 +15,7 @@ murmur_hash_process2a(const void *key, uint32_t length)
15
15
  const unsigned char *data = (const unsigned char *) key;
16
16
 
17
17
  l = length;
18
- h = 0 ^ length;
18
+ h = seed;
19
19
 
20
20
  while (4 <= length) {
21
21
  k = *(uint32_t*)data;
@@ -41,52 +41,38 @@ murmur_hash_process2a(const void *key, uint32_t length)
41
41
  return h;
42
42
  }
43
43
 
44
+ static uint32_t
45
+ _murmur2a_finish(VALUE self)
46
+ {
47
+ const char *seed = RSTRING_PTR(murmur_seed_get32(self));
48
+ MURMURHASH(self, ptr);
49
+ return murmur_hash_process2a(ptr->buffer, ptr->p - ptr->buffer, *(uint32_t*)seed);
50
+ }
51
+
44
52
  VALUE
45
53
  murmur2a_finish(VALUE self)
46
54
  {
47
- uint32_t h;
48
55
  uint8_t digest[4];
49
- MURMURHASH(self, ptr);
50
-
51
- h = murmur_hash_process2a(ptr->buffer, ptr->p - ptr->buffer);
52
-
53
- digest[0] = h >> 24;
54
- digest[1] = h >> 16;
55
- digest[2] = h >> 8;
56
- digest[3] = h;
56
+ uint64_t h;
57
57
 
58
+ h = _murmur2a_finish(self);
59
+ ASSINE_BY_ENDIAN_32(digest, h);
58
60
  return rb_str_new((const char*) digest, 4);
59
61
  }
60
62
 
61
63
  VALUE
62
64
  murmur2a_to_i(VALUE self)
63
65
  {
64
- MURMURHASH(self, ptr);
65
- return UINT2NUM(murmur_hash_process2a(ptr->buffer, ptr->p - ptr->buffer));
66
+ return ULONG2NUM(_murmur2a_finish(self));
66
67
  }
67
68
 
68
69
  VALUE
69
70
  murmur2a_s_digest(int argc, VALUE *argv, VALUE klass)
70
71
  {
71
- VALUE str;
72
- uint32_t h;
73
72
  uint8_t digest[4];
74
-
75
- if (argc < 1)
76
- rb_raise(rb_eArgError, "no data given");
77
-
78
- str = *argv++;
79
- argc--;
80
-
81
- StringValue(str);
82
-
83
- h = murmur_hash_process2a(RSTRING_PTR(str), RSTRING_LEN(str));
84
-
85
- digest[0] = h >> 24;
86
- digest[1] = h >> 16;
87
- digest[2] = h >> 8;
88
- digest[3] = h;
89
-
73
+ uint32_t h;
74
+ h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process2a);
75
+ ASSINE_BY_ENDIAN_32(digest, h);
90
76
  return rb_str_new((const char*) digest, 4);
91
77
  }
92
78
 
@@ -99,16 +85,6 @@ murmur2a_s_hexdigest(int argc, VALUE *argv, VALUE klass)
99
85
  VALUE
100
86
  murmur2a_s_rawdigest(int argc, VALUE *argv, VALUE klass)
101
87
  {
102
- VALUE str;
103
-
104
- if (argc < 1)
105
- rb_raise(rb_eArgError, "no data given");
106
-
107
- str = *argv++;
108
- argc--;
109
-
110
- StringValue(str);
111
-
112
- return UINT2NUM(murmur_hash_process2a(RSTRING_PTR(str), RSTRING_LEN(str)));
88
+ return ULL2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process2a));
113
89
  }
114
90
 
@@ -0,0 +1,87 @@
1
+ /*
2
+ * MurmurHash64A (C) Austin Appleby
3
+ */
4
+
5
+ #include "murmurhash64a.h"
6
+
7
+ static uint64_t
8
+ murmur_hash_process64a(const char *key, uint32_t len, uint64_t seed)
9
+ {
10
+ const uint64_t m = MURMURHASH_MAGIC64A;
11
+ const int r = 47;
12
+
13
+ uint64_t h = seed ^ (len * m);
14
+
15
+ const uint64_t * data = (const uint64_t *)key;
16
+ const uint64_t * end = data + (len/8);
17
+
18
+ while(data != end)
19
+ {
20
+ uint64_t k = *data++;
21
+
22
+ k *= m;
23
+ k ^= k >> r;
24
+ k *= m;
25
+
26
+ h ^= k;
27
+ h *= m;
28
+ }
29
+
30
+ const unsigned char * data2 = (const unsigned char*)data;
31
+
32
+ switch(len & 7) {
33
+ case 7: h ^= (uint64_t)((uint64_t)data2[6] << (uint64_t)48);
34
+ case 6: h ^= (uint64_t)((uint64_t)data2[5] << (uint64_t)40);
35
+ case 5: h ^= (uint64_t)((uint64_t)data2[4] << (uint64_t)32);
36
+ case 4: h ^= (uint64_t)((uint64_t)data2[3] << (uint64_t)24);
37
+ case 3: h ^= (uint64_t)((uint64_t)data2[2] << (uint64_t)16);
38
+ case 2: h ^= (uint64_t)((uint64_t)data2[1] << (uint64_t)8 );
39
+ case 1: h ^= (uint64_t)((uint64_t)data2[0] );
40
+ h *= m;
41
+ };
42
+
43
+ h ^= h >> r;
44
+ h *= m;
45
+ h ^= h >> r;
46
+
47
+ return h;
48
+ }
49
+
50
+ VALUE
51
+ murmur64a_finish(VALUE self)
52
+ {
53
+ uint8_t digest[8];
54
+ uint64_t h;
55
+
56
+ h = _murmur_finish64(self, murmur_hash_process64a);
57
+ ASSINE_BY_ENDIAN_64(digest, h);
58
+ return rb_str_new((const char*) digest, 8);
59
+ }
60
+
61
+ VALUE
62
+ murmur64a_to_i(VALUE self)
63
+ {
64
+ return ULL2NUM(_murmur_finish64(self, murmur_hash_process64a));
65
+ }
66
+
67
+ VALUE
68
+ murmur64a_s_digest(int argc, VALUE *argv, VALUE klass)
69
+ {
70
+ uint8_t digest[8];
71
+ uint64_t h;
72
+ h = _murmur_s_digest64(argc, argv, klass, murmur_hash_process64a);
73
+ ASSINE_BY_ENDIAN_64(digest, h);
74
+ return rb_str_new((const char*) digest, 8);
75
+ }
76
+
77
+ VALUE
78
+ murmur64a_s_hexdigest(int argc, VALUE *argv, VALUE klass)
79
+ {
80
+ return hexencode_str_new(murmur64a_s_digest(argc, argv, klass));
81
+ }
82
+
83
+ VALUE
84
+ murmur64a_s_rawdigest(int argc, VALUE *argv, VALUE klass)
85
+ {
86
+ return ULL2NUM(_murmur_s_digest64(argc, argv, klass, murmur_hash_process64a));
87
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef MURMURHASH64A_INCLUDED
2
+ # define MURMURHASH64A_INCLUDED
3
+
4
+ #include "murmurhash.h"
5
+
6
+ VALUE murmur64a_finish(VALUE self);
7
+ VALUE murmur64a_to_i(VALUE self);
8
+ VALUE murmur64a_s_digest(int argc, VALUE *argv, VALUE klass);
9
+ VALUE murmur64a_s_hexdigest(int argc, VALUE *argv, VALUE klass);
10
+ VALUE murmur64a_s_rawdigest(int argc, VALUE *argv, VALUE klass);
11
+
12
+ #endif /* ifndef MURMURHASH64A_INCLUDED */
13
+
@@ -0,0 +1,93 @@
1
+ /*
2
+ * MurmurHash64B (C) Austin Appleby
3
+ */
4
+
5
+ #include "murmurhash64b.h"
6
+
7
+ uint64_t
8
+ murmur_hash_process64b(const char * key, uint32_t len, uint64_t seed)
9
+ {
10
+ const uint32_t m = MURMURHASH_MAGIC;
11
+ const int r = 24;
12
+
13
+ uint32_t h1 = (uint32_t)(seed) ^ len;
14
+ uint32_t h2 = (uint32_t)(seed >> 32);
15
+
16
+ const uint32_t * data = (const uint32_t *)key;
17
+
18
+ while(len >= 8) {
19
+ uint32_t k1 = *data++;
20
+ k1 *= m; k1 ^= k1 >> r; k1 *= m;
21
+ h1 *= m; h1 ^= k1;
22
+ len -= 4;
23
+
24
+ uint32_t k2 = *data++;
25
+ k2 *= m; k2 ^= k2 >> r; k2 *= m;
26
+ h2 *= m; h2 ^= k2;
27
+ len -= 4;
28
+ }
29
+
30
+ if(len >= 4) {
31
+ uint32_t k1 = *data++;
32
+ k1 *= m; k1 ^= k1 >> r; k1 *= m;
33
+ h1 *= m; h1 ^= k1;
34
+ len -= 4;
35
+ }
36
+
37
+ switch(len) {
38
+ case 3: h2 ^= ((unsigned char*)data)[2] << 16;
39
+ case 2: h2 ^= ((unsigned char*)data)[1] << 8;
40
+ case 1: h2 ^= ((unsigned char*)data)[0];
41
+ h2 *= m;
42
+ };
43
+
44
+ h1 ^= h2 >> 18; h1 *= m;
45
+ h2 ^= h1 >> 22; h2 *= m;
46
+ h1 ^= h2 >> 17; h1 *= m;
47
+ h2 ^= h1 >> 19; h2 *= m;
48
+
49
+ uint64_t h = h1;
50
+
51
+ h = (h << 32) | h2;
52
+
53
+ return h;
54
+ }
55
+
56
+ VALUE
57
+ murmur64b_finish(VALUE self)
58
+ {
59
+ uint8_t digest[8];
60
+ uint64_t h;
61
+
62
+ h = _murmur_finish64(self, murmur_hash_process64b);
63
+ ASSINE_BY_ENDIAN_64(digest, h);
64
+ return rb_str_new((const char*) digest, 8);
65
+ }
66
+
67
+ VALUE
68
+ murmur64b_to_i(VALUE self)
69
+ {
70
+ return ULL2NUM(_murmur_finish64(self, murmur_hash_process64b));
71
+ }
72
+
73
+ VALUE
74
+ murmur64b_s_digest(int argc, VALUE *argv, VALUE klass)
75
+ {
76
+ uint8_t digest[8];
77
+ uint64_t h;
78
+ h = _murmur_s_digest64(argc, argv, klass, murmur_hash_process64b);
79
+ ASSINE_BY_ENDIAN_64(digest, h);
80
+ return rb_str_new((const char*) digest, 8);
81
+ }
82
+
83
+ VALUE
84
+ murmur64b_s_hexdigest(int argc, VALUE *argv, VALUE klass)
85
+ {
86
+ return hexencode_str_new(murmur64b_s_digest(argc, argv, klass));
87
+ }
88
+
89
+ VALUE
90
+ murmur64b_s_rawdigest(int argc, VALUE *argv, VALUE klass)
91
+ {
92
+ return ULL2NUM(_murmur_s_digest64(argc, argv, klass, murmur_hash_process64b));
93
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef MURMURHASH64B_INCLUDED
2
+ # define MURMURHASH64B_INCLUDED
3
+
4
+ #include "murmurhash.h"
5
+
6
+ VALUE murmur64b_finish(VALUE self);
7
+ VALUE murmur64b_to_i(VALUE self);
8
+ VALUE murmur64b_s_digest(int argc, VALUE *argv, VALUE klass);
9
+ VALUE murmur64b_s_hexdigest(int argc, VALUE *argv, VALUE klass);
10
+ VALUE murmur64b_s_rawdigest(int argc, VALUE *argv, VALUE klass);
11
+
12
+ #endif /* ifndef MURMURHASH64B_INCLUDED */
13
+
@@ -0,0 +1,87 @@
1
+ /*
2
+ * MurmurHashAligned2 (C) Austin Appleby
3
+ */
4
+
5
+ #include "murmurhash_aligned2.h"
6
+
7
+ uint32_t
8
+ murmur_hash_process_aligned2(const char * key, uint32_t len, uint32_t seed)
9
+ {
10
+ const uint32_t m = 0x5bd1e995;
11
+ const int r = 24;
12
+
13
+ uint32_t h = seed ^ len;
14
+
15
+ const unsigned char * data = (const unsigned char *)key;
16
+
17
+ while(len >= 4) {
18
+ uint32_t k;
19
+
20
+ k = data[0];
21
+ k |= data[1] << 8;
22
+ k |= data[2] << 16;
23
+ k |= data[3] << 24;
24
+
25
+ k *= m;
26
+ k ^= k >> r;
27
+ k *= m;
28
+
29
+ h *= m;
30
+ h ^= k;
31
+
32
+ data += 4;
33
+ len -= 4;
34
+ }
35
+
36
+ switch(len) {
37
+ case 3: h ^= data[2] << 16;
38
+ case 2: h ^= data[1] << 8;
39
+ case 1: h ^= data[0];
40
+ h *= m;
41
+ };
42
+
43
+ h ^= h >> 13;
44
+ h *= m;
45
+ h ^= h >> 15;
46
+
47
+ return h;
48
+ }
49
+
50
+ VALUE
51
+ murmur_aligned2_finish(VALUE self)
52
+ {
53
+ uint8_t digest[4];
54
+ uint32_t h;
55
+
56
+ h = _murmur_finish32(self, murmur_hash_process_aligned2);
57
+ ASSINE_BY_ENDIAN_32(digest, h);
58
+ return rb_str_new((const char*) digest, 4);
59
+ }
60
+
61
+ VALUE
62
+ murmur_aligned2_to_i(VALUE self)
63
+ {
64
+ return ULL2NUM(_murmur_finish32(self, murmur_hash_process_aligned2));
65
+ }
66
+
67
+ VALUE
68
+ murmur_aligned2_s_digest(int argc, VALUE *argv, VALUE klass)
69
+ {
70
+ uint8_t digest[4];
71
+ uint64_t h;
72
+ h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process_aligned2);
73
+ ASSINE_BY_ENDIAN_32(digest, h);
74
+ return rb_str_new((const char*) digest, 4);
75
+ }
76
+
77
+ VALUE
78
+ murmur_aligned2_s_hexdigest(int argc, VALUE *argv, VALUE klass)
79
+ {
80
+ return hexencode_str_new(murmur_aligned2_s_digest(argc, argv, klass));
81
+ }
82
+
83
+ VALUE
84
+ murmur_aligned2_s_rawdigest(int argc, VALUE *argv, VALUE klass)
85
+ {
86
+ return ULL2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process_aligned2));
87
+ }