From 66a754b84526730b31edf03462163ae42aec5f9e Mon Sep 17 00:00:00 2001 From: Henson Choi 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)