v11-0006-Try-simply-byte-swapping-on-BE-machines-and-then.patch
application/x-patch
Filename: v11-0006-Try-simply-byte-swapping-on-BE-machines-and-then.patch
Type: application/x-patch
Part: 4
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 v11-0006
Subject: Try simply byte-swapping on BE machines and then handling like LE
| File | + | − |
|---|---|---|
| src/include/common/hashfn_unstable.h | 9 | 27 |
From 02875939fa45246140b34554c23eedccc66ba972 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sun, 24 Dec 2023 15:14:46 +0700
Subject: [PATCH v11 6/8] Try simply byte-swapping on BE machines and then
handling like LE
---
src/include/common/hashfn_unstable.h | 36 +++++++---------------------
1 file changed, 9 insertions(+), 27 deletions(-)
diff --git a/src/include/common/hashfn_unstable.h b/src/include/common/hashfn_unstable.h
index 4fc9edba6e..5bc1fc88ec 100644
--- a/src/include/common/hashfn_unstable.h
+++ b/src/include/common/hashfn_unstable.h
@@ -14,6 +14,7 @@ the same hashes between versions.
#define HASHFN_UNSTABLE_H
#include "port/pg_bitutils.h"
+#include "port/pg_bswap.h"
/*
* fasthash is a modification of code taken from
@@ -152,9 +153,6 @@ fasthash_accum(fasthash_state *hs, const char *k, int len)
#define haszero64(v) \
(((v) - 0x0101010101010101UL) & ~(v) & 0x8080808080808080UL)
-#define SIM_BE 1
-#include "port/pg_bswap.h"
-
/*
* With an aligned pointer, we consume the string a word at a time. Loading
* the word containing the NUL terminator cannot segfault since page boundaries
@@ -170,39 +168,27 @@ fasthash_accum_cstring_aligned(fasthash_state *hs, const char *str)
uint64 zero_bytes;
Assert(PointerIsAligned(start, uint64));
- while (true)
+ for (;;)
{
uint64 chunk = *(uint64 *)buf;
-#ifdef SIM_BE
- uint64 low_bits = 0x7F7F7F7F7F7F7F7F;
- chunk = pg_bswap64(chunk); /* simulate BE */
+#ifdef WORDS_BIGENDIAN
+ /* switch to little endian, to make later calculations easier */
+ chunk = pg_bswap64(chunk);
+#endif
/*
- * This expression evaluates has the useful property that all bytes in the result word
- * that correspond to non-zero bytes in the original word have
- * the value 0x00, while all bytes corresponding to zero bytes have
- * the value 0x80.
- */
- zero_bytes = ~(((chunk & low_bits) + low_bits) | chunk | low_bits);
-#else
- /*
- * On little endian machines, we can use a slightly faster calculation,
+ * With little-endian representation, we can use this calculation,
* which sets bits in the first byte in the result word
* that corresponds to a zero byte in the original word.
* The rest of the bytes are indeterminate, so cannot be used
- * on big-endian machines unless we resort to a bytewise check.
+ * on big-endian machines without either swapping or a bytewise check.
*/
zero_bytes = haszero64(chunk);
-#endif
if (zero_bytes)
break;
-#ifdef SIM_BE
- hs->accum = pg_bswap64(chunk); /* not needed with real BE, because we won't need the same answer */
-#else
hs->accum = chunk;
-#endif
fasthash_combine(hs);
buf += FH_SIZEOF_ACCUM;
}
@@ -210,14 +196,10 @@ fasthash_accum_cstring_aligned(fasthash_state *hs, const char *str)
/*
* Bytes with set bits will be 0x80, so
* calculate the first occurrence of a zero byte within the input word
- * by counting the number of leading (on BE) or trailing (on LE)
+ * by counting the number of trailing (for LE)
* zeros and dividing the result by 8.
*/
-#ifdef SIM_BE
- remainder = (63 - pg_leftmost_one_pos64(zero_bytes)) / BITS_PER_BYTE;
-#else
remainder = pg_rightmost_one_pos64(zero_bytes) / BITS_PER_BYTE;
-#endif
fasthash_accum(hs, buf, remainder);
buf += remainder;
--
2.43.0