rust/hg-core/src/copy_tracing.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Wed, 02 Dec 2020 10:51:40 +0100
changeset 46152 e166e8a035a7
parent 46151 c6bc77f7e593
child 46153 0a721fc457bf
permissions -rw-r--r--
copies-rust: use the entry API to overwrite deleted entry This is more efficient, more idiomatic and more compact. The main motivation for this change is to cleanup that area before start to do "overwrite" tracking. Such tracking will ultimately help to avoid costly is_ancestors call when merging changeset. Differential Revision: https://phab.mercurial-scm.org/D9494
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;
45963
0d99778af68a copies-rust: use immutable "OrdMap" to store copies information
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45944
diff changeset
     7
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
     8
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
     9
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
    10
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
    11
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
    12
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
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
    14
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
    15
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
    16
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
    17
#[derive(Clone, Debug, PartialEq, Copy)]
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    18
struct TimeStampedPathCopy {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    19
    /// 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
    20
    rev: Revision,
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    21
    /// 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
    22
    /// 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
    23
    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
    24
}
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
/// maps CopyDestination to Copy Source (+ a "timestamp" for the operation)
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
    27
type TimeStampedPathCopies = OrdMap<PathToken, TimeStampedPathCopy>;
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    28
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    29
/// 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
    30
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
    31
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    32
/// 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
    33
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    34
/// 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
    35
/// 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
    36
/// 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
    37
/// 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
    38
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
    39
    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
    40
    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
    41
    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
    42
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    43
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
    44
/// 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
    45
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
    46
    /// 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
    47
    ///
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
    /// (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
    49
    /// 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
    50
    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
    51
    /// 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
    52
    /// 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
    53
    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
    54
}
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
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    56
/// 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
    57
///
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    58
/// 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
    59
#[derive(PartialEq)]
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    60
enum MergeCase {
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    61
    /// 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
    62
    Merged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    63
    /// 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
    64
    Salvaged,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    65
    /// 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
    66
    Normal,
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    67
}
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
    68
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    69
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
    70
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    71
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
    72
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
    73
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
    74
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
    75
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
    76
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
    77
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
    78
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
    79
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    80
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
    81
    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
    82
    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
    83
    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
    84
    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
    85
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    86
    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
    87
        assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    88
            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
    89
            "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
    90
            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
    91
        );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    92
        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
    93
            .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
    94
            .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
    95
        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
    96
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
    97
        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
    98
        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
    99
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   100
        assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   101
            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
   102
            "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
   103
            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
   104
            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
   105
        );
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
        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
   108
            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
   109
            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
   110
            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
   111
        };
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   112
        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
   113
        assert!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   114
            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
   115
            "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
   116
            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
   117
            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
   118
        );
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   119
        ret
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   120
    }
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
    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
   123
        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
   124
            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
   125
            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
   126
            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
   127
        }
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
    /// 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
   131
    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
   132
        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
   133
            panic!(
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   134
                "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
   135
                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
   136
            )
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
        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
   139
        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
   140
        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
   141
        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
   142
        (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
   143
    }
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
    /// 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
   146
    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
   147
        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
   148
        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
   149
            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
   150
        } else {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   151
            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
   152
        }
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   153
        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
   154
        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
   155
        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
   156
        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
   157
    }
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
    /// 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
   160
    /// index
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   161
    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
   162
        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
   163
        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
   164
    }
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
    /// 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
   167
    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
   168
        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
   169
        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
   170
        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
   171
        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
   172
        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
   173
            .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
   174
            .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
   175
        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
   176
    }
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
    /// 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
   179
    /// 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
   180
    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
   181
        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
   182
        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
   183
        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
   184
        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
   185
        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
   186
            .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
   187
            .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
   188
        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
   189
    }
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
   190
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
    /// 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
   192
    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
   193
        ActionsIterator {
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   194
            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
   195
            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
   196
            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
   197
        }
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
   198
    }
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   199
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   200
    /// 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
   201
    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
   202
        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
   203
            return MergeCase::Normal;
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   204
        }
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   205
        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
   206
        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
   207
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   208
        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
   209
            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
   210
            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
   211
            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
   212
                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
   213
                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
   214
                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
   215
                    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
   216
                        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
   217
                        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
   218
                        _ => 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
   219
                    };
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
        MergeCase::Normal
45975
2367937982ba copies-rust: encapsulate internal sets on `changes`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45974
diff changeset
   224
    }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   225
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   226
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   227
/// 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
   228
///
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   229
/// 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
   230
/// result.
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   231
#[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
   232
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
   233
    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
   234
    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
   235
}
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
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
   238
    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
   239
        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
            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
   241
            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
   242
        }
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
    /// returns `true` if `anc` is an ancestors of `desc`, `false` otherwise
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   246
    fn is_ancestor(&mut self, anc: Revision, desc: 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
   247
        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
   248
            false
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   249
        } 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
   250
            true
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   251
        } else {
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 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
   253
                *b
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 {
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   255
                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
   256
                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
   257
                b
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   258
            }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   259
        }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   260
    }
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   261
}
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45971
diff changeset
   262
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   263
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
   264
    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
   265
    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
   266
    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
   267
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   268
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   269
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
   270
    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
   271
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   272
    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
   273
        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
   274
            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
   275
            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
   276
        };
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   277
        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
   278
            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
   279
            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
   280
            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
   281
                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
   282
            }
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 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
   284
            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
   285
                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
   286
            }
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
        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
   289
    }
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   290
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   291
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   292
/// 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
   293
/// ChangedFiles
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
/// 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
   296
/// 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
   297
/// 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
   298
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
   299
    /// 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
   300
    /// 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
   301
    /// 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
   302
    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
   303
}
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   304
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45975
diff changeset
   305
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
   306
    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
   307
46058
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   308
/// 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
   309
#[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
   310
enum Parent {
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   311
    /// 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
   312
    FirstParent,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   313
    /// 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
   314
    SecondParent,
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   315
}
12192fdbf3ac copies-rust: move the parent token to an enum
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46057
diff changeset
   316
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   317
/// 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
   318
/// PathToken
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   319
///
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   320
/// 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
   321
/// 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
   322
#[derive(Clone, Debug, Default)]
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   323
struct TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   324
    token: HashMap<HgPathBuf, PathToken>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   325
    path: Vec<HgPathBuf>,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   326
}
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   327
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   328
impl TwoWayPathMap {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   329
    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
   330
        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
   331
            Some(a) => *a,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   332
            None => {
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   333
                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
   334
                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
   335
                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
   336
                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
   337
                a
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   338
            }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   339
        }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   340
    }
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   341
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   342
    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
   343
        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
   344
        &self.path[token]
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
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   348
/// 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
   349
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   350
/// Arguments are:
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   351
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   352
/// 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
   353
/// 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
   354
/// 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
   355
/// 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
   356
///   * first parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   357
///   * second parent
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   358
///   * ChangedFiles
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   359
/// 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
   360
///                                 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
   361
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
   362
    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
   363
    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
   364
    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
   365
    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
   366
    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
   367
) -> PathCopies {
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   368
    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
   369
    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
   370
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   371
    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
   372
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   373
    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
   374
        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
   375
        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
   376
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   377
        // 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
   378
        // 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
   379
        // new TimeStampedPath for each `rev` → `children` vertex.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   380
        let mut copies: Option<TimeStampedPathCopies> = None;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   381
        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
   382
            // 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
   383
            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
   384
                &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   385
                &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   386
                p1,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   387
            );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   388
            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
   389
                // 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
   390
                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
   391
                    &mut path_map,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   392
                    &parent_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   393
                    &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   394
                    Parent::FirstParent,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   395
                    rev,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   396
                );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   397
                // 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
   398
                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
   399
            }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   400
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   401
        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
   402
            // 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
   403
            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
   404
                &mut all_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   405
                &mut children_count,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   406
                p2,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   407
            );
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   408
            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
   409
                // 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
   410
                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
   411
                    &mut path_map,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   412
                    &parent_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   413
                    &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   414
                    Parent::SecondParent,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   415
                    rev,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   416
                );
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   417
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   418
                copies = match copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   419
                    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
   420
                    // 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
   421
                    // information.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   422
                    //
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   423
                    // 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
   424
                    // them.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   425
                    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
   426
                        &path_map,
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   427
                        vertex_copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   428
                        copies,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   429
                        &changes,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   430
                        &mut oracle,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   431
                    )),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   432
                };
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   433
            }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   434
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   435
        match copies {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   436
            Some(copies) => {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   437
                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
   438
            }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   439
            _ => {}
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   440
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   441
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   442
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   443
    // 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
   444
    // mapping.
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   445
    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
   446
        .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
   447
        .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
   448
    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
   449
    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
   450
        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
   451
            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
   452
            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
   453
            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
   454
        }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   455
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   456
    result
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   457
}
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   458
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   459
/// 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
   460
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   461
/// 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
   462
/// the cache.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   463
///
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   464
/// 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
   465
fn get_and_clean_parent_copies(
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   466
    all_copies: &mut HashMap<Revision, TimeStampedPathCopies>,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   467
    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
   468
    parent_rev: Revision,
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   469
) -> Option<TimeStampedPathCopies> {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   470
    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
   471
    *count -= 1;
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   472
    if *count == 0 {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   473
        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
   474
            Some(c) => Some(c),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   475
            None => Some(TimeStampedPathCopies::default()),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   476
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   477
    } else {
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   478
        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
   479
            Some(c) => Some(c.clone()),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   480
            None => Some(TimeStampedPathCopies::default()),
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   481
        }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   482
    }
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   483
}
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46129
diff changeset
   484
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
   485
/// 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
   486
/// the result
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   487
fn add_from_changes(
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   488
    path_map: &mut TwoWayPathMap,
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   489
    base_copies: &TimeStampedPathCopies,
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   490
    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
   491
    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
   492
    current_rev: Revision,
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   493
) -> TimeStampedPathCopies {
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   494
    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
   495
    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
   496
        match action {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   497
            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
   498
                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
   499
                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
   500
                let entry;
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   501
                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
   502
                    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
   503
                        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
   504
                        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
   505
                    }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   506
                } 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
   507
                    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
   508
                }
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
                // 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
   510
                // 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
   511
                // 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
   512
                // information. See merge_copies_dict for details.
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
                let ttpc = TimeStampedPathCopy {
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
                    rev: current_rev,
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
                    path: entry,
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
                };
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
                copies.insert(dest.to_owned(), ttpc);
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
            }
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   519
            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
   520
                // 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
   521
                //
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
   522
                // 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
   523
                // propagate this information when merging two
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   524
                // TimeStampedPathCopies object.
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   525
                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
   526
                copies.entry(deleted).and_modify(|old| {
e166e8a035a7 copies-rust: use the entry API to overwrite deleted entry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46151
diff changeset
   527
                    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
   528
                    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
   529
                });
46059
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   530
            }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   531
        }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   532
    }
dacb771f6dd2 copies-rust: extract the processing of a ChangedFiles in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46058
diff changeset
   533
    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
   534
}
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
   535
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   536
/// 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
   537
///
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   538
/// 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
   539
/// 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
   540
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
   541
    path_map: &TwoWayPathMap,
46128
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   542
    mut minor: TimeStampedPathCopies,
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   543
    mut major: TimeStampedPathCopies,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   544
    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
   545
    oracle: &mut AncestorOracle<A>,
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   546
) -> TimeStampedPathCopies {
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
   547
    // 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
   548
    // 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
   549
    // code is more settled.
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
   550
    let mut cmp_value =
46129
818502d2f5e3 copies-rust: pre-introduce a PathToken type and use it where applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46128
diff changeset
   551
        |dest: &PathToken,
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
   552
         src_minor: &TimeStampedPathCopy,
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
   553
         src_major: &TimeStampedPathCopy| {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   554
            compare_value(
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   555
                path_map, changes, oracle, dest, src_minor, src_major,
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   556
            )
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
   557
        };
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   558
    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
   559
        major
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   560
    } 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
   561
        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
   562
    } else if minor.len() * 2 < major.len() {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   563
        // Lets says we are merging two TimeStampedPathCopies instance A and B.
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   564
        //
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
   565
        // 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
   566
        // 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
   567
        //
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
   568
        // 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
   569
        // 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
   570
        // 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
   571
        //
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   572
        // 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
   573
        // 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
   574
        // 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
   575
        //
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   576
        // This help performance a lot in case were a tiny
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   577
        // TimeStampedPathCopies is merged with a much larger one.
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   578
        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
   579
            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
   580
            match src_major {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   581
                None => major.insert(dest, src_minor),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   582
                Some(src_major) => {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   583
                    match cmp_value(&dest, &src_minor, src_major) {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   584
                        MergePick::Any | MergePick::Major => None,
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   585
                        MergePick::Minor => major.insert(dest, src_minor),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   586
                    }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   587
                }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   588
            };
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
        }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   590
        major
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   591
    } 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
   592
        // 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
   593
        // (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
   594
        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
   595
            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
   596
            match src_minor {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   597
                None => minor.insert(dest, src_major),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   598
                Some(src_minor) => {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   599
                    match cmp_value(&dest, src_minor, &src_major) {
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   600
                        MergePick::Any | MergePick::Minor => None,
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   601
                        MergePick::Major => minor.insert(dest, src_major),
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   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
                }
c94d013e2299 copies-rust: add smarter approach for merging small mapping with large mapping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46127
diff changeset
   604
            };
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
        }
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
        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
   607
    } else {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   608
        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
   609
        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
   610
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
   611
        let mut to_major = |k: &PathToken, v: &TimeStampedPathCopy| {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   612
            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
   613
        };
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
   614
        let mut to_minor = |k: &PathToken, v: &TimeStampedPathCopy| {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   615
            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
   616
        };
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   617
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   618
        // 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
   619
        // 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
   620
        // 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
   621
        //
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   622
        // 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
   623
        // 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
   624
        // 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
   625
        // 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
   626
        // 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
   627
        // 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
   628
        // small.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   629
        //
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   630
        // 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
   631
        // differently.
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   632
        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
   633
            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
   634
                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
   635
                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
   636
                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
   637
                    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
   638
                    let (_, src_minor) = old;
46127
c58c8f1d63b1 copies-rust: hide most of the comparison details inside a closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46126
diff changeset
   639
                    match cmp_value(dest, src_minor, src_major) {
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   640
                        MergePick::Major => to_minor(dest, src_major),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   641
                        MergePick::Minor => to_major(dest, src_minor),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   642
                        // If the two entry are identical, no need to do
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   643
                        // anything (but diff should not have yield them)
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   644
                        MergePick::Any => unreachable!(),
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   645
                    }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   646
                }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   647
            };
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   648
        }
45971
cc759d3db1e8 copies-rust: leverage the immutability for efficient update
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45964
diff changeset
   649
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   650
        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
   651
        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
   652
        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
   653
            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
   654
        } 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
   655
            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
   656
        } 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
   657
            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
   658
                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
   659
                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
   660
            } else {
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   661
                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
   662
                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
   663
            }
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   664
            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
   665
                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
   666
            }
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   667
        }
46126
94300498491e copies-rust: move the mapping merging into a else clause
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46125
diff changeset
   668
        result
45944
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   669
    }
595979dc924e copies: introduce a basic Rust function for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
   670
}
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   671
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   672
/// represent the side that should prevail when merging two
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   673
/// TimeStampedPathCopies
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   674
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
   675
    /// 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
   676
    Major,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   677
    /// 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
   678
    Minor,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   679
    /// 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
   680
    Any,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   681
}
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   682
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   683
/// 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
   684
#[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
   685
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
   686
    path_map: &TwoWayPathMap,
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   687
    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
   688
    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
   689
    dest: &PathToken,
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   690
    src_minor: &TimeStampedPathCopy,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   691
    src_major: &TimeStampedPathCopy,
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   692
) -> MergePick {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   693
    if src_major.path == src_minor.path {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   694
        // 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
   695
        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
   696
            // If the two entry are identical, they are both valid
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   697
            MergePick::Any
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   698
        } else if oracle.is_ancestor(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
   699
            MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   700
        } else {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   701
            MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   702
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   703
    } 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
   704
        // 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
   705
        // 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
   706
        unreachable!(
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   707
            "conflict information from p1 and p2 in the same revision"
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   708
        );
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   709
    } else {
46151
c6bc77f7e593 copies-rust: tokenize all paths into integer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   710
        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
   711
        let action = changes.get_merge_case(dest_path);
46125
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   712
        if src_major.path.is_none() && action == MergeCase::Salvaged {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   713
            // 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
   714
            // salvaged by the merge, we keep the minor side alive
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   715
            MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   716
        } else if src_minor.path.is_none() && action == MergeCase::Salvaged {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   717
            // 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
   718
            // 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
   719
            // major side.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   720
            MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   721
        } else if action == MergeCase::Merged {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   722
            // If the file was actively merged, copy information
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   723
            // from each side might conflict.  The major side will
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   724
            // win such conflict.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   725
            MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   726
        } else if oracle.is_ancestor(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
   727
            // If the minor side is strictly newer than the major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   728
            // side, it should be kept.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   729
            MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   730
        } else if src_major.path.is_some() {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   731
            // without any special case, the "major" value win
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   732
            // other the "minor" one.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   733
            MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   734
        } else if oracle.is_ancestor(src_minor.rev, src_major.rev) {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   735
            // the "major" rev is a direct ancestors of "minor",
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   736
            // any different value should
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   737
            // overwrite
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   738
            MergePick::Major
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   739
        } else {
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   740
            // major version is None (so the file was deleted on
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   741
            // that branch) and that branch is independant (neither
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   742
            // minor nor major is an ancestors of the other one.)
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   743
            // We preserve the new
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   744
            // information about the new file.
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   745
            MergePick::Minor
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   746
        }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   747
    }
61afe6215aef copies-rust: extract conflicting value comparison in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46059
diff changeset
   748
}