diff options
author | Sebastian Thiel <sebastian.thiel@icloud.com> | 2020-03-16 07:23:42 +0800 |
---|---|---|
committer | Sebastian Thiel <sebastian.thiel@icloud.com> | 2020-03-16 07:23:42 +0800 |
commit | 0d6116eea1e741bc8bc1fc6d04536c8242c5aa42 (patch) | |
tree | cae291c7f26f429c0c00a87be9b8aa12b867f14e /src | |
parent | 5b696d46bf923f5eb0c7d7b3935e35695dc16318 (diff) |
jwalk 0.5 has landed - now we don't follow symlinks during traversal!
Diffstat (limited to 'src')
-rw-r--r-- | src/aggregate.rs | 19 | ||||
-rw-r--r-- | src/common.rs | 18 | ||||
-rw-r--r-- | src/interactive/app_test/utils.rs | 14 | ||||
-rw-r--r-- | src/traverse.rs | 46 |
4 files changed, 59 insertions, 38 deletions
diff --git a/src/aggregate.rs b/src/aggregate.rs index 0652a03..414a9c0 100644 --- a/src/aggregate.rs +++ b/src/aggregate.rs @@ -29,26 +29,27 @@ pub fn aggregate( stats.entries_traversed += 1; match entry { Ok(entry) => { - let file_size = match entry.metadata { - Some(Ok(ref m)) if !m.is_dir() && (options.count_hard_links || inodes.add(m)) => { + let file_size = match entry.client_state { + Some(Ok(ref m)) + if !m.is_dir() && (options.count_hard_links || inodes.add(m)) => + { if options.apparent_size { m.len() } else { - filesize::file_real_size_fast(&entry.path(), m) - .unwrap_or_else(|_| { + filesize::file_real_size_fast(&entry.path(), m).unwrap_or_else( + |_| { num_errors += 1; 0 - }) + }, + ) } - }, + } Some(Ok(_)) => 0, Some(Err(_)) => { num_errors += 1; 0 } - None => unreachable!( - "we ask for metadata, so we at least have Some(Err(..))). Issue in jwalk?" - ), + None => unreachable!("must have populated client state for metadata"), }; stats.largest_file_in_bytes = stats.largest_file_in_bytes.max(file_size); stats.smallest_file_in_bytes = stats.smallest_file_in_bytes.min(file_size); diff --git a/src/common.rs b/src/common.rs index a1551b8..91a6fb1 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,6 +1,5 @@ use crate::traverse::{EntryData, Tree, TreeIndex}; use byte_unit::{n_gb_bytes, n_gib_bytes, n_mb_bytes, n_mib_bytes, ByteUnit}; -use jwalk::WalkDir; use std::{fmt, path::Path}; pub fn get_entry_or_panic(tree: &Tree, node_idx: TreeIndex) -> &EntryData { @@ -158,16 +157,29 @@ pub struct WalkOptions { pub sorting: TraversalSorting, } +type WalkDir = jwalk::WalkDirGeneric<((), Option<Result<std::fs::Metadata, jwalk::Error>>)>; + impl WalkOptions { pub(crate) fn iter_from_path(&self, path: &Path) -> WalkDir { WalkDir::new(path) - .preload_metadata(true) + .follow_links(false) .sort(match self.sorting { TraversalSorting::None => false, TraversalSorting::AlphabeticalByFileName => true, }) .skip_hidden(false) - .num_threads(self.threads) + .process_read_dir(|_, dir_entry_results| { + dir_entry_results.iter_mut().for_each(|dir_entry_result| { + if let Ok(dir_entry) = dir_entry_result { + dir_entry.client_state = Some(dir_entry.metadata()); + } + }) + }) + .parallelism(if self.threads == 0 { + jwalk::Parallelism::RayonDefaultPool + } else { + jwalk::Parallelism::RayonNewPool(self.threads) + }) } } diff --git a/src/interactive/app_test/utils.rs b/src/interactive/app_test/utils.rs index f95efce..ca9841c 100644 --- a/src/interactive/app_test/utils.rs +++ b/src/interactive/app_test/utils.rs @@ -73,8 +73,11 @@ fn delete_recursive(path: impl AsRef<Path>) -> Result<(), Error> { let mut files: Vec<_> = Vec::new(); let mut dirs: Vec<_> = Vec::new(); - for entry in WalkDir::new(&path).num_threads(1).into_iter() { - let entry: DirEntry = entry?; + for entry in WalkDir::new(&path) + .parallelism(jwalk::Parallelism::Serial) + .into_iter() + { + let entry: DirEntry<_> = entry?; let p = entry.path(); match p.is_dir() { true => dirs.push(p), @@ -99,8 +102,11 @@ fn delete_recursive(path: impl AsRef<Path>) -> Result<(), Error> { } fn copy_recursive(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<(), Error> { - for entry in WalkDir::new(&src).num_threads(1).into_iter() { - let entry: DirEntry = entry?; + for entry in WalkDir::new(&src) + .parallelism(jwalk::Parallelism::Serial) + .into_iter() + { + let entry: DirEntry<_> = entry?; let entry_path = entry.path(); entry_path .strip_prefix(&src) diff --git a/src/traverse.rs b/src/traverse.rs index a65595e..064fcd4 100644 --- a/src/traverse.rs +++ b/src/traverse.rs @@ -93,29 +93,31 @@ impl Traversal { } else { entry.file_name }; - let file_size = match entry.metadata { - Some(Ok(ref m)) if !m.is_dir() && (walk_options.count_hard_links || inodes.add(m)) => { - if walk_options.apparent_size { - m.len() - } else { - filesize::file_real_size_fast(&data.name, m) - .unwrap_or_else(|_| { - t.io_errors += 1; - data.metadata_io_error = true; - 0 - }) - } - }, - Some(Ok(_)) => 0, - Some(Err(_)) => { - t.io_errors += 1; - data.metadata_io_error = true; - 0 + let file_size = match entry.client_state { + Some(Ok(ref m)) + if !m.is_dir() + && (walk_options.count_hard_links || inodes.add(m)) => + { + if walk_options.apparent_size { + m.len() + } else { + filesize::file_real_size_fast(&data.name, m).unwrap_or_else( + |_| { + t.io_errors += 1; + data.metadata_io_error = true; + 0 + }, + ) } - None => unreachable!( - "we ask for metadata, so we at least have Some(Err(..))). Issue in jwalk?" - ), - }; + } + Some(Ok(_)) => 0, + Some(Err(_)) => { + t.io_errors += 1; + data.metadata_io_error = true; + 0 + } + None => unreachable!("must have populated client state for metadata"), + }; match (entry.depth, previous_depth) { (n, p) if n > p => { |