Reduce heap tuple header size

From: Manfred Koizar <mkoi-pg(at)aon(dot)at>
To: pgsql-patches(at)postgresql(dot)org
Subject: Reduce heap tuple header size
Date: 2002-06-14 01:10:07
Message-ID: iafiguckfc819vipdo1h93mt9s4f57q78v@4ax.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

This patch, which is built upon the "HeapTupleHeader accessor macros"
patch from 2002-06-10, is supposed to reduce the heap tuple header size
by four bytes on most architectures. Of course it changes the on-disk
tuple format and therefore requires initdb. As I have (once more)
opened my mouth too wide, I'll have to provide a heap file conversion
utility, if this patch gets accepted... More on this later.

======================
All 81 tests passed.
======================

It's late now, I'll do more tests tomorrow.

Good night
Manfred

diff -ru ../orig/src/backend/access/heap/heapam.c src/backend/access/heap/heapam.c
--- ../orig/src/backend/access/heap/heapam.c 2002-06-13 19:34:48.000000000 +0200
+++ src/backend/access/heap/heapam.c 2002-06-13 22:31:42.000000000 +0200
@@ -2204,7 +2204,7 @@
htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
HeapTupleHeaderSetXmin(htup, record->xl_xid);
HeapTupleHeaderSetCmin(htup, FirstCommandId);
- HeapTupleHeaderSetXmax(htup, InvalidTransactionId);
+ HeapTupleHeaderSetXmaxInvalid(htup);
HeapTupleHeaderSetCmax(htup, FirstCommandId);

offnum = PageAddItem(page, (Item) htup, newlen, offnum,
diff -ru ../orig/src/include/access/htup.h src/include/access/htup.h
--- ../orig/src/include/access/htup.h 2002-06-13 19:34:49.000000000 +0200
+++ src/include/access/htup.h 2002-06-14 01:12:47.000000000 +0200
@@ -57,15 +57,24 @@
* Also note that we omit the nulls bitmap if t_infomask shows that there
* are no nulls in the tuple.
*/
+/*
+** We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac
+** in three physical fields t_xmin, t_cid, t_xmax:
+** CommandId Cmin; insert CID stamp
+** CommandId Cmax; delete CommandId stamp
+** TransactionId Xmin; insert XID stamp
+** TransactionId Xmax; delete XID stamp
+** TransactionId Xvac; used by VACCUUM
+**
+** This assumes, that a CommandId can be stored in a TransactionId.
+*/
typedef struct HeapTupleHeaderData
{
Oid t_oid; /* OID of this tuple -- 4 bytes */

- CommandId t_cmin; /* insert CID stamp -- 4 bytes each */
- CommandId t_cmax; /* delete CommandId stamp */
-
- TransactionId t_xmin; /* insert XID stamp -- 4 bytes each */
- TransactionId t_xmax; /* delete XID stamp */
+ TransactionId t_xmin; /* Xmin -- 4 bytes each */
+ TransactionId t_cid; /* Cmin, Cmax, Xvac */
+ TransactionId t_xmax; /* Xmax, Cmax */

ItemPointerData t_ctid; /* current TID of this or newer tuple */

@@ -75,7 +84,7 @@

uint8 t_hoff; /* sizeof header incl. bitmap, padding */

- /* ^ - 31 bytes - ^ */
+ /* ^ - 27 bytes - ^ */

bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */

@@ -96,6 +105,8 @@
* attribute(s) */
#define HEAP_HASEXTENDED 0x000C /* the two above combined */

+#define HEAP_XMIN_IS_XMAX 0x0040 /* created and deleted in the */
+ /* same transaction
*/
#define HEAP_XMAX_UNLOGGED 0x0080 /* to lock tuple for update */
/* without logging
*/
#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */
@@ -108,6 +119,7 @@
* vacuum */
#define HEAP_MOVED_IN 0x8000 /* moved from another place by
* vacuum */
+#define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)

#define HEAP_XACT_MASK 0xFFF0 /* visibility-related bits */

@@ -116,53 +128,100 @@
/* HeapTupleHeader accessor macros */

#define HeapTupleHeaderGetXmin(tup) \
- ((tup)->t_xmin)
+( \
+ (tup)->t_xmin \
+)

#define HeapTupleHeaderGetXmax(tup) \
- ((tup)->t_xmax)
+( \
+ ((tup)->t_infomask & HEAP_XMIN_IS_XMAX) ? \
+ (tup)->t_xmin \
+ : \
+ (tup)->t_xmax \
+)

-/* no AssertMacro, because this is read as a system-defined attribute also */
+/* no AssertMacro, because this is read as a system-defined attribute */
#define HeapTupleHeaderGetCmin(tup) \
( \
- (tup)->t_cmin \
+ ((tup)->t_infomask & HEAP_MOVED) ? \
+ FirstCommandId \
+ : \
+ ( \
+ ((tup)->t_infomask & (HEAP_XMIN_IS_XMAX | HEAP_XMAX_INVALID)) ? \
+ (CommandId) (tup)->t_cid \
+ : \
+ FirstCommandId \
+ ) \
)

#define HeapTupleHeaderGetCmax(tup) \
- ((tup)->t_cmax)
+( \
+ ((tup)->t_infomask & HEAP_MOVED) ? \
+ FirstCommandId \
+ : \
+ ( \
+ ((tup)->t_infomask & (HEAP_XMIN_IS_XMAX | HEAP_XMAX_INVALID)) ? \
+ (CommandId) (tup)->t_xmax \
+ : \
+ (CommandId) (tup)->t_cid \
+ ) \
+)

#define HeapTupleHeaderGetXvac(tup) \
( \
- AssertMacro((tup)->t_infomask & (HEAP_MOVED_IN | HEAP_MOVED_OFF)), \
- (TransactionId) (tup)->t_cmin \
+ AssertMacro((tup)->t_infomask & HEAP_MOVED), \
+ (tup)->t_cid \
)


#define HeapTupleHeaderSetXmin(tup, xid) \
- (TransactionIdStore((xid), &(tup)->t_xmin))
+( \
+ TransactionIdStore((xid), &(tup)->t_xmin) \
+)

#define HeapTupleHeaderSetXminInvalid(tup) \
- (StoreInvalidTransactionId(&(tup)->t_xmin))
+do { \
+ (tup)->t_infomask &= ~HEAP_XMIN_IS_XMAX; \
+ StoreInvalidTransactionId(&(tup)->t_xmin); \
+} while (0)

#define HeapTupleHeaderSetXmax(tup, xid) \
- (TransactionIdStore((xid), &(tup)->t_xmax))
+do { \
+ if (TransactionIdEquals((tup)->t_xmin, (xid))) \
+ (tup)->t_infomask |= HEAP_XMIN_IS_XMAX; \
+ else \
+ { \
+ (tup)->t_infomask &= ~HEAP_XMIN_IS_XMAX; \
+ TransactionIdStore((xid), &(tup)->t_xmax); \
+ } \
+} while (0)

#define HeapTupleHeaderSetXmaxInvalid(tup) \
- (StoreInvalidTransactionId(&(tup)->t_xmax))
+do { \
+ (tup)->t_infomask &= ~HEAP_XMIN_IS_XMAX; \
+ StoreInvalidTransactionId(&(tup)->t_xmax); \
+} while (0)

#define HeapTupleHeaderSetCmin(tup, cid) \
-( \
- AssertMacro(!((tup)->t_infomask & (HEAP_MOVED_IN | HEAP_MOVED_OFF))), \
- (tup)->t_cmin = (cid) \
-)
+do { \
+ Assert(!((tup)->t_infomask & HEAP_MOVED)); \
+ TransactionIdStore((TransactionId) (cid), &(tup)->t_cid); \
+} while (0)

#define HeapTupleHeaderSetCmax(tup, cid) \
- ((tup)->t_cmax = (cid))
+do { \
+ Assert(!((tup)->t_infomask & HEAP_MOVED)); \
+ if ((tup)->t_infomask & HEAP_XMIN_IS_XMAX) \
+ TransactionIdStore((TransactionId) (cid), &(tup)->t_xmax); \
+ else \
+ TransactionIdStore((TransactionId) (cid), &(tup)->t_cid); \
+} while (0)

#define HeapTupleHeaderSetXvac(tup, xid) \
-( \
- AssertMacro((tup)->t_infomask & (HEAP_MOVED_IN | HEAP_MOVED_OFF)), \
- TransactionIdStore((xid), (TransactionId *) &((tup)->t_cmin)) \
-)
+do { \
+ Assert((tup)->t_infomask & HEAP_MOVED); \
+ TransactionIdStore((xid), &(tup)->t_cid); \
+} while (0)


/*

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Christopher Kings-Lynne 2002-06-14 02:15:06 Re: Making serial survive pg_dump
Previous Message Bear Giles 2002-06-14 00:58:33 Re: [HACKERS] First cut at SSL documentation

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2002-06-14 02:34:09 Re: [HACKERS] First cut at SSL documentation
Previous Message Bear Giles 2002-06-14 00:58:33 Re: [HACKERS] First cut at SSL documentation