From 75a3fa4e68235f956f8761e43adf25be2fc9147c Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 23 Oct 2021 10:41:19 -0500
Subject: [PATCH 2/6] Save bits in xlog FPI record..

2 bits can support 4 methods (including 'none'), and 3 bits can support 8

See also:
https://www.postgresql.org/message-id/20220131222800.GY23027@telsasoft.com
---
 src/backend/access/transam/xloginsert.c | 29 +++----------------------
 src/backend/access/transam/xlogreader.c |  7 +++---
 src/bin/pg_waldump/pg_waldump.c         | 16 +++++---------
 src/include/access/xlogrecord.h         | 17 ++++++++++-----
 4 files changed, 23 insertions(+), 46 deletions(-)

diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c
index 847ce0c3fc..5f9d07156a 100644
--- a/src/backend/access/transam/xloginsert.c
+++ b/src/backend/access/transam/xloginsert.c
@@ -689,33 +689,10 @@ XLogRecordAssemble(RmgrId rmid, uint8 info,
 				bimg.length = compressed_len;
 
 				/* Set the compression method used for this block */
-				switch ((WalCompression) wal_compression)
-				{
-					case WAL_COMPRESSION_PGLZ:
-						bimg.bimg_info |= BKPIMAGE_COMPRESS_PGLZ;
-						break;
-
-					case WAL_COMPRESSION_LZ4:
-#ifdef USE_LZ4
-						bimg.bimg_info |= BKPIMAGE_COMPRESS_LZ4;
-#else
-						elog(ERROR, "LZ4 is not supported by this build");
-#endif
-						break;
+				Assert(wal_compression < (1 << BKPIMAGE_COMPRESS_BITS));
 
-					case WAL_COMPRESSION_ZSTD:
-#ifdef USE_ZSTD
-						bimg.bimg_info |= BKPIMAGE_COMPRESS_ZSTD;
-#else
-						elog(ERROR, "ZSTD is not supported by this build");
-#endif
-						break;
-
-					case WAL_COMPRESSION_NONE:
-						Assert(false);	/* cannot happen */
-						break;
-						/* no default case, so that compiler will warn */
-				}
+				bimg.bimg_info |=
+					wal_compression << BKPIMAGE_COMPRESS_OFFSET_BITS;
 
 				rdt_datas_last->data = regbuf->compressed_page;
 				rdt_datas_last->len = compressed_len;
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index d60e4cbaf6..d2d882d0d1 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -1602,14 +1602,15 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
 	{
 		/* If a backup block image is compressed, decompress it */
 		bool		decomp_success = true;
+		int			compressid = BKPIMAGE_COMPRESSION(bkpb->bimg_info);
 
-		if ((bkpb->bimg_info & BKPIMAGE_COMPRESS_PGLZ) != 0)
+		if (compressid == WAL_COMPRESSION_PGLZ)
 		{
 			if (pglz_decompress(ptr, bkpb->bimg_len, tmp.data,
 								BLCKSZ - bkpb->hole_length, true) < 0)
 				decomp_success = false;
 		}
-		else if ((bkpb->bimg_info & BKPIMAGE_COMPRESS_LZ4) != 0)
+		else if (compressid == WAL_COMPRESSION_LZ4)
 		{
 #ifdef USE_LZ4
 			if (LZ4_decompress_safe(ptr, tmp.data,
@@ -1623,7 +1624,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
 			return false;
 #endif
 		}
-		else if ((bkpb->bimg_info & BKPIMAGE_COMPRESS_ZSTD) != 0)
+		else if (compressid == WAL_COMPRESSION_ZSTD)
 		{
 #ifdef USE_ZSTD
 			size_t decomp_result = ZSTD_decompress(tmp.data,
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index c448658ea2..bec3fda2aa 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -18,6 +18,7 @@
 #include <unistd.h>
 
 #include "access/transam.h"
+#include "access/xlog.h"
 #include "access/xlog_internal.h"
 #include "access/xlogreader.h"
 #include "access/xlogrecord.h"
@@ -559,17 +560,10 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 
 				if (BKPIMAGE_COMPRESSED(bimg_info))
 				{
-					const char *method;
-
-					if ((bimg_info & BKPIMAGE_COMPRESS_PGLZ) != 0)
-						method = "pglz";
-					else if ((bimg_info & BKPIMAGE_COMPRESS_LZ4) != 0)
-						method = "lz4";
-					else if ((bimg_info & BKPIMAGE_COMPRESS_ZSTD) != 0)
-						method = "zstd";
-					else
-						method = "unknown";
+					int compressid = BKPIMAGE_COMPRESSION(bimg_info);
+					const char *methods[] = {"none", "pglz", "lz4", "zstd"};
 
+					Assert(compressid < lengthof(methods));
 					printf(" (FPW%s); hole: offset: %u, length: %u, "
 						   "compression saved: %u, method: %s",
 						   XLogRecBlockImageApply(record, block_id) ?
@@ -579,7 +573,7 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
 						   BLCKSZ -
 						   record->blocks[block_id].hole_length -
 						   record->blocks[block_id].bimg_len,
-						   method);
+						   methods[compressid]);
 				}
 				else
 				{
diff --git a/src/include/access/xlogrecord.h b/src/include/access/xlogrecord.h
index 052ac6817a..2080fb707f 100644
--- a/src/include/access/xlogrecord.h
+++ b/src/include/access/xlogrecord.h
@@ -147,13 +147,18 @@ typedef struct XLogRecordBlockImageHeader
 #define BKPIMAGE_APPLY			0x02	/* page image should be restored
 										 * during replay */
 /* compression methods supported */
-#define BKPIMAGE_COMPRESS_PGLZ	0x04
-#define BKPIMAGE_COMPRESS_LZ4	0x08
-#define BKPIMAGE_COMPRESS_ZSTD	0x10
-
+#define BKPIMAGE_COMPRESS_METHOD1	0x04	/* bits to encode compression method */
+#define BKPIMAGE_COMPRESS_METHOD2	0x08	/* 0=none, 1=pglz, 2=lz4, 3=zstd */
+
+/* How many bits to shift to extract compression */
+#define	BKPIMAGE_COMPRESS_OFFSET_BITS	2
+/* How many bits are for compression */
+#define	BKPIMAGE_COMPRESS_BITS			2
+/* Extract the compression from the bimg_info */
+#define	BKPIMAGE_COMPRESSION(info)		((info >> BKPIMAGE_COMPRESS_OFFSET_BITS) & ((1<<BKPIMAGE_COMPRESS_BITS) - 1))
+// #define	BKPIMAGE_COMPRESSED(info)	(BKPIMAGE_COMPRESSION(info) != 0)
 #define	BKPIMAGE_COMPRESSED(info) \
-	((info & (BKPIMAGE_COMPRESS_PGLZ | BKPIMAGE_COMPRESS_LZ4 | \
-			  BKPIMAGE_COMPRESS_ZSTD)) != 0)
+	((info & (BKPIMAGE_COMPRESS_METHOD1 | BKPIMAGE_COMPRESS_METHOD2)) != 0)
 
 /*
  * Extra header information used when page image has "hole" and
-- 
2.17.1

