MCPcopy Create free account
hub / github.com/apache/arrow / getNextBatch

Method getNextBatch

cpp/src/arrow/acero/sorted_merge_node.cc:465–540  ·  view source on GitHub ↗

Streams the input states in sorted order until we run out of input

Source from the content-addressed store, hash-verified

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 }

Callers

nothing calls this directly

Calls 15

planFunction · 0.85
query_contextMethod · 0.80
backMethod · 0.80
emptyMethod · 0.45
EmptyMethod · 0.45
FinishedMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
nameMethod · 0.45
num_fieldsMethod · 0.45
memory_poolMethod · 0.45

Tested by

no test coverage detected