[Request] [+-- ] D11622: dirstate: simplify cat operation
martinvonz (Martin von Zweigbergk)
phabricator at mercurial-scm.org
Sat Oct 9 00:17:10 UTC 2021
martinvonz created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D11622
AFFECTED FILES
rust/hg-core/src/operations/cat.rs
rust/rhg/src/commands/cat.rs
CHANGE DETAILS
diff --git a/rust/rhg/src/commands/cat.rs b/rust/rhg/src/commands/cat.rs
--- a/rust/rhg/src/commands/cat.rs
+++ b/rust/rhg/src/commands/cat.rs
@@ -73,7 +73,7 @@
None => format!("{:x}", repo.dirstate_parents()?.p1),
};
- let output = cat(&repo, &rev, files).map_err(|e| (e, rev.as_str()))?;
+ let output = cat(&repo, &rev, &files).map_err(|e| (e, rev.as_str()))?;
invocation.ui.write_stdout(&output.concatenated)?;
if !output.missing.is_empty() {
let short = format!("{:x}", output.node.short()).into_bytes();
diff --git a/rust/hg-core/src/operations/cat.rs b/rust/hg-core/src/operations/cat.rs
--- a/rust/hg-core/src/operations/cat.rs
+++ b/rust/hg-core/src/operations/cat.rs
@@ -9,12 +9,9 @@
use crate::revlog::revlog::RevlogError;
use crate::revlog::Node;
-use crate::utils::hg_path::HgPath;
use crate::utils::hg_path::HgPathBuf;
-use itertools::put_back;
-use itertools::PutBack;
-use std::cmp::Ordering;
+use std::collections::HashSet;
pub struct CatOutput {
/// Whether any file in the manifest matched the paths given as CLI
@@ -28,49 +25,6 @@
pub node: Node,
}
-// Find an item in an iterator over a sorted collection.
-fn find_item<'a, 'b, 'c, D, I: Iterator<Item = (&'a HgPath, D)>>(
- i: &mut PutBack<I>,
- needle: &'b HgPath,
-) -> Option<I::Item> {
- loop {
- match i.next() {
- None => return None,
- Some(val) => match needle.as_bytes().cmp(val.0.as_bytes()) {
- Ordering::Less => {
- i.put_back(val);
- return None;
- }
- Ordering::Greater => continue,
- Ordering::Equal => return Some(val),
- },
- }
- }
-}
-
-fn find_files_in_manifest<
- 'a,
- 'b,
- D,
- I: Iterator<Item = (&'a HgPath, D)>,
- J: Iterator<Item = &'b HgPath>,
->(
- manifest: I,
- files: J,
-) -> (Vec<(&'a HgPath, D)>, Vec<&'b HgPath>) {
- let mut manifest = put_back(manifest);
- let mut res = vec![];
- let mut missing = vec![];
-
- for file in files {
- match find_item(&mut manifest, file) {
- None => missing.push(file),
- Some(item) => res.push(item),
- }
- }
- return (res, missing);
-}
-
/// Output the given revision of files
///
/// * `root`: Repository root
@@ -79,7 +33,7 @@
pub fn cat<'a>(
repo: &Repo,
revset: &str,
- mut files: Vec<HgPathBuf>,
+ files: &[HgPathBuf],
) -> Result<CatOutput, RevlogError> {
let rev = crate::revset::resolve_single(revset, repo)?;
let manifest = repo.manifest_for_rev(rev)?;
@@ -87,30 +41,24 @@
.changelog()?
.node_from_rev(rev)
.expect("should succeed when repo.manifest did");
+
+ let mut missing: HashSet<_> = files.iter().map(|x| x.as_ref()).collect();
let mut bytes: Vec<u8> = vec![];
- let mut found_any = false;
-
- files.sort_unstable();
-
- let (found, missing) = find_files_in_manifest(
- manifest.files_with_nodes(),
- files.iter().map(|f| f.as_ref()),
- );
-
- for (manifest_file, node_bytes) in found {
- found_any = true;
- let file_log = repo.filelog(manifest_file)?;
- let file_node = Node::from_hex_for_repo(node_bytes)?;
- bytes.extend(file_log.data_for_node(file_node)?.data()?);
+ if let Some(last_path) = files.iter().max() {
+ for (path, node_bytes) in manifest.files_with_nodes() {
+ if missing.remove(&*path) {
+ let file_log = repo.filelog(path)?;
+ let file_node = Node::from_hex_for_repo(node_bytes)?;
+ bytes.extend(file_log.data_for_node(file_node)?.data()?);
+ }
+ if path >= last_path {
+ break;
+ }
+ }
}
-
- // make the order of the [missing] files
- // match the order they were specified on the command line
- let missing: Vec<_> = files
- .iter()
- .filter(|file| missing.contains(&file.as_ref()))
- .map(|file| file.clone())
- .collect();
+ let found_any = missing.len() != files.len();
+ let missing: Vec<_> =
+ missing.into_iter().map(|path| path.to_owned()).collect();
Ok(CatOutput {
found_any,
concatenated: bytes,
To: martinvonz, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mercurial-scm.org/pipermail/mercurial-patches/attachments/20211009/dfffdf74/attachment-0001.html>
More information about the Mercurial-patches
mailing list