Skip to content
Snippets Groups Projects
Commit ed0e1339e4a8 authored by Pierre-Yves David's avatar Pierre-Yves David :octopus:
Browse files

copies-rust: combine the iteration over remove and copies into one

In the underlying data, the copies information and the removal information are
interleaved. And in the consumer code, the consumption could be interleaved too.
So, we make the processing closer to the underlying data by fusing the two
iterators into one. Later, we will directly consume the underlying data and that
logic to combine the two iterators will be unnecessary.

Differential Revision: https://phab.mercurial-scm.org/D9304
parent 8b99c473aae2
No related branches found
No related tags found
No related merge requests found
use crate::utils::hg_path::HgPath;
use crate::utils::hg_path::HgPathBuf;
use crate::Revision;
......@@ -36,6 +37,18 @@
copied_from_p2: PathCopies,
}
/// Represent active changes that affect the copy tracing.
enum Action<'a> {
/// The parent ? children edge is removing a file
///
/// (actually, this could be the edge from the other parent, but it does
/// not matters)
Removed(&'a HgPath),
/// The parent ? children edge introduce copy information between (dest,
/// source)
Copied(&'a HgPath, &'a HgPath),
}
impl ChangedFiles {
pub fn new(
removed: HashSet<HgPathBuf>,
......@@ -62,6 +75,19 @@
copied_from_p2: PathCopies::new(),
}
}
/// Return an iterator over all the `Action` in this instance.
fn iter_actions(&self, parent: usize) -> impl Iterator<Item = Action> {
let copies_iter = match parent {
1 => self.copied_from_p1.iter(),
2 => self.copied_from_p2.iter(),
_ => unreachable!(),
};
let remove_iter = self.removed.iter();
let copies_iter = copies_iter.map(|(x, y)| Action::Copied(x, y));
let remove_iter = remove_iter.map(|x| Action::Removed(x));
copies_iter.chain(remove_iter)
}
}
/// A struct responsible for answering "is X ancestors of Y" quickly
......@@ -142,7 +168,7 @@
// Creating a new PathCopies for each `rev` ? `children` vertex.
let (p1, p2, changes) = rev_info(*child);
let (parent, child_copies) = if rev == p1 {
(1, &changes.copied_from_p1)
let parent = if rev == p1 {
1
} else {
assert_eq!(rev, p2);
......@@ -147,6 +173,6 @@
} else {
assert_eq!(rev, p2);
(2, &changes.copied_from_p2)
2
};
let mut new_copies = copies.clone();
......@@ -150,10 +176,25 @@
};
let mut new_copies = copies.clone();
for (dest, source) in child_copies {
let entry;
if let Some(v) = copies.get(source) {
entry = match &v.path {
Some(path) => Some((*(path)).to_owned()),
None => Some(source.to_owned()),
for action in changes.iter_actions(parent) {
match action {
Action::Copied(dest, source) => {
let entry;
if let Some(v) = copies.get(source) {
entry = match &v.path {
Some(path) => Some((*(path)).to_owned()),
None => Some(source.to_owned()),
}
} else {
entry = Some(source.to_owned());
}
// Each new entry is introduced by the children, we
// record this information as we will need it to take
// the right decision when merging conflicting copy
// information. See merge_copies_dict for details.
let ttpc = TimeStampedPathCopy {
rev: *child,
path: entry,
};
new_copies.insert(dest.to_owned(), ttpc);
}
......@@ -159,29 +200,18 @@
}
} else {
entry = Some(source.to_owned());
}
// Each new entry is introduced by the children, we record this
// information as we will need it to take the right decision
// when merging conflicting copy information. See
// merge_copies_dict for details.
let ttpc = TimeStampedPathCopy {
rev: *child,
path: entry,
};
new_copies.insert(dest.to_owned(), ttpc);
}
// We must drop copy information for removed file.
//
// We need to explicitly record them as dropped to propagate this
// information when merging two TimeStampedPathCopies object.
for f in changes.removed.iter() {
if new_copies.contains_key(f.as_ref()) {
let ttpc = TimeStampedPathCopy {
rev: *child,
path: None,
};
new_copies.insert(f.to_owned(), ttpc);
Action::Removed(f) => {
// We must drop copy information for removed file.
//
// We need to explicitly record them as dropped to
// propagate this information when merging two
// TimeStampedPathCopies object.
if new_copies.contains_key(f.as_ref()) {
let ttpc = TimeStampedPathCopy {
rev: *child,
path: None,
};
new_copies.insert(f.to_owned(), ttpc);
}
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment