Show More
@@ -1036,14 +1036,40 b' impl Index {' | |||||
1036 |
|
1036 | |||
1037 | /// Given a (possibly overlapping) set of revs, return all the |
|
1037 | /// Given a (possibly overlapping) set of revs, return all the | |
1038 | /// common ancestors heads: `heads(::args[0] and ::a[1] and ...)` |
|
1038 | /// common ancestors heads: `heads(::args[0] and ::a[1] and ...)` | |
1039 |
pub fn common_ancestor_heads( |
|
1039 | pub fn common_ancestor_heads( | |
1040 | todo!() |
|
1040 | &self, | |
|
1041 | revisions: &[Revision], | |||
|
1042 | ) -> Result<Vec<Revision>, GraphError> { | |||
|
1043 | // given that revisions is expected to be small, we find this shortcut | |||
|
1044 | // potentially acceptable, especially given that `hg-cpython` could | |||
|
1045 | // very much bypass this, constructing a vector of unique values from | |||
|
1046 | // the onset. | |||
|
1047 | let as_set: HashSet<Revision> = revisions.iter().copied().collect(); | |||
|
1048 | // Besides deduplicating, the C version also implements the shortcut | |||
|
1049 | // for `NULL_REVISION`: | |||
|
1050 | if as_set.contains(&NULL_REVISION) { | |||
|
1051 | return Ok(vec![]); | |||
|
1052 | } | |||
|
1053 | ||||
|
1054 | let revisions: Vec<Revision> = as_set.into_iter().collect(); | |||
|
1055 | ||||
|
1056 | if revisions.len() <= 63 { | |||
|
1057 | self.find_gca_candidates::<u64>(&revisions) | |||
|
1058 | } else { | |||
|
1059 | self.find_gca_candidates::<NonStaticPoisonableBitSet>(&revisions) | |||
|
1060 | } | |||
|
1061 | } | |||
|
1062 | ||||
|
1063 | pub fn ancestors( | |||
|
1064 | &self, | |||
|
1065 | revisions: &[Revision], | |||
|
1066 | ) -> Result<Vec<Revision>, GraphError> { | |||
|
1067 | self.find_deepest_revs(&self.common_ancestor_heads(revisions)?) | |||
1041 | } |
|
1068 | } | |
1042 |
|
1069 | |||
1043 | /// Given a disjoint set of revs, return all candidates for the |
|
1070 | /// Given a disjoint set of revs, return all candidates for the | |
1044 | /// greatest common ancestor. In revset notation, this is the set |
|
1071 | /// greatest common ancestor. In revset notation, this is the set | |
1045 | /// `heads(::a and ::b and ...)` |
|
1072 | /// `heads(::a and ::b and ...)` | |
1046 | #[allow(dead_code)] |
|
|||
1047 | fn find_gca_candidates<BS: PoisonableBitSet + Clone>( |
|
1073 | fn find_gca_candidates<BS: PoisonableBitSet + Clone>( | |
1048 | &self, |
|
1074 | &self, | |
1049 | revs: &[Revision], |
|
1075 | revs: &[Revision], | |
@@ -1147,7 +1173,6 b' impl Index {' | |||||
1147 |
|
1173 | |||
1148 | /// Given a disjoint set of revs, return the subset with the longest path |
|
1174 | /// Given a disjoint set of revs, return the subset with the longest path | |
1149 | /// to the root. |
|
1175 | /// to the root. | |
1150 | #[allow(dead_code)] |
|
|||
1151 | fn find_deepest_revs( |
|
1176 | fn find_deepest_revs( | |
1152 | &self, |
|
1177 | &self, | |
1153 | revs: &[Revision], |
|
1178 | revs: &[Revision], |
@@ -196,12 +196,24 b' py_class!(pub class MixedIndex |py| {' | |||||
196 |
|
196 | |||
197 | /// return the gca set of the given revs |
|
197 | /// return the gca set of the given revs | |
198 | def ancestors(&self, *args, **kw) -> PyResult<PyObject> { |
|
198 | def ancestors(&self, *args, **kw) -> PyResult<PyObject> { | |
199 |
self. |
|
199 | let rust_res = self.inner_ancestors(py, args)?; | |
|
200 | ||||
|
201 | let c_res = self.call_cindex(py, "ancestors", args, kw)?; | |||
|
202 | // the algorithm should always provide the results in reverse ordering | |||
|
203 | assert_py_eq(py, "ancestors", &rust_res, &c_res)?; | |||
|
204 | ||||
|
205 | Ok(rust_res) | |||
200 | } |
|
206 | } | |
201 |
|
207 | |||
202 | /// return the heads of the common ancestors of the given revs |
|
208 | /// return the heads of the common ancestors of the given revs | |
203 | def commonancestorsheads(&self, *args, **kw) -> PyResult<PyObject> { |
|
209 | def commonancestorsheads(&self, *args, **kw) -> PyResult<PyObject> { | |
204 |
self. |
|
210 | let rust_res = self.inner_commonancestorsheads(py, args)?; | |
|
211 | ||||
|
212 | let c_res = self.call_cindex(py, "commonancestorsheads", args, kw)?; | |||
|
213 | // the algorithm should always provide the results in reverse ordering | |||
|
214 | assert_py_eq(py, "commonancestorsheads", &rust_res, &c_res)?; | |||
|
215 | ||||
|
216 | Ok(rust_res) | |||
205 | } |
|
217 | } | |
206 |
|
218 | |||
207 | /// Clear the index caches and inner py_class data. |
|
219 | /// Clear the index caches and inner py_class data. | |
@@ -850,6 +862,38 b' impl MixedIndex {' | |||||
850 | Ok(PyList::new(py, &as_vec).into_object()) |
|
862 | Ok(PyList::new(py, &as_vec).into_object()) | |
851 | } |
|
863 | } | |
852 |
|
864 | |||
|
865 | fn inner_ancestors( | |||
|
866 | &self, | |||
|
867 | py: Python, | |||
|
868 | py_revs: &PyTuple, | |||
|
869 | ) -> PyResult<PyObject> { | |||
|
870 | let index = &mut *self.index(py).borrow_mut(); | |||
|
871 | let revs: Vec<_> = rev_pyiter_collect(py, py_revs.as_object(), index)?; | |||
|
872 | let as_vec: Vec<_> = index | |||
|
873 | .ancestors(&revs) | |||
|
874 | .map_err(|e| graph_error(py, e))? | |||
|
875 | .iter() | |||
|
876 | .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) | |||
|
877 | .collect(); | |||
|
878 | Ok(PyList::new(py, &as_vec).into_object()) | |||
|
879 | } | |||
|
880 | ||||
|
881 | fn inner_commonancestorsheads( | |||
|
882 | &self, | |||
|
883 | py: Python, | |||
|
884 | py_revs: &PyTuple, | |||
|
885 | ) -> PyResult<PyObject> { | |||
|
886 | let index = &mut *self.index(py).borrow_mut(); | |||
|
887 | let revs: Vec<_> = rev_pyiter_collect(py, py_revs.as_object(), index)?; | |||
|
888 | let as_vec: Vec<_> = index | |||
|
889 | .common_ancestor_heads(&revs) | |||
|
890 | .map_err(|e| graph_error(py, e))? | |||
|
891 | .iter() | |||
|
892 | .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) | |||
|
893 | .collect(); | |||
|
894 | Ok(PyList::new(py, &as_vec).into_object()) | |||
|
895 | } | |||
|
896 | ||||
853 | fn inner_computephasesmapsets( |
|
897 | fn inner_computephasesmapsets( | |
854 | &self, |
|
898 | &self, | |
855 | py: Python, |
|
899 | py: Python, |
General Comments 0
You need to be logged in to leave comments.
Login now