Show More
@@ -13,7 +13,7 b'' | |||||
13 | //! - Similarly *relative roots* of a collection of `Revision`, we mean those |
|
13 | //! - Similarly *relative roots* of a collection of `Revision`, we mean those | |
14 | //! whose parents, if any, don't belong to the collection. |
|
14 | //! whose parents, if any, don't belong to the collection. | |
15 | use super::{Graph, GraphError, Revision, NULL_REVISION}; |
|
15 | use super::{Graph, GraphError, Revision, NULL_REVISION}; | |
16 | use crate::ancestors::AncestorsIterator; |
|
16 | use crate::{ancestors::AncestorsIterator, BaseRevision}; | |
17 | use std::collections::{BTreeSet, HashSet}; |
|
17 | use std::collections::{BTreeSet, HashSet}; | |
18 |
|
18 | |||
19 | fn remove_parents<S: std::hash::BuildHasher>( |
|
19 | fn remove_parents<S: std::hash::BuildHasher>( | |
@@ -81,6 +81,32 b' pub fn retain_heads<S: std::hash::BuildH' | |||||
81 | Ok(()) |
|
81 | Ok(()) | |
82 | } |
|
82 | } | |
83 |
|
83 | |||
|
84 | /// Optimized version of `retain_heads` that expects an zeroed array of the size | |||
|
85 | /// of the graph, to act as a faster but less space-efficient `HashSet`. | |||
|
86 | /// | |||
|
87 | /// # Panics | |||
|
88 | /// | |||
|
89 | /// Can panic if `not_heads` is shorten than the length of graph. | |||
|
90 | pub fn retain_heads_fast( | |||
|
91 | graph: &impl Graph, | |||
|
92 | not_heads: &mut [bool], | |||
|
93 | filtered_revs: &HashSet<Revision>, | |||
|
94 | ) -> Result<(), GraphError> { | |||
|
95 | for idx in (0..not_heads.len()).rev() { | |||
|
96 | let rev = Revision(idx as BaseRevision); | |||
|
97 | if !not_heads[idx] && filtered_revs.contains(&rev) { | |||
|
98 | not_heads[idx] = true; | |||
|
99 | continue; | |||
|
100 | } | |||
|
101 | for parent in graph.parents(rev)?.iter() { | |||
|
102 | if *parent != NULL_REVISION { | |||
|
103 | not_heads[parent.0 as usize] = true; | |||
|
104 | } | |||
|
105 | } | |||
|
106 | } | |||
|
107 | Ok(()) | |||
|
108 | } | |||
|
109 | ||||
84 | /// Roots of `revs`, passed as a `HashSet` |
|
110 | /// Roots of `revs`, passed as a `HashSet` | |
85 | /// |
|
111 | /// | |
86 | /// They are returned in arbitrary order |
|
112 | /// They are returned in arbitrary order |
@@ -1,4 +1,3 b'' | |||||
1 | use std::collections::hash_map::RandomState; |
|
|||
2 |
|
|
1 | use std::collections::{HashMap, HashSet}; | |
3 | use std::fmt::Debug; |
|
2 | use std::fmt::Debug; | |
4 | use std::ops::Deref; |
|
3 | use std::ops::Deref; | |
@@ -565,32 +564,24 b' impl Index {' | |||||
565 | return Ok(self_head_revs.to_owned()); |
|
564 | return Ok(self_head_revs.to_owned()); | |
566 | } |
|
565 | } | |
567 | } |
|
566 | } | |
568 | let mut revs: HashSet<Revision, RandomState> = |
|
567 | ||
569 |
|
|
568 | let as_vec = if self.is_empty() { | |
570 | (0..self.len()) |
|
569 | vec![NULL_REVISION] | |
571 | .into_iter() |
|
570 | } else { | |
572 | .map(|i| Revision(i as BaseRevision)) |
|
571 | let mut not_heads = vec![false; self.len()]; | |
573 | .collect() |
|
572 | dagops::retain_heads_fast(self, &mut not_heads, filtered_revs)?; | |
574 |
|
|
573 | not_heads | |
575 |
|
|
574 | .into_iter() | |
576 |
|
|
575 | .enumerate() | |
577 |
|
|
576 | .filter_map(|(idx, is_not_head)| { | |
578 | let r = Revision(i as BaseRevision); |
|
577 | if is_not_head { | |
579 |
|
|
578 | None | |
580 |
|
|
579 | } else { | |
581 | } else { |
|
580 | Some(Revision(idx as BaseRevision)) | |
582 |
|
|
581 | } | |
583 |
|
|
582 | }) | |
584 |
|
|
583 | .collect() | |
585 | .collect() |
|
584 | }; | |
586 | }; |
|
|||
587 | dagops::retain_heads(self, &mut revs)?; |
|
|||
588 | if self.is_empty() { |
|
|||
589 | revs.insert(NULL_REVISION); |
|
|||
590 | } |
|
|||
591 | let mut as_vec: Vec<Revision> = |
|
|||
592 | revs.into_iter().map(Into::into).collect(); |
|
|||
593 | as_vec.sort_unstable(); |
|
|||
594 | *self |
|
585 | *self | |
595 | .head_revs |
|
586 | .head_revs | |
596 | .write() |
|
587 | .write() |
General Comments 0
You need to be logged in to leave comments.
Login now