PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pairingheap.c File Reference
#include "postgres.h"
#include "lib/pairingheap.h"
Include dependency graph for pairingheap.c:

Go to the source code of this file.

Functions

static pairingheap_nodemerge (pairingheap *heap, pairingheap_node *a, pairingheap_node *b)
 
static pairingheap_nodemerge_children (pairingheap *heap, pairingheap_node *children)
 
pairingheappairingheap_allocate (pairingheap_comparator compare, void *arg)
 
void pairingheap_initialize (pairingheap *heap, pairingheap_comparator compare, void *arg)
 
void pairingheap_free (pairingheap *heap)
 
void pairingheap_add (pairingheap *heap, pairingheap_node *node)
 
pairingheap_nodepairingheap_first (pairingheap *heap)
 
pairingheap_nodepairingheap_remove_first (pairingheap *heap)
 
void pairingheap_remove (pairingheap *heap, pairingheap_node *node)
 

Function Documentation

◆ merge()

static pairingheap_node * merge ( pairingheap heap,
pairingheap_node a,
pairingheap_node b 
)
static

Definition at line 93 of file pairingheap.c.

94{
95 if (a == NULL)
96 return b;
97 if (b == NULL)
98 return a;
99
100 /* swap 'a' and 'b' so that 'a' is the one with larger value */
101 if (heap->ph_compare(a, b, heap->ph_arg) < 0)
102 {
103 pairingheap_node *tmp;
104
105 tmp = a;
106 a = b;
107 b = tmp;
108 }
109
110 /* and put 'b' as a child of 'a' */
111 if (a->first_child)
112 a->first_child->prev_or_parent = b;
113 b->prev_or_parent = a;
114 b->next_sibling = a->first_child;
115 a->first_child = b;
116
117 return a;
118}
int b
Definition: isn.c:74
int a
Definition: isn.c:73
pairingheap_comparator ph_compare
Definition: pairingheap.h:73
void * ph_arg
Definition: pairingheap.h:74

References a, b, pairingheap::ph_arg, and pairingheap::ph_compare.

Referenced by _bt_load(), merge_children(), and pairingheap_add().

◆ merge_children()

static pairingheap_node * merge_children ( pairingheap heap,
pairingheap_node children 
)
static

Definition at line 248 of file pairingheap.c.

249{
250 pairingheap_node *curr,
251 *next;
252 pairingheap_node *pairs;
253 pairingheap_node *newroot;
254
255 if (children == NULL || children->next_sibling == NULL)
256 return children;
257
258 /* Walk the subheaps from left to right, merging in pairs */
259 next = children;
260 pairs = NULL;
261 for (;;)
262 {
263 curr = next;
264
265 if (curr == NULL)
266 break;
267
268 if (curr->next_sibling == NULL)
269 {
270 /* last odd node at the end of list */
271 curr->next_sibling = pairs;
272 pairs = curr;
273 break;
274 }
275
277
278 /* merge this and the next subheap, and add to 'pairs' list. */
279
280 curr = merge(heap, curr, curr->next_sibling);
281 curr->next_sibling = pairs;
282 pairs = curr;
283 }
284
285 /*
286 * Merge all the pairs together to form a single heap.
287 */
288 newroot = pairs;
289 next = pairs->next_sibling;
290 while (next)
291 {
292 curr = next;
293 next = curr->next_sibling;
294
295 newroot = merge(heap, newroot, curr);
296 }
297
298 return newroot;
299}
static int32 next
Definition: blutils.c:224
static pairingheap_node * merge(pairingheap *heap, pairingheap_node *a, pairingheap_node *b)
Definition: pairingheap.c:93
struct pairingheap_node * next_sibling
Definition: pairingheap.h:33

References merge(), next, and pairingheap_node::next_sibling.

Referenced by pairingheap_remove(), and pairingheap_remove_first().

◆ pairingheap_add()

void pairingheap_add ( pairingheap heap,
pairingheap_node node 
)

Definition at line 126 of file pairingheap.c.

127{
128 node->first_child = NULL;
129
130 /* Link the new node as a new tree */
131 heap->ph_root = merge(heap, heap->ph_root, node);
132 heap->ph_root->prev_or_parent = NULL;
133 heap->ph_root->next_sibling = NULL;
134}
struct pairingheap_node * prev_or_parent
Definition: pairingheap.h:34
struct pairingheap_node * first_child
Definition: pairingheap.h:32
pairingheap_node * ph_root
Definition: pairingheap.h:75

References pairingheap_node::first_child, merge(), pairingheap_node::next_sibling, pairingheap::ph_root, and pairingheap_node::prev_or_parent.

Referenced by addLSNWaiter(), ExportSnapshot(), GetNonHistoricCatalogSnapshot(), GetTransactionSnapshot(), gistScanPage(), RegisterSnapshotOnOwner(), ReorderBufferChangeMemoryUpdate(), reorderqueue_push(), SetTransactionSnapshot(), and spgAddSearchItemToQueue().

◆ pairingheap_allocate()

pairingheap * pairingheap_allocate ( pairingheap_comparator  compare,
void *  arg 
)

Definition at line 42 of file pairingheap.c.

43{
44 pairingheap *heap;
45
46 heap = (pairingheap *) palloc(sizeof(pairingheap));
48
49 return heap;
50}
static int compare(const void *arg1, const void *arg2)
Definition: geqo_pool.c:145
void * palloc(Size size)
Definition: mcxt.c:1365
void pairingheap_initialize(pairingheap *heap, pairingheap_comparator compare, void *arg)
Definition: pairingheap.c:60
void * arg

References arg, compare(), pairingheap_initialize(), and palloc().

Referenced by ExecInitIndexScan(), gistrescan(), ReorderBufferAllocate(), and resetSpGistScanOpaque().

◆ pairingheap_first()

pairingheap_node * pairingheap_first ( pairingheap heap)

Definition at line 144 of file pairingheap.c.

145{
147
148 return heap->ph_root;
149}
Assert(PointerIsAligned(start, uint64))
#define pairingheap_is_empty(h)
Definition: pairingheap.h:99

References Assert(), pairingheap_is_empty, and pairingheap::ph_root.

Referenced by IndexNextWithReorder(), ReorderBufferLargestTXN(), SnapshotResetXmin(), updateMinWaitedLSN(), and wakeupWaiters().

◆ pairingheap_free()

void pairingheap_free ( pairingheap heap)

Definition at line 77 of file pairingheap.c.

78{
79 pfree(heap);
80}
void pfree(void *pointer)
Definition: mcxt.c:1594

References pfree().

◆ pairingheap_initialize()

void pairingheap_initialize ( pairingheap heap,
pairingheap_comparator  compare,
void *  arg 
)

Definition at line 60 of file pairingheap.c.

62{
63 heap->ph_compare = compare;
64 heap->ph_arg = arg;
65
66 heap->ph_root = NULL;
67}

References arg, compare(), pairingheap::ph_arg, pairingheap::ph_compare, and pairingheap::ph_root.

Referenced by pairingheap_allocate(), and WaitLSNShmemInit().

◆ pairingheap_remove()

void pairingheap_remove ( pairingheap heap,
pairingheap_node node 
)

Definition at line 184 of file pairingheap.c.

185{
186 pairingheap_node *children;
187 pairingheap_node *replacement;
188 pairingheap_node *next_sibling;
189 pairingheap_node **prev_ptr;
190
191 /*
192 * If the removed node happens to be the root node, do it with
193 * pairingheap_remove_first().
194 */
195 if (node == heap->ph_root)
196 {
197 (void) pairingheap_remove_first(heap);
198 return;
199 }
200
201 /*
202 * Before we modify anything, remember the removed node's first_child and
203 * next_sibling pointers.
204 */
205 children = node->first_child;
206 next_sibling = node->next_sibling;
207
208 /*
209 * Also find the pointer to the removed node in its previous sibling, or
210 * if this is the first child of its parent, in its parent.
211 */
212 if (node->prev_or_parent->first_child == node)
213 prev_ptr = &node->prev_or_parent->first_child;
214 else
215 prev_ptr = &node->prev_or_parent->next_sibling;
216 Assert(*prev_ptr == node);
217
218 /*
219 * If this node has children, make a new subheap of the children and link
220 * the subheap in place of the removed node. Otherwise just unlink this
221 * node.
222 */
223 if (children)
224 {
225 replacement = merge_children(heap, children);
226
227 replacement->prev_or_parent = node->prev_or_parent;
228 replacement->next_sibling = node->next_sibling;
229 *prev_ptr = replacement;
230 if (next_sibling)
231 next_sibling->prev_or_parent = replacement;
232 }
233 else
234 {
235 *prev_ptr = next_sibling;
236 if (next_sibling)
237 next_sibling->prev_or_parent = node->prev_or_parent;
238 }
239}
pairingheap_node * pairingheap_remove_first(pairingheap *heap)
Definition: pairingheap.c:159
static pairingheap_node * merge_children(pairingheap *heap, pairingheap_node *children)
Definition: pairingheap.c:248

References Assert(), pairingheap_node::first_child, merge_children(), pairingheap_node::next_sibling, pairingheap_remove_first(), pairingheap::ph_root, and pairingheap_node::prev_or_parent.

Referenced by AtEOXact_Snapshot(), deleteLSNWaiter(), InvalidateCatalogSnapshot(), ReorderBufferChangeMemoryUpdate(), and UnregisterSnapshotNoOwner().

◆ pairingheap_remove_first()

pairingheap_node * pairingheap_remove_first ( pairingheap heap)

Definition at line 159 of file pairingheap.c.

160{
161 pairingheap_node *result;
162 pairingheap_node *children;
163
165
166 /* Remove the root, and form a new heap of its children. */
167 result = heap->ph_root;
168 children = result->first_child;
169
170 heap->ph_root = merge_children(heap, children);
171 if (heap->ph_root)
172 {
173 heap->ph_root->prev_or_parent = NULL;
174 heap->ph_root->next_sibling = NULL;
175 }
176
177 return result;
178}

References Assert(), pairingheap_node::first_child, merge_children(), pairingheap_node::next_sibling, pairingheap_is_empty, pairingheap::ph_root, and pairingheap_node::prev_or_parent.

Referenced by getNextGISTSearchItem(), pairingheap_remove(), reorderqueue_pop(), spgGetNextQueueItem(), and wakeupWaiters().