From e7e8aa07af0466f4a05d7df1c002596b69563f4a Mon Sep 17 00:00:00 2001 From: Nikhil Kumar Veldanda Date: Mon, 14 Apr 2025 21:07:00 +0000 Subject: [PATCH v11 1/7] varattrib_4b changes and macros update needed to support zstd dictionary based compression. --- src/include/varatt.h | 57 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/include/varatt.h b/src/include/varatt.h index 2e8564d4998..ba06250b6ce 100644 --- a/src/include/varatt.h +++ b/src/include/varatt.h @@ -42,8 +42,9 @@ typedef struct varatt_external * These macros define the "saved size" portion of va_extinfo. Its remaining * two high-order bits identify the compression method. */ -#define VARLENA_EXTSIZE_BITS 30 -#define VARLENA_EXTSIZE_MASK ((1U << VARLENA_EXTSIZE_BITS) - 1) +#define VARLENA_EXTSIZE_BITS 30 +#define VARLENA_EXTSIZE_MASK ((1U << VARLENA_EXTSIZE_BITS) - 1) +#define VARLENA_EXTENDED_COMPRESSION_FLAG 0x3 /* * struct varatt_indirect is a "TOAST pointer" representing an out-of-line @@ -122,6 +123,14 @@ typedef union * compression method; see va_extinfo */ char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Compressed data */ } va_compressed; + struct + { + uint32 va_header; + uint32 va_tcinfo; + uint32 va_cmp_alg; + uint32 va_cmp_dictid; + char va_data[FLEXIBLE_ARRAY_MEMBER]; + } va_compressed_ext; } varattrib_4b; typedef struct @@ -242,7 +251,14 @@ typedef struct #endif /* WORDS_BIGENDIAN */ #define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data) -#define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data) +/* + * If va_tcinfo >> VARLENA_EXTSIZE_BITS == VARLENA_EXTENDED_COMPRESSION_FLAG + * use va_compressed_ext; otherwise, use the va_compressed. + */ +#define VARDATA_4B_C(PTR) \ +( (((varattrib_4b *)(PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS) == VARLENA_EXTENDED_COMPRESSION_FLAG \ + ? ((varattrib_4b *)(PTR))->va_compressed_ext.va_data \ + : ((varattrib_4b *)(PTR))->va_compressed.va_data ) #define VARDATA_1B(PTR) (((varattrib_1b *) (PTR))->va_data) #define VARDATA_1B_E(PTR) (((varattrib_1b_e *) (PTR))->va_data) @@ -252,6 +268,7 @@ typedef struct #define VARHDRSZ_EXTERNAL offsetof(varattrib_1b_e, va_data) #define VARHDRSZ_COMPRESSED offsetof(varattrib_4b, va_compressed.va_data) +#define VARHDRSZ_COMPRESSED_EXT offsetof(varattrib_4b, va_compressed_ext.va_data) #define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data) #define VARATT_SHORT_MAX 0x7F @@ -327,8 +344,20 @@ typedef struct /* Decompressed size and compression method of a compressed-in-line Datum */ #define VARDATA_COMPRESSED_GET_EXTSIZE(PTR) \ (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo & VARLENA_EXTSIZE_MASK) +/* + * - "Extended" format is indicated by (va_tcinfo >> VARLENA_EXTSIZE_BITS) == VARLENA_EXTENDED_COMPRESSION_FLAG + * - For the non-extended formats, the method code is stored in the top bits of va_tcinfo. + * - In the extended format, the method code is stored in va_cmp_alg instead. + */ #define VARDATA_COMPRESSED_GET_COMPRESS_METHOD(PTR) \ - (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS) +( ((((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS) == VARLENA_EXTENDED_COMPRESSION_FLAG ) \ + ? (((varattrib_4b *) (PTR))->va_compressed_ext.va_cmp_alg) \ + : ( (((varattrib_4b *) (PTR))->va_compressed.va_tcinfo) >> VARLENA_EXTSIZE_BITS)) + +#define VARDATA_COMPRESSED_GET_DICTID(PTR) \ + ( ((((varattrib_4b *) (PTR))->va_compressed.va_tcinfo >> VARLENA_EXTSIZE_BITS) == VARLENA_EXTENDED_COMPRESSION_FLAG ) \ + ? (((varattrib_4b *) (PTR))->va_compressed_ext.va_cmp_dictid) \ + : InvalidDictId) /* Same for external Datums; but note argument is a struct varatt_external */ #define VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer) \ @@ -338,10 +367,24 @@ typedef struct #define VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(toast_pointer, len, cm) \ do { \ + /* If desired, keep or expand the Assert checks for known methods: */ \ Assert((cm) == TOAST_PGLZ_COMPRESSION_ID || \ - (cm) == TOAST_LZ4_COMPRESSION_ID); \ - ((toast_pointer).va_extinfo = \ - (len) | ((uint32) (cm) << VARLENA_EXTSIZE_BITS)); \ + (cm) == TOAST_LZ4_COMPRESSION_ID || \ + (cm) == TOAST_ZSTD_COMPRESSION_ID); \ + if ((cm) < TOAST_ZSTD_COMPRESSION_ID) \ + { \ + /* Store the actual method in va_extinfo */ \ + (toast_pointer).va_extinfo = (uint32)(len) \ + | ((uint32)(cm) << VARLENA_EXTSIZE_BITS); \ + } \ + else \ + { \ + /* Store VARLENA_EXTENDED_COMPRESSION_FLAG in the top bits, \ + meaning "extended" method. */ \ + (toast_pointer).va_extinfo = (uint32)(len) | \ + ((uint32)VARLENA_EXTENDED_COMPRESSION_FLAG \ + << VARLENA_EXTSIZE_BITS); \ + } \ } while (0) /* base-commit: 7c872849407730fa01e2c13b2d47483bc3ff6e7e -- 2.47.1