From b9bd5c82336decc3124b10a6d34d8222d0dd487f Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 8 Mar 2017 13:49:22 -0300 Subject: [PATCH 4/6] freeup 3bits ip_posid v16 --- src/backend/access/gin/ginget.c | 2 +- src/backend/access/gin/ginpostinglist.c | 2 +- src/include/access/ginblock.h | 10 +++++----- src/include/access/gist_private.h | 4 ++-- src/include/access/htup_details.h | 2 +- src/include/storage/itemptr.h | 32 ++++++++++++++++++++++++++++---- src/include/storage/off.h | 9 ++++++++- 7 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index aa0b02f..1e1c978 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -928,7 +928,7 @@ keyGetItem(GinState *ginstate, MemoryContext tempCtx, GinScanKey key, * Find the minimum item > advancePast among the active entry streams. * * Note: a lossy-page entry is encoded by a ItemPointer with max value for - * offset (0xffff), so that it will sort after any exact entries for the + * offset (0x1fff), so that it will sort after any exact entries for the * same page. So we'll prefer to return exact pointers not lossy * pointers, which is good. */ diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c index 8d2d31a..b22b9f5 100644 --- a/src/backend/access/gin/ginpostinglist.c +++ b/src/backend/access/gin/ginpostinglist.c @@ -253,7 +253,7 @@ ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, Assert(ndecoded == totalpacked); for (i = 0; i < ndecoded; i++) - Assert(memcmp(&tmp[i], &ipd[i], sizeof(ItemPointerData)) == 0); + Assert(ItemPointerEquals(&tmp[i], &ipd[i])); pfree(tmp); } #endif diff --git a/src/include/access/ginblock.h b/src/include/access/ginblock.h index 438912c..3f7a3f0 100644 --- a/src/include/access/ginblock.h +++ b/src/include/access/ginblock.h @@ -160,14 +160,14 @@ typedef struct GinMetaPageData (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)0 && \ GinItemPointerGetBlockNumber(p) == (BlockNumber)0) #define ItemPointerSetMax(p) \ - ItemPointerSet((p), InvalidBlockNumber, (OffsetNumber)0xffff) + ItemPointerSet((p), InvalidBlockNumber, (OffsetNumber)OffsetNumberMask) #define ItemPointerIsMax(p) \ - (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)0xffff && \ + (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)OffsetNumberMask && \ GinItemPointerGetBlockNumber(p) == InvalidBlockNumber) #define ItemPointerSetLossyPage(p, b) \ - ItemPointerSet((p), (b), (OffsetNumber)0xffff) + ItemPointerSet((p), (b), (OffsetNumber)OffsetNumberMask) #define ItemPointerIsLossyPage(p) \ - (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)0xffff && \ + (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)OffsetNumberMask && \ GinItemPointerGetBlockNumber(p) != InvalidBlockNumber) /* @@ -218,7 +218,7 @@ typedef signed char GinNullCategory; */ #define GinGetNPosting(itup) GinItemPointerGetOffsetNumber(&(itup)->t_tid) #define GinSetNPosting(itup,n) ItemPointerSetOffsetNumber(&(itup)->t_tid,n) -#define GIN_TREE_POSTING ((OffsetNumber)0xffff) +#define GIN_TREE_POSTING ((OffsetNumber)OffsetNumberMask) #define GinIsPostingTree(itup) (GinGetNPosting(itup) == GIN_TREE_POSTING) #define GinSetPostingTree(itup, blkno) ( GinSetNPosting((itup),GIN_TREE_POSTING), ItemPointerSetBlockNumber(&(itup)->t_tid, blkno) ) #define GinGetPostingTree(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid) diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 1ad4ed6..0ad11f1 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -269,8 +269,8 @@ typedef struct * invalid tuples in an index, so throwing an error is as far as we go with * supporting that. */ -#define TUPLE_IS_VALID 0xffff -#define TUPLE_IS_INVALID 0xfffe +#define TUPLE_IS_VALID OffsetNumberMask +#define TUPLE_IS_INVALID OffsetNumberPrev(OffsetNumberMask) #define GistTupleIsInvalid(itup) ( ItemPointerGetOffsetNumber( &((itup)->t_tid) ) == TUPLE_IS_INVALID ) #define GistTupleSetValid(itup) ItemPointerSetOffsetNumber( &((itup)->t_tid), TUPLE_IS_VALID ) diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h index 24433c7..4d614b7 100644 --- a/src/include/access/htup_details.h +++ b/src/include/access/htup_details.h @@ -288,7 +288,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 60d0070..3144bdd 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))) /* * ItemPointerGetBlockNumber @@ -82,13 +82,37 @@ typedef ItemPointerData *ItemPointer; #define ItemPointerGetOffsetNumber(pointer) \ ( \ AssertMacro(ItemPointerIsValid(pointer)), \ - (pointer)->ip_posid \ + ((pointer)->ip_posid & OffsetNumberMask) \ ) /* Same as ItemPointerGetOffsetNumber but without any assert-checks */ #define ItemPointerGetOffsetNumberNoCheck(pointer) \ ( \ - (pointer)->ip_posid \ + ((pointer)->ip_posid & OffsetNumberMask) \ +) + +/* + * 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) \ ) /* @@ -99,7 +123,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..fe1834c 100644 --- a/src/include/storage/off.h +++ b/src/include/storage/off.h @@ -26,8 +26,15 @@ typedef uint16 OffsetNumber; #define InvalidOffsetNumber ((OffsetNumber) 0) #define FirstOffsetNumber ((OffsetNumber) 1) #define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData))) -#define OffsetNumberMask (0xffff) /* valid uint16 bits */ +/* + * Currently we support maxinum 32kB blocks and each ItemId takes 6 bytes. That + * limits the number of line pointers to (32kB/6 = 5461). 13 bits are enought o + * represent all line pointers. Hence we can reuse the high order bits in + * OffsetNumber for other purposes. + */ +#define OffsetNumberMask (0x1fff) /* valid uint16 bits */ +#define OffsetNumberBits 13 /* number of valid bits in OffsetNumber */ /* ---------------- * support macros * ---------------- -- 2.1.4