nocfbot-0030-Demote-RPR-nfaVisitedNWords-to-a-local-per-Jian-H.txt

text/plain

Filename: nocfbot-0030-Demote-RPR-nfaVisitedNWords-to-a-local-per-Jian-H.txt
Type: text/plain
Part: 29
Message: Re: Row pattern recognition
From 66a754b84526730b31edf03462163ae42aec5f9e Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Mon, 1 Jun 2026 11:38:09 +0900
Subject: [PATCH 30/68] Demote RPR nfaVisitedNWords to a local per Jian He's
 round-3 review

nfaVisitedNWords is read only once, at init, to size the visited bitmap
(the per-row reset clears just the high-water range), so it need not live
in WindowAggState.  nfaStateSize is kept: it is recomputed per state
allocation, the engine's hottest path.
---
 src/backend/executor/README.rpr      | 2 --
 src/backend/executor/execRPR.c       | 2 +-
 src/backend/executor/nodeWindowAgg.c | 6 ++++--
 src/include/nodes/execnodes.h        | 2 --
 4 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/backend/executor/README.rpr b/src/backend/executor/README.rpr
index 9396a569fbd..26c1a1ea236 100644
--- a/src/backend/executor/README.rpr
+++ b/src/backend/executor/README.rpr
@@ -522,7 +522,6 @@ V-3. RPR Fields of WindowAggState
   nfaStateFree                  Reuse pool for states
   nfaVarMatched                 Per-row cache: varMatched[varId]
   nfaVisitedElems               Bitmap for cycle detection
-  nfaVisitedNWords              Number of bitmapwords in nfaVisitedElems
   nfaVisitedMinWord             Lowest bitmapword index touched since last reset
   nfaVisitedMaxWord             Highest bitmapword index touched since last reset
   nfaStateSize                  Precomputed size of RPRNFAState
@@ -1542,7 +1541,6 @@ Appendix B. Data Structure Relationship Diagram
     |--- defineMatchStartDependent: Bitmapset* (match_start_dependent
     |        DEFINE vars; see VI-4)
     |--- nfaVisitedElems: bitmapword* (cycle detection)
-    |--- nfaVisitedNWords: int (size of nfaVisitedElems)
     |--- nfaVisitedMinWord / nfaVisitedMaxWord: int16
     |        (touched-word range for fast reset)
     |--- nfaLastProcessedRow: int64 (-1 = none)
diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c
index 4022ca66e84..dca1e45be57 100644
--- a/src/backend/executor/execRPR.c
+++ b/src/backend/executor/execRPR.c
@@ -41,7 +41,7 @@
 /*
  * Set the visited bit for elemIdx and update the high-water marks
  * (nfaVisitedMin/MaxWord) so that the next reset only has to clear
- * the touched range instead of the full nfaVisitedNWords array.
+ * the touched range instead of the full nfaVisitedElems bitmap.
  */
 static inline void
 nfa_mark_visited(WindowAggState *winstate, int16 elemIdx)
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index bcb3614e96e..0b0196e7e40 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -3058,12 +3058,14 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
 	/* Calculate NFA state size and allocate cycle detection bitmap */
 	if (node->rpPattern != NULL)
 	{
+		int			nfaVisitedNWords;
+
 		winstate->nfaStateSize = offsetof(RPRNFAState, counts) +
 			sizeof(int32) * node->rpPattern->maxDepth;
-		winstate->nfaVisitedNWords =
+		nfaVisitedNWords =
 			(node->rpPattern->numElements - 1) / BITS_PER_BITMAPWORD + 1;
 		winstate->nfaVisitedElems = palloc0(sizeof(bitmapword) *
-											winstate->nfaVisitedNWords);
+											nfaVisitedNWords);
 		/* High-water mark sentinels: no bits set yet. */
 		winstate->nfaVisitedMinWord = INT16_MAX;
 		winstate->nfaVisitedMaxWord = -1;
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 1fba14b892e..4641ed36cee 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2671,8 +2671,6 @@ typedef struct WindowAggState
 											 * (match_start-dependent) */
 	bitmapword *nfaVisitedElems;	/* elemIdx visited bitmap for cycle
 									 * detection */
-	int			nfaVisitedNWords;	/* number of bitmapwords in
-									 * nfaVisitedElems */
 	int16		nfaVisitedMinWord;	/* lowest bitmapword index touched since
 									 * last reset (INT16_MAX = none) */
 	int16		nfaVisitedMaxWord;	/* highest bitmapword index touched since
-- 
2.50.1 (Apple Git-155)