qzyu999 opened a new pull request, #3734:
URL: https://github.com/apache/parquet-java/pull/3734

   ## Summary
   
   Adds `ArrowParquetWriter` to the `parquet-arrow` module — a page-level 
writer that accepts Arrow `VectorSchemaRoot` batches and produces valid Parquet 
files without per-row object construction.
   
   Closes #3733. Related: #2264, #3353.
   
   ## Design
   
   Bypasses `RecordConsumer`/`ColumnWriter` entirely. Writes assembled pages 
directly to `PageWriter` with per-column strategy selection:
   
   - **ZeroCopyPlainWriter** (required fixed-width): wraps Arrow data buffer as 
page `BytesInput` directly. O(1) level encoding, O(N) stats scan, zero 
per-value dispatch.
   - **NullablePlainWriter** (optional fixed-width): single-pass compaction of 
non-null values with inline statistics.
   - **VarWidthPlainWriter** (STRING/BINARY): single-pass transformation from 
Arrow offset+data buffers to Parquet length-prefixed format.
   - **BooleanPlainWriter** (BOOLEAN): bit-pack compaction with null handling.
   
   Does not extend `ParquetWriter<T>` because `ParquetWriter.write(T)` 
increments its internal record count by 1 per call, which is incompatible with 
batch semantics.
   
   ## Key properties
   
   - Page format: V1 with length-prefixed RLE-encoded RL/DL sections
   - Buffer safety: `PageWriter.writePage()` copies bytes immediately via 
`ConcatenatingByteBufferCollector.collect()` — Arrow buffers can be freed after 
`writeBatch()` returns
   - Thread-safe statistics: `StatsResult` return object, no shared mutable 
state
   - NaN tracking for float/double columns
   - Page-size chunking: large batches split into ~1MB pages for column-index 
effectiveness
   - Row group flush: based on actual `PageWriter.getMemSize()`, not heuristic
   - Defensive null-buffer checks on all nullable writers
   
   ## Types supported
   
   INT32, INT64, FLOAT, DOUBLE, BOOLEAN, BINARY (string), FIXED_LEN_BYTE_ARRAY. 
Nullable and required. Covers common streaming workload schemas.
   
   ## Not included (follow-up PRs)
   
   - Dictionary encoding (requires two-pass algorithm — build dict, then write 
indices)
   - Nested types (requires recursive RL/DL computation)
   
   Both throw clear `UnsupportedOperationException`.
   
   ## Tests
   
   10 round-trip tests (write via ArrowParquetWriter, read via standard 
ParquetReader):
   - Required and nullable integers
   - Floats/doubles including NaN
   - Strings with nulls and empty values
   - Booleans with nulls
   - Mixed-type schema
   - Multi-batch writes
   - Large batch page splitting (500K rows)
   - Footer row count verification
   - Zero-copy path with manually-constructed REQUIRED schema
   
   ## Dependencies added to parquet-arrow POM
   
   - `parquet-hadoop` (compile) — for ParquetFileWriter, 
ColumnChunkPageWriteStore
   - `arrow-memory-netty` (test) — Arrow allocator runtime
   - `hadoop-common` (test) — for ParquetReader in round-trip tests
   - `hadoop-mapreduce-client-core` (test) — required by ParquetReader
   - `parquet-hadoop` test-jar (test) — GroupReadSupport
   
   ## Discussion point
   
   Adding `parquet-hadoop` as a compile dependency to `parquet-arrow` changes 
the module's weight. Alternative: create a new `parquet-arrow-hadoop` module. 
Open to guidance from maintainers.
   
   ## How to run tests
   
   ```
   mvn test -pl parquet-arrow \
     -Dsurefire.argLine="--add-opens=java.base/java.nio=ALL-UNNAMED 
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to