44
44
FORCE_INLINE REBCNT getblock32 (const REBCNT * p , int i ) {
45
45
return p [i ];
46
46
}
47
+ /*-----------------------------------------------------------------------------
48
+ // Block mix - mix the key block, combine with hash block, mix the hash block,
49
+ // repeat. */
50
+
51
+ FORCE_INLINE void bmix (REBCNT * h1 , REBCNT * k1 )
52
+ {
53
+ * k1 *= MURMUR_HASH_3_X86_32_C1 ;
54
+ * k1 = ROTL32 (* k1 , 15 );
55
+ * k1 *= MURMUR_HASH_3_X86_32_C2 ;
56
+ * h1 ^= * k1 ;
57
+ * h1 = ROTL32 (* h1 , 13 ); * h1 = * h1 * 5 + 0xe6546b64 ;
58
+ }
47
59
//-----------------------------------------------------------------------------
48
60
// Finalization mix - force all bits of a hash block to avalanche
49
61
FORCE_INLINE REBCNT fmix32 (REBCNT h ) {
@@ -69,14 +81,7 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
69
81
for (int i = - nblocks ; i ; i ++ )
70
82
{
71
83
REBCNT k1 = getblock32 (blocks , i );
72
-
73
- k1 *= MURMUR_HASH_3_X86_32_C1 ;
74
- k1 = ROTL32 (k1 , 15 );
75
- k1 *= MURMUR_HASH_3_X86_32_C2 ;
76
-
77
- h1 ^= k1 ;
78
- h1 = ROTL32 (h1 , 13 );
79
- h1 = h1 * 5 + 0xe6546b64 ;
84
+ bmix (& h1 , & k1 );
80
85
}
81
86
82
87
//----------
@@ -90,7 +95,7 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
90
95
case 2 : k1 ^= tail [1 ] << 8 ;
91
96
case 1 : k1 ^= tail [0 ];
92
97
k1 *= MURMUR_HASH_3_X86_32_C1 ;
93
- k1 = ROTL32 (k1 , 15 );
98
+ k1 = ROTL32 (k1 , 16 );
94
99
k1 *= MURMUR_HASH_3_X86_32_C2 ;
95
100
h1 ^= k1 ;
96
101
};
@@ -101,8 +106,6 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
101
106
h1 = fmix32 (h1 );
102
107
103
108
return h1 ;
104
-
105
- //*(REBCNT*)out = h1;
106
109
}
107
110
108
111
@@ -120,9 +123,10 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
120
123
return R_RET ;
121
124
}
122
125
126
+ FORCE_INLINE
123
127
/***********************************************************************
124
128
**
125
- */ FORCE_INLINE REBCNT Hash_Probe (REBCNT hash , REBCNT idx , REBCNT len )
129
+ */ REBCNT Hash_Probe (REBCNT hash , REBCNT idx , REBCNT len )
126
130
/*
127
131
** Calculates the index based on a quadratic probing approach.
128
132
**
@@ -147,7 +151,7 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
147
151
if (ANY_WORD (val ))
148
152
return VAL_WORD_CANON (val ); //plain value seems to be faster than: fmix32(VAL_WORD_CANON(val));
149
153
if (ANY_STR (val ))
150
- return CRC_String ( VAL_BIN_DATA ( val ), Val_Byte_Len ( val ) ) ^ VAL_TYPE (val );
154
+ return Hash_String_Value ( val ) ^ VAL_TYPE (val );
151
155
if (ANY_BLOCK (val ))
152
156
return Hash_Block_Value (val );
153
157
@@ -203,26 +207,15 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
203
207
***********************************************************************/
204
208
{
205
209
REBCNT k1 , h1 = 0 ;
206
- REBCNT n ;
207
210
REBVAL * data = VAL_BLK_DATA (block );
208
211
REBLEN len = VAL_LEN (block );
209
212
210
213
k1 = VAL_TYPE (block );
211
- k1 *= MURMUR_HASH_3_X86_32_C1 ;
212
- k1 = ROTL32 (k1 , 15 );
213
- k1 *= MURMUR_HASH_3_X86_32_C2 ;
214
- h1 ^= k1 ;
215
- h1 = ROTL32 (h1 , 13 );
216
- h1 = h1 * 5 + 0xe6546b64 ;
214
+ bmix (& h1 , & k1 );
217
215
218
216
while (NZ (VAL_TYPE (data ))) {
219
217
k1 = Hash_Value (data ++ );
220
- k1 *= MURMUR_HASH_3_X86_32_C1 ;
221
- k1 = ROTL32 (k1 , 15 );
222
- k1 *= MURMUR_HASH_3_X86_32_C2 ;
223
- h1 ^= k1 ;
224
- h1 = ROTL32 (h1 , 13 );
225
- h1 = h1 * 5 + 0xe6546b64 ;
218
+ bmix (& h1 , & k1 );
226
219
}
227
220
h1 ^= len ;
228
221
h1 = fmix32 (h1 );
@@ -232,49 +225,53 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
232
225
233
226
/***********************************************************************
234
227
**
235
- */ FORCE_INLINE REBCNT Hash_Binary ( const REBYTE * bin , REBCNT len )
228
+ */ REBCNT Hash_String_Value ( REBVAL * val )
236
229
/*
237
- ** Return a case sensitive hash value for the binary .
230
+ ** Return a case insensitive hash value for the string value .
238
231
**
239
232
***********************************************************************/
240
233
{
241
- return MurmurHash3_x86_32 (bin , len , 0 );
242
- //return XXH64(bin, len, 0);
243
-
234
+ REBYTE * bin ;
235
+ REBUNI * uni ;
236
+ REBLEN len ;
237
+ REBCNT n , ch ;
238
+ REBCNT hash = 0 ;
239
+
240
+ if (BYTE_SIZE (VAL_SERIES (val ))) {
241
+ bin = VAL_BIN_DATA (val );
242
+ len = VAL_TAIL (val ) - VAL_INDEX (val );
243
+ for (n = 0 ; n < len ; n ++ ) {
244
+ ch = (REBCNT )LO_CASE (* bin ++ );
245
+ bmix (& hash , & ch );
246
+ }
247
+ }
248
+ else {
249
+ uni = VAL_UNI_DATA (val );
250
+ len = Val_Series_Len (val );
251
+ for (n = 0 ; n < len ; n ++ ) {
252
+ ch = (REBCNT )(* uni ++ );
253
+ if (ch < UNICODE_CASES )
254
+ ch = (REBCNT )LO_CASE (ch );
255
+ bmix (& hash , & ch );
256
+ }
257
+ }
258
+ hash ^= len ;
259
+ hash = fmix32 (hash );
260
+ return hash ;
244
261
}
245
262
263
+ FORCE_INLINE
246
264
/***********************************************************************
247
265
**
248
- */ REBCNT Hash_String ( REBVAL * val )
266
+ */ REBCNT Hash_Binary ( const REBYTE * bin , REBCNT len )
249
267
/*
250
- ** Return a case insensitive hash value for the string. The
251
- ** string does not have to be zero terminated and UTF8 is ok.
268
+ ** Return a case sensitive hash value for the binary.
252
269
**
253
270
***********************************************************************/
254
271
{
255
- REBSER * ser = VAL_SERIES (val );
256
- REBCNT pos = VAL_INDEX (val );
257
- REBCNT tail = VAL_TAIL (val );
258
- REBLEN len = VAL_TAIL (val ) - pos ;
259
- REBUNI ch ;
260
- REBCNT hash = 0 ;
261
-
262
- for (; pos < tail ; pos ++ ) {
263
- ch = GET_ANY_CHAR (ser , pos );
264
- if (ch < UNICODE_CASES )
265
- ch = LO_CASE (ch );
266
-
267
- ch *= MURMUR_HASH_3_X86_32_C1 ;
268
- ch = ROTL32 (ch , 15 );
269
- ch *= MURMUR_HASH_3_X86_32_C2 ;
270
-
271
- hash ^= ch ;
272
- hash = ROTL32 (hash , 13 );
273
- hash = hash * 5 + 0xe6546b64 ;
274
- }
275
- hash ^= len ;
276
- hash = fmix32 (hash );
277
- return hash ;
272
+ return MurmurHash3_x86_32 (bin , len , 0 );
273
+ //return XXH64(bin, len, 0);
274
+
278
275
}
279
276
280
277
@@ -298,13 +295,7 @@ REBCNT MurmurHash3_x86_32(const void* key, int len, REBCNT seed)
298
295
if (!ch ) Trap0 (RE_INVALID_CHARS );
299
296
}
300
297
if (ch < UNICODE_CASES ) ch = LO_CASE (ch );
301
- ch *= MURMUR_HASH_3_X86_32_C1 ;
302
- ch = ROTL32 (ch , 15 );
303
- ch *= MURMUR_HASH_3_X86_32_C2 ;
304
-
305
- hash ^= ch ;
306
- hash = ROTL32 (hash , 13 );
307
- hash = hash * 5 + 0xe6546b64 ;
298
+ bmix (& hash , & ch );
308
299
}
309
300
hash ^= len ;
310
301
hash = fmix32 (hash );
0 commit comments