comparison rust/hg-core/src/dirstate/status.rs @ 43456:ab9b0a20b9e6

rust-status: remove dead code The `walk_explicit` function is only called when using a prefix matcher, which the Rust code does not yet support. This function will return in a future patch, probably with a different signature for performance reasons. With it, the `files` argument and its interface code can be removed for now. Differential Revision: https://phab.mercurial-scm.org/D7253
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 06 Nov 2019 13:46:16 +0100
parents 99394e6c5d12
children 889ac87e8bfd
comparison
equal deleted inserted replaced
43455:6792da448437 43456:ab9b0a20b9e6
8 //! Rust implementation of dirstate.status (dirstate.py). 8 //! Rust implementation of dirstate.status (dirstate.py).
9 //! It is currently missing a lot of functionality compared to the Python one 9 //! It is currently missing a lot of functionality compared to the Python one
10 //! and will only be triggered in narrow cases. 10 //! and will only be triggered in narrow cases.
11 11
12 use crate::utils::files::HgMetadata; 12 use crate::utils::files::HgMetadata;
13 use crate::utils::hg_path::{hg_path_to_path_buf, HgPath, HgPathBuf}; 13 use crate::utils::hg_path::{hg_path_to_path_buf, HgPathBuf};
14 use crate::{DirstateEntry, DirstateMap, EntryState}; 14 use crate::{DirstateEntry, DirstateMap, EntryState};
15 use rayon::prelude::*; 15 use rayon::prelude::*;
16 use std::collections::HashMap;
17 use std::fs::Metadata;
18 use std::path::Path; 16 use std::path::Path;
19
20 /// Get stat data about the files explicitly specified by match.
21 /// TODO subrepos
22 fn walk_explicit(
23 files: &[impl AsRef<HgPath> + Sync],
24 dmap: &DirstateMap,
25 root_dir: impl AsRef<Path> + Sync,
26 ) -> std::io::Result<HashMap<HgPathBuf, Option<HgMetadata>>> {
27 let mut results = HashMap::new();
28
29 // A tuple of the normalized filename and the `Result` of the call to
30 // `symlink_metadata` for separate handling.
31 type WalkTuple<'a> = (&'a HgPath, std::io::Result<Metadata>);
32
33 let stats_res: std::io::Result<Vec<WalkTuple>> = files
34 .par_iter()
35 .map(|filename| {
36 // TODO normalization
37 let normalized = filename.as_ref();
38
39 let target_filename =
40 root_dir.as_ref().join(hg_path_to_path_buf(normalized)?);
41
42 Ok((normalized, target_filename.symlink_metadata()))
43 })
44 .collect();
45
46 for res in stats_res? {
47 match res {
48 (normalized, Ok(stat)) => {
49 if stat.is_file() {
50 results.insert(
51 normalized.to_owned(),
52 Some(HgMetadata::from_metadata(stat)),
53 );
54 } else {
55 if dmap.contains_key(normalized) {
56 results.insert(normalized.to_owned(), None);
57 }
58 }
59 }
60 (normalized, Err(_)) => {
61 if dmap.contains_key(normalized) {
62 results.insert(normalized.to_owned(), None);
63 }
64 }
65 };
66 }
67
68 Ok(results)
69 }
70 17
71 // Stat all entries in the `DirstateMap` and return their new metadata. 18 // Stat all entries in the `DirstateMap` and return their new metadata.
72 pub fn stat_dmap_entries( 19 pub fn stat_dmap_entries(
73 dmap: &DirstateMap, 20 dmap: &DirstateMap,
74 results: &HashMap<HgPathBuf, Option<HgMetadata>>,
75 root_dir: impl AsRef<Path> + Sync, 21 root_dir: impl AsRef<Path> + Sync,
76 ) -> std::io::Result<Vec<(HgPathBuf, Option<HgMetadata>)>> { 22 ) -> std::io::Result<Vec<(HgPathBuf, Option<HgMetadata>)>> {
77 dmap.par_iter() 23 dmap.par_iter()
78 .filter_map( 24 .filter_map(
79 // Getting file metadata is costly, so we don't do it if the 25 // Getting file metadata is costly, so we don't do it if the
80 // file is already present in the results, hence `filter_map` 26 // file is already present in the results, hence `filter_map`
81 |(filename, _)| -> Option< 27 |(filename, _)| -> Option<
82 std::io::Result<(HgPathBuf, Option<HgMetadata>)> 28 std::io::Result<(HgPathBuf, Option<HgMetadata>)>
83 > { 29 > {
84 if results.contains_key(filename) {
85 return None;
86 }
87 let meta = match hg_path_to_path_buf(filename) { 30 let meta = match hg_path_to_path_buf(filename) {
88 Ok(p) => root_dir.as_ref().join(p).symlink_metadata(), 31 Ok(p) => root_dir.as_ref().join(p).symlink_metadata(),
89 Err(e) => return Some(Err(e.into())), 32 Err(e) => return Some(Err(e.into())),
90 }; 33 };
91 34
130 fn build_response( 73 fn build_response(
131 dmap: &DirstateMap, 74 dmap: &DirstateMap,
132 list_clean: bool, 75 list_clean: bool,
133 last_normal_time: i64, 76 last_normal_time: i64,
134 check_exec: bool, 77 check_exec: bool,
135 results: HashMap<HgPathBuf, Option<HgMetadata>>, 78 results: Vec<(HgPathBuf, Option<HgMetadata>)>,
136 ) -> (Vec<HgPathBuf>, StatusResult) { 79 ) -> (Vec<HgPathBuf>, StatusResult) {
137 let mut lookup = vec![]; 80 let mut lookup = vec![];
138 let mut modified = vec![]; 81 let mut modified = vec![];
139 let mut added = vec![]; 82 let mut added = vec![];
140 let mut removed = vec![]; 83 let mut removed = vec![];
227 } 170 }
228 171
229 pub fn status( 172 pub fn status(
230 dmap: &DirstateMap, 173 dmap: &DirstateMap,
231 root_dir: impl AsRef<Path> + Sync + Copy, 174 root_dir: impl AsRef<Path> + Sync + Copy,
232 files: &[impl AsRef<HgPath> + Sync],
233 list_clean: bool, 175 list_clean: bool,
234 last_normal_time: i64, 176 last_normal_time: i64,
235 check_exec: bool, 177 check_exec: bool,
236 ) -> std::io::Result<(Vec<HgPathBuf>, StatusResult)> { 178 ) -> std::io::Result<(Vec<HgPathBuf>, StatusResult)> {
237 let mut results = walk_explicit(files, &dmap, root_dir)?; 179 let results = stat_dmap_entries(&dmap, root_dir)?;
238
239 results.extend(stat_dmap_entries(&dmap, &results, root_dir)?);
240 180
241 Ok(build_response( 181 Ok(build_response(
242 &dmap, 182 &dmap,
243 list_clean, 183 list_clean,
244 last_normal_time, 184 last_normal_time,