v9-0003-Make-fetch_att-faster-on-little-endian-hardware.patch
application/octet-stream
Filename: v9-0003-Make-fetch_att-faster-on-little-endian-hardware.patch
Type: application/octet-stream
Part: 3
Message:
Re: Make tuple deformation faster
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 v9-0003
Subject: Make fetch_att() faster on little-endian hardware
| File | + | − |
|---|---|---|
| src/include/access/tupmacs.h | 32 | 0 |
From 0b23daeed4b74cbe442dd9cb512815df2c3e65b8 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Fri, 27 Dec 2024 01:17:04 +1300
Subject: [PATCH v9 3/3] Make fetch_att() faster on little-endian hardware
Is it always safe to defererence 64-bytes when the attlen is smaller
than 8?
---
src/include/access/tupmacs.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h
index c4ab2cd3ee..0ec409df98 100644
--- a/src/include/access/tupmacs.h
+++ b/src/include/access/tupmacs.h
@@ -46,6 +46,29 @@ att_isnull(int ATT, const bits8 *BITS)
*/
#define fetchatt(A,T) fetch_att(T, (A)->attbyval, (A)->attlen)
+#ifndef WORDS_BIGENDIAN
+
+static const Datum fetch_mask[] = {
+#if SIZEOF_DATUM == 8
+ UINT64CONST(0x0),
+ UINT64CONST(0xFF), /* attlen == 1 */
+ UINT64CONST(0xFFFF), /* attlen == 2 */
+ UINT64CONST(0x0), /* 3 is an invalid attlen */
+ UINT64CONST(0xFFFFFFFF), /* attlen == 4 */
+ UINT64CONST(0x0), /* 5 is an invalid attlen */
+ UINT64CONST(0x0), /* 6 is an invalid attlen */
+ UINT64CONST(0x0), /* 7 is an invalid attlen */
+ UINT64CONST(0xFFFFFFFFFFFFFFFF) /* attlen == 8 */
+#else
+ 0x0,
+ 0xFF, /* attlen == 1 */
+ 0xFFFF, /* attlen == 2 */
+ 0x0, /* 3 is an invalid attlen */
+ 0xFFFFFFFF, /* attlen == 4 */
+#endif
+};
+#endif
+
/*
* Same, but work from byval/len parameters rather than Form_pg_attribute.
*/
@@ -54,6 +77,14 @@ fetch_att(const void *T, bool attbyval, int attlen)
{
if (attbyval)
{
+#ifndef WORDS_BIGENDIAN
+ /*
+ * On little-endian machines, we cheat and just mask out the unneeded
+ * bytes. XXX this assumes it's always safe to access 8 bytes of T.
+ * Is it?
+ */
+ return *((const Datum *) T) & fetch_mask[attlen];
+#else
switch (attlen)
{
case sizeof(char):
@@ -70,6 +101,7 @@ fetch_att(const void *T, bool attbyval, int attlen)
elog(ERROR, "unsupported byval length: %d", attlen);
return 0;
}
+#endif
}
else
return PointerGetDatum(T);
--
2.34.1