From 0027dcec705d9267d7639d482587287c5480e582 Mon Sep 17 00:00:00 2001
From: David Christensen <david.christensen@crunchydata.com>
Date: Wed, 7 Feb 2024 10:49:31 -0500
Subject: [PATCH v1 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 7a20a967ad..60324780df 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -533,12 +533,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 4674e5267a..ccc2454801 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 2a4f990583..520e52ee12 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -263,8 +263,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 63ee9ba225..4925ace477 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

