-
Notifications
You must be signed in to change notification settings - Fork 1.6k
GH-3697: Reuse hadoop file status and footer in ParquetRecordReader #3698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,7 @@ | |
| */ | ||
| package org.apache.parquet.hadoop; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonIgnore; | ||
| import java.io.ByteArrayInputStream; | ||
| import java.io.ByteArrayOutputStream; | ||
| import java.io.DataInput; | ||
|
|
@@ -36,6 +37,7 @@ | |
| import org.apache.hadoop.mapreduce.lib.input.FileSplit; | ||
| import org.apache.parquet.hadoop.metadata.BlockMetaData; | ||
| import org.apache.parquet.hadoop.metadata.ColumnChunkMetaData; | ||
| import org.apache.parquet.hadoop.metadata.ParquetMetadata; | ||
| import org.apache.parquet.schema.MessageType; | ||
| import org.apache.parquet.schema.MessageTypeParser; | ||
|
|
||
|
|
@@ -55,6 +57,13 @@ public class ParquetInputSplit extends FileSplit implements Writable { | |
| private long end; | ||
| private long[] rowGroupOffsets; | ||
|
|
||
| /** | ||
| * Footer of the file, if the split was built by a caller which had already read it. | ||
| * Not written by {@link #write(DataOutput)}, so it is only visible within the JVM which set it. | ||
| */ | ||
| @JsonIgnore | ||
| private volatile ParquetMetadata footer; | ||
|
|
||
| /** | ||
| * Writables must have a parameterless constructor | ||
| */ | ||
|
|
@@ -222,6 +231,24 @@ public long[] getRowGroupOffsets() { | |
| return rowGroupOffsets; | ||
| } | ||
|
|
||
| /** | ||
| * @return the footer of the file, if it was passed in by whoever built the split, else null. | ||
| */ | ||
| public ParquetMetadata getFooter() { | ||
| return footer; | ||
| } | ||
|
|
||
| /** | ||
| * Pass in a footer already read from the file, so that a reader created from this split does not have to read it | ||
| * again. As the footer is not serialized with the split, this only has an effect on readers created in the same | ||
| * JVM. | ||
| * | ||
| * @param footer footer of the file this split refers to | ||
| */ | ||
| public void setFooter(ParquetMetadata footer) { | ||
| this.footer = footer; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good one. Needs fix. |
||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| String hosts; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,9 +43,11 @@ | |
| import org.apache.parquet.hadoop.metadata.BlockMetaData; | ||
| import org.apache.parquet.hadoop.metadata.ColumnChunkMetaData; | ||
| import org.apache.parquet.hadoop.metadata.FileMetaData; | ||
| import org.apache.parquet.hadoop.metadata.ParquetMetadata; | ||
| import org.apache.parquet.hadoop.util.ContextUtil; | ||
| import org.apache.parquet.hadoop.util.HadoopInputFile; | ||
| import org.apache.parquet.hadoop.util.counters.BenchmarkCounter; | ||
| import org.apache.parquet.io.InputFile; | ||
| import org.apache.parquet.io.ParquetDecodingException; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
@@ -154,9 +156,16 @@ private void initializeInternalReader(ParquetInputSplit split, Configuration con | |
| optionsBuilder.withRange(split.getStart(), split.getEnd()); | ||
| } | ||
|
|
||
| // open a reader with the metadata filter | ||
| ParquetFileReader reader = | ||
| ParquetFileReader.open(HadoopInputFile.fromPath(path, configuration), optionsBuilder.build()); | ||
| // open a reader with the metadata filter, reusing the footer of the split and the file it was read from | ||
| // when the split was built by a caller which had already read them | ||
| ParquetMetadata footer = split.getFooter(); | ||
| InputFile inputFile = footer != null && footer.getInputFile() != null | ||
| ? footer.getInputFile() | ||
| : HadoopInputFile.fromPath(path, configuration); | ||
| ParquetReadOptions options = optionsBuilder.build(); | ||
| ParquetFileReader reader = footer != null | ||
| ? ParquetFileReader.open(inputFile, footer, options, inputFile.newStream()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Readers opened from the same encrypted footer share its mutable |
||
| : ParquetFileReader.open(inputFile, options); | ||
|
|
||
| if (rowGroupOffsets != null) { | ||
| // verify a row group was found for each offset | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
JsonIgnoreis relocated in the published jar and is invisible to an externalObjectMapper, as the new CLI mix-in notes. The current test runs before shading. Please use a serialization-neutral exclusion and test the shaded artifact;ParquetMetadata.inputFilehas the same issue.