rabenhorst opened a new pull request, #12073:
URL: https://github.com/apache/arrow-rs/pull/12073

   # Which issue does this PR close?
   
   - Closes #12072.
   
   # Rationale for this change
   
   `SerializedFileWriter` keeps one `Vec<Option<Sbbf>>`, 
`Vec<Option<ColumnIndexMetaData>>`
   and `Vec<Option<OffsetIndexMetaData>>` per row group until close, with one 
entry per
   leaf column even when every entry is `None`. On 64-bit targets that is 24 + 
232 + 48 =
   304 bytes per column per row group. This happens when column chunks are 
copied with
   `SerializedRowGroupWriter::append_column` without indexes, when page 
statistics are
   disabled, and for bloom filters already written with 
`BloomFilterPosition::AfterRowGroup`.
   When many small files are concatenated into a large one with 
`append_column`, these
   all-`None` vectors can be a large part of the writer's heap.
   
   # What changes are included in this PR?
   
   - `SerializedFileWriter` stores `None` instead of a vector for a row group 
that has no
     bloom filter, column index or offset index entry.
   - `write_bloom_filters` skips such row groups, and takes the row group's 
vector after
     writing it, so `AfterRowGroup` no longer retains a vector of `None`s.
   - At close, absent row groups are expanded to the existing dense layout when 
building
     the `PageIndex`, so the metadata writer and the returned `ParquetMetaData` 
see exactly
     what they saw before.
   
   `SerializedRowGroupWriter` and the public `OnCloseRowGroup` callback are 
unchanged
   (the callback still receives one entry per column).
   
   # Are these changes tested?
   
   Yes. Two new tests in `file::writer`, using `append_column`:
   
   - no bloom filters or indexes, with the offset index enabled and disabled: 
nothing is
     retained per row group, and the returned page index is unchanged;
   - some row groups with and some without bloom filters and page indexes, for 
some
     columns, for `BloomFilterPosition::End` and `AfterRowGroup`, with the 
offset index
     enabled and disabled: bloom filter and index locations, bloom filter 
contents, and the
     returned `PageIndex` compared with what is read back from the file.
   
   I also compared this branch with `main` outside the crate: 36 files 
(appended chunks
   with no, all, mixed, offset-only and bloom-only indexes; `next_column` with 
no, chunk and
   mixed per-column statistics and bloom filters; both bloom filter positions; 
offset index
   enabled and disabled) are byte-identical, and so is the `Debug` output of 
the returned
   `ParquetMetaData`.
   
   Heap held by the writer (counting allocator), 200 nullable INT64 leaves, 
chunks
   appended with `append_column`, no indexes, default `WriterProperties`:
   
   | row groups | before close, `main` | before close, this PR | peak during 
close, `main` | peak during close, this PR |
   |---:|---:|---:|---:|---:|
   | 1,000 | 152.2 MB | 91.4 MB | 152.3 MB | 101.1 MB |
   | 10,000 | 1,522.8 MB | 914.8 MB | 1,523.8 MB | 1,011.8 MB |
   
   That is 304 bytes less per column per row group before close. The returned
   `ParquetMetaData` is the same size (it still contains the dense offset index 
of
   `None`s, 48 bytes per column per row group), and the number of allocations is
   unchanged.
   
   # Are there any user-facing changes?
   
   No. Written files, the returned `ParquetMetaData` and the public API are 
unchanged.
   
   # AI usage
   
   The implementation, the tests, the comparison harness and this description 
were
   written with Claude Code (Claude Opus 5.5).
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
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]

Reply via email to