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.
@@ -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
+ }