wgtmac commented on code in PR #3698:
URL: https://github.com/apache/parquet-java/pull/3698#discussion_r3699472107


##########
parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetInputSplit.java:
##########
@@ -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;

Review Comment:
   `footer` is omitted from `write()`, but `readFields()` never clears it. 
Hadoop may reuse Writable instances, so a split can retain the footer from 
another file and `ParquetRecordReader` may open the wrong `InputFile`. Please 
clear `footer` in `readFields()` and cover object reuse in the round-trip test.



##########
parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetRecordReader.java:
##########
@@ -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())

Review Comment:
   Readers opened from the same encrypted footer share its mutable 
`InternalFileDecryptor` and JCE `Cipher` state, so concurrent splits in one JVM 
can race. Please use reader-local decryption state or skip footer reuse for 
encrypted files, and add a concurrent encrypted test.



##########
parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetInputSplit.java:
##########
@@ -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

Review Comment:
   This `JsonIgnore` is relocated in the published jar and is invisible to an 
external `ObjectMapper`, 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.inputFile` has the same issue.



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