14
14
#ifndef HASHFN_UNSTABLE_H
15
15
#define HASHFN_UNSTABLE_H
16
16
17
- #include "port/pg_bitutils.h"
18
- #include "port/pg_bswap.h"
19
17
20
18
/*
21
19
* fasthash is a modification of code taken from
@@ -219,13 +217,6 @@ fasthash_accum(fasthash_state *hs, const char *k, size_t len)
219
217
#define haszero64 (v ) \
220
218
(((v) - 0x0101010101010101) & ~(v) & 0x8080808080808080)
221
219
222
- /* get first byte in memory order */
223
- #ifdef WORDS_BIGENDIAN
224
- #define firstbyte64 (v ) ((v) >> 56)
225
- #else
226
- #define firstbyte64 (v ) ((v) & 0xFF)
227
- #endif
228
-
229
220
/*
230
221
* all-purpose workhorse for fasthash_accum_cstring
231
222
*/
@@ -262,33 +253,20 @@ static inline size_t
262
253
fasthash_accum_cstring_aligned (fasthash_state * hs , const char * str )
263
254
{
264
255
const char * const start = str ;
265
- uint64 chunk ;
256
+ size_t remainder ;
266
257
uint64 zero_byte_low ;
267
258
268
259
Assert (PointerIsAligned (start , uint64 ));
269
260
270
261
/*
271
262
* For every chunk of input, check for zero bytes before mixing into the
272
- * hash. The chunk with zeros must contain the NUL terminator. We arrange
273
- * so that zero_byte_low tells us not only that a zero exists, but also
274
- * where it is, so we can hash the remainder of the string.
275
- *
276
- * The haszero64 calculation will set bits corresponding to the lowest
277
- * byte where a zero exists, so that suffices for little-endian machines.
278
- * For big-endian machines, we would need bits set for the highest zero
279
- * byte in the chunk, since the trailing junk past the terminator could
280
- * contain additional zeros. haszero64 does not give us that, so we
281
- * byteswap the chunk first.
263
+ * hash. The chunk with zeros must contain the NUL terminator.
282
264
*/
283
265
for (;;)
284
266
{
285
- chunk = * (uint64 * ) str ;
267
+ uint64 chunk = * (uint64 * ) str ;
286
268
287
- #ifdef WORDS_BIGENDIAN
288
- zero_byte_low = haszero64 (pg_bswap64 (chunk ));
289
- #else
290
269
zero_byte_low = haszero64 (chunk );
291
- #endif
292
270
if (zero_byte_low )
293
271
break ;
294
272
@@ -297,33 +275,9 @@ fasthash_accum_cstring_aligned(fasthash_state *hs, const char *str)
297
275
str += FH_SIZEOF_ACCUM ;
298
276
}
299
277
300
- if (firstbyte64 (chunk ) != 0 )
301
- {
302
- size_t remainder ;
303
- uint64 mask ;
304
-
305
- /*
306
- * The byte corresponding to the NUL will be 0x80, so the rightmost
307
- * bit position will be in the range 15, 23, ..., 63. Turn this into
308
- * byte position by dividing by 8.
309
- */
310
- remainder = pg_rightmost_one_pos64 (zero_byte_low ) / BITS_PER_BYTE ;
311
-
312
- /*
313
- * Create a mask for the remaining bytes so we can combine them into
314
- * the hash. This must have the same result as mixing the remaining
315
- * bytes with fasthash_accum().
316
- */
317
- #ifdef WORDS_BIGENDIAN
318
- mask = ~UINT64CONST (0 ) << BITS_PER_BYTE * (FH_SIZEOF_ACCUM - remainder );
319
- #else
320
- mask = ~UINT64CONST (0 ) >> BITS_PER_BYTE * (FH_SIZEOF_ACCUM - remainder );
321
- #endif
322
- hs -> accum = chunk & mask ;
323
- fasthash_combine (hs );
324
-
325
- str += remainder ;
326
- }
278
+ /* mix in remaining bytes */
279
+ remainder = fasthash_accum_cstring_unaligned (hs , str );
280
+ str += remainder ;
327
281
328
282
return str - start ;
329
283
}
0 commit comments