##// END OF EJS Templates
rhg: faster hg cat when many files are requested...
Arseniy Alekseyev -
r49038:6b5773f8 default
parent child Browse files
Show More
@@ -11,6 +11,9 b' use crate::revlog::Node;'
11
11
12 use crate::utils::hg_path::HgPathBuf;
12 use crate::utils::hg_path::HgPathBuf;
13
13
14 use itertools::EitherOrBoth::{Both, Left, Right};
15 use itertools::Itertools;
16
14 pub struct CatOutput {
17 pub struct CatOutput {
15 /// Whether any file in the manifest matched the paths given as CLI
18 /// Whether any file in the manifest matched the paths given as CLI
16 /// arguments
19 /// arguments
@@ -31,7 +34,7 b' pub struct CatOutput {'
31 pub fn cat<'a>(
34 pub fn cat<'a>(
32 repo: &Repo,
35 repo: &Repo,
33 revset: &str,
36 revset: &str,
34 files: &'a [HgPathBuf],
37 mut files: Vec<HgPathBuf>,
35 ) -> Result<CatOutput, RevlogError> {
38 ) -> Result<CatOutput, RevlogError> {
36 let rev = crate::revset::resolve_single(revset, repo)?;
39 let rev = crate::revset::resolve_single(revset, repo)?;
37 let manifest = repo.manifest_for_rev(rev)?;
40 let manifest = repo.manifest_for_rev(rev)?;
@@ -40,13 +43,21 b" pub fn cat<'a>("
40 .node_from_rev(rev)
43 .node_from_rev(rev)
41 .expect("should succeed when repo.manifest did");
44 .expect("should succeed when repo.manifest did");
42 let mut bytes = vec![];
45 let mut bytes = vec![];
43 let mut matched = vec![false; files.len()];
44 let mut found_any = false;
46 let mut found_any = false;
47 files.sort_unstable();
48
49 let mut missing = vec![];
45
50
46 for (manifest_file, node_bytes) in manifest.files_with_nodes() {
51 for entry in manifest
47 for (cat_file, is_matched) in files.iter().zip(&mut matched) {
52 .files_with_nodes()
48 if cat_file.as_bytes() == manifest_file.as_bytes() {
53 .merge_join_by(files.iter(), |(manifest_file, _), file| {
49 *is_matched = true;
54 manifest_file.cmp(&file.as_ref())
55 })
56 {
57 match entry {
58 Left(_) => (),
59 Right(path) => missing.push(path),
60 Both((manifest_file, node_bytes), _) => {
50 found_any = true;
61 found_any = true;
51 let file_log = repo.filelog(manifest_file)?;
62 let file_log = repo.filelog(manifest_file)?;
52 let file_node = Node::from_hex_for_repo(node_bytes)?;
63 let file_node = Node::from_hex_for_repo(node_bytes)?;
@@ -56,11 +67,9 b" pub fn cat<'a>("
56 }
67 }
57 }
68 }
58
69
59 let missing: Vec<_> = files
70 let missing: Vec<HgPathBuf> = missing
60 .iter()
71 .iter()
61 .zip(&matched)
72 .map(|file| (*(file.as_ref())).to_owned())
62 .filter(|pair| !*pair.1)
63 .map(|pair| pair.0.clone())
64 .collect();
73 .collect();
65 Ok(CatOutput {
74 Ok(CatOutput {
66 found_any,
75 found_any,
@@ -73,7 +73,7 b' pub fn run(invocation: &crate::CliInvoca'
73 None => format!("{:x}", repo.dirstate_parents()?.p1),
73 None => format!("{:x}", repo.dirstate_parents()?.p1),
74 };
74 };
75
75
76 let output = cat(&repo, &rev, &files).map_err(|e| (e, rev.as_str()))?;
76 let output = cat(&repo, &rev, files).map_err(|e| (e, rev.as_str()))?;
77 invocation.ui.write_stdout(&output.concatenated)?;
77 invocation.ui.write_stdout(&output.concatenated)?;
78 if !output.missing.is_empty() {
78 if !output.missing.is_empty() {
79 let short = format!("{:x}", output.node.short()).into_bytes();
79 let short = format!("{:x}", output.node.short()).into_bytes();
General Comments 0
You need to be logged in to leave comments. Login now