v17-0002-Shorten-dependency-chain-for-computing-hash-mask.patch
text/x-patch
Filename: v17-0002-Shorten-dependency-chain-for-computing-hash-mask.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v17-0002
Subject: Shorten dependency chain for computing hash mask
| File | + | − |
|---|---|---|
| src/include/common/hashfn_unstable.h | 13 | 17 |
From 77d848a83930abe2badd8c0f1ade79c88c27b455 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Tue, 30 Jan 2024 16:14:57 +0700
Subject: [PATCH v17 2/2] Shorten dependency chain for computing hash mask
---
src/include/common/hashfn_unstable.h | 30 ++++++++++++----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h
index 8ee1b99a20..3a74e6e33b 100644
--- a/src/include/common/hashfn_unstable.h
+++ b/src/include/common/hashfn_unstable.h
@@ -176,19 +176,6 @@ fasthash_accum(fasthash_state *hs, const char *k, int len)
#define haszero64(v) \
(((v) - 0x0101010101010101) & ~(v) & 0x8080808080808080)
-/*
- * Returns non-zero when first byte in memory order is not NUL
- */
-static inline int
-first_byte_nonzero(uint64 v)
-{
-#ifdef WORDS_BIGENDIAN
- return v >> 56;
-#else
- return v & 0xFF;
-#endif
-}
-
/*
* all-purpose workhorse for fasthash_accum_cstring
*/
@@ -225,6 +212,7 @@ fasthash_accum_cstring_aligned(fasthash_state *hs, const char *str)
int remainder;
uint64 zero_bytes_le;
uint64 chunk;
+ uint64 mask;
Assert(PointerIsAligned(start, uint64));
for (;;)
@@ -257,14 +245,22 @@ fasthash_accum_cstring_aligned(fasthash_state *hs, const char *str)
* byte within the input word by counting the number of trailing (because
* little-endian) zeros and dividing the result by 8.
*/
- if (first_byte_nonzero(chunk))
+ /* If the first byte in the input is the NUL terminator, we have nothing to do */
+ if ((zero_bytes_le & 0xFF) == 0)
{
remainder = pg_rightmost_one_pos64(zero_bytes_le) / BITS_PER_BYTE;
+ /*
+ * Create a mask for the remaining bytes and
+ * combine them into the hash. The mask also covers the NUL
+ * terminator, but that's harmless. The mask could contain 0x80
+ * in higher bytes where the input is non-zero, but only if the
+ * input byte is 0x01, so also harmless.
+ */
+ mask = zero_bytes_le | (zero_bytes_le - 1);
#ifdef WORDS_BIGENDIAN
- hs->accum = chunk & ((~0ULL) << (64 - BITS_PER_BYTE*remainder));
-#else
- hs->accum = chunk & ((~0ULL) >> (64 - BITS_PER_BYTE*remainder));
+ mask = pg_bswap64(mask);
#endif
+ hs->accum = chunk & mask;
fasthash_combine(hs);
str += remainder;
--
2.43.0