Skip to content

Commit 7a28ed7

Browse files
committed
estimate remaining rows by avg_row_bytes instead of buffered bytes
1 parent 8059517 commit 7a28ed7

2 files changed

Lines changed: 61 additions & 21 deletions

File tree

cpp/src/parquet/arrow/arrow_reader_writer_test.cc

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5797,11 +5797,11 @@ TEST(TestArrowReadWrite, WriteRecordBatchNotProduceEmptyRowGroup) {
57975797
TEST(TestArrowReadWrite, WriteRecordBatchFlushRowGroupByBufferedSize) {
57985798
auto pool = ::arrow::default_memory_pool();
57995799
auto sink = CreateOutputStream();
5800-
// Limit the max bytes in a row group to 100 so that each batch produces a new group.
5800+
// Limit the max bytes in a row group to 100.
58015801
auto writer_properties = WriterProperties::Builder().max_row_group_bytes(100)->build();
58025802
auto arrow_writer_properties = default_arrow_writer_properties();
58035803

5804-
// Prepare schema
5804+
// Prepare schema.
58055805
auto schema = ::arrow::schema({::arrow::field("a", ::arrow::int64())});
58065806
std::shared_ptr<SchemaDescriptor> parquet_schema;
58075807
ASSERT_OK_NO_THROW(ToParquetSchema(schema.get(), *writer_properties,
@@ -5825,9 +5825,49 @@ TEST(TestArrowReadWrite, WriteRecordBatchFlushRowGroupByBufferedSize) {
58255825
ASSERT_OK_AND_ASSIGN(auto buffer, sink->Finish());
58265826

58275827
auto file_metadata = arrow_writer->metadata();
5828-
EXPECT_EQ(2, file_metadata->num_row_groups());
5829-
EXPECT_EQ(3, file_metadata->RowGroup(0)->num_rows());
5828+
EXPECT_EQ(3, file_metadata->num_row_groups());
5829+
EXPECT_EQ(1, file_metadata->RowGroup(0)->num_rows());
58305830
EXPECT_EQ(2, file_metadata->RowGroup(1)->num_rows());
5831+
EXPECT_EQ(2, file_metadata->RowGroup(2)->num_rows());
5832+
}
5833+
5834+
TEST(TestArrowReadWrite, WriteRecordBatchWithSmallMaxRowGroupBytes) {
5835+
auto pool = ::arrow::default_memory_pool();
5836+
auto sink = CreateOutputStream();
5837+
// Limit the max bytes in a row group to 1, then each row starts a new row group.
5838+
auto writer_properties = WriterProperties::Builder().max_row_group_bytes(1)->build();
5839+
auto arrow_writer_properties = default_arrow_writer_properties();
5840+
5841+
// Prepare schema.
5842+
auto schema = ::arrow::schema({::arrow::field("a", ::arrow::int64())});
5843+
std::shared_ptr<SchemaDescriptor> parquet_schema;
5844+
ASSERT_OK_NO_THROW(ToParquetSchema(schema.get(), *writer_properties,
5845+
*arrow_writer_properties, &parquet_schema));
5846+
auto schema_node = std::static_pointer_cast<GroupNode>(parquet_schema->schema_root());
5847+
5848+
auto gen = ::arrow::random::RandomArrayGenerator(/*seed=*/42);
5849+
5850+
// Create writer to write data via RecordBatch.
5851+
ASSERT_OK_AND_ASSIGN(auto arrow_writer, parquet::arrow::FileWriter::Open(
5852+
*schema, pool, sink, writer_properties,
5853+
arrow_writer_properties));
5854+
// NewBufferedRowGroup() is not called explicitly and it will be called
5855+
// inside WriteRecordBatch().
5856+
for (int i = 0; i < 5; ++i) {
5857+
auto record_batch =
5858+
gen.BatchOf({::arrow::field("a", ::arrow::int64())}, /*length=*/1);
5859+
ASSERT_OK_NO_THROW(arrow_writer->WriteRecordBatch(*record_batch));
5860+
}
5861+
ASSERT_OK_NO_THROW(arrow_writer->Close());
5862+
ASSERT_OK_AND_ASSIGN(auto buffer, sink->Finish());
5863+
5864+
auto file_metadata = arrow_writer->metadata();
5865+
EXPECT_EQ(5, file_metadata->num_row_groups());
5866+
EXPECT_EQ(1, file_metadata->RowGroup(0)->num_rows());
5867+
EXPECT_EQ(1, file_metadata->RowGroup(1)->num_rows());
5868+
EXPECT_EQ(1, file_metadata->RowGroup(2)->num_rows());
5869+
EXPECT_EQ(1, file_metadata->RowGroup(3)->num_rows());
5870+
EXPECT_EQ(1, file_metadata->RowGroup(4)->num_rows());
58315871
}
58325872

58335873
TEST(TestArrowReadWrite, WriteTableFlushRowGroupByBufferedSize) {

cpp/src/parquet/arrow/writer.cc

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -405,12 +405,13 @@ class FileWriterImpl : public FileWriter {
405405
chunk_size = this->properties().max_row_group_length();
406406
}
407407
if (auto avg_row_size = EstimateCompressedBytesPerRow()) {
408-
chunk_size = std::min(
409-
chunk_size, static_cast<int64_t>(this->properties().max_row_group_bytes() /
410-
avg_row_size.value()));
408+
chunk_size =
409+
std::min(chunk_size,
410+
// Ensure chunk_size is at least 1 to avoid infinite loops.
411+
std::max<int64_t>(
412+
1, static_cast<int64_t>(this->properties().max_row_group_bytes() /
413+
avg_row_size.value())));
411414
}
412-
// Ensure chunk_size is at least 1 to avoid infinite loops.
413-
chunk_size = std::max<int64_t>(chunk_size, 1);
414415

415416
auto WriteRowGroup = [&](int64_t offset, int64_t size) {
416417
RETURN_NOT_OK(NewRowGroup());
@@ -488,21 +489,20 @@ class FileWriterImpl : public FileWriter {
488489

489490
int64_t offset = 0;
490491
while (offset < batch.num_rows()) {
491-
if (row_group_writer_->num_rows() >= max_row_group_length ||
492-
row_group_writer_->EstimatedTotalCompressedBytes() >= max_row_group_bytes) {
492+
auto avg_row_size = EstimateCompressedBytesPerRow();
493+
int64_t max_rows =
494+
avg_row_size
495+
? std::min(max_row_group_length,
496+
// Ensure batch_size is at least 1 to avoid infinite loops.
497+
std::max(1L, static_cast<int64_t>(max_row_group_bytes /
498+
avg_row_size.value())))
499+
: max_row_group_length;
500+
if (row_group_writer_->num_rows() >= max_rows) {
493501
// Current row group is full, start a new one.
494502
RETURN_NOT_OK(NewBufferedRowGroup());
495503
}
496-
int64_t batch_size = std::min(max_row_group_length - row_group_writer_->num_rows(),
497-
batch.num_rows() - offset);
498-
if (auto avg_row_size = EstimateCompressedBytesPerRow()) {
499-
int64_t buffered_bytes = row_group_writer_->EstimatedTotalCompressedBytes();
500-
batch_size = std::min(
501-
batch_size, static_cast<int64_t>((max_row_group_bytes - buffered_bytes) /
502-
avg_row_size.value()));
503-
}
504-
// Ensure batch_size is at least 1 to avoid infinite loops.
505-
batch_size = std::max<int64_t>(batch_size, 1);
504+
int64_t batch_size =
505+
std::min(max_rows - row_group_writer_->num_rows(), batch.num_rows() - offset);
506506
RETURN_NOT_OK(WriteBatch(offset, batch_size));
507507
offset += batch_size;
508508
}

0 commit comments

Comments
 (0)