| 449 | } |
| 450 | |
| 451 | Status WriteRecordBatch(const RecordBatch& batch) override { |
| 452 | RETURN_NOT_OK(CheckClosed()); |
| 453 | if (batch.num_rows() == 0) { |
| 454 | return Status::OK(); |
| 455 | } |
| 456 | |
| 457 | // Max number of rows allowed in a row group. |
| 458 | const int64_t max_row_group_length = this->properties().max_row_group_length(); |
| 459 | |
| 460 | // Initialize a new buffered row group writer if necessary. |
| 461 | if (row_group_writer_ == nullptr || !row_group_writer_->buffered() || |
| 462 | row_group_writer_->num_rows() >= max_row_group_length) { |
| 463 | RETURN_NOT_OK(NewBufferedRowGroup()); |
| 464 | } |
| 465 | |
| 466 | auto WriteBatch = [&](int64_t offset, int64_t size) { |
| 467 | std::vector<std::unique_ptr<ArrowColumnWriterV2>> writers; |
| 468 | int column_index_start = 0; |
| 469 | |
| 470 | for (int i = 0; i < batch.num_columns(); i++) { |
| 471 | ChunkedArray chunked_array{batch.column(i)}; |
| 472 | ARROW_ASSIGN_OR_RAISE( |
| 473 | std::unique_ptr<ArrowColumnWriterV2> writer, |
| 474 | ArrowColumnWriterV2::Make(chunked_array, offset, size, schema_manifest_, |
| 475 | row_group_writer_, column_index_start)); |
| 476 | column_index_start += writer->leaf_count(); |
| 477 | if (arrow_properties_->use_threads()) { |
| 478 | writers.emplace_back(std::move(writer)); |
| 479 | } else { |
| 480 | RETURN_NOT_OK(writer->Write(&column_write_context_)); |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | if (arrow_properties_->use_threads()) { |
| 485 | DCHECK_EQ(parallel_column_write_contexts_.size(), writers.size()); |
| 486 | RETURN_NOT_OK(::arrow::internal::ParallelFor( |
| 487 | static_cast<int>(writers.size()), |
| 488 | [&](int i) { return writers[i]->Write(¶llel_column_write_contexts_[i]); }, |
| 489 | arrow_properties_->executor())); |
| 490 | } |
| 491 | |
| 492 | return Status::OK(); |
| 493 | }; |
| 494 | |
| 495 | int64_t offset = 0; |
| 496 | while (offset < batch.num_rows()) { |
| 497 | const int64_t batch_size = |
| 498 | std::min(max_row_group_length - row_group_writer_->num_rows(), |
| 499 | batch.num_rows() - offset); |
| 500 | RETURN_NOT_OK(WriteBatch(offset, batch_size)); |
| 501 | offset += batch_size; |
| 502 | |
| 503 | // Flush current row group writer and create a new writer if it is full. |
| 504 | if (row_group_writer_->num_rows() >= max_row_group_length && |
| 505 | offset < batch.num_rows()) { |
| 506 | RETURN_NOT_OK(NewBufferedRowGroup()); |
| 507 | } |
| 508 | } |