rust/hg-core/src/copy_tracing.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Mon, 21 Dec 2020 08:42:30 +0100
changeset 46565 2bd069788367
parent 46564 313610be4147
child 46566 3c5a8b13206a
permissions -rw-r--r--
copies-rust: rename TimeStampedPathCopy to CopySource Same rational as the previous changesets. CopySource is a clear descriptive name that does not depends on an implementation details that we are about to the change. Differential Revision: https://phab.mercurial-scm.org/D9642
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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)]
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
    19
struct CopySource {
45944
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)
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
    28
type InternalPathCopies = OrdMap<PathToken, CopySource>;
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
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   246
    fn record_overwrite(&mut self, anc: Revision, desc: Revision) {
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   247
        self.pairs.insert((anc, desc), true);
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   248
    }
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   249
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   250
    /// 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
   251
    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
   252
        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
   253
            false
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   254
        } 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
   255
            true
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   256
        } else {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   257
            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
   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
            } else {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   260
                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
   261
                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
   262
                b
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   263
            }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   264
        }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   265
    }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   266
}
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   267
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   268
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
   269
    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
   270
    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
   271
    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
   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
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   274
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
   275
    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
   276
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   277
    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
   278
        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
   279
            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
   280
            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
   281
        };
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   282
        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
   283
            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
   284
            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
   285
            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
   286
                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
   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
            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
   289
            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
   290
                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
   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
        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
   294
    }
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
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   297
/// 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
   298
/// ChangedFiles
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   299
///
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   300
/// 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
   301
/// 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
   302
/// 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
   303
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
   304
    /// 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
   305
    /// 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
   306
    /// 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
   307
    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
   308
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   309
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   310
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
   311
    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
   312
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   313
/// 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
   314
#[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
   315
enum Parent {
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   316
    /// 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
   317
    FirstParent,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   318
    /// 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
   319
    SecondParent,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   320
}
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   321
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   322
/// 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
   323
/// PathToken
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   324
///
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   325
/// 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
   326
/// 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
   327
#[derive(Clone, Debug, Default)]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   328
struct TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   329
    token: HashMap<HgPathBuf, PathToken>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   330
    path: Vec<HgPathBuf>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   331
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   332
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   333
impl TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   334
    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
   335
        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
   336
            Some(a) => *a,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   337
            None => {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   338
                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
   339
                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
   340
                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
   341
                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
   342
                a
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   343
            }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   344
        }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   345
    }
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
    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
   348
        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
   349
        &self.path[token]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   350
    }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   351
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   352
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   353
/// 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
   354
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   355
/// Arguments are:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   356
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   357
/// 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
   358
/// 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
   359
/// 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
   360
/// 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
   361
///   * first parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   362
///   * second parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   363
///   * ChangedFiles
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   364
/// 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
   365
///                                 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
   366
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
   367
    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
   368
    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
   369
    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
   370
    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
   371
    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
   372
) -> PathCopies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   373
    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
   374
    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
   375
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   376
    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
   377
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   378
    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
   379
        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
   380
        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
   381
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   382
        // 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
   383
        // 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
   384
        // new TimeStampedPath for each `rev` → `children` vertex.
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   385
        let mut copies: Option<InternalPathCopies> = None;
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   386
        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
   387
            // 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
   388
            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
   389
                &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   390
                &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   391
                p1,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   392
            );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   393
            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
   394
                // 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
   395
                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
   396
                    &mut path_map,
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   397
                    &mut oracle,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   398
                    &parent_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   399
                    &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   400
                    Parent::FirstParent,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   401
                    rev,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   402
                );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   403
                // 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
   404
                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
   405
            }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   406
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   407
        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
   408
            // 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
   409
            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
   410
                &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   411
                &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   412
                p2,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   413
            );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   414
            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
   415
                // 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
   416
                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
   417
                    &mut path_map,
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   418
                    &mut oracle,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   419
                    &parent_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   420
                    &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   421
                    Parent::SecondParent,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   422
                    rev,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   423
                );
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   424
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   425
                copies = match copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   426
                    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
   427
                    // 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
   428
                    // information.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   429
                    //
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   430
                    // 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
   431
                    // them.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   432
                    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
   433
                        &path_map,
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   434
                        rev,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   435
                        vertex_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   436
                        copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   437
                        &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   438
                        &mut oracle,
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
                };
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   441
            }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   442
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   443
        match copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   444
            Some(copies) => {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   445
                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
   446
            }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   447
            _ => {}
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   448
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   449
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   450
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   451
    // 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
   452
    // mapping.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   453
    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
   454
        .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
   455
        .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
   456
    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
   457
    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
   458
        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
   459
            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
   460
            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
   461
            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
   462
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   463
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   464
    result
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   465
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   466
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   467
/// 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
   468
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   469
/// 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
   470
/// the cache.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   471
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   472
/// 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
   473
fn get_and_clean_parent_copies(
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   474
    all_copies: &mut HashMap<Revision, InternalPathCopies>,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   475
    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
   476
    parent_rev: Revision,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   477
) -> Option<InternalPathCopies> {
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   478
    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
   479
    *count -= 1;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   480
    if *count == 0 {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   481
        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
   482
            Some(c) => Some(c),
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   483
            None => Some(InternalPathCopies::default()),
46149
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
    } else {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   486
        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
   487
            Some(c) => Some(c.clone()),
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   488
            None => Some(InternalPathCopies::default()),
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   489
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   490
    }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   491
}
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   492
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
   493
/// 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
   494
/// the result
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   495
fn add_from_changes<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
   496
    path_map: &mut TwoWayPathMap,
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   497
    oracle: &mut AncestorOracle<A>,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   498
    base_copies: &InternalPathCopies,
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
   499
    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
   500
    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
   501
    current_rev: Revision,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   502
) -> InternalPathCopies {
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
    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
   504
    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
   505
        match action {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   506
            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
   507
                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
   508
                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
   509
                let entry;
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   510
                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
   511
                    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
   512
                        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
   513
                        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
   514
                    }
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
   515
                } 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
   516
                    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
   517
                }
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
   518
                // 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
   519
                // 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
   520
                // 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
   521
                // 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
   522
                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
   523
                    Entry::Vacant(slot) => {
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   524
                        let ttpc = CopySource {
46153
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
   525
                            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
   526
                            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
   527
                        };
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
   528
                        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
   529
                    }
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
   530
                    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
   531
                        let mut ttpc = slot.get_mut();
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   532
                        oracle.record_overwrite(ttpc.rev, current_rev);
46153
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
   533
                        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
   534
                        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
   535
                    }
0a721fc457bf copies-rust: use the `entry` API for copy information too
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46152
diff changeset
   536
                }
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
   537
            }
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   538
            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
   539
                // 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
   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
                // 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
   542
                // propagate this information when merging two
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   543
                // InternalPathCopies object.
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   544
                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
   545
                copies.entry(deleted).and_modify(|old| {
46155
fce2f20a54ce copies-rust: start recording overwrite as they happens
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46154
diff changeset
   546
                    oracle.record_overwrite(old.rev, current_rev);
46152
e166e8a035a7 copies-rust: use the entry API to overwrite deleted entry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46151
diff changeset
   547
                    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
   548
                    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
   549
                });
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
   550
            }
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
   551
        }
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
   552
    }
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
   553
    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
   554
}
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
   555
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   556
/// 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
   557
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   558
/// 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
   559
/// 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
   560
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
   561
    path_map: &TwoWayPathMap,
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   562
    current_merge: Revision,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   563
    mut minor: InternalPathCopies,
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   564
    mut major: InternalPathCopies,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   565
    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
   566
    oracle: &mut AncestorOracle<A>,
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   567
) -> InternalPathCopies {
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
   568
    // 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
   569
    // 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
   570
    // code is more settled.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   571
    let cmp_value = |oracle: &mut AncestorOracle<A>,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   572
                     dest: &PathToken,
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   573
                     src_minor: &CopySource,
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   574
                     src_major: &CopySource| {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   575
        compare_value(
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   576
            path_map,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   577
            current_merge,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   578
            changes,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   579
            oracle,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   580
            dest,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   581
            src_minor,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   582
            src_major,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   583
        )
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   584
    };
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   585
    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
   586
        major
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   587
    } 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
   588
        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
   589
    } else if minor.len() * 2 < major.len() {
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   590
        // Lets says we are merging two InternalPathCopies instance A and B.
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
   591
        //
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
        // 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
   593
        // 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
   594
        //
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
        // 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
   596
        // 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
   597
        // 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
   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
        // 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
   600
        // 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
   601
        // 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
   602
        //
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
        // This help performance a lot in case were a tiny
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   604
        // InternalPathCopies is merged with a much larger one.
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
   605
        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
   606
            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
   607
            match src_major {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   608
                None => {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   609
                    major.insert(dest, src_minor);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   610
                }
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
   611
                Some(src_major) => {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   612
                    let (pick, overwrite) =
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   613
                        cmp_value(oracle, &dest, &src_minor, src_major);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   614
                    if overwrite {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   615
                        oracle.record_overwrite(src_minor.rev, current_merge);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   616
                        oracle.record_overwrite(src_major.rev, current_merge);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   617
                        let path = match pick {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   618
                            MergePick::Major => src_major.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   619
                            MergePick::Minor => src_minor.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   620
                            MergePick::Any => src_major.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   621
                        };
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   622
                        let src = CopySource {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   623
                            rev: current_merge,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   624
                            path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   625
                        };
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   626
                        major.insert(dest, src);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   627
                    } else {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   628
                        match pick {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   629
                            MergePick::Any | MergePick::Major => None,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   630
                            MergePick::Minor => major.insert(dest, src_minor),
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   631
                        };
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
   632
                    }
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
   633
                }
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
   634
            };
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
   635
        }
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
   636
        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
   637
    } 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
   638
        // 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
   639
        // (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
   640
        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
   641
            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
   642
            match src_minor {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   643
                None => {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   644
                    minor.insert(dest, src_major);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   645
                }
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
   646
                Some(src_minor) => {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   647
                    let (pick, overwrite) =
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   648
                        cmp_value(oracle, &dest, &src_major, src_minor);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   649
                    if overwrite {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   650
                        oracle.record_overwrite(src_minor.rev, current_merge);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   651
                        oracle.record_overwrite(src_major.rev, current_merge);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   652
                        let path = match pick {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   653
                            MergePick::Major => src_minor.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   654
                            MergePick::Minor => src_major.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   655
                            MergePick::Any => src_major.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   656
                        };
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   657
                        let src = CopySource {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   658
                            rev: current_merge,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   659
                            path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   660
                        };
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   661
                        minor.insert(dest, src);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   662
                    } else {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   663
                        match pick {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   664
                            MergePick::Any | MergePick::Major => None,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   665
                            MergePick::Minor => minor.insert(dest, src_major),
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   666
                        };
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
   667
                    }
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
   668
                }
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
   669
            };
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
   670
        }
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
   671
        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
   672
    } else {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   673
        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
   674
        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
   675
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   676
        let mut to_major = |k: &PathToken, v: &CopySource| {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   677
            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
   678
        };
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   679
        let mut to_minor = |k: &PathToken, v: &CopySource| {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   680
            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
   681
        };
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   682
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   683
        // 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
   684
        // 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
   685
        // 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
   686
        //
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   687
        // 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
   688
        // 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
   689
        // 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
   690
        // 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
   691
        // 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
   692
        // 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
   693
        // small.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   694
        //
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   695
        // 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
   696
        // differently.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   697
        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
   698
            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
   699
                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
   700
                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
   701
                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
   702
                    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
   703
                    let (_, src_minor) = old;
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   704
                    let (pick, overwrite) =
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   705
                        cmp_value(oracle, dest, src_minor, src_major);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   706
                    if overwrite {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   707
                        oracle.record_overwrite(src_minor.rev, current_merge);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   708
                        oracle.record_overwrite(src_major.rev, current_merge);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   709
                        let path = match pick {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   710
                            MergePick::Major => src_major.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   711
                            MergePick::Minor => src_minor.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   712
                            // If the two entry are identical, no need to do
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   713
                            // anything (but diff should not have yield them)
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   714
                            MergePick::Any => src_major.path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   715
                        };
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   716
                        let src = CopySource {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   717
                            rev: current_merge,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   718
                            path,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   719
                        };
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   720
                        to_minor(dest, &src);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   721
                        to_major(dest, &src);
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   722
                    } else {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   723
                        match pick {
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   724
                            MergePick::Major => to_minor(dest, src_major),
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   725
                            MergePick::Minor => to_major(dest, src_minor),
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   726
                            // If the two entry are identical, no need to do
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   727
                            // anything (but diff should not have yield them)
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   728
                            MergePick::Any => unreachable!(),
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   729
                        }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   730
                    }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   731
                }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   732
            };
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   733
        }
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   734
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   735
        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
   736
        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
   737
        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
   738
            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
   739
        } 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
   740
            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
   741
        } 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
   742
            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
   743
                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
   744
                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
   745
            } else {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   746
                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
   747
                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
   748
            }
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   749
            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
   750
                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
   751
            }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   752
        }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   753
        result
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   754
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   755
}
46125
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
/// represent the side that should prevail when merging two
46564
313610be4147 copies-rust: rename TimeStampedPathCopies to InternalPathCopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46563
diff changeset
   758
/// InternalPathCopies
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   759
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
   760
    /// 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
   761
    Major,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   762
    /// 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
   763
    Minor,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   764
    /// 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
   765
    Any,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   766
}
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   767
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   768
/// 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
   769
#[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
   770
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
   771
    path_map: &TwoWayPathMap,
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   772
    current_merge: Revision,
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   773
    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
   774
    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
   775
    dest: &PathToken,
46565
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   776
    src_minor: &CopySource,
2bd069788367 copies-rust: rename TimeStampedPathCopy to CopySource
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46564
diff changeset
   777
    src_major: &CopySource,
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   778
) -> (MergePick, bool) {
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   779
    if src_major.rev == current_merge {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   780
        if src_minor.rev == current_merge {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   781
            if src_major.path.is_none() {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   782
                // We cannot get different copy information for both p1 and p2
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   783
                // from the same revision. Unless this was a
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   784
                // deletion
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   785
                (MergePick::Any, false)
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   786
            } else {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   787
                unreachable!();
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   788
            }
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   789
        } else {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   790
            // The last value comes the current merge, this value -will- win
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   791
            // eventually.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   792
            (MergePick::Major, true)
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   793
        }
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   794
    } else if src_minor.rev == current_merge {
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   795
        // The last value comes the current merge, this value -will- win
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   796
        // eventually.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   797
        (MergePick::Minor, true)
46156
7d99614b7b77 copies-rust: make the comparison aware of the revision being current merged
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46155
diff changeset
   798
    } else if src_major.path == src_minor.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
   799
        // 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
   800
        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
   801
            // If the two entry are identical, they are both valid
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   802
            (MergePick::Any, false)
46154
ecbb2fc9418c copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46153
diff changeset
   803
        } else if oracle.is_overwrite(src_major.rev, src_minor.rev) {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   804
            (MergePick::Minor, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   805
        } else if oracle.is_overwrite(src_minor.rev, src_major.rev) {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   806
            (MergePick::Major, false)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   807
        } else {
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   808
            (MergePick::Any, true)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   809
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   810
    } 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
   811
        // 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
   812
        // 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
   813
        unreachable!(
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   814
            "conflicting information from p1 and p2 in the same revision"
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   815
        );
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   816
    } else {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   817
        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
   818
        let action = changes.get_merge_case(dest_path);
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   819
        if src_minor.path.is_some()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   820
            && src_major.path.is_none()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   821
            && action == MergeCase::Salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   822
        {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   823
            // 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
   824
            // salvaged by the merge, we keep the minor side alive
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   825
            (MergePick::Minor, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   826
        } else if src_major.path.is_some()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   827
            && src_minor.path.is_none()
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   828
            && action == MergeCase::Salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   829
        {
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   830
            // 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
   831
            // 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
   832
            // major side.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   833
            (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   834
        } else if oracle.is_overwrite(src_minor.rev, src_major.rev) {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   835
            // The information from the minor version are strictly older than
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   836
            // the major version
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   837
            if action == MergeCase::Merged {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   838
                // If the file was actively merged, its means some non-copy
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   839
                // activity happened on the other branch. It
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   840
                // mean the older copy information are still relevant.
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   841
                //
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   842
                // The major side wins such conflict.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   843
                (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   844
            } else {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   845
                // No activity on the minor branch, pick the newer one.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   846
                (MergePick::Major, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   847
            }
46154
ecbb2fc9418c copies-rust: rename Oracle.is_ancestor to Oracle.is_overwrite
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46153
diff changeset
   848
        } else if oracle.is_overwrite(src_major.rev, src_minor.rev) {
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   849
            if action == MergeCase::Merged {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   850
                // If the file was actively merged, its means some non-copy
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   851
                // activity happened on the other branch. It
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   852
                // mean the older copy information are still relevant.
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   853
                //
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   854
                // The major side wins such conflict.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   855
                (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   856
            } else {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   857
                // No activity on the minor branch, pick the newer one.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   858
                (MergePick::Minor, false)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   859
            }
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   860
        } else if src_minor.path.is_none() {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   861
            // the minor side has no relevant information, pick the alive one
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   862
            (MergePick::Major, true)
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   863
        } else if src_major.path.is_none() {
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   864
            // the major side has no relevant information, pick the alive one
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   865
            (MergePick::Minor, true)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   866
        } else {
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46157
diff changeset
   867
            // by default the major side wins
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
   868
            (MergePick::Major, true)
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   869
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   870
    }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   871
}