/* * binaryheap_replace_first * * Replace the topmost element of a non-empty heap, preserving the heap * property. O(1) in the best case, or O(log n) if it must fall back to * sifting the new node down. */ void binaryheap_replace_first(binaryheap *heap, Datum d) { Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property); heap->bh_nodes[0] = d; if (heap->bh_size > 1) sift_down(heap, 0); }
/* * Read the next tuple for gather merge. * * Fetch the sorted tuple out of the heap. */ static TupleTableSlot * gather_merge_getnext(GatherMergeState *gm_state) { int i; if (!gm_state->gm_initialized) { /* * First time through: pull the first tuple from each participant, and * set up the heap. */ gather_merge_init(gm_state); } else { /* * Otherwise, pull the next tuple from whichever participant we * returned from last time, and reinsert that participant's index into * the heap, because it might now compare differently against the * other elements of the heap. */ i = DatumGetInt32(binaryheap_first(gm_state->gm_heap)); if (gather_merge_readnext(gm_state, i, false)) binaryheap_replace_first(gm_state->gm_heap, Int32GetDatum(i)); else { /* reader exhausted, remove it from heap */ (void) binaryheap_remove_first(gm_state->gm_heap); } } if (binaryheap_empty(gm_state->gm_heap)) { /* All the queues are exhausted, and so is the heap */ gather_merge_clear_tuples(gm_state); return NULL; } else { /* Return next tuple from whichever participant has the leading one */ i = DatumGetInt32(binaryheap_first(gm_state->gm_heap)); return gm_state->gm_slots[i]; } }
/* * binaryheap_remove_first * * Removes the first (root, topmost) node in the heap and returns a * pointer to it after rebalancing the heap. The caller must ensure * that this routine is not used on an empty heap. O(log n) worst * case. */ Datum binaryheap_remove_first(binaryheap *heap) { Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property); if (heap->bh_size == 1) { heap->bh_size--; return heap->bh_nodes[0]; } /* * Swap the root and last nodes, decrease the size of the heap (i.e. * remove the former root node) and sift the new root node down to its * correct position. */ swap_nodes(heap, 0, heap->bh_size - 1); heap->bh_size--; sift_down(heap, 0); return heap->bh_nodes[heap->bh_size]; }
/* * binaryheap_first * * Returns a pointer to the first (root, topmost) node in the heap * without modifying the heap. The caller must ensure that this * routine is not used on an empty heap. Always O(1). */ Datum binaryheap_first(binaryheap *heap) { Assert(!binaryheap_empty(heap) && heap->bh_has_heap_property); return heap->bh_nodes[0]; }