annotate rust/hg-core/src/copy_tracing.rs @ 46154:ecbb2fc9418c

copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite The core information that we want here is about "does information from revision X overwrite information in Y". To do so, we check is X is an ancestors of Y, but this is an implementation details, they could be other ways. We update the naming to clarify this (and align more with wording used in upcoming changesets. For people curious about other ways: for example we could record the overwrite graph as it happens and reuse that to check if X overwrite Y, without having to do potential expensive `is_ancestor` call on the revision graph. Differential Revision: https://phab.mercurial-scm.org/D9496
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 02 Dec 2020 16:11:35 +0100
parents 0a721fc457bf
children fce2f20a54ce
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
1 use crate::utils::hg_path::HgPath;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
2 use crate::utils::hg_path::HgPathBuf;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
3 use crate::Revision;
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
4 use crate::NULL_REVISION;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
5
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
6 use im_rc::ordmap::DiffItem;
46153
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
7 use im_rc::ordmap::Entry;
45963
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
8 use im_rc::ordmap::OrdMap;
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
9
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
10 use std::cmp::Ordering;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
11 use std::collections::HashMap;
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
12 use std::convert::TryInto;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
13
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
14 pub type PathCopies = HashMap<HgPathBuf, HgPathBuf>;
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
15
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
16 type PathToken = usize;
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
17
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
18 #[derive(Clone, Debug, PartialEq, Copy)]
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
19 struct TimeStampedPathCopy {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
20 /// revision at which the copy information was added
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
21 rev: Revision,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
22 /// the copy source, (Set to None in case of deletion of the associated
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
23 /// key)
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
24 path: Option<PathToken>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
25 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
26
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
27 /// maps CopyDestination to Copy Source (+ a "timestamp" for the operation)
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
28 type TimeStampedPathCopies = OrdMap<PathToken, TimeStampedPathCopy>;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
29
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
30 /// hold parent 1, parent 2 and relevant files actions.
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
31 pub type RevInfo<'a> = (Revision, Revision, ChangedFiles<'a>);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
32
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
33 /// represent the files affected by a changesets
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
34 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
35 /// This hold a subset of mercurial.metadata.ChangingFiles as we do not need
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
36 /// all the data categories tracked by it.
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
37 /// This hold a subset of mercurial.metadata.ChangingFiles as we do not need
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
38 /// all the data categories tracked by it.
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
39 pub struct ChangedFiles<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
40 nb_items: u32,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
41 index: &'a [u8],
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
42 data: &'a [u8],
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
43 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
44
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
45 /// Represent active changes that affect the copy tracing.
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
46 enum Action<'a> {
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
47 /// The parent ? children edge is removing a file
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
48 ///
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
49 /// (actually, this could be the edge from the other parent, but it does
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
50 /// not matters)
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
51 Removed(&'a HgPath),
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
52 /// The parent ? children edge introduce copy information between (dest,
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
53 /// source)
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
54 Copied(&'a HgPath, &'a HgPath),
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
55 }
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
56
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
57 /// This express the possible "special" case we can get in a merge
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
58 ///
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
59 /// See mercurial/metadata.py for details on these values.
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
60 #[derive(PartialEq)]
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
61 enum MergeCase {
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
62 /// Merged: file had history on both side that needed to be merged
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
63 Merged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
64 /// Salvaged: file was candidate for deletion, but survived the merge
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
65 Salvaged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
66 /// Normal: Not one of the two cases above
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
67 Normal,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
68 }
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
69
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
70 type FileChange<'a> = (u8, &'a HgPath, &'a HgPath);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
71
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
72 const EMPTY: &[u8] = b"";
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
73 const COPY_MASK: u8 = 3;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
74 const P1_COPY: u8 = 2;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
75 const P2_COPY: u8 = 3;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
76 const ACTION_MASK: u8 = 28;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
77 const REMOVED: u8 = 12;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
78 const MERGED: u8 = 8;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
79 const SALVAGED: u8 = 16;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
80
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
81 impl<'a> ChangedFiles<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
82 const INDEX_START: usize = 4;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
83 const ENTRY_SIZE: u32 = 9;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
84 const FILENAME_START: u32 = 1;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
85 const COPY_SOURCE_START: u32 = 5;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
86
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
87 pub fn new(data: &'a [u8]) -> Self {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
88 assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
89 data.len() >= 4,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
90 "data size ({}) is too small to contain the header (4)",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
91 data.len()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
92 );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
93 let nb_items_raw: [u8; 4] = (&data[0..=3])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
94 .try_into()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
95 .expect("failed to turn 4 bytes into 4 bytes");
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
96 let nb_items = u32::from_be_bytes(nb_items_raw);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
97
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
98 let index_size = (nb_items * Self::ENTRY_SIZE) as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
99 let index_end = Self::INDEX_START + index_size;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
100
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
101 assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
102 data.len() >= index_end,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
103 "data size ({}) is too small to fit the index_data ({})",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
104 data.len(),
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
105 index_end
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
106 );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
107
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
108 let ret = ChangedFiles {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
109 nb_items,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
110 index: &data[Self::INDEX_START..index_end],
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
111 data: &data[index_end..],
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
112 };
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
113 let max_data = ret.filename_end(nb_items - 1) as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
114 assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
115 ret.data.len() >= max_data,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
116 "data size ({}) is too small to fit all data ({})",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
117 data.len(),
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
118 index_end + max_data
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
119 );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
120 ret
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
121 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
122
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
123 pub fn new_empty() -> Self {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
124 ChangedFiles {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
125 nb_items: 0,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
126 index: EMPTY,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
127 data: EMPTY,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
128 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
129 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
130
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
131 /// internal function to return an individual entry at a given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
132 fn entry(&'a self, idx: u32) -> FileChange<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
133 if idx >= self.nb_items {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
134 panic!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
135 "index for entry is higher that the number of file {} >= {}",
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
136 idx, self.nb_items
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
137 )
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
138 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
139 let flags = self.flags(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
140 let filename = self.filename(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
141 let copy_idx = self.copy_idx(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
142 let copy_source = self.filename(copy_idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
143 (flags, filename, copy_source)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
144 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
145
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
146 /// internal function to return the filename of the entry at a given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
147 fn filename(&self, idx: u32) -> &HgPath {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
148 let filename_start;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
149 if idx == 0 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
150 filename_start = 0;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
151 } else {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
152 filename_start = self.filename_end(idx - 1)
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
153 }
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
154 let filename_end = self.filename_end(idx);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
155 let filename_start = filename_start as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
156 let filename_end = filename_end as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
157 HgPath::new(&self.data[filename_start..filename_end])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
158 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
159
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
160 /// internal function to return the flag field of the entry at a given
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
161 /// index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
162 fn flags(&self, idx: u32) -> u8 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
163 let idx = idx as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
164 self.index[idx * (Self::ENTRY_SIZE as usize)]
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
165 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
166
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
167 /// internal function to return the end of a filename part at a given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
168 fn filename_end(&self, idx: u32) -> u32 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
169 let start = (idx * Self::ENTRY_SIZE) + Self::FILENAME_START;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
170 let end = (idx * Self::ENTRY_SIZE) + Self::COPY_SOURCE_START;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
171 let start = start as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
172 let end = end as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
173 let raw = (&self.index[start..end])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
174 .try_into()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
175 .expect("failed to turn 4 bytes into 4 bytes");
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
176 u32::from_be_bytes(raw)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
177 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
178
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
179 /// internal function to return index of the copy source of the entry at a
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
180 /// given index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
181 fn copy_idx(&self, idx: u32) -> u32 {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
182 let start = (idx * Self::ENTRY_SIZE) + Self::COPY_SOURCE_START;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
183 let end = (idx + 1) * Self::ENTRY_SIZE;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
184 let start = start as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
185 let end = end as usize;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
186 let raw = (&self.index[start..end])
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
187 .try_into()
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
188 .expect("failed to turn 4 bytes into 4 bytes");
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
189 u32::from_be_bytes(raw)
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
190 }
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
191
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
192 /// Return an iterator over all the `Action` in this instance.
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
193 fn iter_actions(&self, parent: Parent) -> ActionsIterator {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
194 ActionsIterator {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
195 changes: &self,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
196 parent: parent,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
197 current: 0,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
198 }
45973
ed0e1339e4a8 copies-rust: combine the iteration over remove and copies into one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45972
diff changeset
199 }
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
200
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
201 /// return the MergeCase value associated with a filename
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
202 fn get_merge_case(&self, path: &HgPath) -> MergeCase {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
203 if self.nb_items == 0 {
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
204 return MergeCase::Normal;
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
205 }
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
206 let mut low_part = 0;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
207 let mut high_part = self.nb_items;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
208
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
209 while low_part < high_part {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
210 let cursor = (low_part + high_part - 1) / 2;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
211 let (flags, filename, _source) = self.entry(cursor);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
212 match path.cmp(filename) {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
213 Ordering::Less => low_part = cursor + 1,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
214 Ordering::Greater => high_part = cursor,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
215 Ordering::Equal => {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
216 return match flags & ACTION_MASK {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
217 MERGED => MergeCase::Merged,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
218 SALVAGED => MergeCase::Salvaged,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
219 _ => MergeCase::Normal,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
220 };
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
221 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
222 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
223 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
224 MergeCase::Normal
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
225 }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
226 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
227
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
228 /// A struct responsible for answering "is X ancestors of Y" quickly
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
229 ///
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
230 /// The structure will delegate ancestors call to a callback, and cache the
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
231 /// result.
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
232 #[derive(Debug)]
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
233 struct AncestorOracle<'a, A: Fn(Revision, Revision) -> bool> {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
234 inner: &'a A,
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
235 pairs: HashMap<(Revision, Revision), bool>,
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
236 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
237
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
238 impl<'a, A: Fn(Revision, Revision) -> bool> AncestorOracle<'a, A> {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
239 fn new(func: &'a A) -> Self {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
240 Self {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
241 inner: func,
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
242 pairs: HashMap::default(),
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
243 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
244 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
245
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
246 /// returns `true` if `anc` is an ancestors of `desc`, `false` otherwise
46154
ecbb2fc9418c copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46153
diff changeset
247 fn is_overwrite(&mut self, anc: Revision, desc: Revision) -> bool {
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
248 if anc > desc {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
249 false
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
250 } else if anc == desc {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
251 true
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
252 } else {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
253 if let Some(b) = self.pairs.get(&(anc, desc)) {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
254 *b
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
255 } else {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
256 let b = (self.inner)(anc, desc);
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
257 self.pairs.insert((anc, desc), b);
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
258 b
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
259 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
260 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
261 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
262 }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
263
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
264 struct ActionsIterator<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
265 changes: &'a ChangedFiles<'a>,
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
266 parent: Parent,
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
267 current: u32,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
268 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
269
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
270 impl<'a> Iterator for ActionsIterator<'a> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
271 type Item = Action<'a>;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
272
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
273 fn next(&mut self) -> Option<Action<'a>> {
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
274 let copy_flag = match self.parent {
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
275 Parent::FirstParent => P1_COPY,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
276 Parent::SecondParent => P2_COPY,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
277 };
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
278 while self.current < self.changes.nb_items {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
279 let (flags, file, source) = self.changes.entry(self.current);
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
280 self.current += 1;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
281 if (flags & ACTION_MASK) == REMOVED {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
282 return Some(Action::Removed(file));
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
283 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
284 let copy = flags & COPY_MASK;
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
285 if copy == copy_flag {
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
286 return Some(Action::Copied(file, source));
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
287 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
288 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
289 return None;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
290 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
291 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
292
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
293 /// A small struct whose purpose is to ensure lifetime of bytes referenced in
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
294 /// ChangedFiles
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
295 ///
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
296 /// It is passed to the RevInfoMaker callback who can assign any necessary
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
297 /// content to the `data` attribute. The copy tracing code is responsible for
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
298 /// keeping the DataHolder alive at least as long as the ChangedFiles object.
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
299 pub struct DataHolder<D> {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
300 /// RevInfoMaker callback should assign data referenced by the
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
301 /// ChangedFiles struct it return to this attribute. The DataHolder
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
302 /// lifetime will be at least as long as the ChangedFiles one.
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
303 pub data: Option<D>,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
304 }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
305
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
306 pub type RevInfoMaker<'a, D> =
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
307 Box<dyn for<'r> Fn(Revision, &'r mut DataHolder<D>) -> RevInfo<'r> + 'a>;
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
308
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
309 /// enum used to carry information about the parent → child currently processed
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
310 #[derive(Copy, Clone, Debug)]
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
311 enum Parent {
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
312 /// The `p1(x) → x` edge
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
313 FirstParent,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
314 /// The `p2(x) → x` edge
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
315 SecondParent,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
316 }
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
317
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
318 /// A small "tokenizer" responsible of turning full HgPath into lighter
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
319 /// PathToken
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
320 ///
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
321 /// Dealing with small object, like integer is much faster, so HgPath input are
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
322 /// turned into integer "PathToken" and converted back in the end.
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
323 #[derive(Clone, Debug, Default)]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
324 struct TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
325 token: HashMap<HgPathBuf, PathToken>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
326 path: Vec<HgPathBuf>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
327 }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
328
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
329 impl TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
330 fn tokenize(&mut self, path: &HgPath) -> PathToken {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
331 match self.token.get(path) {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
332 Some(a) => *a,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
333 None => {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
334 let a = self.token.len();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
335 let buf = path.to_owned();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
336 self.path.push(buf.clone());
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
337 self.token.insert(buf, a);
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
338 a
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
339 }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
340 }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
341 }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
342
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
343 fn untokenize(&self, token: PathToken) -> &HgPathBuf {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
344 assert!(token < self.path.len(), format!("Unknown token: {}", token));
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
345 &self.path[token]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
346 }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
347 }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
348
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
349 /// Same as mercurial.copies._combine_changeset_copies, but in Rust.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
350 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
351 /// Arguments are:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
352 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
353 /// revs: all revisions to be considered
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
354 /// children: a {parent ? [childrens]} mapping
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
355 /// target_rev: the final revision we are combining copies to
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
356 /// rev_info(rev): callback to get revision information:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
357 /// * first parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
358 /// * second parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
359 /// * ChangedFiles
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
360 /// isancestors(low_rev, high_rev): callback to check if a revision is an
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
361 /// ancestor of another
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
362 pub fn combine_changeset_copies<A: Fn(Revision, Revision) -> bool, D>(
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
363 revs: Vec<Revision>,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
364 mut children_count: HashMap<Revision, usize>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
365 target_rev: Revision,
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
366 rev_info: RevInfoMaker<D>,
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
367 is_ancestor: &A,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
368 ) -> PathCopies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
369 let mut all_copies = HashMap::new();
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
370 let mut oracle = AncestorOracle::new(is_ancestor);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
371
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
372 let mut path_map = TwoWayPathMap::default();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
373
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
374 for rev in revs {
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
375 let mut d: DataHolder<D> = DataHolder { data: None };
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
376 let (p1, p2, changes) = rev_info(rev, &mut d);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
377
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
378 // We will chain the copies information accumulated for the parent with
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
379 // the individual copies information the curent revision. Creating a
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
380 // new TimeStampedPath for each `rev` → `children` vertex.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
381 let mut copies: Option<TimeStampedPathCopies> = None;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
382 if p1 != NULL_REVISION {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
383 // Retrieve data computed in a previous iteration
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
384 let parent_copies = get_and_clean_parent_copies(
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
385 &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
386 &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
387 p1,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
388 );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
389 if let Some(parent_copies) = parent_copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
390 // combine it with data for that revision
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
391 let vertex_copies = add_from_changes(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
392 &mut path_map,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
393 &parent_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
394 &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
395 Parent::FirstParent,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
396 rev,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
397 );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
398 // keep that data around for potential later combination
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
399 copies = Some(vertex_copies);
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
400 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
401 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
402 if p2 != NULL_REVISION {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
403 // Retrieve data computed in a previous iteration
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
404 let parent_copies = get_and_clean_parent_copies(
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
405 &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
406 &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
407 p2,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
408 );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
409 if let Some(parent_copies) = parent_copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
410 // combine it with data for that revision
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
411 let vertex_copies = add_from_changes(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
412 &mut path_map,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
413 &parent_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
414 &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
415 Parent::SecondParent,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
416 rev,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
417 );
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
418
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
419 copies = match copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
420 None => Some(vertex_copies),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
421 // Merge has two parents needs to combines their copy
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
422 // information.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
423 //
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
424 // If we got data from both parents, We need to combine
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
425 // them.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
426 Some(copies) => Some(merge_copies_dict(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
427 &path_map,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
428 vertex_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
429 copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
430 &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
431 &mut oracle,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
432 )),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
433 };
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
434 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
435 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
436 match copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
437 Some(copies) => {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
438 all_copies.insert(rev, copies);
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
439 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
440 _ => {}
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
441 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
442 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
443
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
444 // Drop internal information (like the timestamp) and return the final
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
445 // mapping.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
446 let tt_result = all_copies
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
447 .remove(&target_rev)
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
448 .expect("target revision was not processed");
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
449 let mut result = PathCopies::default();
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
450 for (dest, tt_source) in tt_result {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
451 if let Some(path) = tt_source.path {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
452 let path_dest = path_map.untokenize(dest).to_owned();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
453 let path_path = path_map.untokenize(path).to_owned();
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
454 result.insert(path_dest, path_path);
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
455 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
456 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
457 result
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
458 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
459
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
460 /// fetch previous computed information
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
461 ///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
462 /// If no other children are expected to need this information, we drop it from
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
463 /// the cache.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
464 ///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
465 /// If parent is not part of the set we are expected to walk, return None.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
466 fn get_and_clean_parent_copies(
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
467 all_copies: &mut HashMap<Revision, TimeStampedPathCopies>,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
468 children_count: &mut HashMap<Revision, usize>,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
469 parent_rev: Revision,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
470 ) -> Option<TimeStampedPathCopies> {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
471 let count = children_count.get_mut(&parent_rev)?;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
472 *count -= 1;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
473 if *count == 0 {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
474 match all_copies.remove(&parent_rev) {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
475 Some(c) => Some(c),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
476 None => Some(TimeStampedPathCopies::default()),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
477 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
478 } else {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
479 match all_copies.get(&parent_rev) {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
480 Some(c) => Some(c.clone()),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
481 None => Some(TimeStampedPathCopies::default()),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
482 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
483 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
484 }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
485
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
486 /// Combine ChangedFiles with some existing PathCopies information and return
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
487 /// the result
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
488 fn add_from_changes(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
489 path_map: &mut TwoWayPathMap,
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
490 base_copies: &TimeStampedPathCopies,
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
491 changes: &ChangedFiles,
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
492 parent: Parent,
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
493 current_rev: Revision,
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
494 ) -> TimeStampedPathCopies {
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
495 let mut copies = base_copies.clone();
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
496 for action in changes.iter_actions(parent) {
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
497 match action {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
498 Action::Copied(path_dest, path_source) => {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
499 let dest = path_map.tokenize(path_dest);
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
500 let source = path_map.tokenize(path_source);
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
501 let entry;
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
502 if let Some(v) = base_copies.get(&source) {
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
503 entry = match &v.path {
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
504 Some(path) => Some((*(path)).to_owned()),
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
505 None => Some(source.to_owned()),
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
506 }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
507 } else {
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
508 entry = Some(source.to_owned());
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
509 }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
510 // Each new entry is introduced by the children, we
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
511 // record this information as we will need it to take
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
512 // the right decision when merging conflicting copy
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
513 // information. See merge_copies_dict for details.
46153
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
514 match copies.entry(dest) {
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
515 Entry::Vacant(slot) => {
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
516 let ttpc = TimeStampedPathCopy {
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
517 rev: current_rev,
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
518 path: entry,
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
519 };
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
520 slot.insert(ttpc);
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
521 }
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
522 Entry::Occupied(mut slot) => {
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
523 let mut ttpc = slot.get_mut();
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
524 ttpc.rev = current_rev;
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
525 ttpc.path = entry;
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
526 }
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
527 }
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
528 }
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
529 Action::Removed(deleted_path) => {
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
530 // We must drop copy information for removed file.
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
531 //
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
532 // We need to explicitly record them as dropped to
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
533 // propagate this information when merging two
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
534 // TimeStampedPathCopies object.
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
535 let deleted = path_map.tokenize(deleted_path);
46152
e166e8a035a7 copies-rust: use the entry API to overwrite deleted entry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46151
diff changeset
536 copies.entry(deleted).and_modify(|old| {
e166e8a035a7 copies-rust: use the entry API to overwrite deleted entry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46151
diff changeset
537 old.rev = current_rev;
e166e8a035a7 copies-rust: use the entry API to overwrite deleted entry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46151
diff changeset
538 old.path = None;
e166e8a035a7 copies-rust: use the entry API to overwrite deleted entry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46151
diff changeset
539 });
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
540 }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
541 }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
542 }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
543 copies
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
544 }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
545
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
546 /// merge two copies-mapping together, minor and major
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
547 ///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
548 /// In case of conflict, value from "major" will be picked, unless in some
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
549 /// cases. See inline documentation for details.
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
550 fn merge_copies_dict<A: Fn(Revision, Revision) -> bool>(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
551 path_map: &TwoWayPathMap,
46128
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
552 mut minor: TimeStampedPathCopies,
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
553 mut major: TimeStampedPathCopies,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
554 changes: &ChangedFiles,
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
555 oracle: &mut AncestorOracle<A>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
556 ) -> TimeStampedPathCopies {
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
557 // This closure exist as temporary help while multiple developper are
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
558 // actively working on this code. Feel free to re-inline it once this
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
559 // code is more settled.
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
560 let mut cmp_value =
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
561 |dest: &PathToken,
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
562 src_minor: &TimeStampedPathCopy,
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
563 src_major: &TimeStampedPathCopy| {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
564 compare_value(
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
565 path_map, changes, oracle, dest, src_minor, src_major,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
566 )
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
567 };
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
568 if minor.is_empty() {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
569 major
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
570 } else if major.is_empty() {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
571 minor
46128
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
572 } else if minor.len() * 2 < major.len() {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
573 // Lets says we are merging two TimeStampedPathCopies instance A and B.
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
574 //
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
575 // If A contains N items, the merge result will never contains more
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
576 // than N values differents than the one in A
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
577 //
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
578 // If B contains M items, with M > N, the merge result will always
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
579 // result in a minimum of M - N value differents than the on in
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
580 // A
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
581 //
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
582 // As a result, if N < (M-N), we know that simply iterating over A will
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
583 // yield less difference than iterating over the difference
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
584 // between A and B.
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
585 //
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
586 // This help performance a lot in case were a tiny
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
587 // TimeStampedPathCopies is merged with a much larger one.
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
588 for (dest, src_minor) in minor {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
589 let src_major = major.get(&dest);
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
590 match src_major {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
591 None => major.insert(dest, src_minor),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
592 Some(src_major) => {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
593 match cmp_value(&dest, &src_minor, src_major) {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
594 MergePick::Any | MergePick::Major => None,
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
595 MergePick::Minor => major.insert(dest, src_minor),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
596 }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
597 }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
598 };
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
599 }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
600 major
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
601 } else if major.len() * 2 < minor.len() {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
602 // This use the same rational than the previous block.
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
603 // (Check previous block documentation for details.)
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
604 for (dest, src_major) in major {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
605 let src_minor = minor.get(&dest);
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
606 match src_minor {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
607 None => minor.insert(dest, src_major),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
608 Some(src_minor) => {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
609 match cmp_value(&dest, src_minor, &src_major) {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
610 MergePick::Any | MergePick::Minor => None,
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
611 MergePick::Major => minor.insert(dest, src_major),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
612 }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
613 }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
614 };
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
615 }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
616 minor
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
617 } else {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
618 let mut override_minor = Vec::new();
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
619 let mut override_major = Vec::new();
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
620
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
621 let mut to_major = |k: &PathToken, v: &TimeStampedPathCopy| {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
622 override_major.push((k.clone(), v.clone()))
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
623 };
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
624 let mut to_minor = |k: &PathToken, v: &TimeStampedPathCopy| {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
625 override_minor.push((k.clone(), v.clone()))
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
626 };
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
627
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
628 // The diff function leverage detection of the identical subpart if
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
629 // minor and major has some common ancestors. This make it very
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
630 // fast is most case.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
631 //
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
632 // In case where the two map are vastly different in size, the current
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
633 // approach is still slowish because the iteration will iterate over
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
634 // all the "exclusive" content of the larger on. This situation can be
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
635 // frequent when the subgraph of revision we are processing has a lot
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
636 // of roots. Each roots adding they own fully new map to the mix (and
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
637 // likely a small map, if the path from the root to the "main path" is
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
638 // small.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
639 //
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
640 // We could do better by detecting such situation and processing them
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
641 // differently.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
642 for d in minor.diff(&major) {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
643 match d {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
644 DiffItem::Add(k, v) => to_minor(k, v),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
645 DiffItem::Remove(k, v) => to_major(k, v),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
646 DiffItem::Update { old, new } => {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
647 let (dest, src_major) = new;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
648 let (_, src_minor) = old;
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
649 match cmp_value(dest, src_minor, src_major) {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
650 MergePick::Major => to_minor(dest, src_major),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
651 MergePick::Minor => to_major(dest, src_minor),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
652 // If the two entry are identical, no need to do
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
653 // anything (but diff should not have yield them)
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
654 MergePick::Any => unreachable!(),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
655 }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
656 }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
657 };
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
658 }
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
659
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
660 let updates;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
661 let mut result;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
662 if override_major.is_empty() {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
663 result = major
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
664 } else if override_minor.is_empty() {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
665 result = minor
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
666 } else {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
667 if override_minor.len() < override_major.len() {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
668 updates = override_minor;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
669 result = minor;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
670 } else {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
671 updates = override_major;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
672 result = major;
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
673 }
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
674 for (k, v) in updates {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
675 result.insert(k, v);
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
676 }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
677 }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
678 result
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
679 }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
680 }
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
681
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
682 /// represent the side that should prevail when merging two
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
683 /// TimeStampedPathCopies
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
684 enum MergePick {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
685 /// The "major" (p1) side prevails
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
686 Major,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
687 /// The "minor" (p2) side prevails
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
688 Minor,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
689 /// Any side could be used (because they are the same)
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
690 Any,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
691 }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
692
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
693 /// decide which side prevails in case of conflicting values
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
694 #[allow(clippy::if_same_then_else)]
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
695 fn compare_value<A: Fn(Revision, Revision) -> bool>(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
696 path_map: &TwoWayPathMap,
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
697 changes: &ChangedFiles,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
698 oracle: &mut AncestorOracle<A>,
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
699 dest: &PathToken,
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
700 src_minor: &TimeStampedPathCopy,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
701 src_major: &TimeStampedPathCopy,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
702 ) -> MergePick {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
703 if src_major.path == src_minor.path {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
704 // we have the same value, but from other source;
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
705 if src_major.rev == src_minor.rev {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
706 // If the two entry are identical, they are both valid
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
707 MergePick::Any
46154
ecbb2fc9418c copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46153
diff changeset
708 } else if oracle.is_overwrite(src_major.rev, src_minor.rev) {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
709 MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
710 } else {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
711 MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
712 }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
713 } else if src_major.rev == src_minor.rev {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
714 // We cannot get copy information for both p1 and p2 in the
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
715 // same rev. So this is the same value.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
716 unreachable!(
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
717 "conflict information from p1 and p2 in the same revision"
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
718 );
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
719 } else {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
720 let dest_path = path_map.untokenize(*dest);
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
721 let action = changes.get_merge_case(dest_path);
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
722 if src_major.path.is_none() && action == MergeCase::Salvaged {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
723 // If the file is "deleted" in the major side but was
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
724 // salvaged by the merge, we keep the minor side alive
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
725 MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
726 } else if src_minor.path.is_none() && action == MergeCase::Salvaged {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
727 // If the file is "deleted" in the minor side but was
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
728 // salvaged by the merge, unconditionnaly preserve the
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
729 // major side.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
730 MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
731 } else if action == MergeCase::Merged {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
732 // If the file was actively merged, copy information
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
733 // from each side might conflict. The major side will
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
734 // win such conflict.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
735 MergePick::Major
46154
ecbb2fc9418c copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46153
diff changeset
736 } else if oracle.is_overwrite(src_major.rev, src_minor.rev) {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
737 // If the minor side is strictly newer than the major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
738 // side, it should be kept.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
739 MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
740 } else if src_major.path.is_some() {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
741 // without any special case, the "major" value win
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
742 // other the "minor" one.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
743 MergePick::Major
46154
ecbb2fc9418c copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46153
diff changeset
744 } else if oracle.is_overwrite(src_minor.rev, src_major.rev) {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
745 // the "major" rev is a direct ancestors of "minor",
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
746 // any different value should
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
747 // overwrite
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
748 MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
749 } else {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
750 // major version is None (so the file was deleted on
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
751 // that branch) and that branch is independant (neither
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
752 // minor nor major is an ancestors of the other one.)
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
753 // We preserve the new
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
754 // information about the new file.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
755 MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
756 }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
757 }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
758 }