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> {