v16-0002-Shorten-dependency-chain-for-computing-hash-mask.patch

text/x-patch

Filename: v16-0002-Shorten-dependency-chain-for-computing-hash-mask.patch
Type: text/x-patch
Part: 1
Message: Re: Change GUC hashtable to use simplehash?

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 v16-0002
Subject: Shorten dependency chain for computing hash mask
File+
src/include/common/hashfn_unstable.h 13 17
From a1e1648f3f3a25001c62fffe7dcd422273619e3e 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 v16 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..0cac3aa380 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))
+	/*
+	 * Create a mask for the remaining bytes and
+	 * combine them into the hash. It would be harmless if the mask also covered the NUL
+	 * terminator, except for the case where it is the first byte in the last input read.
+	 * In that case, we need to return, so we perform a check for that as we form the mask
+	 * for the bytes we need.
+	 */
+	mask = zero_bytes_le >> BITS_PER_BYTE;
+	if (mask)
 	{
 		remainder = pg_rightmost_one_pos64(zero_bytes_le) / BITS_PER_BYTE;
+		mask |= mask - 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