aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-11-01 16:24:40 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2021-11-01 16:24:40 -0400
commite477642a1ba8041c94cae2f8bbdb689f05cb0260 (patch)
treea476a1eff3c80c95badd87efd02d72b54f927700 /src
parent17227825ca4288c70af45038ac6af26be7fde570 (diff)
downloadpostgresql-e477642a1ba8041c94cae2f8bbdb689f05cb0260.tar.gz
postgresql-e477642a1ba8041c94cae2f8bbdb689f05cb0260.zip
Avoid some other O(N^2) hazards in list manipulation.
In the same spirit as 6301c3ada, fix some more places where we were using list_delete_first() in a loop and thereby risking O(N^2) behavior. It's not clear that the lists manipulated in these spots can get long enough to be really problematic ... but it's not clear that they can't, either, and the fixes are simple enough. As before, back-patch to v13. Discussion: https://postgr.es/m/CD2F0E7F-9822-45EC-A411-AE56F14DEA9F@amazon.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/nodeAgg.c17
-rw-r--r--src/backend/jit/llvm/llvmjit.c10
2 files changed, 10 insertions, 17 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 4b62323e218..3bc78331e45 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -2610,8 +2610,9 @@ agg_refill_hash_table(AggState *aggstate)
if (aggstate->hash_batches == NIL)
return false;
- batch = linitial(aggstate->hash_batches);
- aggstate->hash_batches = list_delete_first(aggstate->hash_batches);
+ /* hash_batches is a stack, with the top item at the end of the list */
+ batch = llast(aggstate->hash_batches);
+ aggstate->hash_batches = list_delete_last(aggstate->hash_batches);
hash_agg_set_limits(aggstate->hashentrysize, batch->input_card,
batch->used_bits, &aggstate->hash_mem_limit,
@@ -3190,7 +3191,7 @@ hashagg_spill_finish(AggState *aggstate, HashAggSpill *spill, int setno)
new_batch = hashagg_batch_new(tapeset, tapenum, setno,
spill->ntuples[i], cardinality,
used_bits);
- aggstate->hash_batches = lcons(new_batch, aggstate->hash_batches);
+ aggstate->hash_batches = lappend(aggstate->hash_batches, new_batch);
aggstate->hash_batches_used++;
}
@@ -3205,8 +3206,6 @@ hashagg_spill_finish(AggState *aggstate, HashAggSpill *spill, int setno)
static void
hashagg_reset_spill_state(AggState *aggstate)
{
- ListCell *lc;
-
/* free spills from initial pass */
if (aggstate->hash_spills != NULL)
{
@@ -3224,13 +3223,7 @@ hashagg_reset_spill_state(AggState *aggstate)
}
/* free batches */
- foreach(lc, aggstate->hash_batches)
- {
- HashAggBatch *batch = (HashAggBatch *) lfirst(lc);
-
- pfree(batch);
- }
- list_free(aggstate->hash_batches);
+ list_free_deep(aggstate->hash_batches);
aggstate->hash_batches = NIL;
/* close tape set */
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index b73705d4ad3..8babf09f2a6 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -171,6 +171,7 @@ static void
llvm_release_context(JitContext *context)
{
LLVMJitContext *llvm_context = (LLVMJitContext *) context;
+ ListCell *lc;
/*
* When this backend is exiting, don't clean up LLVM. As an error might
@@ -188,12 +189,9 @@ llvm_release_context(JitContext *context)
llvm_context->module = NULL;
}
- while (llvm_context->handles != NIL)
+ foreach(lc, llvm_context->handles)
{
- LLVMJitHandle *jit_handle;
-
- jit_handle = (LLVMJitHandle *) linitial(llvm_context->handles);
- llvm_context->handles = list_delete_first(llvm_context->handles);
+ LLVMJitHandle *jit_handle = (LLVMJitHandle *) lfirst(lc);
#if LLVM_VERSION_MAJOR > 11
{
@@ -221,6 +219,8 @@ llvm_release_context(JitContext *context)
pfree(jit_handle);
}
+ list_free(llvm_context->handles);
+ llvm_context->handles = NIL;
}
/*