Mercurial > public > mercurial-scm > hg
comparison rust/hg-cpython/src/revlog.rs @ 51222:89ce6a49bfeb
rust-index: implement common_ancestors_heads() and ancestors()
The only differences betwwen `common_ancestors_heads()` and
`find_gca_candidates()` seems to be that:
- the former accepts "overlapping" input revisions (meaning with duplicates).
- limitation to 24 inputs (in the C code), that we translate to using the
arbitrary size bit sets in the Rust code because we cannot bail to Python.
Given that the input is expected to be small in most cases, we take the
heavy handed approach of going through a HashSet and wait for perfomance
assessment
In case this is used via `hg-cpython`, we can anyway absorb the overhead
by having `commonancestorheads` build a vector of unique values
directly, and introduce a thin wrapper over `find_gca_candidates`, to take
care of bit set type dispatching only.
As far as `ancestors` is concerneed, this is just chaining
`common_ancestors_heads()` with `find_deepest_revs`.
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Wed, 18 Oct 2023 15:35:38 +0200 |
parents | fc05dd74e907 |
children | 1b23aaf5eb7b |
comparison
equal
deleted
inserted
replaced
51221:43241f31cf5b | 51222:89ce6a49bfeb |
---|---|
194 | 194 |
195 // index_methods (tp_methods). Same ordering as in revlog.c | 195 // index_methods (tp_methods). Same ordering as in revlog.c |
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.call_cindex(py, "ancestors", args, kw) | 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.call_cindex(py, "commonancestorsheads", args, kw) | 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. |
208 /// It is Python's responsibility to call `update_nodemap_data` again. | 220 /// It is Python's responsibility to call `update_nodemap_data` again. |
209 def clearcaches(&self, *args, **kw) -> PyResult<PyObject> { | 221 def clearcaches(&self, *args, **kw) -> PyResult<PyObject> { |
848 .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) | 860 .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) |
849 .collect(); | 861 .collect(); |
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, |
856 py_roots: PyDict, | 900 py_roots: PyDict, |
857 ) -> PyResult<PyObject> { | 901 ) -> PyResult<PyObject> { |