Mercurial > hg
comparison rust/hg-core/src/ancestors.rs @ 41246:619ee4039bd4
rust: MissingAncestors.basesheads()
This new API method on `MissingAncestors` leverages directly the
Rust implementation for relative heads of a set, and also
lowers the cost of returning the results to Python in the context of
discovery.
These interchange costs can probably be further reduced by implementing
the `partialdiscovery` class in Rust, but that will be investigated in the
5.0 development cycle.
Differential Revision: https://phab.mercurial-scm.org/D5584
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Mon, 14 Jan 2019 17:07:39 +0100 |
parents | 168041fa6d5f |
children | 70827ebba453 |
comparison
equal
deleted
inserted
replaced
41245:2a8782cc2e16 | 41246:619ee4039bd4 |
---|---|
8 //! Rust versions of generic DAG ancestors algorithms for Mercurial | 8 //! Rust versions of generic DAG ancestors algorithms for Mercurial |
9 | 9 |
10 use super::{Graph, GraphError, Revision, NULL_REVISION}; | 10 use super::{Graph, GraphError, Revision, NULL_REVISION}; |
11 use std::cmp::max; | 11 use std::cmp::max; |
12 use std::collections::{BinaryHeap, HashSet}; | 12 use std::collections::{BinaryHeap, HashSet}; |
13 use crate::dagops; | |
13 | 14 |
14 /// Iterator over the ancestors of a given list of revisions | 15 /// Iterator over the ancestors of a given list of revisions |
15 /// This is a generic type, defined and implemented for any Graph, so that | 16 /// This is a generic type, defined and implemented for any Graph, so that |
16 /// it's easy to | 17 /// it's easy to |
17 /// | 18 /// |
225 /// | 226 /// |
226 /// This is useful in unit tests, but also setdiscovery.py does | 227 /// This is useful in unit tests, but also setdiscovery.py does |
227 /// read the bases attribute of a ancestor.missingancestors instance. | 228 /// read the bases attribute of a ancestor.missingancestors instance. |
228 pub fn get_bases<'a>(&'a self) -> &'a HashSet<Revision> { | 229 pub fn get_bases<'a>(&'a self) -> &'a HashSet<Revision> { |
229 &self.bases | 230 &self.bases |
231 } | |
232 | |
233 /// Computes the relative heads of current bases. | |
234 /// | |
235 /// The object is still usable after this. | |
236 pub fn bases_heads(&self) -> Result<HashSet<Revision>, GraphError> { | |
237 dagops::heads(&self.graph, self.bases.iter()) | |
238 } | |
239 | |
240 /// Consumes the object and returns the relative heads of its bases. | |
241 pub fn into_bases_heads(mut self) -> Result<HashSet<Revision>, GraphError> { | |
242 dagops::retain_heads(&self.graph, &mut self.bases)?; | |
243 Ok(self.bases) | |
230 } | 244 } |
231 | 245 |
232 pub fn add_bases( | 246 pub fn add_bases( |
233 &mut self, | 247 &mut self, |
234 new_bases: impl IntoIterator<Item = Revision>, | 248 new_bases: impl IntoIterator<Item = Revision>, |
554 let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); | 568 let revs: Vec<Revision> = lazy.iter().map(|r| r.unwrap()).collect(); |
555 assert_eq!(revs, vec![8, 7, 4, 3, 2, 1, 0]); | 569 assert_eq!(revs, vec![8, 7, 4, 3, 2, 1, 0]); |
556 } | 570 } |
557 | 571 |
558 #[test] | 572 #[test] |
559 /// Test constructor, add/get bases | 573 /// Test constructor, add/get bases and heads |
560 fn test_missing_bases() { | 574 fn test_missing_bases() -> Result<(), GraphError> { |
561 let mut missing_ancestors = | 575 let mut missing_ancestors = |
562 MissingAncestors::new(SampleGraph, [5, 3, 1, 3].iter().cloned()); | 576 MissingAncestors::new(SampleGraph, [5, 3, 1, 3].iter().cloned()); |
563 let mut as_vec: Vec<Revision> = | 577 let mut as_vec: Vec<Revision> = |
564 missing_ancestors.get_bases().iter().cloned().collect(); | 578 missing_ancestors.get_bases().iter().cloned().collect(); |
565 as_vec.sort(); | 579 as_vec.sort(); |
567 | 581 |
568 missing_ancestors.add_bases([3, 7, 8].iter().cloned()); | 582 missing_ancestors.add_bases([3, 7, 8].iter().cloned()); |
569 as_vec = missing_ancestors.get_bases().iter().cloned().collect(); | 583 as_vec = missing_ancestors.get_bases().iter().cloned().collect(); |
570 as_vec.sort(); | 584 as_vec.sort(); |
571 assert_eq!(as_vec, [1, 3, 5, 7, 8]); | 585 assert_eq!(as_vec, [1, 3, 5, 7, 8]); |
586 | |
587 as_vec = missing_ancestors.bases_heads()?.iter().cloned().collect(); | |
588 as_vec.sort(); | |
589 assert_eq!(as_vec, [3, 5, 7, 8]); | |
590 Ok(()) | |
572 } | 591 } |
573 | 592 |
574 fn assert_missing_remove( | 593 fn assert_missing_remove( |
575 bases: &[Revision], | 594 bases: &[Revision], |
576 revs: &[Revision], | 595 revs: &[Revision], |