103 /// consistent and more efficient to filter them from the end caller. |
103 /// consistent and more efficient to filter them from the end caller. |
104 /// - we don't have the optimization for adjacent revs |
104 /// - we don't have the optimization for adjacent revs |
105 /// (case where p1 == rev-1), because it amounts to update the first element |
105 /// (case where p1 == rev-1), because it amounts to update the first element |
106 /// of the heap without sifting, which Rust's BinaryHeap doesn't let us do. |
106 /// of the heap without sifting, which Rust's BinaryHeap doesn't let us do. |
107 /// - we save a few pushes by comparing with `stoprev` before pushing |
107 /// - we save a few pushes by comparing with `stoprev` before pushing |
108 /// |
|
109 /// Error treatment: |
|
110 /// We swallow the possible GraphError of conditionally_push_parents() to |
|
111 /// respect the Iterator trait in a simple manner: never emitting parents |
|
112 /// for the returned revision. We finds this good enough for now, because: |
|
113 /// |
|
114 /// - there's a good chance that invalid revisionss are fed from the start, |
|
115 /// and `new()` doesn't swallow the error result. |
|
116 /// - this is probably what the Python implementation produces anyway, due |
|
117 /// to filtering at each step, and Python code is currently the only |
|
118 /// concrete caller we target, so we shouldn't need a finer error treatment |
|
119 /// for the time being. |
|
120 impl<G: Graph> Iterator for AncestorsIterator<G> { |
108 impl<G: Graph> Iterator for AncestorsIterator<G> { |
121 type Item = Result<Revision, GraphError>; |
109 type Item = Result<Revision, GraphError>; |
122 |
110 |
123 fn next(&mut self) -> Option<Self::Item> { |
111 fn next(&mut self) -> Option<Self::Item> { |
124 let current = match self.visit.peek() { |
112 let current = match self.visit.peek() { |