mirror of
https://github.com/postgres/postgres.git
synced 2025-05-17 06:41:24 +03:00
Make binaryheap enlargeable.
The node array space of the binaryheap is doubled when there is no available space. Reviewed-by: Vignesh C, Peter Smith, Hayato Kuroda, Ajin Cherian, Tomas Vondra, Shubham Khanna Discussion: https://postgr.es/m/CAD21AoDffo37RC-eUuyHJKVEr017V2YYDLyn1xF_00ofptWbkg%40mail.gmail.com
This commit is contained in:
parent
2c91e13013
commit
bcb14f4abc
@ -30,25 +30,24 @@ static void sift_up(binaryheap *heap, int node_off);
|
|||||||
/*
|
/*
|
||||||
* binaryheap_allocate
|
* binaryheap_allocate
|
||||||
*
|
*
|
||||||
* Returns a pointer to a newly-allocated heap that has the capacity to
|
* Returns a pointer to a newly-allocated heap with the given initial number
|
||||||
* store the given number of nodes, with the heap property defined by
|
* of nodes, and with the heap property defined by the given comparator
|
||||||
* the given comparator function, which will be invoked with the additional
|
* function, which will be invoked with the additional argument specified by
|
||||||
* argument specified by 'arg'.
|
* 'arg'.
|
||||||
*/
|
*/
|
||||||
binaryheap *
|
binaryheap *
|
||||||
binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
|
binaryheap_allocate(int num_nodes, binaryheap_comparator compare, void *arg)
|
||||||
{
|
{
|
||||||
int sz;
|
|
||||||
binaryheap *heap;
|
binaryheap *heap;
|
||||||
|
|
||||||
sz = offsetof(binaryheap, bh_nodes) + sizeof(bh_node_type) * capacity;
|
heap = (binaryheap *) palloc(sizeof(binaryheap));
|
||||||
heap = (binaryheap *) palloc(sz);
|
heap->bh_space = num_nodes;
|
||||||
heap->bh_space = capacity;
|
|
||||||
heap->bh_compare = compare;
|
heap->bh_compare = compare;
|
||||||
heap->bh_arg = arg;
|
heap->bh_arg = arg;
|
||||||
|
|
||||||
heap->bh_size = 0;
|
heap->bh_size = 0;
|
||||||
heap->bh_has_heap_property = true;
|
heap->bh_has_heap_property = true;
|
||||||
|
heap->bh_nodes = (bh_node_type *) palloc(sizeof(bh_node_type) * num_nodes);
|
||||||
|
|
||||||
return heap;
|
return heap;
|
||||||
}
|
}
|
||||||
@ -74,6 +73,7 @@ binaryheap_reset(binaryheap *heap)
|
|||||||
void
|
void
|
||||||
binaryheap_free(binaryheap *heap)
|
binaryheap_free(binaryheap *heap)
|
||||||
{
|
{
|
||||||
|
pfree(heap->bh_nodes);
|
||||||
pfree(heap);
|
pfree(heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +104,17 @@ parent_offset(int i)
|
|||||||
return (i - 1) / 2;
|
return (i - 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Double the space allocated for nodes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
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
|
* binaryheap_add_unordered
|
||||||
*
|
*
|
||||||
@ -115,14 +126,10 @@ parent_offset(int i)
|
|||||||
void
|
void
|
||||||
binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
|
binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
|
||||||
{
|
{
|
||||||
|
/* make sure enough space for a new node */
|
||||||
if (heap->bh_size >= heap->bh_space)
|
if (heap->bh_size >= heap->bh_space)
|
||||||
{
|
enlarge_node_array(heap);
|
||||||
#ifdef FRONTEND
|
|
||||||
pg_fatal("out of binary heap slots");
|
|
||||||
#else
|
|
||||||
elog(ERROR, "out of binary heap slots");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
heap->bh_has_heap_property = false;
|
heap->bh_has_heap_property = false;
|
||||||
heap->bh_nodes[heap->bh_size] = d;
|
heap->bh_nodes[heap->bh_size] = d;
|
||||||
heap->bh_size++;
|
heap->bh_size++;
|
||||||
@ -153,14 +160,10 @@ binaryheap_build(binaryheap *heap)
|
|||||||
void
|
void
|
||||||
binaryheap_add(binaryheap *heap, bh_node_type d)
|
binaryheap_add(binaryheap *heap, bh_node_type d)
|
||||||
{
|
{
|
||||||
|
/* make sure enough space for a new node */
|
||||||
if (heap->bh_size >= heap->bh_space)
|
if (heap->bh_size >= heap->bh_space)
|
||||||
{
|
enlarge_node_array(heap);
|
||||||
#ifdef FRONTEND
|
|
||||||
pg_fatal("out of binary heap slots");
|
|
||||||
#else
|
|
||||||
elog(ERROR, "out of binary heap slots");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
heap->bh_nodes[heap->bh_size] = d;
|
heap->bh_nodes[heap->bh_size] = d;
|
||||||
heap->bh_size++;
|
heap->bh_size++;
|
||||||
sift_up(heap, heap->bh_size - 1);
|
sift_up(heap, heap->bh_size - 1);
|
||||||
|
@ -46,10 +46,10 @@ typedef struct binaryheap
|
|||||||
bool bh_has_heap_property; /* debugging cross-check */
|
bool bh_has_heap_property; /* debugging cross-check */
|
||||||
binaryheap_comparator bh_compare;
|
binaryheap_comparator bh_compare;
|
||||||
void *bh_arg;
|
void *bh_arg;
|
||||||
bh_node_type bh_nodes[FLEXIBLE_ARRAY_MEMBER];
|
bh_node_type *bh_nodes;
|
||||||
} binaryheap;
|
} binaryheap;
|
||||||
|
|
||||||
extern binaryheap *binaryheap_allocate(int capacity,
|
extern binaryheap *binaryheap_allocate(int num_nodes,
|
||||||
binaryheap_comparator compare,
|
binaryheap_comparator compare,
|
||||||
void *arg);
|
void *arg);
|
||||||
extern void binaryheap_reset(binaryheap *heap);
|
extern void binaryheap_reset(binaryheap *heap);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user