CTTY commented on code in PR #2349:
URL: https://github.com/apache/iceberg-rust/pull/2349#discussion_r3114171661
##########
crates/iceberg/src/arrow/reader.rs:
##########
@@ -242,34 +244,51 @@ pub struct ArrowReader {
parquet_read_options: ParquetReadOptions,
}
+/// Per-scan state for processing [`FileScanTask`]s. Created once per
+/// [`ArrowReader::read`] call and cloned per task.
+#[derive(Clone)]
+struct FileScanTaskReader {
+ batch_size: Option<usize>,
+ file_io: FileIO,
+ delete_file_loader: CachingDeleteFileLoader,
+ row_group_filtering_enabled: bool,
+ row_selection_enabled: bool,
+ parquet_read_options: ParquetReadOptions,
+ scan_metrics: ScanMetrics,
+}
+
impl ArrowReader {
/// Take a stream of FileScanTasks and reads all the files.
- /// Returns a stream of Arrow RecordBatches containing the data from the
files
+ /// Returns a stream of Arrow RecordBatches containing the data from the
files.
pub fn read(self, tasks: FileScanTaskStream) ->
Result<ArrowRecordBatchStream> {
- let file_io = self.file_io.clone();
- let batch_size = self.batch_size;
+ let (stream, _metrics) = self.read_with_metrics(tasks)?;
+ Ok(stream)
+ }
+
+ /// Same as [`read`](Self::read), but also returns [`ScanMetrics`] tracking
+ /// I/O during the scan.
+ pub fn read_with_metrics(
Review Comment:
Why not always track metrics? Tracking metrics seems very low effort and
shouldn't impact performance. I think the design here also depends on how
engines like datafusion-comet track/handle metrics usually
##########
crates/iceberg/src/arrow/reader.rs:
##########
@@ -301,32 +308,29 @@ impl ArrowReader {
)
};
- Ok(stream)
+ Ok((stream, scan_metrics))
}
+}
- async fn process_file_scan_task(
- task: FileScanTask,
- batch_size: Option<usize>,
- file_io: FileIO,
- delete_file_loader: CachingDeleteFileLoader,
- row_group_filtering_enabled: bool,
- row_selection_enabled: bool,
- parquet_read_options: ParquetReadOptions,
- ) -> Result<ArrowRecordBatchStream> {
+impl FileScanTaskReader {
Review Comment:
nit: we can stick struct and impl of `FileScanTaskReader` together to make
it more readable
##########
crates/iceberg/src/arrow/reader.rs:
##########
@@ -301,32 +308,29 @@ impl ArrowReader {
)
};
- Ok(stream)
+ Ok((stream, scan_metrics))
}
+}
- async fn process_file_scan_task(
- task: FileScanTask,
- batch_size: Option<usize>,
- file_io: FileIO,
- delete_file_loader: CachingDeleteFileLoader,
- row_group_filtering_enabled: bool,
- row_selection_enabled: bool,
- parquet_read_options: ParquetReadOptions,
- ) -> Result<ArrowRecordBatchStream> {
+impl FileScanTaskReader {
+ async fn process(self, task: FileScanTask) ->
Result<ArrowRecordBatchStream> {
let should_load_page_index =
- (row_selection_enabled && task.predicate.is_some()) ||
!task.deletes.is_empty();
- let mut parquet_read_options = parquet_read_options;
+ (self.row_selection_enabled && task.predicate.is_some()) ||
!task.deletes.is_empty();
+ let mut parquet_read_options = self.parquet_read_options;
parquet_read_options.preload_page_index = should_load_page_index;
- let delete_filter_rx =
- delete_file_loader.load_deletes(&task.deletes,
Arc::clone(&task.schema));
+ let delete_filter_rx = self
+ .delete_file_loader
+ .load_deletes(&task.deletes, Arc::clone(&task.schema));
Review Comment:
Should we account for bytes read when loading delete files?
--
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]