diff options
author | Colin Finck <colin@reactos.org> | 2021-06-04 12:57:00 +0300 |
---|---|---|
committer | Colin Finck <colin@reactos.org> | 2021-06-04 12:57:00 +0300 |
commit | 2410b41bbf633bb136364cce63f631a2e219a76d (patch) | |
tree | aae08e21ee64dc9a367a3a2f172858654217edd0 | |
parent | 8206512fd216682b1e160331565a45ddc760a787 (diff) |
Optimize a common case when seeking non-resident values.
This translates `SeekFrom::Start(n)` into a more efficient `SeekFrom::Current` if n >= self.stream_position.
We don't need to traverse data runs from the very beginning then.
-rw-r--r-- | src/attribute_value.rs | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/attribute_value.rs b/src/attribute_value.rs index 251a761..647e644 100644 --- a/src/attribute_value.rs +++ b/src/attribute_value.rs @@ -385,10 +385,21 @@ impl<'n> NtfsAttributeNonResidentValue<'n> { self.data_size } - fn do_seek<T>(&mut self, fs: &mut T, bytes_to_seek: SeekFrom) -> Result<u64> + fn do_seek<T>(&mut self, fs: &mut T, mut bytes_to_seek: SeekFrom) -> Result<u64> where T: Read + Seek, { + // Translate `SeekFrom::Start(n)` into a more efficient `SeekFrom::Current` + // if n >= self.stream_position. + // We don't need to traverse data runs from the very beginning then. + if let SeekFrom::Start(n) = bytes_to_seek { + if let Some(n_from_current) = n.checked_sub(self.stream_position) { + if n_from_current <= i64::MAX as u64 { + bytes_to_seek = SeekFrom::Current(n_from_current as i64); + } + } + } + let mut bytes_left_to_seek = match bytes_to_seek { SeekFrom::Start(n) => { // Reset `stream_data_runs` and `stream_data_run` to read from the very beginning. |