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: 28
Message:
Re: Row pattern recognition
From 469690fa37365a5350a7fa6bcdc3f3e1f459a935 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/38] 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 7e636f8cb12..141ab91caf5 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -2672,8 +2672,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)