Add Parquet DocValues read foundation: types + native bridge - #22599
Add Parquet DocValues read foundation: types + native bridge#22599manaslohani wants to merge 2 commits into
Conversation
Introduce the foundational, runtime-inert pieces the Parquet DocValues codec read path builds on, so a Parquet-primary composite index can later serve its columns as Lucene doc values for DSL aggregations. This change adds only the leaf dependencies; nothing wires them into the query path yet, so there is no functional change at runtime. Java (parquet-data-format): - ParquetPhysicalType: enum of Parquet physical types whose code() (0-5) is the discriminant exchanged with the native reader; pinned by test to the ffm.rs TYPE_* constants. - FieldTypeMapping: OpenSearch mapping type -> (single/multi Lucene DocValuesType, ParquetPhysicalType), with forType/isSupported/validate. Unmapped types throw rather than serve wrong values. Native (ffm.rs, additive to the write/merge path): - Column-reader read functions: open/close/count, single-row and repeated reads, page-count, page-index, and whole-page decode into caller buffers with a packed presence bitset. A retained forward cursor keeps an ascending scan from reopening the row group per page. - Per-file metadata cache (footer + page layouts) shared across readers. Bridge: - RustBridge: MethodHandle binds + wrappers for the read functions. - NativeCall: invokeStatic/invokeIOStatic helpers for allocation-free native invocation with status checking. The DocValuesSkipper, multi-valued wiring, and the reader wrapper that turns this on arrive in later changes. Signed-off-by: Manas Lohani <manloh@amazon.com>
PR Reviewer Guide 🔍(Review updated until commit 91c6d64)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 91c6d64
Previous suggestionsSuggestions up to commit 3e0079d
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #22599 +/- ##
=========================================
Coverage 71.43% 71.44%
+ Complexity 76760 76746 -14
=========================================
Files 6142 6142
Lines 357766 357794 +28
Branches 52148 52162 +14
=========================================
+ Hits 255581 255631 +50
+ Misses 81861 81801 -60
- Partials 20324 20362 +38 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| } | ||
|
|
||
| /** True for the fixed-width primitive types whose values are exchanged as raw {@code long} bits. */ | ||
| public boolean isPrimitive() { |
There was a problem hiding this comment.
In Parquet's own type taxonomy, BYTE_ARRAY is a primitive type, should we call it IsFixedWidthPrimitive?
| * when {@code >= 0} (positive status codes are passed through), throws {@link IOException} | ||
| * when {@code < 0}. Static (no {@link Arena}), so the caller must own every argument. | ||
| */ | ||
| public static long invokeIOStatic(MethodHandle handle, Object... args) throws IOException { |
There was a problem hiding this comment.
why do we need static methods? why can't we use non static versions of these which are already there?
- Reject byte pages whose total exceeds i32::MAX instead of wrapping the offset accumulator (silent corruption / out-of-bounds write); accumulate in i64 and validate before storing into the i32 offset array. - Install the retained decode cursor only on a successful decode in the byte-array arms, matching the primitive path (an overflow retry reopens a fresh reader anyway). - Add a debug assertion guarding the unchecked def-level read in pack_presence_from_def_levels so a corrupt page index fails loudly in tests. - Rename ParquetPhysicalType.isPrimitive to isFixedWidth: Parquet's own taxonomy counts BYTE_ARRAY as a primitive, so the previous name was misleading; the real distinction is fixed- vs variable-width. - Document the Mapping record's (single, multi, physical) triple, including why boolean maps to a numeric DocValues type (0/1, as core OpenSearch does). - Explain why NativeCall exposes static invoke variants alongside the instance ones (read path owns its buffers in a pooled Arena; static calls allocate nothing and are stateless). Signed-off-by: Manas Lohani <manloh@amazon.com>
|
Persistent review updated to latest commit 91c6d64 |
Description
#22598
Introduce the foundational pieces the Parquet DocValues codec read path builds on, so a Parquet-primary composite index can later serve its columns as Lucene doc values for DSL aggregations.
This change adds only the leaf dependencies; nothing wires them into the query path yet, so there is no functional change at runtime.
Java (parquet-data-format):
Native (ffm.rs, additive to the write/merge path):
Bridge:
Test Coverage
ParquetPhysicalTypeTests— pins eachcode()(0–5) to theffm.rsTYPE_*constants so the Java<->Rust discriminant contract cannot drift.
FieldTypeMappingTests— mapped types resolve to the expected DocValuesType +physical type;
validateaccepts single/multi forms; unmapped types throw.ffm.rs):cargo check(with--cfg tokio_unstable, matching thebuild) passes with no errors/warnings. The read-path FFI is exercised end-to-end
(write-then-read) by
ParquetColumnReaderTests, which lands with the column-readerchange in the next PR (it depends on
ParquetColumnReader, not present here).aggregation/integration coverage to add here; that arrives with the reader-wrapper PR.
spotlessJavaCheck,compileJava, andcompileTestJavaall pass on thetouched modules.
Notes for reviewers
RustBridge.openColumnReaderCount()is a test-only leak check; its caller(
ParquetColumnReaderTests) arrives in the next PR.TODO(consider optimisation)markers are intentional: the secondFile::openatreader open (re-reads the footer already parsed into the cache) and the linear
locate()scan over row groups (off the aggregation path).Related Issues
Resolves #[Issue number to be closed when this PR is merged]
#22598
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.