From 65232ff8bbba85a69836b45360494fe590945b5b Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Fri, 26 Jan 2024 17:12:20 +0900 Subject: [PATCH v7 1/3] Make binaryheap enlargeable. The node array space of the binaryheap is doubled when there is no available space. Reviewed-by: Hayato Kuroda, Vignesh C, Ajin Cherian, Tomas Vondra, Shubham Khanna Discussion: https://postgr.es/m/CAD21AoDffo37RC-eUuyHJKVEr017V2YYDLyn1xF_00ofptWbkg%40mail.gmail.com --- src/common/binaryheap.c | 36 +++++++++++++++++++----------------- src/include/lib/binaryheap.h | 2 +- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/common/binaryheap.c b/src/common/binaryheap.c index 7377ebdf15..6f16c83295 100644 --- a/src/common/binaryheap.c +++ b/src/common/binaryheap.c @@ -38,17 +38,16 @@ static void sift_up(binaryheap *heap, int node_off); binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg) { - int sz; binaryheap *heap; - sz = offsetof(binaryheap, bh_nodes) + sizeof(bh_node_type) * capacity; - heap = (binaryheap *) palloc(sz); + heap = (binaryheap *) palloc(sizeof(binaryheap)); heap->bh_space = capacity; heap->bh_compare = compare; heap->bh_arg = arg; heap->bh_size = 0; heap->bh_has_heap_property = true; + heap->bh_nodes = (bh_node_type *) palloc(sizeof(bh_node_type) * capacity); return heap; } @@ -104,6 +103,17 @@ parent_offset(int i) return (i - 1) / 2; } +/* + * Make sure there is enough space for nodes. + */ +static void +bh_enlarge_node_array(binaryheap *heap) +{ + heap->bh_space *= 2; + heap->bh_nodes = repalloc(heap->bh_nodes, + sizeof(bh_node_type) * heap->bh_space); +} + /* * binaryheap_add_unordered * @@ -115,14 +125,10 @@ parent_offset(int i) void binaryheap_add_unordered(binaryheap *heap, bh_node_type d) { + /* make sure enough space for a new node */ if (heap->bh_size >= heap->bh_space) - { -#ifdef FRONTEND - pg_fatal("out of binary heap slots"); -#else - elog(ERROR, "out of binary heap slots"); -#endif - } + bh_enlarge_node_array(heap); + heap->bh_has_heap_property = false; heap->bh_nodes[heap->bh_size] = d; heap->bh_size++; @@ -153,14 +159,10 @@ binaryheap_build(binaryheap *heap) void binaryheap_add(binaryheap *heap, bh_node_type d) { + /* make sure enough space for a new node */ if (heap->bh_size >= heap->bh_space) - { -#ifdef FRONTEND - pg_fatal("out of binary heap slots"); -#else - elog(ERROR, "out of binary heap slots"); -#endif - } + bh_enlarge_node_array(heap); + heap->bh_nodes[heap->bh_size] = d; heap->bh_size++; sift_up(heap, heap->bh_size - 1); diff --git a/src/include/lib/binaryheap.h b/src/include/lib/binaryheap.h index 19025c08ef..1439f20803 100644 --- a/src/include/lib/binaryheap.h +++ b/src/include/lib/binaryheap.h @@ -46,7 +46,7 @@ typedef struct binaryheap bool bh_has_heap_property; /* debugging cross-check */ binaryheap_comparator bh_compare; void *bh_arg; - bh_node_type bh_nodes[FLEXIBLE_ARRAY_MEMBER]; + bh_node_type *bh_nodes; } binaryheap; extern binaryheap *binaryheap_allocate(int capacity, -- 2.39.3