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