rust/hg-core/src/discovery.rs
author Georges Racinet <georges.racinet@octobus.net>
Tue, 19 Feb 2019 23:42:31 +0100
changeset 42178 10b465d61556
child 42180 1b0be75cb61f
permissions -rw-r--r--
rust-discovery: starting core implementation Once exposed to the Python side, this core object will avoid costly roundtrips with potentially big sets of revisions. This changeset implements the core logic of the object only, i.e., manipulation of the missing, common and undefined set-like revision attributes. Differential Revision: https://phab.mercurial-scm.org/D6231
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42178
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     1
// discovery.rs
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     2
//
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     3
// Copyright 2019 Georges Racinet <georges.racinet@octobus.net>
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     4
//
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     7
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     8
//! Discovery operations
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
     9
//!
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    10
//! This is a Rust counterpart to the `partialdiscovery` class of
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    11
//! `mercurial.setdiscovery`
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    12
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    13
use super::{Graph, GraphError, Revision};
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    14
use crate::ancestors::MissingAncestors;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    15
use crate::dagops;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    16
use std::collections::HashSet;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    17
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    18
pub struct PartialDiscovery<G: Graph + Clone> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    19
    target_heads: Option<Vec<Revision>>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    20
    graph: G, // plays the role of self._repo
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    21
    common: MissingAncestors<G>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    22
    undecided: Option<HashSet<Revision>>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    23
    missing: HashSet<Revision>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    24
}
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    25
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    26
impl<G: Graph + Clone> PartialDiscovery<G> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    27
    /// Create a PartialDiscovery object, with the intent
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    28
    /// of comparing our `::<target_heads>` revset to the contents of another
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    29
    /// repo.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    30
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    31
    /// For now `target_heads` is passed as a vector, and will be used
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    32
    /// at the first call to `ensure_undecided()`.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    33
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    34
    /// If we want to make the signature more flexible,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    35
    /// we'll have to make it a type argument of `PartialDiscovery` or a trait
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    36
    /// object since we'll keep it in the meanwhile
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    37
    pub fn new(graph: G, target_heads: Vec<Revision>) -> Self {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    38
        PartialDiscovery {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    39
            undecided: None,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    40
            target_heads: Some(target_heads),
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    41
            graph: graph.clone(),
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    42
            common: MissingAncestors::new(graph, vec![]),
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    43
            missing: HashSet::new(),
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    44
        }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    45
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    46
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    47
    /// Register revisions known as being common
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    48
    pub fn add_common_revisions(
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    49
        &mut self,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    50
        common: impl IntoIterator<Item = Revision>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    51
    ) -> Result<(), GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    52
        self.common.add_bases(common);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    53
        if let Some(ref mut undecided) = self.undecided {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    54
            self.common.remove_ancestors_from(undecided)?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    55
        }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    56
        Ok(())
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    57
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    58
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    59
    /// Register revisions known as being missing
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    60
    pub fn add_missing_revisions(
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    61
        &mut self,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    62
        missing: impl IntoIterator<Item = Revision>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    63
    ) -> Result<(), GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    64
        self.ensure_undecided()?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    65
        let range = dagops::range(
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    66
            &self.graph,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    67
            missing,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    68
            self.undecided.as_ref().unwrap().iter().cloned(),
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    69
        )?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    70
        let undecided_mut = self.undecided.as_mut().unwrap();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    71
        for missrev in range {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    72
            self.missing.insert(missrev);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    73
            undecided_mut.remove(&missrev);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    74
        }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    75
        Ok(())
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    76
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    77
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    78
    /// Do we have any information about the peer?
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    79
    pub fn has_info(&self) -> bool {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    80
        self.common.has_bases()
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    81
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    82
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    83
    /// Did we acquire full knowledge of our Revisions that the peer has?
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    84
    pub fn is_complete(&self) -> bool {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    85
        self.undecided.as_ref().map_or(false, |s| s.is_empty())
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    86
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    87
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    88
    /// Return the heads of the currently known common set of revisions.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    89
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    90
    /// If the discovery process is not complete (see `is_complete()`), the
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    91
    /// caller must be aware that this is an intermediate state.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    92
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    93
    /// On the other hand, if it is complete, then this is currently
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    94
    /// the only way to retrieve the end results of the discovery process.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    95
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    96
    /// We may introduce in the future an `into_common_heads` call that
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    97
    /// would be more appropriate for normal Rust callers, dropping `self`
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    98
    /// if it is complete.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
    99
    pub fn common_heads(&self) -> Result<HashSet<Revision>, GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   100
        self.common.bases_heads()
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   101
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   102
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   103
    /// Force first computation of `self.undecided`
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   104
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   105
    /// After this, `self.undecided.as_ref()` and `.as_mut()` can be
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   106
    /// unwrapped to get workable immutable or mutable references without
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   107
    /// any panic.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   108
    ///
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   109
    /// This is an imperative call instead of an access with added lazyness
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   110
    /// to reduce easily the scope of mutable borrow for the caller,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   111
    /// compared to undecided(&'a mut self) -> &'a… that would keep it
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   112
    /// as long as the resulting immutable one.
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   113
    fn ensure_undecided(&mut self) -> Result<(), GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   114
        if self.undecided.is_some() {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   115
            return Ok(());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   116
        }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   117
        let tgt = self.target_heads.take().unwrap();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   118
        self.undecided =
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   119
            Some(self.common.missing_ancestors(tgt)?.into_iter().collect());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   120
        Ok(())
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   121
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   122
}
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   123
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   124
#[cfg(test)]
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   125
mod tests {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   126
    use super::*;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   127
    use crate::testing::SampleGraph;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   128
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   129
    /// A PartialDiscovery as for pushing all the heads of `SampleGraph`
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   130
    fn full_disco() -> PartialDiscovery<SampleGraph> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   131
        PartialDiscovery::new(SampleGraph, vec![10, 11, 12, 13])
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   132
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   133
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   134
    fn sorted_undecided(
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   135
        disco: &PartialDiscovery<SampleGraph>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   136
    ) -> Vec<Revision> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   137
        let mut as_vec: Vec<Revision> =
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   138
            disco.undecided.as_ref().unwrap().iter().cloned().collect();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   139
        as_vec.sort();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   140
        as_vec
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   141
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   142
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   143
    fn sorted_missing(disco: &PartialDiscovery<SampleGraph>) -> Vec<Revision> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   144
        let mut as_vec: Vec<Revision> =
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   145
            disco.missing.iter().cloned().collect();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   146
        as_vec.sort();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   147
        as_vec
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   148
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   149
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   150
    fn sorted_common_heads(
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   151
        disco: &PartialDiscovery<SampleGraph>,
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   152
    ) -> Result<Vec<Revision>, GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   153
        let mut as_vec: Vec<Revision> =
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   154
            disco.common_heads()?.iter().cloned().collect();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   155
        as_vec.sort();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   156
        Ok(as_vec)
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   157
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   158
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   159
    #[test]
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   160
    fn test_add_common_get_undecided() -> Result<(), GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   161
        let mut disco = full_disco();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   162
        assert_eq!(disco.undecided, None);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   163
        assert!(!disco.has_info());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   164
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   165
        disco.add_common_revisions(vec![11, 12])?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   166
        assert!(disco.has_info());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   167
        assert!(!disco.is_complete());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   168
        assert!(disco.missing.is_empty());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   169
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   170
        // add_common_revisions did not trigger a premature computation
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   171
        // of `undecided`, let's check that and ask for them
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   172
        assert_eq!(disco.undecided, None);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   173
        disco.ensure_undecided()?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   174
        assert_eq!(sorted_undecided(&disco), vec![5, 8, 10, 13]);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   175
        Ok(())
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   176
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   177
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   178
    /// in this test, we pretend that our peer misses exactly (8+10)::
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   179
    /// and we're comparing all our repo to it (as in a bare push)
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   180
    #[test]
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   181
    fn test_discovery() -> Result<(), GraphError> {
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   182
        let mut disco = full_disco();
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   183
        disco.add_common_revisions(vec![11, 12])?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   184
        disco.add_missing_revisions(vec![8, 10])?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   185
        assert_eq!(sorted_undecided(&disco), vec![5]);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   186
        assert_eq!(sorted_missing(&disco), vec![8, 10, 13]);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   187
        assert!(!disco.is_complete());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   188
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   189
        disco.add_common_revisions(vec![5])?;
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   190
        assert_eq!(sorted_undecided(&disco), vec![]);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   191
        assert_eq!(sorted_missing(&disco), vec![8, 10, 13]);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   192
        assert!(disco.is_complete());
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   193
        assert_eq!(sorted_common_heads(&disco)?, vec![5, 11, 12]);
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   194
        Ok(())
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   195
    }
10b465d61556 rust-discovery: starting core implementation
Georges Racinet <georges.racinet@octobus.net>
parents:
diff changeset
   196
}