* Initialize the Gather Merge. * * Reset data structures to ensure they're empty. Then pull at least one * tuple from leader + each worker (or set its "done" indicator), and set up * the heap. */
| 441 | * the heap. |
| 442 | */ |
| 443 | static void |
| 444 | gather_merge_init(GatherMergeState *gm_state) |
| 445 | { |
| 446 | int nreaders = gm_state->nreaders; |
| 447 | bool nowait = true; |
| 448 | int i; |
| 449 | |
| 450 | /* Assert that gather_merge_setup made enough space */ |
| 451 | Assert(nreaders <= castNode(GatherMerge, gm_state->ps.plan)->num_workers); |
| 452 | |
| 453 | /* Reset leader's tuple slot to empty */ |
| 454 | gm_state->gm_slots[0] = NULL; |
| 455 | |
| 456 | /* Reset the tuple slot and tuple array for each worker */ |
| 457 | for (i = 0; i < nreaders; i++) |
| 458 | { |
| 459 | /* Reset tuple array to empty */ |
| 460 | gm_state->gm_tuple_buffers[i].nTuples = 0; |
| 461 | gm_state->gm_tuple_buffers[i].readCounter = 0; |
| 462 | /* Reset done flag to not-done */ |
| 463 | gm_state->gm_tuple_buffers[i].done = false; |
| 464 | /* Ensure output slot is empty */ |
| 465 | ExecClearTuple(gm_state->gm_slots[i + 1]); |
| 466 | } |
| 467 | |
| 468 | /* Reset binary heap to empty */ |
| 469 | binaryheap_reset(gm_state->gm_heap); |
| 470 | |
| 471 | /* |
| 472 | * First, try to read a tuple from each worker (including leader) in |
| 473 | * nowait mode. After this, if not all workers were able to produce a |
| 474 | * tuple (or a "done" indication), then re-read from remaining workers, |
| 475 | * this time using wait mode. Add all live readers (those producing at |
| 476 | * least one tuple) to the heap. |
| 477 | */ |
| 478 | reread: |
| 479 | for (i = 0; i <= nreaders; i++) |
| 480 | { |
| 481 | CHECK_FOR_INTERRUPTS(); |
| 482 | |
| 483 | /* skip this source if already known done */ |
| 484 | if ((i == 0) ? gm_state->need_to_scan_locally : |
| 485 | !gm_state->gm_tuple_buffers[i - 1].done) |
| 486 | { |
| 487 | if (TupIsNull(gm_state->gm_slots[i])) |
| 488 | { |
| 489 | /* Don't have a tuple yet, try to get one */ |
| 490 | if (gather_merge_readnext(gm_state, i, nowait)) |
| 491 | binaryheap_add_unordered(gm_state->gm_heap, |
| 492 | Int32GetDatum(i)); |
| 493 | } |
| 494 | else |
| 495 | { |
| 496 | /* |
| 497 | * We already got at least one tuple from this worker, but |
| 498 | * might as well see if it has any more ready by now. |
| 499 | */ |
| 500 | load_tuple_array(gm_state, i); |
no test coverage detected