Mercurial > public > mercurial-scm > hg
comparison rust/hg-cpython/src/revlog.rs @ 51394:b01e7d97e167
revlog: add a Rust implementation of `headrevsdiff`
Python implementation of `headrevsdiff` can be very slow in the worst
case compared with the `heads` computation it replaces, since the
latter is done in Rust.
Even the average case of this Python implementation is still
noticeable in the profiles.
This patch makes the computation much much faster by doing it in Rust.
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Mon, 12 Feb 2024 20:01:27 +0000 |
parents | 5b4995b40db0 |
children | f8bf1a8e9181 |
comparison
equal
deleted
inserted
replaced
51393:3f37d80d3ab4 | 51394:b01e7d97e167 |
---|---|
310 } | 310 } |
311 | 311 |
312 /// get head nodeids | 312 /// get head nodeids |
313 def head_node_ids(&self) -> PyResult<PyObject> { | 313 def head_node_ids(&self) -> PyResult<PyObject> { |
314 let rust_res = self.inner_head_node_ids(py)?; | 314 let rust_res = self.inner_head_node_ids(py)?; |
315 Ok(rust_res) | |
316 } | |
317 | |
318 /// get diff in head revisions | |
319 def headrevsdiff(&self, *args, **_kw) -> PyResult<PyObject> { | |
320 let rust_res = self.inner_headrevsdiff( | |
321 py, | |
322 &args.get_item(py, 0), | |
323 &args.get_item(py, 1))?; | |
315 Ok(rust_res) | 324 Ok(rust_res) |
316 } | 325 } |
317 | 326 |
318 /// get filtered head revisions | 327 /// get filtered head revisions |
319 def headrevsfiltered(&self, *args, **_kw) -> PyResult<PyObject> { | 328 def headrevsfiltered(&self, *args, **_kw) -> PyResult<PyObject> { |
825 .expect("head revs should be cached") | 834 .expect("head revs should be cached") |
826 .clone_ref(py) | 835 .clone_ref(py) |
827 .into_object()) | 836 .into_object()) |
828 } | 837 } |
829 | 838 |
839 fn check_revision( | |
840 index: &hg::index::Index, | |
841 rev: UncheckedRevision, | |
842 py: Python, | |
843 ) -> PyResult<Revision> { | |
844 index | |
845 .check_revision(rev) | |
846 .ok_or_else(|| rev_not_in_index(py, rev)) | |
847 } | |
848 | |
849 fn inner_headrevsdiff( | |
850 &self, | |
851 py: Python, | |
852 begin: &PyObject, | |
853 end: &PyObject, | |
854 ) -> PyResult<PyObject> { | |
855 let begin = begin.extract::<BaseRevision>(py)?; | |
856 let end = end.extract::<BaseRevision>(py)?; | |
857 let index = &mut *self.index(py).borrow_mut(); | |
858 let begin = | |
859 Self::check_revision(index, UncheckedRevision(begin - 1), py)?; | |
860 let end = Self::check_revision(index, UncheckedRevision(end - 1), py)?; | |
861 let (removed, added) = index | |
862 .head_revs_diff(begin, end) | |
863 .map_err(|e| graph_error(py, e))?; | |
864 let removed: Vec<_> = | |
865 removed.into_iter().map(PyRevision::from).collect(); | |
866 let added: Vec<_> = added.into_iter().map(PyRevision::from).collect(); | |
867 let res = (removed, added).to_py_object(py).into_object(); | |
868 Ok(res) | |
869 } | |
870 | |
830 fn inner_headrevsfiltered( | 871 fn inner_headrevsfiltered( |
831 &self, | 872 &self, |
832 py: Python, | 873 py: Python, |
833 filtered_revs: &PyObject, | 874 filtered_revs: &PyObject, |
834 ) -> PyResult<PyObject> { | 875 ) -> PyResult<PyObject> { |