D9304: copies-rust: combine the iteration over remove and copies into one
marmoute (Pierre-Yves David)
phabricator at mercurial-scm.org
Thu Nov 12 15:17:00 UTC 2020
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
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 iterator will unnecessary.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D9304
AFFECTED FILES
rust/hg-core/src/copy_tracing.rs
CHANGE DETAILS
diff --git a/rust/hg-core/src/copy_tracing.rs b/rust/hg-core/src/copy_tracing.rs
--- a/rust/hg-core/src/copy_tracing.rs
+++ b/rust/hg-core/src/copy_tracing.rs
@@ -1,3 +1,4 @@
+use crate::utils::hg_path::HgPath;
use crate::utils::hg_path::HgPathBuf;
use crate::Revision;
@@ -34,6 +35,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>,
@@ -60,6 +73,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
@@ -141,49 +167,50 @@
let (p1, p2, changes) = rev_info(*child);
let parent;
- let child_copies;
if rev == p1 {
parent = 1;
- child_copies = &changes.copied_from_p1;
} else {
assert_eq!(rev, p2);
parent = 2;
- child_copies = &changes.copied_from_p2;
}
let mut new_copies = copies.clone();
- for (dest, source) in child_copies.into_iter() {
- 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);
}
- } 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);
+ }
+ }
}
}
To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list