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

copies-rust: process copy information of both parent at the same time

This avoid a double iteration and this open the way to a better handing of
deletion. That better handling of deletion is the core reason we are doing this
refactoring.

Differential Revision: https://phab.mercurial-scm.org/D9650
parent 7797b76c
No related branches found
No related tags found
No related merge requests found
......@@ -323,15 +323,6 @@
pub type RevInfoMaker<'a, D> =
Box<dyn for<'r> Fn(Revision, &'r mut DataHolder<D>) -> RevInfo<'r> + 'a>;
/// enum used to carry information about the parent → child currently processed
#[derive(Copy, Clone, Debug)]
enum Parent {
/// The `p1(x) → x` edge
FirstParent,
/// The `p2(x) → x` edge
SecondParent,
}
/// A small "tokenizer" responsible of turning full HgPath into lighter
/// PathToken
///
......@@ -393,7 +384,6 @@
// We will chain the copies information accumulated for the parent with
// the individual copies information the curent revision. Creating a
// new TimeStampedPath for each `rev` → `children` vertex.
let mut copies: Option<InternalPathCopies> = None;
// Retrieve data computed in a previous iteration
let p1_copies = match p1 {
NULL_REVISION => None,
......@@ -412,26 +402,8 @@
), // will be None if the vertex is not to be traversed
};
// combine it with data for that revision
let p1_copies = match p1_copies {
None => None,
Some(parent_copies) => Some(add_from_changes(
&mut path_map,
&parent_copies,
&changes,
Parent::FirstParent,
rev,
)),
};
let p2_copies = match p2_copies {
None => None,
Some(parent_copies) => Some(add_from_changes(
&mut path_map,
&parent_copies,
&changes,
Parent::SecondParent,
rev,
)),
};
let (p1_copies, p2_copies) =
chain_changes(&mut path_map, p1_copies, p2_copies, &changes, rev);
let copies = match (p1_copies, p2_copies) {
(None, None) => None,
(c, None) => c,
......@@ -489,5 +461,5 @@
/// Combine ChangedFiles with some existing PathCopies information and return
/// the result
fn add_from_changes(
fn chain_changes(
path_map: &mut TwoWayPathMap,
......@@ -493,3 +465,4 @@
path_map: &mut TwoWayPathMap,
base_copies: &InternalPathCopies,
base_p1_copies: Option<InternalPathCopies>,
base_p2_copies: Option<InternalPathCopies>,
changes: &ChangedFiles,
......@@ -495,3 +468,2 @@
changes: &ChangedFiles,
parent: Parent,
current_rev: Revision,
......@@ -497,6 +469,19 @@
current_rev: Revision,
) -> InternalPathCopies {
let mut copies = base_copies.clone();
) -> (Option<InternalPathCopies>, Option<InternalPathCopies>) {
// Fast path the "nothing to do" case.
match (&base_p1_copies, &base_p2_copies) {
(None, None) => return (None, None),
_ => (),
}
let mut p1_copies = match &base_p1_copies {
Some(c) => Some(c.clone()),
None => None,
};
let mut p2_copies = match &base_p2_copies {
Some(c) => Some(c.clone()),
None => None,
};
for action in changes.iter_actions() {
match action {
Action::CopiedFromP1(path_dest, path_source) => {
......@@ -500,8 +485,8 @@
for action in changes.iter_actions() {
match action {
Action::CopiedFromP1(path_dest, path_source) => {
match parent {
_ => (), // not the parent we are looking for
Parent::FirstParent => add_one_copy(
match &mut p1_copies {
None => (), // This is not a vertex we should proceed.
Some(copies) => add_one_copy(
current_rev,
path_map,
......@@ -506,7 +491,7 @@
current_rev,
path_map,
&mut copies,
&base_copies,
copies,
base_p1_copies.as_ref().unwrap(),
path_dest,
path_source,
),
......@@ -510,6 +495,6 @@
path_dest,
path_source,
),
};
},
}
}
Action::CopiedFromP2(path_dest, path_source) => {
......@@ -515,6 +500,6 @@
Action::CopiedFromP2(path_dest, path_source) => {
match parent {
_ => (), //not the parent we are looking for
Parent::SecondParent => add_one_copy(
match &mut p2_copies {
None => (), // This is not a vertex we should proceed.
Some(copies) => add_one_copy(
current_rev,
path_map,
......@@ -519,7 +504,7 @@
current_rev,
path_map,
&mut copies,
&base_copies,
copies,
base_p2_copies.as_ref().unwrap(),
path_dest,
path_source,
),
......@@ -523,8 +508,8 @@
path_dest,
path_source,
),
};
},
}
}
Action::Removed(deleted_path) => {
// We must drop copy information for removed file.
//
......@@ -532,9 +517,22 @@
// propagate this information when merging two
// InternalPathCopies object.
let deleted = path_map.tokenize(deleted_path);
copies.entry(deleted).and_modify(|old| {
old.mark_delete(current_rev);
});
match &mut p1_copies {
None => (),
Some(copies) => {
copies.entry(deleted).and_modify(|old| {
old.mark_delete(current_rev);
});
}
};
match &mut p2_copies {
None => (),
Some(copies) => {
copies.entry(deleted).and_modify(|old| {
old.mark_delete(current_rev);
});
}
};
}
}
}
......@@ -538,7 +536,7 @@
}
}
}
copies
(p1_copies, p2_copies)
}
// insert one new copy information in an InternalPathCopies
......
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