Mercurial > hg
annotate rust/hg-core/src/ancestors.rs @ 41134:17a195676472
rust-ancestors: adjust branches and inline comments per previous change
Now the top-level "if" can be read as both_visit|revs_visit|bases_visit.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Wed, 19 Dec 2018 22:24:20 +0900 |
parents | a1b3800c8a19 |
children | 168041fa6d5f |
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}; |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
11 use std::cmp::max; |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
12 use std::collections::{BinaryHeap, HashSet}; |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
13 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
14 /// Iterator over the ancestors of a given list of revisions |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
15 /// 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
|
16 /// it's easy to |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
17 /// |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
18 /// - unit test in pure Rust |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
19 /// - 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
|
20 /// bindings evolve over time |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
21 pub struct AncestorsIterator<G: Graph> { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
22 graph: G, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
23 visit: BinaryHeap<Revision>, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
24 seen: HashSet<Revision>, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
25 stoprev: Revision, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
26 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
27 |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
28 /// Lazy ancestors set, backed by AncestorsIterator |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
29 pub struct LazyAncestors<G: Graph + Clone> { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
30 graph: G, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
31 containsiter: AncestorsIterator<G>, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
32 initrevs: Vec<Revision>, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
33 stoprev: Revision, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
34 inclusive: bool, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
35 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
36 |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
37 pub struct MissingAncestors<G: Graph> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
38 graph: G, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
39 bases: HashSet<Revision>, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
40 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
41 |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
42 impl<G: Graph> AncestorsIterator<G> { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
43 /// Constructor. |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
44 /// |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
45 /// 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
|
46 /// 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
|
47 pub fn new( |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
48 graph: G, |
41105
35ee590b1892
rust: use 'impl Trait' in method argument of AncestorsIterator
Yuya Nishihara <yuya@tcha.org>
parents:
41104
diff
changeset
|
49 initrevs: impl IntoIterator<Item = Revision>, |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
50 stoprev: Revision, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
51 inclusive: bool, |
41105
35ee590b1892
rust: use 'impl Trait' in method argument of AncestorsIterator
Yuya Nishihara <yuya@tcha.org>
parents:
41104
diff
changeset
|
52 ) -> Result<Self, GraphError> { |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
53 let filtered_initrevs = initrevs.into_iter().filter(|&r| r >= stoprev); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
54 if inclusive { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
55 let visit: BinaryHeap<Revision> = filtered_initrevs.collect(); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
56 let seen = visit.iter().map(|&x| x).collect(); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
57 return Ok(AncestorsIterator { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
58 visit: visit, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
59 seen: seen, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
60 stoprev: stoprev, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
61 graph: graph, |
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 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
64 let mut this = AncestorsIterator { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
65 visit: BinaryHeap::new(), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
66 seen: HashSet::new(), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
67 stoprev: stoprev, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
68 graph: graph, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
69 }; |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
70 this.seen.insert(NULL_REVISION); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
71 for rev in filtered_initrevs { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
72 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
|
73 this.conditionally_push_rev(parent); |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
74 } |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
75 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
76 Ok(this) |
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 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
79 #[inline] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
80 fn conditionally_push_rev(&mut self, rev: Revision) { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
81 if self.stoprev <= rev && !self.seen.contains(&rev) { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
82 self.seen.insert(rev); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
83 self.visit.push(rev); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
84 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
85 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
86 |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
87 /// Consumes partially the iterator to tell if the given target |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
88 /// revision |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
89 /// is in the ancestors it emits. |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
90 /// This is meant for iterators actually dedicated to that kind of |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
91 /// purpose |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
92 pub fn contains(&mut self, target: Revision) -> Result<bool, GraphError> { |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
93 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
|
94 return Ok(true); |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
95 } |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
96 for item in self { |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
97 let rev = item?; |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
98 if rev == target { |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
99 return Ok(true); |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
100 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
101 if rev < target { |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
102 return Ok(false); |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
103 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
104 } |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
105 Ok(false) |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
106 } |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
107 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
108 pub fn peek(&self) -> Option<Revision> { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
109 self.visit.peek().map(|&r| r) |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
110 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
111 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
112 /// Tell if the iterator is about an empty set |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
113 /// |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
114 /// 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
|
115 /// or not. |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
116 /// 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
|
117 pub fn is_empty(&self) -> bool { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
118 if self.visit.len() > 0 { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
119 return false; |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
120 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
121 if self.seen.len() > 1 { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
122 return false; |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
123 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
124 // 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
|
125 // 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
|
126 // the null revision |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
127 self.seen.is_empty() || self.seen.contains(&NULL_REVISION) |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
128 } |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
129 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
130 |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
131 /// Main implementation for the iterator |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
132 /// |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
133 /// 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
|
134 /// with a few non crucial differences: |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
135 /// |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
136 /// - 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
|
137 /// 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
|
138 /// - 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
|
139 /// 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
|
140 /// 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
|
141 /// - 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
|
142 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
|
143 type Item = Result<Revision, GraphError>; |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
144 |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
145 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
|
146 let current = match self.visit.peek() { |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
147 None => { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
148 return None; |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
149 } |
40811
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
150 Some(c) => *c, |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
151 }; |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
152 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
|
153 Ok(ps) => ps, |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
154 Err(e) => return Some(Err(e)), |
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
155 }; |
40811
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
156 if p1 < self.stoprev || self.seen.contains(&p1) { |
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
157 self.visit.pop(); |
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
158 } else { |
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
159 *(self.visit.peek_mut().unwrap()) = p1; |
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
160 self.seen.insert(p1); |
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
161 }; |
e13ab4acf555
rust: peek_mut optim for lazy ancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40300
diff
changeset
|
162 |
40832
70976974c14a
rust: rename local variables in AncestorsIterator::next
Georges Racinet <georges@racinet.fr>
parents:
40811
diff
changeset
|
163 self.conditionally_push_rev(p2); |
40863
443eb4bc41af
rust: propagate error of index_get_parents() properly
Yuya Nishihara <yuya@tcha.org>
parents:
40832
diff
changeset
|
164 Some(Ok(current)) |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
165 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
166 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
167 |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
168 impl<G: Graph + Clone> LazyAncestors<G> { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
169 pub fn new( |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
170 graph: G, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
171 initrevs: impl IntoIterator<Item = Revision>, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
172 stoprev: Revision, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
173 inclusive: bool, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
174 ) -> Result<Self, GraphError> { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
175 let v: Vec<Revision> = initrevs.into_iter().collect(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
176 Ok(LazyAncestors { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
177 graph: graph.clone(), |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
178 containsiter: AncestorsIterator::new( |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
179 graph, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
180 v.iter().cloned(), |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
181 stoprev, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
182 inclusive, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
183 )?, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
184 initrevs: v, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
185 stoprev: stoprev, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
186 inclusive: inclusive, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
187 }) |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
188 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
189 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
190 pub fn contains(&mut self, rev: Revision) -> Result<bool, GraphError> { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
191 self.containsiter.contains(rev) |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
192 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
193 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
194 pub fn is_empty(&self) -> bool { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
195 self.containsiter.is_empty() |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
196 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
197 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
198 pub fn iter(&self) -> AncestorsIterator<G> { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
199 // the arguments being the same as for self.containsiter, we know |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
200 // for sure that AncestorsIterator constructor can't fail |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
201 AncestorsIterator::new( |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
202 self.graph.clone(), |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
203 self.initrevs.iter().cloned(), |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
204 self.stoprev, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
205 self.inclusive, |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
206 ) |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
207 .unwrap() |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
208 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
209 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
210 |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
211 impl<G: Graph> MissingAncestors<G> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
212 pub fn new(graph: G, bases: impl IntoIterator<Item = Revision>) -> Self { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
213 let mut bases: HashSet<Revision> = bases.into_iter().collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
214 if bases.is_empty() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
215 bases.insert(NULL_REVISION); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
216 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
217 MissingAncestors { graph, bases } |
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 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
220 pub fn has_bases(&self) -> bool { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
221 self.bases.iter().any(|&b| b != NULL_REVISION) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
222 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
223 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
224 /// Return a reference to current bases. |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
225 /// |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
226 /// 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
|
227 /// read the bases attribute of a ancestor.missingancestors instance. |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
228 pub fn get_bases<'a>(&'a self) -> &'a HashSet<Revision> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
229 &self.bases |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
230 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
231 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
232 pub fn add_bases( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
233 &mut self, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
234 new_bases: impl IntoIterator<Item = Revision>, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
235 ) { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
236 self.bases.extend(new_bases); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
237 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
238 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
239 /// 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
|
240 pub fn remove_ancestors_from( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
241 &mut self, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
242 revs: &mut HashSet<Revision>, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
243 ) -> Result<(), GraphError> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
244 revs.retain(|r| !self.bases.contains(r)); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
245 // the null revision is always an ancestor |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
246 revs.remove(&NULL_REVISION); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
247 if revs.is_empty() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
248 return Ok(()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
249 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
250 // 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
|
251 // revs <= start need to be investigated |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
252 // TODO optim: if a missingancestors is to be used several times, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
253 // we shouldn't need to iterate each time on bases |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
254 let start = match self.bases.iter().cloned().max() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
255 Some(m) => m, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
256 None => { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
257 // bases is empty (shouldn't happen, but let's be safe) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
258 return Ok(()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
259 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
260 }; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
261 // whatever happens, we'll keep at least keepcount of them |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
262 // knowing this gives us a earlier stop condition than |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
263 // going all the way to the root |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
264 let keepcount = revs.iter().filter(|r| **r > start).count(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
265 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
266 let mut curr = start; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
267 while curr != NULL_REVISION && revs.len() > keepcount { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
268 if self.bases.contains(&curr) { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
269 revs.remove(&curr); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
270 self.add_parents(curr)?; |
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 curr -= 1; |
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 Ok(()) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
275 } |
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 /// Add rev's parents to self.bases |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
278 #[inline] |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
279 fn add_parents(&mut self, rev: Revision) -> Result<(), GraphError> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
280 // No need to bother the set with inserting NULL_REVISION over and |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
281 // over |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
282 for p in self.graph.parents(rev)?.iter().cloned() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
283 if p != NULL_REVISION { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
284 self.bases.insert(p); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
285 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
286 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
287 Ok(()) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
288 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
289 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
290 /// 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
|
291 /// |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
292 /// This may include elements from revs. |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
293 /// |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
294 /// 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
|
295 /// revision number order, which is a topological order. |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
296 pub fn missing_ancestors( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
297 &mut self, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
298 revs: impl IntoIterator<Item = Revision>, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
299 ) -> Result<Vec<Revision>, GraphError> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
300 // just for convenience and comparison with Python version |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
301 let bases_visit = &mut self.bases; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
302 let mut revs: HashSet<Revision> = revs |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
303 .into_iter() |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
304 .filter(|r| !bases_visit.contains(r)) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
305 .collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
306 let revs_visit = &mut revs; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
307 let mut both_visit: HashSet<Revision> = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
308 revs_visit.intersection(&bases_visit).cloned().collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
309 if revs_visit.is_empty() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
310 return Ok(Vec::new()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
311 } |
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 let max_bases = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
314 bases_visit.iter().cloned().max().unwrap_or(NULL_REVISION); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
315 let max_revs = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
316 revs_visit.iter().cloned().max().unwrap_or(NULL_REVISION); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
317 let start = max(max_bases, max_revs); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
318 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
319 // TODO heuristics for with_capacity()? |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
320 let mut missing: Vec<Revision> = Vec::new(); |
41104
247f51cfc668
rust: use .rev() for reverse range
Yuya Nishihara <yuya@tcha.org>
parents:
41054
diff
changeset
|
321 for curr in (0..=start).rev() { |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
322 if revs_visit.is_empty() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
323 break; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
324 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
325 if both_visit.contains(&curr) { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
326 // 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
|
327 // another path |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
328 // TODO optim: Rust's HashSet.remove returns a boolean telling |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
329 // if it happened. This will spare us one set lookup |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
330 both_visit.remove(&curr); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
331 for p in self.graph.parents(curr)?.iter().cloned() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
332 if p == NULL_REVISION { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
333 continue; |
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 revs_visit.remove(&p); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
336 bases_visit.insert(p); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
337 both_visit.insert(p); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
338 } |
41134
17a195676472
rust-ancestors: adjust branches and inline comments per previous change
Yuya Nishihara <yuya@tcha.org>
parents:
41133
diff
changeset
|
339 } else if revs_visit.remove(&curr) { |
41131
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
340 missing.push(curr); |
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
341 for p in self.graph.parents(curr)?.iter().cloned() { |
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
342 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
|
343 continue; |
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
344 } |
41133
a1b3800c8a19
rust-ancestors: remove unreachable conditions from missing_ancestors()
Yuya Nishihara <yuya@tcha.org>
parents:
41132
diff
changeset
|
345 if bases_visit.contains(&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
|
346 // p is an ancestor of revs_visit, and is implicitly |
17a195676472
rust-ancestors: adjust branches and inline comments per previous change
Yuya Nishihara <yuya@tcha.org>
parents:
41133
diff
changeset
|
347 // in bases_visit, which means p is ::revs & ::bases. |
41131
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
348 // TODO optim: hence if bothvisit, we look up twice |
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
349 revs_visit.remove(&p); |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
350 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
|
351 both_visit.insert(p); |
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
352 } else { |
486908e691be
rust-ancestors: adjust indent level to make next change easier to follow
Yuya Nishihara <yuya@tcha.org>
parents:
41105
diff
changeset
|
353 // visit later |
41133
a1b3800c8a19
rust-ancestors: remove unreachable conditions from missing_ancestors()
Yuya Nishihara <yuya@tcha.org>
parents:
41132
diff
changeset
|
354 revs_visit.insert(p); |
40959
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 } |
41132
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
357 } else if bases_visit.contains(&curr) { |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
358 for p in self.graph.parents(curr)?.iter().cloned() { |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
359 if p == NULL_REVISION { |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
360 continue; |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
361 } |
41133
a1b3800c8a19
rust-ancestors: remove unreachable conditions from missing_ancestors()
Yuya Nishihara <yuya@tcha.org>
parents:
41132
diff
changeset
|
362 if revs_visit.contains(&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
|
363 // 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
|
364 // 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
|
365 // TODO optim: hence if bothvisit, we look up twice |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
366 revs_visit.remove(&p); |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
367 bases_visit.insert(p); |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
368 both_visit.insert(p); |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
369 } else { |
41133
a1b3800c8a19
rust-ancestors: remove unreachable conditions from missing_ancestors()
Yuya Nishihara <yuya@tcha.org>
parents:
41132
diff
changeset
|
370 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
|
371 } |
55dc1da8df2f
rust-ancestors: duplicate loop that visits parents of revs/bases
Yuya Nishihara <yuya@tcha.org>
parents:
41131
diff
changeset
|
372 } |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
373 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
374 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
375 missing.reverse(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
376 Ok(missing) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
377 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
378 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
379 |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
380 #[cfg(test)] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
381 mod tests { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
382 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
383 use super::*; |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
384 use std::iter::FromIterator; |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
385 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
386 #[derive(Clone, Debug)] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
387 struct Stub; |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
388 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
389 /// This is the same as the dict from test-ancestors.py |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
390 impl Graph for Stub { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
391 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
392 match rev { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
393 0 => Ok([-1, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
394 1 => Ok([0, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
395 2 => Ok([1, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
396 3 => Ok([1, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
397 4 => Ok([2, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
398 5 => Ok([4, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
399 6 => Ok([4, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
400 7 => Ok([4, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
401 8 => Ok([-1, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
402 9 => Ok([6, 7]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
403 10 => Ok([5, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
404 11 => Ok([3, 7]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
405 12 => Ok([9, -1]), |
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
406 13 => Ok([8, -1]), |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
407 r => Err(GraphError::ParentOutOfRange(r)), |
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 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
410 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
411 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
412 fn list_ancestors<G: Graph>( |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
413 graph: G, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
414 initrevs: Vec<Revision>, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
415 stoprev: Revision, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
416 inclusive: bool, |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
417 ) -> Vec<Revision> { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
418 AncestorsIterator::new(graph, initrevs, stoprev, inclusive) |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
419 .unwrap() |
40929
43ca24b772d6
rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents:
40927
diff
changeset
|
420 .map(|res| res.unwrap()) |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
421 .collect() |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
422 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
423 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
424 #[test] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
425 /// Same tests as test-ancestor.py, without membership |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
426 /// (see also test-ancestor.py.out) |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
427 fn test_list_ancestor() { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
428 assert_eq!(list_ancestors(Stub, vec![], 0, false), vec![]); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
429 assert_eq!( |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
430 list_ancestors(Stub, vec![11, 13], 0, false), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
431 vec![8, 7, 4, 3, 2, 1, 0] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
432 ); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
433 assert_eq!(list_ancestors(Stub, vec![1, 3], 0, false), vec![1, 0]); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
434 assert_eq!( |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
435 list_ancestors(Stub, vec![11, 13], 0, true), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
436 vec![13, 11, 8, 7, 4, 3, 2, 1, 0] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
437 ); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
438 assert_eq!(list_ancestors(Stub, vec![11, 13], 6, false), vec![8, 7]); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
439 assert_eq!( |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
440 list_ancestors(Stub, vec![11, 13], 6, true), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
441 vec![13, 11, 8, 7] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
442 ); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
443 assert_eq!(list_ancestors(Stub, vec![11, 13], 11, true), vec![13, 11]); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
444 assert_eq!(list_ancestors(Stub, vec![11, 13], 12, true), vec![13]); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
445 assert_eq!( |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
446 list_ancestors(Stub, vec![10, 1], 0, true), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
447 vec![10, 5, 4, 2, 1, 0] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
448 ); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
449 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
450 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
451 #[test] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
452 /// 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
|
453 /// that happens quite often, as demonstrated by running the whole |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
454 /// suite. |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
455 /// For instance, run tests/test-obsolete-checkheads.t |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
456 fn test_nullrev_input() { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
457 let mut iter = |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
458 AncestorsIterator::new(Stub, vec![-1], 0, false).unwrap(); |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
459 assert_eq!(iter.next(), None) |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
460 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
461 |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
462 #[test] |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
463 fn test_contains() { |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
464 let mut lazy = |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
465 AncestorsIterator::new(Stub, vec![10, 1], 0, true).unwrap(); |
40929
43ca24b772d6
rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents:
40927
diff
changeset
|
466 assert!(lazy.contains(1).unwrap()); |
43ca24b772d6
rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents:
40927
diff
changeset
|
467 assert!(!lazy.contains(3).unwrap()); |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
468 |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
469 let mut lazy = |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
470 AncestorsIterator::new(Stub, vec![0], 0, false).unwrap(); |
40929
43ca24b772d6
rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents:
40927
diff
changeset
|
471 assert!(!lazy.contains(NULL_REVISION).unwrap()); |
40300
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
472 } |
72b94f946e90
rust: rustlazyancestors.__contains__
Georges Racinet <gracinet@anybox.fr>
parents:
40271
diff
changeset
|
473 |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
474 #[test] |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
475 fn test_peek() { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
476 let mut iter = |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
477 AncestorsIterator::new(Stub, vec![10], 0, true).unwrap(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
478 // peek() gives us the next value |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
479 assert_eq!(iter.peek(), Some(10)); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
480 // but it's not been consumed |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
481 assert_eq!(iter.next(), Some(Ok(10))); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
482 // and iteration resumes normally |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
483 assert_eq!(iter.next(), Some(Ok(5))); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
484 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
485 // 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
|
486 while iter.next().is_some() {} |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
487 assert_eq!(iter.peek(), None); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
488 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
489 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
490 #[test] |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
491 fn test_empty() { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
492 let mut iter = |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
493 AncestorsIterator::new(Stub, vec![10], 0, true).unwrap(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
494 assert!(!iter.is_empty()); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
495 while iter.next().is_some() {} |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
496 assert!(!iter.is_empty()); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
497 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
498 let iter = AncestorsIterator::new(Stub, vec![], 0, true).unwrap(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
499 assert!(iter.is_empty()); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
500 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
501 // case where iter.seen == {NULL_REVISION} |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
502 let iter = AncestorsIterator::new(Stub, vec![0], 0, false).unwrap(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
503 assert!(iter.is_empty()); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
504 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
505 |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
506 /// A corrupted Graph, supporting error handling tests |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
507 #[derive(Clone, Debug)] |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
508 struct Corrupted; |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
509 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
510 impl Graph for Corrupted { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
511 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
512 match rev { |
40933
18513d6ef7d4
rust: changed Graph.parents to return [Revision; 2]
Georges Racinet <gracinet@anybox.fr>
parents:
40932
diff
changeset
|
513 1 => Ok([0, -1]), |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
514 r => Err(GraphError::ParentOutOfRange(r)), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
515 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
516 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
517 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
518 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
519 #[test] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
520 fn test_initrev_out_of_range() { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
521 // inclusive=false looks up initrev's parents right away |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
522 match AncestorsIterator::new(Stub, vec![25], 0, false) { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
523 Ok(_) => panic!("Should have been ParentOutOfRange"), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
524 Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25)), |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
525 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
526 } |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
527 |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
528 #[test] |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
529 fn test_next_out_of_range() { |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
530 // inclusive=false looks up initrev's parents right away |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
531 let mut iter = |
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
532 AncestorsIterator::new(Corrupted, vec![1], 0, false).unwrap(); |
40929
43ca24b772d6
rust: adapted hg-core tests for iteration over Result
Georges Racinet <gracinet@anybox.fr>
parents:
40927
diff
changeset
|
533 assert_eq!(iter.next(), Some(Err(GraphError::ParentOutOfRange(0)))); |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
534 } |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
535 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
536 #[test] |
41054
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
537 fn test_lazy_iter_contains() { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
538 let mut lazy = |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
539 LazyAncestors::new(Stub, vec![11, 13], 0, false).unwrap(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
540 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
541 let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
542 // compare with iterator tests on the same initial revisions |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
543 assert_eq!(revs, vec![8, 7, 4, 3, 2, 1, 0]); |
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 // contains() results are correct, unaffected by the fact that |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
546 // we consumed entirely an iterator out of lazy |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
547 assert_eq!(lazy.contains(2), Ok(true)); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
548 assert_eq!(lazy.contains(9), Ok(false)); |
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 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
551 #[test] |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
552 fn test_lazy_contains_iter() { |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
553 let mut lazy = |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
554 LazyAncestors::new(Stub, vec![11, 13], 0, false).unwrap(); // reminder: [8, 7, 4, 3, 2, 1, 0] |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
555 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
556 assert_eq!(lazy.contains(2), Ok(true)); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
557 assert_eq!(lazy.contains(6), Ok(false)); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
558 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
559 // after consumption of 2 by the inner iterator, results stay |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
560 // consistent |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
561 assert_eq!(lazy.contains(2), Ok(true)); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
562 assert_eq!(lazy.contains(5), Ok(false)); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
563 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
564 // iter() still gives us a fresh iterator |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
565 let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
566 assert_eq!(revs, vec![8, 7, 4, 3, 2, 1, 0]); |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
567 } |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
568 |
ef54bd33b476
rust: core implementation for lazyancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40959
diff
changeset
|
569 #[test] |
40959
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
570 /// Test constructor, add/get bases |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
571 fn test_missing_bases() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
572 let mut missing_ancestors = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
573 MissingAncestors::new(Stub, [5, 3, 1, 3].iter().cloned()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
574 let mut as_vec: Vec<Revision> = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
575 missing_ancestors.get_bases().iter().cloned().collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
576 as_vec.sort(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
577 assert_eq!(as_vec, [1, 3, 5]); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
578 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
579 missing_ancestors.add_bases([3, 7, 8].iter().cloned()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
580 as_vec = missing_ancestors.get_bases().iter().cloned().collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
581 as_vec.sort(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
582 assert_eq!(as_vec, [1, 3, 5, 7, 8]); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
583 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
584 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
585 fn assert_missing_remove( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
586 bases: &[Revision], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
587 revs: &[Revision], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
588 expected: &[Revision], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
589 ) { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
590 let mut missing_ancestors = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
591 MissingAncestors::new(Stub, bases.iter().cloned()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
592 let mut revset: HashSet<Revision> = revs.iter().cloned().collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
593 missing_ancestors |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
594 .remove_ancestors_from(&mut revset) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
595 .unwrap(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
596 let mut as_vec: Vec<Revision> = revset.into_iter().collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
597 as_vec.sort(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
598 assert_eq!(as_vec.as_slice(), expected); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
599 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
600 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
601 #[test] |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
602 fn test_missing_remove() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
603 assert_missing_remove( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
604 &[1, 2, 3, 4, 7], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
605 Vec::from_iter(1..10).as_slice(), |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
606 &[5, 6, 8, 9], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
607 ); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
608 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
|
609 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
|
610 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
611 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
612 fn assert_missing_ancestors( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
613 bases: &[Revision], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
614 revs: &[Revision], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
615 expected: &[Revision], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
616 ) { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
617 let mut missing_ancestors = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
618 MissingAncestors::new(Stub, bases.iter().cloned()); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
619 let missing = missing_ancestors |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
620 .missing_ancestors(revs.iter().cloned()) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
621 .unwrap(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
622 assert_eq!(missing.as_slice(), expected); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
623 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
624 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
625 #[test] |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
626 fn test_missing_ancestors() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
627 // examples taken from test-ancestors.py by having it run |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
628 // on the same graph (both naive and fast Python algs) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
629 assert_missing_ancestors(&[10], &[11], &[3, 7, 11]); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
630 assert_missing_ancestors(&[11], &[10], &[5, 10]); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
631 assert_missing_ancestors(&[7], &[9, 11], &[3, 6, 9, 11]); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
632 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
633 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
634 // A Graph represented by a vector whose indices are revisions |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
635 // and values are parents of the revisions |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
636 type VecGraph = Vec<[Revision; 2]>; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
637 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
638 impl Graph for VecGraph { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
639 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
640 Ok(self[rev as usize]) |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
641 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
642 } |
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 /// An interesting case found by a random generator similar to |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
645 /// 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
|
646 /// 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
|
647 /// catched it. |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
648 #[test] |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
649 fn test_remove_ancestors_from_case1() { |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
650 let graph: VecGraph = vec![ |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
651 [NULL_REVISION, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
652 [0, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
653 [1, 0], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
654 [2, 1], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
655 [3, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
656 [4, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
657 [5, 1], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
658 [2, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
659 [7, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
660 [8, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
661 [9, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
662 [10, 1], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
663 [3, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
664 [12, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
665 [13, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
666 [14, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
667 [4, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
668 [16, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
669 [17, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
670 [18, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
671 [19, 11], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
672 [20, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
673 [21, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
674 [22, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
675 [23, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
676 [2, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
677 [3, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
678 [26, 24], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
679 [27, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
680 [28, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
681 [12, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
682 [1, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
683 [1, 9], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
684 [32, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
685 [33, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
686 [34, 31], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
687 [35, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
688 [36, 26], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
689 [37, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
690 [38, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
691 [39, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
692 [40, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
693 [41, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
694 [42, 26], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
695 [0, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
696 [44, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
697 [45, 4], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
698 [40, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
699 [47, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
700 [36, 0], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
701 [49, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
702 [NULL_REVISION, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
703 [51, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
704 [52, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
705 [53, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
706 [14, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
707 [55, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
708 [15, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
709 [23, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
710 [58, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
711 [59, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
712 [2, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
713 [61, 59], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
714 [62, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
715 [63, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
716 [NULL_REVISION, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
717 [65, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
718 [66, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
719 [67, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
720 [68, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
721 [37, 28], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
722 [69, 25], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
723 [71, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
724 [72, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
725 [50, 2], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
726 [74, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
727 [12, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
728 [18, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
729 [77, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
730 [78, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
731 [79, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
732 [43, 33], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
733 [81, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
734 [82, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
735 [83, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
736 [84, 45], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
737 [85, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
738 [86, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
739 [NULL_REVISION, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
740 [88, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
741 [NULL_REVISION, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
742 [76, 83], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
743 [44, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
744 [92, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
745 [93, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
746 [9, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
747 [95, 67], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
748 [96, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
749 [97, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
750 [NULL_REVISION, NULL_REVISION], |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
751 ]; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
752 let problem_rev = 28 as Revision; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
753 let problem_base = 70 as Revision; |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
754 // 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
|
755 assert_eq!(graph.parents(problem_base).unwrap()[1], problem_rev); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
756 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
757 let mut missing_ancestors: MissingAncestors<VecGraph> = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
758 MissingAncestors::new( |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
759 graph, |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
760 [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
|
761 .iter() |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
762 .cloned(), |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
763 ); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
764 assert!(missing_ancestors.bases.contains(&problem_base)); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
765 |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
766 let mut revs: HashSet<Revision> = |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
767 [4, 12, 41, 28, 68, 38, 1, 30, 56, 44] |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
768 .iter() |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
769 .cloned() |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
770 .collect(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
771 missing_ancestors.remove_ancestors_from(&mut revs).unwrap(); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
772 assert!(!revs.contains(&problem_rev)); |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
773 } |
d097dd0afc19
rust: translation of missingancestors
Georges Racinet <gracinet@anybox.fr>
parents:
40933
diff
changeset
|
774 |
40271
dbc28c91f7ff
rust: pure Rust lazyancestors iterator
Georges Racinet <gracinet@anybox.fr>
parents:
diff
changeset
|
775 } |