From 6f5c9f8b4c92d7610a86e993525e4fbd87401ef4 Mon Sep 17 00:00:00 2001 From: jian he Date: Fri, 29 May 2026 12:27:13 +0800 Subject: [PATCH v47 1/3] remove nfaStateSize and nfaVisitedNWords Refactor struct WindowAggState: Remove the nfaStateSize and nfaVisitedNWords fields because they are constant, and we can easily compute it. --- src/backend/executor/README.rpr | 2 -- src/backend/executor/execRPR.c | 12 +++++++----- src/backend/executor/nodeWindowAgg.c | 10 ++++------ src/include/nodes/execnodes.h | 3 --- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/backend/executor/README.rpr b/src/backend/executor/README.rpr index 2bf7703c777..05e1609a666 100644 --- a/src/backend/executor/README.rpr +++ b/src/backend/executor/README.rpr @@ -508,7 +508,6 @@ V-3. RPR Fields of WindowAggState nfaStateFree Reuse pool for states nfaVarMatched Per-row cache: varMatched[varId] nfaVisitedElems Bitmap for cycle detection - nfaStateSize Precomputed size of RPRNFAState Memory management: @@ -1461,7 +1460,6 @@ Appendix B. Data Structure Relationship Diagram |--- defineClauseList: List |--- nfaVarMatched: bool[] (per-row cache) |--- nfaVisitedElems: bitmapword* (cycle detection) - |--- nfaStateSize: Size (pre-calculated RPRNFAState allocation size) |--- nfaContext <-> nfaContextTail (doubly-linked list) | +--- RPRNFAContext | |--- states: RPRNFAState* (linked list) diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index f381a84961d..8664cf7acc3 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -193,23 +193,25 @@ static void nfa_advance(WindowAggState *winstate, RPRNFAContext *ctx, static RPRNFAState * nfa_state_alloc(WindowAggState *winstate) { + int nfaStateSize; RPRNFAState *state; + nfaStateSize = offsetof(RPRNFAState, counts) + sizeof(int32) * winstate->rpPattern->maxDepth; + /* Try to reuse from free list first */ if (winstate->nfaStateFree != NULL) { state = winstate->nfaStateFree; winstate->nfaStateFree = state->next; + memset(state, 0, nfaStateSize); } else { /* Allocate in partition context for proper lifetime */ - state = MemoryContextAlloc(winstate->partcontext, winstate->nfaStateSize); + state = MemoryContextAllocZero(winstate->partcontext, + nfaStateSize); } - /* Initialize entire state to zero */ - memset(state, 0, winstate->nfaStateSize); - /* Update statistics */ winstate->nfaStatesActive++; winstate->nfaStatesTotalCreated++; @@ -1396,7 +1398,7 @@ nfa_advance(WindowAggState *winstate, RPRNFAContext *ctx, int64 currentPos) /* Clear visited bitmap before each state's DFS expansion */ memset(winstate->nfaVisitedElems, 0, - sizeof(bitmapword) * winstate->nfaVisitedNWords); + sizeof(bitmapword) * ((winstate->rpPattern->numElements - 1) / BITS_PER_BITMAPWORD + 1)); state = states; states = states->next; diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index d4d57ffd795..7682a12402c 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -3056,12 +3056,10 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) /* Calculate NFA state size and allocate cycle detection bitmap */ if (node->rpPattern != NULL) { - winstate->nfaStateSize = offsetof(RPRNFAState, counts) + - sizeof(int32) * node->rpPattern->maxDepth; - winstate->nfaVisitedNWords = - (node->rpPattern->numElements - 1) / BITS_PER_BITMAPWORD + 1; - winstate->nfaVisitedElems = palloc0(sizeof(bitmapword) * - winstate->nfaVisitedNWords); + int nfaVisitedNWords; + + nfaVisitedNWords = (node->rpPattern->numElements - 1) / BITS_PER_BITMAPWORD + 1; + winstate->nfaVisitedElems = palloc0(sizeof(bitmapword) * nfaVisitedNWords); } /* Set up row pattern recognition DEFINE clause */ diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 0cb01baa949..3ef0127c105 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -2663,7 +2663,6 @@ typedef struct WindowAggState * traversal) */ RPRNFAContext *nfaContextFree; /* recycled NFA context nodes */ RPRNFAState *nfaStateFree; /* recycled NFA state nodes */ - Size nfaStateSize; /* pre-calculated RPRNFAState size */ bool *nfaVarMatched; /* per-row cache: varMatched[varId] for varId * < numDefines */ Bitmapset *defineMatchStartDependent; /* DEFINE vars needing per-context @@ -2671,8 +2670,6 @@ typedef struct WindowAggState * (match_start-dependent) */ bitmapword *nfaVisitedElems; /* elemIdx visited bitmap for cycle * detection */ - int nfaVisitedNWords; /* number of bitmapwords in - * nfaVisitedElems */ int64 nfaLastProcessedRow; /* last row processed by NFA (-1 = * none) */ -- 2.34.1