From f6ba238dd46416eb29ac43dadac0c69a75f106fe Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 28 Mar 2017 17:39:26 -0300 Subject: [PATCH] Free 3 bits of ItemPointerData.ip_posid Since we limit block size to 32 kB, the highest offset number used in a bufpage.h-organized page is 5461, which can be represented with 13 bits. Therefore, the upper 3 bits in 16-bit ItemPointerData.ip_posid are unused and this commit reserves them for other purposes. Author: Pavan Deolasee --- src/include/access/htup_details.h | 2 +- src/include/storage/itemptr.h | 30 +++++++++++++++++++++++++++--- src/include/storage/off.h | 11 ++++++++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h index 7b6285d..d3cc0ad 100644 --- a/src/include/access/htup_details.h +++ b/src/include/access/htup_details.h @@ -282,7 +282,7 @@ struct HeapTupleHeaderData * than MaxOffsetNumber, so that it can be distinguished from a valid * offset number in a regular item pointer. */ -#define SpecTokenOffsetNumber 0xfffe +#define SpecTokenOffsetNumber OffsetNumberPrev(OffsetNumberMask) /* * HeapTupleHeader accessor macros diff --git a/src/include/storage/itemptr.h b/src/include/storage/itemptr.h index c21d2ad..74eed4e 100644 --- a/src/include/storage/itemptr.h +++ b/src/include/storage/itemptr.h @@ -57,7 +57,7 @@ typedef ItemPointerData *ItemPointer; * True iff the disk item pointer is not NULL. */ #define ItemPointerIsValid(pointer) \ - ((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0))) + ((bool) (PointerIsValid(pointer) && (((pointer)->ip_posid & OffsetNumberMask) != 0))) /* * ItemPointerGetBlockNumberNoCheck @@ -84,7 +84,7 @@ typedef ItemPointerData *ItemPointer; */ #define ItemPointerGetOffsetNumberNoCheck(pointer) \ ( \ - (pointer)->ip_posid \ + ((pointer)->ip_posid & OffsetNumberMask) \ ) /* @@ -98,6 +98,30 @@ typedef ItemPointerData *ItemPointer; ) /* + * Get the flags stored in high order bits in the OffsetNumber. + */ +#define ItemPointerGetFlags(pointer) \ +( \ + ((pointer)->ip_posid & ~OffsetNumberMask) >> OffsetNumberBits \ +) + +/* + * Set the flag bits. We first left-shift since flags are defined starting 0x01 + */ +#define ItemPointerSetFlags(pointer, flags) \ +( \ + ((pointer)->ip_posid |= ((flags) << OffsetNumberBits)) \ +) + +/* + * Clear all flags. + */ +#define ItemPointerClearFlags(pointer) \ +( \ + ((pointer)->ip_posid &= OffsetNumberMask) \ +) + +/* * ItemPointerSet * Sets a disk item pointer to the specified block and offset. */ @@ -105,7 +129,7 @@ typedef ItemPointerData *ItemPointer; ( \ AssertMacro(PointerIsValid(pointer)), \ BlockIdSet(&((pointer)->ip_blkid), blockNumber), \ - (pointer)->ip_posid = offNum \ + (pointer)->ip_posid = (offNum) \ ) /* diff --git a/src/include/storage/off.h b/src/include/storage/off.h index fe8638f..f058fe1 100644 --- a/src/include/storage/off.h +++ b/src/include/storage/off.h @@ -26,7 +26,16 @@ typedef uint16 OffsetNumber; #define InvalidOffsetNumber ((OffsetNumber) 0) #define FirstOffsetNumber ((OffsetNumber) 1) #define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData))) -#define OffsetNumberMask (0xffff) /* valid uint16 bits */ + +/* + * The biggest BLCKSZ we support is 32kB, and each ItemId takes 6 bytes. + * That limits the number of line pointers in a page to 32kB/6B = 5461. + * Therefore, 13 bits in OffsetNumber are enough to represent all valid + * on-disk line pointers. Hence, we can reserve the high-order bits in + * OffsetNumber for other purposes. + */ +#define OffsetNumberBits 13 +#define OffsetNumberMask ((((uint16) 1) << OffsetNumberBits) - 1) /* ---------------- * support macros -- 2.1.4