PostgreSQL Source Code git master
Loading...
Searching...
No Matches
binaryheap.c File Reference
#include "postgres.h"
#include "lib/binaryheap.h"
Include dependency graph for binaryheap.c:

Go to the source code of this file.

Functions

static void sift_down (binaryheap *heap, int node_off)
 
static void sift_up (binaryheap *heap, int node_off)
 
binaryheapbinaryheap_allocate (int capacity, binaryheap_comparator compare, void *arg)
 
void binaryheap_reset (binaryheap *heap)
 
void binaryheap_free (binaryheap *heap)
 
static int left_offset (int i)
 
static int right_offset (int i)
 
static int parent_offset (int i)
 
void binaryheap_add_unordered (binaryheap *heap, bh_node_type d)
 
void binaryheap_build (binaryheap *heap)
 
void binaryheap_add (binaryheap *heap, bh_node_type d)
 
bh_node_type binaryheap_first (binaryheap *heap)
 
bh_node_type binaryheap_remove_first (binaryheap *heap)
 
void binaryheap_remove_node (binaryheap *heap, int n)
 
void binaryheap_replace_first (binaryheap *heap, bh_node_type d)
 

Function Documentation

◆ binaryheap_add()

void binaryheap_add ( binaryheap heap,
bh_node_type  d 
)

Definition at line 152 of file binaryheap.c.

153{
154 if (heap->bh_size >= heap->bh_space)
155 {
156#ifdef FRONTEND
157 pg_fatal("out of binary heap slots");
158#else
159 elog(ERROR, "out of binary heap slots");
160#endif
161 }
162 heap->bh_nodes[heap->bh_size] = d;
163 heap->bh_size++;
164 sift_up(heap, heap->bh_size - 1);
165}
static void sift_up(binaryheap *heap, int node_off)
Definition binaryheap.c:268
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define pg_fatal(...)
bh_node_type bh_nodes[FLEXIBLE_ARRAY_MEMBER]
Definition binaryheap.h:49

References binaryheap::bh_nodes, binaryheap::bh_size, binaryheap::bh_space, elog, ERROR, pg_fatal, and sift_up().

Referenced by move_to_ready_heap(), pgarch_readyXlog(), reduce_dependencies(), test_basic(), test_duplicates(), test_remove_node(), test_replace_first(), test_reset(), and TopoSort().

◆ binaryheap_add_unordered()

void binaryheap_add_unordered ( binaryheap heap,
bh_node_type  d 
)

Definition at line 114 of file binaryheap.c.

115{
116 if (heap->bh_size >= heap->bh_space)
117 {
118#ifdef FRONTEND
119 pg_fatal("out of binary heap slots");
120#else
121 elog(ERROR, "out of binary heap slots");
122#endif
123 }
124 heap->bh_has_heap_property = false;
125 heap->bh_nodes[heap->bh_size] = d;
126 heap->bh_size++;
127}
bool bh_has_heap_property
Definition binaryheap.h:46

References binaryheap::bh_has_heap_property, binaryheap::bh_nodes, binaryheap::bh_size, binaryheap::bh_space, elog, ERROR, and pg_fatal.

Referenced by BufferSync(), ExecMergeAppend(), gather_merge_init(), pgarch_readyXlog(), ReorderBufferIterTXNInit(), test_build(), and TopoSort().

◆ binaryheap_allocate()

binaryheap * binaryheap_allocate ( int  capacity,
binaryheap_comparator  compare,
void arg 
)

Definition at line 37 of file binaryheap.c.

38{
39 int sz;
40 binaryheap *heap;
41
42 sz = offsetof(binaryheap, bh_nodes) + sizeof(bh_node_type) * capacity;
43 heap = (binaryheap *) palloc(sz);
44 heap->bh_space = capacity;
45 heap->bh_compare = compare;
46 heap->bh_arg = arg;
47
48 heap->bh_size = 0;
49 heap->bh_has_heap_property = true;
50
51 return heap;
52}
Datum bh_node_type
Definition binaryheap.h:23
static int compare(const void *arg1, const void *arg2)
Definition geqo_pool.c:144
void * palloc(Size size)
Definition mcxt.c:1387
void * arg
static int fb(int x)
binaryheap_comparator bh_compare
Definition binaryheap.h:47
void * bh_arg
Definition binaryheap.h:48

References arg, binaryheap::bh_arg, binaryheap::bh_compare, binaryheap::bh_has_heap_property, binaryheap::bh_size, binaryheap::bh_space, compare(), fb(), and palloc().

Referenced by BufferSync(), ExecInitMergeAppend(), gather_merge_setup(), PgArchiverMain(), ReorderBufferIterTXNInit(), restore_toc_entries_parallel(), test_basic(), test_build(), test_duplicates(), test_remove_node(), test_replace_first(), test_reset(), and TopoSort().

◆ binaryheap_build()

void binaryheap_build ( binaryheap heap)

Definition at line 136 of file binaryheap.c.

137{
138 int i;
139
140 for (i = parent_offset(heap->bh_size - 1); i >= 0; i--)
141 sift_down(heap, i);
142 heap->bh_has_heap_property = true;
143}
static void sift_down(binaryheap *heap, int node_off)
Definition binaryheap.c:311
static int parent_offset(int i)
Definition binaryheap.c:100
int i
Definition isn.c:77

References binaryheap::bh_has_heap_property, binaryheap::bh_size, i, parent_offset(), and sift_down().

Referenced by BufferSync(), ExecMergeAppend(), gather_merge_init(), pgarch_readyXlog(), ReorderBufferIterTXNInit(), test_build(), and TopoSort().

◆ binaryheap_first()

bh_node_type binaryheap_first ( binaryheap heap)

Definition at line 175 of file binaryheap.c.

176{
178 return heap->bh_nodes[0];
179}
#define binaryheap_empty(h)
Definition binaryheap.h:65
#define Assert(condition)
Definition c.h:873

References Assert, binaryheap::bh_has_heap_property, binaryheap::bh_nodes, and binaryheap_empty.

Referenced by BufferSync(), ExecMergeAppend(), gather_merge_getnext(), pgarch_readyXlog(), ReorderBufferIterTXNNext(), and test_basic().

◆ binaryheap_free()

void binaryheap_free ( binaryheap heap)

Definition at line 73 of file binaryheap.c.

74{
75 pfree(heap);
76}
void pfree(void *pointer)
Definition mcxt.c:1616

References pfree().

Referenced by BufferSync(), ReorderBufferIterTXNFinish(), restore_toc_entries_parallel(), and TopoSort().

◆ binaryheap_remove_first()

bh_node_type binaryheap_remove_first ( binaryheap heap)

Definition at line 190 of file binaryheap.c.

191{
192 bh_node_type result;
193
195
196 /* extract the root node, which will be the result */
197 result = heap->bh_nodes[0];
198
199 /* easy if heap contains one element */
200 if (heap->bh_size == 1)
201 {
202 heap->bh_size--;
203 return result;
204 }
205
206 /*
207 * Remove the last node, placing it in the vacated root entry, and sift
208 * the new root node down to its correct position.
209 */
210 heap->bh_nodes[0] = heap->bh_nodes[--heap->bh_size];
211 sift_down(heap, 0);
212
213 return result;
214}

References Assert, binaryheap::bh_has_heap_property, binaryheap::bh_nodes, binaryheap::bh_size, binaryheap_empty, and sift_down().

Referenced by BufferSync(), ExecMergeAppend(), gather_merge_getnext(), pgarch_readyXlog(), ReorderBufferIterTXNNext(), test_basic(), test_duplicates(), and TopoSort().

◆ binaryheap_remove_node()

void binaryheap_remove_node ( binaryheap heap,
int  n 
)

Definition at line 223 of file binaryheap.c.

224{
225 int cmp;
226
228 Assert(n >= 0 && n < heap->bh_size);
229
230 /* compare last node to the one that is being removed */
231 cmp = heap->bh_compare(heap->bh_nodes[--heap->bh_size],
232 heap->bh_nodes[n],
233 heap->bh_arg);
234
235 /* remove the last node, placing it in the vacated entry */
236 heap->bh_nodes[n] = heap->bh_nodes[heap->bh_size];
237
238 /* sift as needed to preserve the heap property */
239 if (cmp > 0)
240 sift_up(heap, n);
241 else if (cmp < 0)
242 sift_down(heap, n);
243}
static int cmp(const chr *x, const chr *y, size_t len)

References Assert, binaryheap::bh_arg, binaryheap::bh_compare, binaryheap::bh_has_heap_property, binaryheap::bh_nodes, binaryheap::bh_size, binaryheap_empty, cmp(), fb(), sift_down(), and sift_up().

Referenced by pop_next_work_item(), and test_remove_node().

◆ binaryheap_replace_first()

void binaryheap_replace_first ( binaryheap heap,
bh_node_type  d 
)

◆ binaryheap_reset()

void binaryheap_reset ( binaryheap heap)

Definition at line 61 of file binaryheap.c.

62{
63 heap->bh_size = 0;
64 heap->bh_has_heap_property = true;
65}

References binaryheap::bh_has_heap_property, and binaryheap::bh_size.

Referenced by ExecReScanMergeAppend(), gather_merge_init(), pgarch_readyXlog(), and test_reset().

◆ left_offset()

static int left_offset ( int  i)
inlinestatic

Definition at line 88 of file binaryheap.c.

89{
90 return 2 * i + 1;
91}

References i.

Referenced by sift_down().

◆ parent_offset()

static int parent_offset ( int  i)
inlinestatic

Definition at line 100 of file binaryheap.c.

101{
102 return (i - 1) / 2;
103}

References i.

Referenced by binaryheap_build(), and sift_up().

◆ right_offset()

static int right_offset ( int  i)
inlinestatic

Definition at line 94 of file binaryheap.c.

95{
96 return 2 * i + 2;
97}

References i.

Referenced by sift_down().

◆ sift_down()

static void sift_down ( binaryheap heap,
int  node_off 
)
static

Definition at line 311 of file binaryheap.c.

312{
314
315 /*
316 * Within the loop, the node_off'th array entry is a "hole" that
317 * notionally holds node_val, but we don't actually store node_val there
318 * till the end, saving some unnecessary data copying steps.
319 */
320 while (true)
321 {
324 int swap_off = left_off;
325
326 /* Is the right child larger than the left child? */
327 if (right_off < heap->bh_size &&
328 heap->bh_compare(heap->bh_nodes[left_off],
329 heap->bh_nodes[right_off],
330 heap->bh_arg) < 0)
332
333 /*
334 * If no children or parent is >= the larger child, heap condition is
335 * satisfied, and we're done.
336 */
337 if (left_off >= heap->bh_size ||
338 heap->bh_compare(node_val,
339 heap->bh_nodes[swap_off],
340 heap->bh_arg) >= 0)
341 break;
342
343 /*
344 * Otherwise, swap the hole with the child that violates the heap
345 * property; then go on to check its children.
346 */
347 heap->bh_nodes[node_off] = heap->bh_nodes[swap_off];
349 }
350 /* Re-fill the hole */
351 heap->bh_nodes[node_off] = node_val;
352}
static int right_offset(int i)
Definition binaryheap.c:94
static int left_offset(int i)
Definition binaryheap.c:88

References binaryheap::bh_arg, binaryheap::bh_compare, binaryheap::bh_nodes, binaryheap::bh_size, fb(), left_offset(), and right_offset().

Referenced by binaryheap_build(), binaryheap_remove_first(), binaryheap_remove_node(), and binaryheap_replace_first().

◆ sift_up()

static void sift_up ( binaryheap heap,
int  node_off 
)
static

Definition at line 268 of file binaryheap.c.

269{
271
272 /*
273 * Within the loop, the node_off'th array entry is a "hole" that
274 * notionally holds node_val, but we don't actually store node_val there
275 * till the end, saving some unnecessary data copying steps.
276 */
277 while (node_off != 0)
278 {
279 int cmp;
280 int parent_off;
282
283 /*
284 * If this node is smaller than its parent, the heap condition is
285 * satisfied, and we're done.
286 */
289 cmp = heap->bh_compare(node_val,
291 heap->bh_arg);
292 if (cmp <= 0)
293 break;
294
295 /*
296 * Otherwise, swap the parent value with the hole, and go on to check
297 * the node's new parent.
298 */
301 }
302 /* Re-fill the hole */
303 heap->bh_nodes[node_off] = node_val;
304}

References binaryheap::bh_arg, binaryheap::bh_compare, binaryheap::bh_nodes, cmp(), fb(), and parent_offset().

Referenced by binaryheap_add(), and binaryheap_remove_node().