From 5c024ee72abe7033c1d691e2e2a83d4b9ff2085a Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Wed, 27 Mar 2024 23:37:35 +0200
Subject: [PATCH v9 17/21] Move 'frozen' array to PruneState.

It can be internal to heap_page_prune_and_freeze(), like the other
arrays. The freeze subroutines don't need it.
---
 src/backend/access/heap/pruneheap.c | 22 ++++++++++++----------
 src/include/access/heapam.h         |  8 +-------
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 6f039002684..fd8dc0bc85b 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -43,10 +43,12 @@ typedef struct
 	int			nredirected;	/* numbers of entries in arrays below */
 	int			ndead;
 	int			nunused;
+	int			nfrozen;
 	/* arrays that accumulate indexes of items to be changed */
 	OffsetNumber redirected[MaxHeapTuplesPerPage * 2];
 	OffsetNumber nowdead[MaxHeapTuplesPerPage];
 	OffsetNumber nowunused[MaxHeapTuplesPerPage];
+	HeapTupleFreeze frozen[MaxHeapTuplesPerPage];
 
 	/*
 	 * marked[i] is true if item i is entered in one of the above arrays.
@@ -320,7 +322,7 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 	prstate.vistest = vistest;
 	prstate.actions = actions;
 	prstate.latest_xid_removed = InvalidTransactionId;
-	prstate.nredirected = prstate.ndead = prstate.nunused = 0;
+	prstate.nredirected = prstate.ndead = prstate.nunused = prstate.nfrozen = 0;
 	memset(prstate.marked, 0, sizeof(prstate.marked));
 	memset(prstate.counted, 0, sizeof(prstate.counted));
 
@@ -363,7 +365,6 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 		presult->set_all_frozen = true;
 	else
 		presult->set_all_frozen = false;
-	presult->nfrozen = 0;
 
 	/*
 	 * Deliberately delay unsetting all_visible until later during pruning.
@@ -512,7 +513,7 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 
 		if (prstate.pagefrz.freeze_required)
 			do_freeze = true;
-		else if (whole_page_freezable && presult->nfrozen > 0)
+		else if (whole_page_freezable && prstate.nfrozen > 0)
 		{
 			/*
 			 * Freezing would make the page all-frozen. In this case, we will
@@ -535,8 +536,8 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 	 * want to avoid doing the pre-freeze checks in a critical section.
 	 */
 	if (do_freeze)
-		heap_pre_freeze_checks(buffer, prstate.pagefrz.frozen, presult->nfrozen);
-	else if (!presult->set_all_frozen || presult->nfrozen > 0)
+		heap_pre_freeze_checks(buffer, prstate.frozen, prstate.nfrozen);
+	else if (!presult->set_all_frozen || prstate.nfrozen > 0)
 	{
 		/*
 		 * If we will neither freeze tuples on the page nor set the page all
@@ -544,7 +545,7 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 		 * will be no newly frozen tuples.
 		 */
 		presult->set_all_frozen = false;
-		presult->nfrozen = 0;	/* avoid miscounts in instrumenation */
+		prstate.nfrozen = 0;	/* avoid miscounts in instrumenation */
 	}
 
 	/* Any error while applying the changes is critical */
@@ -602,7 +603,7 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 				frz_conflict_horizon = prstate.pagefrz.cutoffs->OldestXmin;
 				TransactionIdRetreat(frz_conflict_horizon);
 			}
-			heap_freeze_prepared_tuples(buffer, prstate.pagefrz.frozen, presult->nfrozen);
+			heap_freeze_prepared_tuples(buffer, prstate.frozen, prstate.nfrozen);
 		}
 
 		MarkBufferDirty(buffer);
@@ -632,7 +633,7 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 			log_heap_prune_and_freeze(relation, buffer,
 									  conflict_xid,
 									  true, reason,
-									  prstate.pagefrz.frozen, presult->nfrozen,
+									  prstate.frozen, prstate.nfrozen,
 									  prstate.redirected, prstate.nredirected,
 									  prstate.nowdead, prstate.ndead,
 									  prstate.nowunused, prstate.nunused);
@@ -649,6 +650,7 @@ heap_page_prune_and_freeze(Relation relation, Buffer buffer,
 	 */
 	if (!presult->set_all_frozen)
 		presult->vm_conflict_horizon = prstate.visibility_cutoff_xid;
+	presult->nfrozen = prstate.nfrozen;
 
 	/*
 	 * If we will freeze tuples on the page or, even if we don't freeze tuples
@@ -1298,11 +1300,11 @@ heap_prune_record_live_or_recently_dead(Page page, PruneState *prstate, OffsetNu
 	{
 		/* Tuple with storage -- consider need to freeze */
 		if ((heap_prepare_freeze_tuple(htup, &prstate->pagefrz,
-									   &prstate->pagefrz.frozen[presult->nfrozen],
+									   &prstate->frozen[presult->nfrozen],
 									   &totally_frozen)))
 		{
 			/* Save prepared freeze plan for later */
-			prstate->pagefrz.frozen[presult->nfrozen++].offset = offnum;
+			prstate->frozen[presult->nfrozen++].offset = offnum;
 		}
 
 		/*
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index a0420bea2eb..ef61e0277ee 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -191,11 +191,6 @@ typedef struct HeapPageFreeze
 	MultiXactId NoFreezePageRelminMxid;
 
 	struct VacuumCutoffs *cutoffs;
-
-	/*
-	 * One entry for every tuple that we may freeze.
-	 */
-	HeapTupleFreeze frozen[MaxHeapTuplesPerPage];
 } HeapPageFreeze;
 
 /*
@@ -227,14 +222,13 @@ typedef struct PruneFreezeResult
 {
 	int			ndeleted;		/* Number of tuples deleted from the page */
 	int			nnewlpdead;		/* Number of newly LP_DEAD items */
+	int			nfrozen;		/* Number of tuples we froze */
 
 	/*
 	 * The rest of the fields in PruneFreezeResult are only guaranteed to be
 	 * initialized if heap_page_prune_and_freeze() is passed
 	 * PRUNE_DO_TRY_FREEZE.
 	 */
-	/* Number of tuples we froze */
-	int			nfrozen;
 	/* Whether or not the page should be set all-frozen in the VM */
 	bool		set_all_frozen;
 
-- 
2.40.1

