Streams the input states in sorted order until we run out of input
| 463 | |
| 464 | /// Streams the input states in sorted order until we run out of input |
| 465 | arrow::Result<std::shared_ptr<arrow::RecordBatch>> getNextBatch() { |
| 466 | DCHECK(!state.empty()); |
| 467 | for (const auto& s : state) { |
| 468 | if (s->Empty() && !s->Finished()) { |
| 469 | return nullptr; // not enough data, wait |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | std::vector<std::shared_ptr<InputState>> heap = state; |
| 474 | // filter out finished states |
| 475 | heap.erase(std::remove_if( |
| 476 | heap.begin(), heap.end(), |
| 477 | [](const std::shared_ptr<InputState>& s) { return s->Finished(); }), |
| 478 | heap.end()); |
| 479 | |
| 480 | // If any are Empty(), then return early since we don't have enough data |
| 481 | if (std::any_of(heap.begin(), heap.end(), |
| 482 | [](const std::shared_ptr<InputState>& s) { return s->Empty(); })) { |
| 483 | return nullptr; |
| 484 | } |
| 485 | |
| 486 | // Currently we only support one sort key |
| 487 | const auto sort_col = *ordering_.sort_keys().at(0).target.name(); |
| 488 | const auto comp = InputStateComparator(); |
| 489 | std::make_heap(heap.begin(), heap.end(), comp); |
| 490 | |
| 491 | // Each slice only has one record batch with the same schema as the output |
| 492 | std::unordered_map<int, std::pair<int, int>> output_col_to_src; |
| 493 | for (int i = 0; i < output_schema_->num_fields(); i++) { |
| 494 | output_col_to_src[i] = std::make_pair(0, i); |
| 495 | } |
| 496 | SingleRecordBatchCompositeTable output(output_schema(), 1, |
| 497 | std::move(output_col_to_src), |
| 498 | plan()->query_context()->memory_pool()); |
| 499 | |
| 500 | // Generate rows until we run out of data or we exceed the target output |
| 501 | // size |
| 502 | bool waiting_for_more_data = false; |
| 503 | while (!waiting_for_more_data && !heap.empty() && |
| 504 | output.Size() < kTargetOutputBatchSize) { |
| 505 | std::pop_heap(heap.begin(), heap.end(), comp); |
| 506 | |
| 507 | auto& next_item = heap.back(); |
| 508 | time_unit_t latest_time = std::numeric_limits<time_unit_t>::min(); |
| 509 | time_unit_t new_time = next_item->GetLatestTime(); |
| 510 | ARROW_CHECK(new_time >= latest_time) |
| 511 | << "Input state " << next_item->index() |
| 512 | << " has out of order data. newTime=" << new_time |
| 513 | << " latestTime=" << latest_time; |
| 514 | |
| 515 | latest_time = new_time; |
| 516 | SingleRecordBatchSliceBuilder builder{&output}; |
| 517 | next_item->Advance(builder); |
| 518 | |
| 519 | if (builder.Size() > 0) { |
| 520 | output_counter[next_item->index()] += builder.Size(); |
| 521 | builder.Finalize(); |
| 522 | } |
nothing calls this directly
no test coverage detected