annotate rust/hg-core/src/ancestors.rs @ 51470:406b413e3cf2 stable

rust-filepatterns: export glob_to_re function Making this function public should not risk freezing the internal API, and it can be useful for all downstream code that needs to perform glob matching against byte strings, such as RHGitaly where it will be useful to match on branches and tags.
author Georges Racinet <georges.racinet@octobus.net>
date Mon, 11 Mar 2024 13:23:18 +0100
parents 4c5f6e95df84
children b08c5fbe0e70
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
1 // ancestors.rs
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
2 //
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
3 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
4 //
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
7
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
8 //! Rust versions of generic DAG ancestors algorithms for Mercurial
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
9
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
10 use super::{Graph, GraphError, Revision, NULL_REVISION};
42327
e8f3740cc067 rust-filepatterns: add a Rust implementation of pattern-related utils
Raphaël Gomès <rgomes@octobus.net>
parents: 41717
diff changeset
11 use crate::dagops;
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
12 use std::cmp::max;
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
13 use std::collections::{BinaryHeap, HashSet};
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
14
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
15 /// Iterator over the ancestors of a given list of revisions
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
16 /// This is a generic type, defined and implemented for any Graph, so that
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
17 /// it's easy to
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
18 ///
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
19 /// - unit test in pure Rust
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
20 /// - bind to main Mercurial code, potentially in several ways and have these
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
21 /// bindings evolve over time
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
22 pub struct AncestorsIterator<G: Graph> {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
23 graph: G,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
24 visit: BinaryHeap<Revision>,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
25 seen: HashSet<Revision>,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
26 stoprev: Revision,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
27 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
28
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
29 pub struct MissingAncestors<G: Graph> {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
30 graph: G,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
31 bases: HashSet<Revision>,
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
32 max_base: Revision,
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
33 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
34
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
35 impl<G: Graph> AncestorsIterator<G> {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
36 /// Constructor.
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
37 ///
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
38 /// if `inclusive` is true, then the init revisions are emitted in
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
39 /// particular, otherwise iteration starts from their parents.
41105
35ee590b1892 rust: use 'impl Trait' in method argument of AncestorsIterator
Yuya Nishihara <yuya@tcha.org>
parents: 41104
diff changeset
40 pub fn new(
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
41 graph: G,
41105
35ee590b1892 rust: use 'impl Trait' in method argument of AncestorsIterator
Yuya Nishihara <yuya@tcha.org>
parents: 41104
diff changeset
42 initrevs: impl IntoIterator<Item = Revision>,
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
43 stoprev: Revision,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
44 inclusive: bool,
41105
35ee590b1892 rust: use 'impl Trait' in method argument of AncestorsIterator
Yuya Nishihara <yuya@tcha.org>
parents: 41104
diff changeset
45 ) -> Result<Self, GraphError> {
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
46 let filtered_initrevs = initrevs.into_iter().filter(|&r| r >= stoprev);
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
47 if inclusive {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
48 let visit: BinaryHeap<Revision> = filtered_initrevs.collect();
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
49 let seen = visit.iter().cloned().collect();
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
50 return Ok(AncestorsIterator {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
51 visit,
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
52 seen,
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
53 stoprev,
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
54 graph,
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
55 });
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
56 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
57 let mut this = AncestorsIterator {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
58 visit: BinaryHeap::new(),
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
59 seen: HashSet::new(),
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
60 stoprev,
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
61 graph,
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
62 };
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
63 this.seen.insert(NULL_REVISION);
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
64 for rev in filtered_initrevs {
40933
18513d6ef7d4 rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents: 40932
diff changeset
65 for parent in this.graph.parents(rev)?.iter().cloned() {
18513d6ef7d4 rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents: 40932
diff changeset
66 this.conditionally_push_rev(parent);
18513d6ef7d4 rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents: 40932
diff changeset
67 }
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
68 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
69 Ok(this)
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
70 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
71
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
72 #[inline]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
73 fn conditionally_push_rev(&mut self, rev: Revision) {
41714
70827ebba453 rust: less set lookups in AncestorsIterator
Georges Racinet <georges.racinet@octobus.net>
parents: 41246
diff changeset
74 if self.stoprev <= rev && self.seen.insert(rev) {
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
75 self.visit.push(rev);
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
76 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
77 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
78
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
79 /// Consumes partially the iterator to tell if the given target
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
80 /// revision
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
81 /// is in the ancestors it emits.
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
82 /// This is meant for iterators actually dedicated to that kind of
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
83 /// purpose
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
84 pub fn contains(&mut self, target: Revision) -> Result<bool, GraphError> {
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
85 if self.seen.contains(&target) && target != NULL_REVISION {
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
86 return Ok(true);
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
87 }
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
88 for item in self {
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
89 let rev = item?;
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
90 if rev == target {
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
91 return Ok(true);
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
92 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
93 if rev < target {
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
94 return Ok(false);
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
95 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
96 }
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
97 Ok(false)
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
98 }
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
99
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
100 pub fn peek(&self) -> Option<Revision> {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
101 self.visit.peek().cloned()
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
102 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
103
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
104 /// Tell if the iterator is about an empty set
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
105 ///
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
106 /// The result does not depend whether the iterator has been consumed
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
107 /// or not.
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
108 /// This is mostly meant for iterators backing a lazy ancestors set
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
109 pub fn is_empty(&self) -> bool {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
110 if self.visit.len() > 0 {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
111 return false;
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
112 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
113 if self.seen.len() > 1 {
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
114 return false;
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
115 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
116 // at this point, the seen set is at most a singleton.
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
117 // If not `self.inclusive`, it's still possible that it has only
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
118 // the null revision
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
119 self.seen.is_empty() || self.seen.contains(&NULL_REVISION)
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
120 }
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
121 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
122
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
123 /// Main implementation for the iterator
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
124 ///
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
125 /// The algorithm is the same as in `_lazyancestorsiter()` from `ancestors.py`
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
126 /// with a few non crucial differences:
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
127 ///
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
128 /// - there's no filtering of invalid parent revisions. Actually, it should be
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
129 /// consistent and more efficient to filter them from the end caller.
40932
dc38d976ff4d rust: improved docstring
Georges Racinet <gracinet@anybox.fr>
parents: 40929
diff changeset
130 /// - we don't have the optimization for adjacent revisions (i.e., the case
dc38d976ff4d rust: improved docstring
Georges Racinet <gracinet@anybox.fr>
parents: 40929
diff changeset
131 /// where `p1 == rev - 1`), because it amounts to update the first element of
dc38d976ff4d rust: improved docstring
Georges Racinet <gracinet@anybox.fr>
parents: 40929
diff changeset
132 /// the heap without sifting, which Rust's BinaryHeap doesn't let us do.
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
133 /// - we save a few pushes by comparing with `stoprev` before pushing
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
134 impl<G: Graph> Iterator for AncestorsIterator<G> {
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
135 type Item = Result<Revision, GraphError>;
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
136
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
137 fn next(&mut self) -> Option<Self::Item> {
40811
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
138 let current = match self.visit.peek() {
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
139 None => {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
140 return None;
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
141 }
40811
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
142 Some(c) => *c,
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
143 };
40933
18513d6ef7d4 rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents: 40932
diff changeset
144 let [p1, p2] = match self.graph.parents(current) {
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
145 Ok(ps) => ps,
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
146 Err(e) => return Some(Err(e)),
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
147 };
41714
70827ebba453 rust: less set lookups in AncestorsIterator
Georges Racinet <georges.racinet@octobus.net>
parents: 41246
diff changeset
148 if p1 < self.stoprev || !self.seen.insert(p1) {
40811
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
149 self.visit.pop();
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
150 } else {
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
151 *(self.visit.peek_mut().unwrap()) = p1;
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
152 };
e13ab4acf555 rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40300
diff changeset
153
40832
70976974c14a rust: rename local variables in AncestorsIterator::next
Georges Racinet <georges@racinet.fr>
parents: 40811
diff changeset
154 self.conditionally_push_rev(p2);
40863
443eb4bc41af rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents: 40832
diff changeset
155 Some(Ok(current))
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
156 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
157 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
158
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
159 impl<G: Graph> MissingAncestors<G> {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
160 pub fn new(graph: G, bases: impl IntoIterator<Item = Revision>) -> Self {
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
161 let mut created = MissingAncestors {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 42841
diff changeset
162 graph,
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
163 bases: HashSet::new(),
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
164 max_base: NULL_REVISION,
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
165 };
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
166 created.add_bases(bases);
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
167 created
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
168 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
169
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
170 pub fn has_bases(&self) -> bool {
41716
977432970080 rust: stop putting NULL_REVISION in MissingAncestors.bases
Georges Racinet <georges.racinet@octobus.net>
parents: 41715
diff changeset
171 !self.bases.is_empty()
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
172 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
173
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
174 /// Return a reference to current bases.
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
175 ///
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
176 /// This is useful in unit tests, but also setdiscovery.py does
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
177 /// read the bases attribute of a ancestor.missingancestors instance.
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
178 pub fn get_bases(&self) -> &HashSet<Revision> {
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
179 &self.bases
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
180 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
181
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
182 /// Computes the relative heads of current bases.
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
183 ///
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
184 /// The object is still usable after this.
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
185 pub fn bases_heads(&self) -> Result<HashSet<Revision>, GraphError> {
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
186 dagops::heads(&self.graph, self.bases.iter())
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
187 }
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
188
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
189 /// Consumes the object and returns the relative heads of its bases.
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
190 pub fn into_bases_heads(
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
191 mut self,
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
192 ) -> Result<HashSet<Revision>, GraphError> {
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
193 dagops::retain_heads(&self.graph, &mut self.bases)?;
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
194 Ok(self.bases)
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
195 }
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
196
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
197 /// Add some revisions to `self.bases`
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
198 ///
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
199 /// Takes care of keeping `self.max_base` up to date.
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
200 pub fn add_bases(
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
201 &mut self,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
202 new_bases: impl IntoIterator<Item = Revision>,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
203 ) {
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
204 let mut max_base = self.max_base;
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
205 self.bases.extend(
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
206 new_bases
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
207 .into_iter()
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
208 .filter(|&rev| rev != NULL_REVISION)
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
209 .map(|r| {
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
210 if r > max_base {
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
211 max_base = r;
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
212 }
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
213 r
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
214 }),
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
215 );
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
216 self.max_base = max_base;
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
217 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
218
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
219 /// Remove all ancestors of self.bases from the revs set (in place)
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
220 pub fn remove_ancestors_from(
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
221 &mut self,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
222 revs: &mut HashSet<Revision>,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
223 ) -> Result<(), GraphError> {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
224 revs.retain(|r| !self.bases.contains(r));
41716
977432970080 rust: stop putting NULL_REVISION in MissingAncestors.bases
Georges Racinet <georges.racinet@octobus.net>
parents: 41715
diff changeset
225 // the null revision is always an ancestor. Logically speaking
977432970080 rust: stop putting NULL_REVISION in MissingAncestors.bases
Georges Racinet <georges.racinet@octobus.net>
parents: 41715
diff changeset
226 // it's debatable in case bases is empty, but the Python
977432970080 rust: stop putting NULL_REVISION in MissingAncestors.bases
Georges Racinet <georges.racinet@octobus.net>
parents: 41715
diff changeset
227 // implementation always adds NULL_REVISION to bases, making it
977432970080 rust: stop putting NULL_REVISION in MissingAncestors.bases
Georges Racinet <georges.racinet@octobus.net>
parents: 41715
diff changeset
228 // unconditionnally true.
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
229 revs.remove(&NULL_REVISION);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
230 if revs.is_empty() {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
231 return Ok(());
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
232 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
233 // anything in revs > start is definitely not an ancestor of bases
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
234 // revs <= start need to be investigated
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
235 if self.max_base == NULL_REVISION {
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
236 return Ok(());
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
237 }
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
238
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
239 // whatever happens, we'll keep at least keepcount of them
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
240 // knowing this gives us a earlier stop condition than
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
241 // going all the way to the root
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
242 let keepcount = revs.iter().filter(|r| **r > self.max_base).count();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
243
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
244 let mut curr = self.max_base;
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
245 while curr != NULL_REVISION && revs.len() > keepcount {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
246 if self.bases.contains(&curr) {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
247 revs.remove(&curr);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
248 self.add_parents(curr)?;
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
249 }
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
250 // We know this revision is safe because we've checked the bounds
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
251 // before.
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
252 curr = Revision(curr.0 - 1);
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
253 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
254 Ok(())
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
255 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
256
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
257 /// Add the parents of `rev` to `self.bases`
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
258 ///
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
259 /// This has no effect on `self.max_base`
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
260 #[inline]
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
261 fn add_parents(&mut self, rev: Revision) -> Result<(), GraphError> {
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
262 if rev == NULL_REVISION {
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
263 return Ok(());
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
264 }
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
265 for p in self.graph.parents(rev)?.iter().cloned() {
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
266 // No need to bother the set with inserting NULL_REVISION over and
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
267 // over
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
268 if p != NULL_REVISION {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
269 self.bases.insert(p);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
270 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
271 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
272 Ok(())
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
273 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
274
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
275 /// Return all the ancestors of revs that are not ancestors of self.bases
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
276 ///
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
277 /// This may include elements from revs.
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
278 ///
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
279 /// Equivalent to the revset (::revs - ::self.bases). Revs are returned in
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
280 /// revision number order, which is a topological order.
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
281 pub fn missing_ancestors(
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
282 &mut self,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
283 revs: impl IntoIterator<Item = Revision>,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
284 ) -> Result<Vec<Revision>, GraphError> {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
285 // just for convenience and comparison with Python version
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
286 let bases_visit = &mut self.bases;
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
287 let mut revs: HashSet<Revision> = revs
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
288 .into_iter()
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
289 .filter(|r| !bases_visit.contains(r))
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
290 .collect();
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
291 let revs_visit = &mut revs;
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
292 let mut both_visit: HashSet<Revision> =
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
293 revs_visit.intersection(bases_visit).cloned().collect();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
294 if revs_visit.is_empty() {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
295 return Ok(Vec::new());
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
296 }
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
297 let max_revs = revs_visit.iter().cloned().max().unwrap();
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
298 let start = max(self.max_base, max_revs);
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
299
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
300 // TODO heuristics for with_capacity()?
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
301 let mut missing: Vec<Revision> = Vec::new();
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
302 for curr in (0..=start.0).rev() {
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
303 if revs_visit.is_empty() {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
304 break;
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
305 }
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
306 if both_visit.remove(&Revision(curr)) {
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
307 // curr's parents might have made it into revs_visit through
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
308 // another path
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
309 for p in self.graph.parents(Revision(curr))?.iter().cloned() {
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
310 if p == NULL_REVISION {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
311 continue;
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
312 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
313 revs_visit.remove(&p);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
314 bases_visit.insert(p);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
315 both_visit.insert(p);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
316 }
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
317 } else if revs_visit.remove(&Revision(curr)) {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
318 missing.push(Revision(curr));
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
319 for p in self.graph.parents(Revision(curr))?.iter().cloned() {
41131
486908e691be rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents: 41105
diff changeset
320 if p == NULL_REVISION {
486908e691be rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents: 41105
diff changeset
321 continue;
486908e691be rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents: 41105
diff changeset
322 }
41715
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
323 if bases_visit.contains(&p) {
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
324 // p is already known to be an ancestor of revs_visit
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
325 revs_visit.remove(&p);
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
326 both_visit.insert(p);
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
327 } else if both_visit.contains(&p) {
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
328 // p should have been in bases_visit
41131
486908e691be rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents: 41105
diff changeset
329 revs_visit.remove(&p);
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
330 bases_visit.insert(p);
41131
486908e691be rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents: 41105
diff changeset
331 } else {
486908e691be rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents: 41105
diff changeset
332 // visit later
41133
a1b3800c8a19 rust-ancestors: remove unreachable conditions from missing_ancestors()
Yuya Nishihara <yuya@tcha.org>
parents: 41132
diff changeset
333 revs_visit.insert(p);
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
334 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
335 }
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
336 } else if bases_visit.contains(&Revision(curr)) {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
337 for p in self.graph.parents(Revision(curr))?.iter().cloned() {
41132
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
338 if p == NULL_REVISION {
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
339 continue;
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
340 }
41715
fccb61a1777b rust: less set lookups in MissingAncestors
Georges Racinet <georges.racinet@octobus.net>
parents: 41714
diff changeset
341 if revs_visit.remove(&p) || both_visit.contains(&p) {
41134
17a195676472 rust-ancestors: adjust branches and inline comments per previous change
Yuya Nishihara <yuya@tcha.org>
parents: 41133
diff changeset
342 // p is an ancestor of bases_visit, and is implicitly
17a195676472 rust-ancestors: adjust branches and inline comments per previous change
Yuya Nishihara <yuya@tcha.org>
parents: 41133
diff changeset
343 // in revs_visit, which means p is ::revs & ::bases.
41132
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
344 bases_visit.insert(p);
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
345 both_visit.insert(p);
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
346 } else {
41133
a1b3800c8a19 rust-ancestors: remove unreachable conditions from missing_ancestors()
Yuya Nishihara <yuya@tcha.org>
parents: 41132
diff changeset
347 bases_visit.insert(p);
41132
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
348 }
55dc1da8df2f rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents: 41131
diff changeset
349 }
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
350 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
351 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
352 missing.reverse();
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
353 Ok(missing)
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
354 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
355 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
356
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
357 #[cfg(test)]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
358 mod tests {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
359
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
360 use super::*;
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
361 use crate::{
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
362 testing::{SampleGraph, VecGraph},
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
363 BaseRevision,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
364 };
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
365
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
366 impl From<BaseRevision> for Revision {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
367 fn from(value: BaseRevision) -> Self {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
368 if !cfg!(test) {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
369 panic!("should only be used in tests")
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
370 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
371 Revision(value)
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
372 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
373 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
374
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
375 impl PartialEq<BaseRevision> for Revision {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
376 fn eq(&self, other: &BaseRevision) -> bool {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
377 if !cfg!(test) {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
378 panic!("should only be used in tests")
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
379 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
380 self.0.eq(other)
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
381 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
382 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
383
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
384 impl PartialEq<u32> for Revision {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
385 fn eq(&self, other: &u32) -> bool {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
386 if !cfg!(test) {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
387 panic!("should only be used in tests")
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
388 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
389 let check: Result<u32, _> = self.0.try_into();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
390 match check {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
391 Ok(value) => value.eq(other),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
392 Err(_) => false,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
393 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
394 }
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
395 }
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
396
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
397 fn list_ancestors<G: Graph>(
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
398 graph: G,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
399 initrevs: Vec<Revision>,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
400 stoprev: Revision,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
401 inclusive: bool,
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
402 ) -> Vec<Revision> {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
403 AncestorsIterator::new(graph, initrevs, stoprev, inclusive)
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
404 .unwrap()
40929
43ca24b772d6 rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents: 40927
diff changeset
405 .map(|res| res.unwrap())
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
406 .collect()
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
407 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
408
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
409 #[test]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
410 /// Same tests as test-ancestor.py, without membership
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
411 /// (see also test-ancestor.py.out)
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
412 fn test_list_ancestor() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
413 assert_eq!(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
414 list_ancestors(SampleGraph, vec![], 0.into(), false),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
415 Vec::<Revision>::new()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
416 );
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
417 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
418 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
419 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
420 vec![11.into(), 13.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
421 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
422 false
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
423 ),
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
424 vec![8, 7, 4, 3, 2, 1, 0]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
425 );
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
426 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
427 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
428 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
429 vec![1.into(), 3.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
430 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
431 false
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
432 ),
41241
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
433 vec![1, 0]
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
434 );
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
435 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
436 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
437 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
438 vec![11.into(), 13.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
439 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
440 true
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
441 ),
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
442 vec![13, 11, 8, 7, 4, 3, 2, 1, 0]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
443 );
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
444 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
445 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
446 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
447 vec![11.into(), 13.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
448 6.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
449 false
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
450 ),
41241
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
451 vec![8, 7]
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
452 );
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
453 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
454 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
455 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
456 vec![11.into(), 13.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
457 6.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
458 true
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
459 ),
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
460 vec![13, 11, 8, 7]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
461 );
41241
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
462 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
463 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
464 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
465 vec![11.into(), 13.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
466 11.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
467 true
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
468 ),
41241
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
469 vec![13, 11]
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
470 );
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
471 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
472 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
473 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
474 vec![11.into(), 13.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
475 12.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
476 true
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
477 ),
41241
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
478 vec![13]
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
479 );
168041fa6d5f rust: factorized testing Graphs
Georges Racinet <georges.racinet@octobus.net>
parents: 41134
diff changeset
480 assert_eq!(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
481 list_ancestors(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
482 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
483 vec![10.into(), 1.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
484 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
485 true
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
486 ),
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
487 vec![10, 5, 4, 2, 1, 0]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
488 );
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
489 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
490
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
491 #[test]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
492 /// Corner case that's not directly in test-ancestors.py, but
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
493 /// that happens quite often, as demonstrated by running the whole
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
494 /// suite.
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
495 /// For instance, run tests/test-obsolete-checkheads.t
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
496 fn test_nullrev_input() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
497 let mut iter = AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
498 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
499 vec![Revision(-1)],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
500 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
501 false,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
502 )
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
503 .unwrap();
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
504 assert_eq!(iter.next(), None)
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
505 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
506
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
507 #[test]
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
508 fn test_contains() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
509 let mut lazy = AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
510 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
511 vec![10.into(), 1.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
512 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
513 true,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
514 )
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
515 .unwrap();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
516 assert!(lazy.contains(1.into()).unwrap());
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
517 assert!(!lazy.contains(3.into()).unwrap());
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
518
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
519 let mut lazy = AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
520 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
521 vec![0.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
522 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
523 false,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
524 )
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
525 .unwrap();
40929
43ca24b772d6 rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents: 40927
diff changeset
526 assert!(!lazy.contains(NULL_REVISION).unwrap());
40300
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
527 }
72b94f946e90 rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents: 40271
diff changeset
528
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
529 #[test]
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
530 fn test_peek() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
531 let mut iter = AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
532 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
533 vec![10.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
534 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
535 true,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
536 )
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
537 .unwrap();
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
538 // peek() gives us the next value
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
539 assert_eq!(iter.peek(), Some(10.into()));
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
540 // but it's not been consumed
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
541 assert_eq!(iter.next(), Some(Ok(10.into())));
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
542 // and iteration resumes normally
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
543 assert_eq!(iter.next(), Some(Ok(5.into())));
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
544
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
545 // let's drain the iterator to test peek() at the end
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
546 while iter.next().is_some() {}
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
547 assert_eq!(iter.peek(), None);
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
548 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
549
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
550 #[test]
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
551 fn test_empty() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
552 let mut iter = AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
553 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
554 vec![10.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
555 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
556 true,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
557 )
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
558 .unwrap();
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
559 assert!(!iter.is_empty());
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
560 while iter.next().is_some() {}
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
561 assert!(!iter.is_empty());
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
562
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
563 let iter = AncestorsIterator::new(SampleGraph, vec![], 0.into(), true)
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
564 .unwrap();
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
565 assert!(iter.is_empty());
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
566
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
567 // case where iter.seen == {NULL_REVISION}
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
568 let iter = AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
569 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
570 vec![0.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
571 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
572 false,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
573 )
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
574 .unwrap();
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
575 assert!(iter.is_empty());
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
576 }
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
577
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
578 /// A corrupted Graph, supporting error handling tests
41054
ef54bd33b476 rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40959
diff changeset
579 #[derive(Clone, Debug)]
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
580 struct Corrupted;
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
581
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
582 impl Graph for Corrupted {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
583 // FIXME what to do about this? Are we just not supposed to get them
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
584 // anymore?
40933
18513d6ef7d4 rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents: 40932
diff changeset
585 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
586 match rev {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
587 Revision(1) => Ok([0.into(), (-1).into()]),
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
588 r => Err(GraphError::ParentOutOfRange(r)),
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
589 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
590 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
591 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
592
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
593 #[test]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
594 fn test_initrev_out_of_range() {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
595 // inclusive=false looks up initrev's parents right away
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
596 match AncestorsIterator::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
597 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
598 vec![25.into()],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
599 0.into(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
600 false,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
601 ) {
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
602 Ok(_) => panic!("Should have been ParentOutOfRange"),
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
603 Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25.into())),
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
604 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
605 }
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
606
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
607 #[test]
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
608 fn test_next_out_of_range() {
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
609 // inclusive=false looks up initrev's parents right away
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
610 let mut iter =
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
611 AncestorsIterator::new(Corrupted, vec![1.into()], 0.into(), false)
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
612 .unwrap();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
613 assert_eq!(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
614 iter.next(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
615 Some(Err(GraphError::ParentOutOfRange(0.into())))
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
616 );
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
617 }
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
618
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
619 #[test]
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
620 /// Test constructor, add/get bases and heads
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
621 fn test_missing_bases() -> Result<(), GraphError> {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
622 let mut missing_ancestors = MissingAncestors::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
623 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
624 [5.into(), 3.into(), 1.into(), 3.into()].iter().cloned(),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
625 );
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
626 let mut as_vec: Vec<Revision> =
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
627 missing_ancestors.get_bases().iter().cloned().collect();
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
628 as_vec.sort_unstable();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
629 assert_eq!(as_vec, [1, 3, 5]);
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
630 assert_eq!(missing_ancestors.max_base, 5);
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
631
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
632 missing_ancestors
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
633 .add_bases([3.into(), 7.into(), 8.into()].iter().cloned());
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
634 as_vec = missing_ancestors.get_bases().iter().cloned().collect();
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
635 as_vec.sort_unstable();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
636 assert_eq!(as_vec, [1, 3, 5, 7, 8]);
41717
9060af281be7 rust: itering less on MissingAncestors.bases for max()
Georges Racinet <georges.racinet@octobus.net>
parents: 41716
diff changeset
637 assert_eq!(missing_ancestors.max_base, 8);
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
638
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
639 as_vec = missing_ancestors.bases_heads()?.iter().cloned().collect();
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
640 as_vec.sort_unstable();
41246
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
641 assert_eq!(as_vec, [3, 5, 7, 8]);
619ee4039bd4 rust: MissingAncestors.basesheads()
Georges Racinet <georges.racinet@octobus.net>
parents: 41241
diff changeset
642 Ok(())
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
643 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
644
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
645 fn assert_missing_remove(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
646 bases: &[BaseRevision],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
647 revs: &[BaseRevision],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
648 expected: &[BaseRevision],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
649 ) {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
650 let mut missing_ancestors = MissingAncestors::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
651 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
652 bases.iter().map(|r| Revision(*r)),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
653 );
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
654 let mut revset: HashSet<Revision> =
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
655 revs.iter().map(|r| Revision(*r)).collect();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
656 missing_ancestors
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
657 .remove_ancestors_from(&mut revset)
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
658 .unwrap();
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
659 let mut as_vec: Vec<Revision> = revset.into_iter().collect();
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
660 as_vec.sort_unstable();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
661 assert_eq!(as_vec.as_slice(), expected);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
662 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
663
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
664 #[test]
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
665 fn test_missing_remove() {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
666 assert_missing_remove(
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
667 &[1, 2, 3, 4, 7],
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
668 Vec::from_iter(1..10).as_slice(),
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
669 &[5, 6, 8, 9],
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
670 );
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
671 assert_missing_remove(&[10], &[11, 12, 13, 14], &[11, 12, 13, 14]);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
672 assert_missing_remove(&[7], &[1, 2, 3, 4, 5], &[3, 5]);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
673 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
674
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
675 fn assert_missing_ancestors(
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
676 bases: &[BaseRevision],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
677 revs: &[BaseRevision],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
678 expected: &[BaseRevision],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
679 ) {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
680 let mut missing_ancestors = MissingAncestors::new(
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
681 SampleGraph,
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
682 bases.iter().map(|r| Revision(*r)),
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
683 );
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
684 let missing = missing_ancestors
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
685 .missing_ancestors(revs.iter().map(|r| Revision(*r)))
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
686 .unwrap();
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
687 assert_eq!(missing.as_slice(), expected);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
688 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
689
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
690 #[test]
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
691 fn test_missing_ancestors() {
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
692 // examples taken from test-ancestors.py by having it run
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
693 // on the same graph (both naive and fast Python algs)
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
694 assert_missing_ancestors(&[10], &[11], &[3, 7, 11]);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
695 assert_missing_ancestors(&[11], &[10], &[5, 10]);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
696 assert_missing_ancestors(&[7], &[9, 11], &[3, 6, 9, 11]);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
697 }
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
698
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
699 /// An interesting case found by a random generator similar to
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
700 /// the one in test-ancestor.py. An early version of Rust MissingAncestors
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
701 /// failed this, yet none of the integration tests of the whole suite
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
702 /// catched it.
49930
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Raphaël Gomès <rgomes@octobus.net>
parents: 49631
diff changeset
703 #[allow(clippy::unnecessary_cast)]
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
704 #[test]
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
705 fn test_remove_ancestors_from_case1() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
706 const FAKE_NULL_REVISION: BaseRevision = -1;
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
707 assert_eq!(FAKE_NULL_REVISION, NULL_REVISION.0);
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
708 let graph: VecGraph = vec![
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
709 [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
710 [0, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
711 [1, 0],
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
712 [2, 1],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
713 [3, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
714 [4, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
715 [5, 1],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
716 [2, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
717 [7, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
718 [8, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
719 [9, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
720 [10, 1],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
721 [3, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
722 [12, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
723 [13, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
724 [14, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
725 [4, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
726 [16, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
727 [17, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
728 [18, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
729 [19, 11],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
730 [20, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
731 [21, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
732 [22, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
733 [23, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
734 [2, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
735 [3, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
736 [26, 24],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
737 [27, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
738 [28, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
739 [12, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
740 [1, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
741 [1, 9],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
742 [32, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
743 [33, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
744 [34, 31],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
745 [35, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
746 [36, 26],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
747 [37, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
748 [38, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
749 [39, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
750 [40, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
751 [41, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
752 [42, 26],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
753 [0, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
754 [44, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
755 [45, 4],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
756 [40, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
757 [47, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
758 [36, 0],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
759 [49, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
760 [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
761 [51, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
762 [52, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
763 [53, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
764 [14, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
765 [55, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
766 [15, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
767 [23, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
768 [58, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
769 [59, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
770 [2, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
771 [61, 59],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
772 [62, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
773 [63, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
774 [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
775 [65, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
776 [66, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
777 [67, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
778 [68, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
779 [37, 28],
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
780 [69, 25],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
781 [71, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
782 [72, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
783 [50, 2],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
784 [74, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
785 [12, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
786 [18, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
787 [77, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
788 [78, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
789 [79, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
790 [43, 33],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
791 [81, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
792 [82, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
793 [83, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
794 [84, 45],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
795 [85, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
796 [86, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
797 [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
798 [88, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
799 [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
800 [76, 83],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
801 [44, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
802 [92, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
803 [93, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
804 [9, FAKE_NULL_REVISION],
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
805 [95, 67],
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
806 [96, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
807 [97, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
808 [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
809 ]
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
810 .into_iter()
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
811 .map(|[a, b]| [Revision(a), Revision(b)])
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
812 .collect();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
813 let problem_rev = 28.into();
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
814 let problem_base = 70.into();
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
815 // making the problem obvious: problem_rev is a parent of problem_base
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
816 assert_eq!(graph.parents(problem_base).unwrap()[1], problem_rev);
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
817
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
818 let mut missing_ancestors: MissingAncestors<VecGraph> =
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
819 MissingAncestors::new(
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
820 graph,
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
821 [60, 26, 70, 3, 96, 19, 98, 49, 97, 47, 1, 6]
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
822 .iter()
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
823 .map(|r| Revision(*r)),
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
824 );
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
825 assert!(missing_ancestors.bases.contains(&problem_base));
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
826
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
827 let mut revs: HashSet<Revision> =
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
828 [4, 12, 41, 28, 68, 38, 1, 30, 56, 44]
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
829 .iter()
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 49930
diff changeset
830 .map(|r| Revision(*r))
40959
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
831 .collect();
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
832 missing_ancestors.remove_ancestors_from(&mut revs).unwrap();
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
833 assert!(!revs.contains(&problem_rev));
d097dd0afc19 rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents: 40933
diff changeset
834 }
40271
dbc28c91f7ff rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff changeset
835 }