# HG changeset patch # User Raphaël Gomès # Date 1573118622 -3600 # Node ID 75fe6e71ddb86bb91dcdb5b24017e940f1d7aac3 # Parent 889ac87e8bfd04d7ef1af57df863e3d2e9ca2680 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries This allows the caller function to choose when and how the iteration and/or collection happens. This change also cleans up the now unused `filter_map`. Differential Revision: https://phab.mercurial-scm.org/D7299 diff -r 889ac87e8bfd -r 75fe6e71ddb8 rust/hg-core/src/dirstate/status.rs --- a/rust/hg-core/src/dirstate/status.rs Wed Nov 06 13:43:18 2019 +0100 +++ b/rust/hg-core/src/dirstate/status.rs Thu Nov 07 10:23:42 2019 +0100 @@ -113,53 +113,48 @@ /// the relevant collections. fn stat_dmap_entries( dmap: &DirstateMap, - root_dir: impl AsRef + Sync, + root_dir: impl AsRef + Sync + Send, check_exec: bool, list_clean: bool, last_normal_time: i64, -) -> std::io::Result> { - dmap.par_iter() - .filter_map( - // Getting file metadata is costly, so we don't do it if the - // file is already present in the results, hence `filter_map` - |(filename, entry)| -> Option< - std::io::Result<(&HgPath, Dispatch)> - > { - let meta = match hg_path_to_path_buf(filename) { - Ok(p) => root_dir.as_ref().join(p).symlink_metadata(), - Err(e) => return Some(Err(e.into())), - }; +) -> impl ParallelIterator> { + dmap.par_iter().map(move |(filename, entry)| { + let filename: &HgPath = filename; + let filename_as_path = hg_path_to_path_buf(filename)?; + let meta = root_dir.as_ref().join(filename_as_path).symlink_metadata(); - Some(match meta { - Ok(ref m) - if !(m.file_type().is_file() - || m.file_type().is_symlink()) => - { - Ok((filename, dispatch_missing(entry.state))) - } - Ok(m) => Ok((filename, dispatch_found( - filename, - *entry, - HgMetadata::from_metadata(m), - &dmap.copy_map, - check_exec, - list_clean, - last_normal_time))), - Err(ref e) - if e.kind() == std::io::ErrorKind::NotFound - || e.raw_os_error() == Some(20) => - { - // Rust does not yet have an `ErrorKind` for - // `NotADirectory` (errno 20) - // It happens if the dirstate contains `foo/bar` and - // foo is not a directory - Ok((filename, dispatch_missing(entry.state))) - } - Err(e) => Err(e), - }) - }, - ) - .collect() + match meta { + Ok(ref m) + if !(m.file_type().is_file() + || m.file_type().is_symlink()) => + { + Ok((filename, dispatch_missing(entry.state))) + } + Ok(m) => Ok(( + filename, + dispatch_found( + filename, + *entry, + HgMetadata::from_metadata(m), + &dmap.copy_map, + check_exec, + list_clean, + last_normal_time, + ), + )), + Err(ref e) + if e.kind() == std::io::ErrorKind::NotFound + || e.raw_os_error() == Some(20) => + { + // Rust does not yet have an `ErrorKind` for + // `NotADirectory` (errno 20) + // It happens if the dirstate contains `foo/bar` and + // foo is not a directory + Ok((filename, dispatch_missing(entry.state))) + } + Err(e) => Err(e), + } + }) } pub struct StatusResult<'a> { @@ -208,18 +203,19 @@ pub fn status( dmap: &DirstateMap, - root_dir: impl AsRef + Sync + Copy, + root_dir: impl AsRef + Sync + Send + Copy, list_clean: bool, last_normal_time: i64, check_exec: bool, ) -> std::io::Result<(Vec<&HgPath>, StatusResult)> { - let results = stat_dmap_entries( + let results: std::io::Result<_> = stat_dmap_entries( &dmap, root_dir, check_exec, list_clean, last_normal_time, - )?; + ) + .collect(); - Ok(build_response(results)) + Ok(build_response(results?)) }