From 3f02fe6f75a9eb49bea6582d10ba4bdb8a62c29b Mon Sep 17 00:00:00 2001 From: David Christensen Date: Wed, 7 Feb 2024 10:49:31 -0500 Subject: [PATCH v2 4/4] Split MaxTIDsPerBTreePage into runtime and max values --- contrib/amcheck/verify_nbtree.c | 4 ++-- src/backend/access/nbtree/nbtdedup.c | 4 ++-- src/backend/access/nbtree/nbtinsert.c | 4 ++-- src/backend/access/nbtree/nbtree.c | 4 ++-- src/backend/access/nbtree/nbtsearch.c | 8 ++++---- src/include/access/nbtree.h | 24 ++++++++++++++++++------ 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index b1089693be..73352296e2 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -534,12 +534,12 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace, /* * Size Bloom filter based on estimated number of tuples in index, * while conservatively assuming that each block must contain at least - * MaxTIDsPerBTreePage / 3 "plain" tuples -- see + * ClusterMaxTIDsPerBTreePage / 3 "plain" tuples -- see * bt_posting_plain_tuple() for definition, and details of how posting * list tuples are handled. */ total_pages = RelationGetNumberOfBlocks(rel); - total_elems = Max(total_pages * (MaxTIDsPerBTreePage / 3), + total_elems = Max(total_pages * (ClusterMaxTIDsPerBTreePage / 3), (int64) state->rel->rd_rel->reltuples); /* Generate a random seed to avoid repetition */ seed = pg_prng_uint64(&pg_global_prng_state); diff --git a/src/backend/access/nbtree/nbtdedup.c b/src/backend/access/nbtree/nbtdedup.c index 456d86b51c..c8af6cbc2a 100644 --- a/src/backend/access/nbtree/nbtdedup.c +++ b/src/backend/access/nbtree/nbtdedup.c @@ -355,8 +355,8 @@ _bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel, delstate.bottomup = true; delstate.bottomupfreespace = Max(BLCKSZ / 16, newitemsz); delstate.ndeltids = 0; - delstate.deltids = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexDelete)); - delstate.status = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexStatus)); + delstate.deltids = palloc(ClusterMaxTIDsPerBTreePage * sizeof(TM_IndexDelete)); + delstate.status = palloc(ClusterMaxTIDsPerBTreePage * sizeof(TM_IndexStatus)); minoff = P_FIRSTDATAKEY(opaque); maxoff = PageGetMaxOffsetNumber(page); diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 711b7afff3..da8352d403 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -2829,8 +2829,8 @@ _bt_simpledel_pass(Relation rel, Buffer buffer, Relation heapRel, delstate.bottomup = false; delstate.bottomupfreespace = 0; delstate.ndeltids = 0; - delstate.deltids = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexDelete)); - delstate.status = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexStatus)); + delstate.deltids = palloc(ClusterMaxTIDsPerBTreePage * sizeof(TM_IndexDelete)); + delstate.status = palloc(ClusterMaxTIDsPerBTreePage * sizeof(TM_IndexStatus)); for (offnum = minoff; offnum <= maxoff; diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 55bd14fecd..ad37c05205 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -246,8 +246,8 @@ btgettuple(IndexScanDesc scan, ScanDirection dir) */ if (so->killedItems == NULL) so->killedItems = (int *) - palloc(MaxTIDsPerBTreePage * sizeof(int)); - if (so->numKilled < MaxTIDsPerBTreePage) + palloc(ClusterMaxTIDsPerBTreePage * sizeof(int)); + if (so->numKilled < ClusterMaxTIDsPerBTreePage) so->killedItems[so->numKilled++] = so->currPos.itemIndex; } diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 23e723a233..1d77f1303f 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -1726,7 +1726,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, if (!continuescan) so->currPos.moreRight = false; - Assert(itemIndex <= MaxTIDsPerBTreePage); + Assert(itemIndex <= ClusterMaxTIDsPerBTreePage); so->currPos.firstItem = 0; so->currPos.lastItem = itemIndex - 1; so->currPos.itemIndex = 0; @@ -1734,7 +1734,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, else { /* load items[] in descending order */ - itemIndex = MaxTIDsPerBTreePage; + itemIndex = ClusterMaxTIDsPerBTreePage; offnum = Min(offnum, maxoff); @@ -1836,8 +1836,8 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, Assert(itemIndex >= 0); so->currPos.firstItem = itemIndex; - so->currPos.lastItem = MaxTIDsPerBTreePage - 1; - so->currPos.itemIndex = MaxTIDsPerBTreePage - 1; + so->currPos.lastItem = ClusterMaxTIDsPerBTreePage - 1; + so->currPos.itemIndex = ClusterMaxTIDsPerBTreePage - 1; } return (so->currPos.firstItem <= so->currPos.lastItem); diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 676fa5e0a9..568646a146 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -172,9 +172,17 @@ typedef struct BTMetaPageData MAXALIGN(sizeof(BTPageOpaqueData))) / 3) /* - * MaxTIDsPerBTreePage is an upper bound on the number of heap TIDs tuples - * that may be stored on a btree leaf page. It is used to size the - * per-page temporary buffers. + * ClusterMaxTIDsPerBTreePage is a cluster-specific upper bound on the number + * of heap TIDs tuples that may be stored on a btree leaf page. It is used to + * size the per-page temporary buffers. + * + * MaxTIDsPerBTreePageLimit is the largest value that + * ClusterMaxTIDsPerBTreePage could be. While these currently evaluate to the + * same value, these are being split out so ClusterMaxTIDsPerBTreePage can + * become a variable instead of a constant. + * + * The CalcMaxTIDsPerBTreePage() macro is used to determine the appropriate + * values, given the usable page space on a given page. * * Note: we don't bother considering per-tuple overheads here to keep * things simple (value is based on how many elements a single array of @@ -182,9 +190,13 @@ typedef struct BTMetaPageData * special area). The value is slightly higher (i.e. more conservative) * than necessary as a result, which is considered acceptable. */ -#define MaxTIDsPerBTreePage \ - (int) ((BLCKSZ - SizeOfPageHeaderData - sizeof(BTPageOpaqueData)) / \ +#define CalcMaxTIDsPerBTreePage(size) \ + (int) (((size) - sizeof(BTPageOpaqueData)) / \ sizeof(ItemPointerData)) +#define ClusterMaxTIDsPerBTreePage \ + CalcMaxTIDsPerBTreePage(BLCKSZ - SizeOfPageHeaderData) +#define MaxTIDsPerBTreePageLimit \ + CalcMaxTIDsPerBTreePage(BLCKSZ - SizeOfPageHeaderData) /* * The leaf-page fillfactor defaults to 90% but is user-adjustable. @@ -982,7 +994,7 @@ typedef struct BTScanPosData int lastItem; /* last valid index in items[] */ int itemIndex; /* current index in items[] */ - BTScanPosItem items[MaxTIDsPerBTreePage]; /* MUST BE LAST */ + BTScanPosItem items[MaxTIDsPerBTreePageLimit]; /* MUST BE LAST */ } BTScanPosData; typedef BTScanPosData *BTScanPos; -- 2.40.1