diff rust/hg-cpython/src/revlog.rs @ 51404:f8bf1a8e9181

phases: keep internal state as rev-num instead of node-id Node-id are expensive to work with, dealing with revision is much simple and faster. The fact we still used node-id here shows how few effort have been put into making the phase logic fast. We tend to no longer use node-id internally for about ten years. This has a large impact of repository with many draft roots. For example this Mozilla-try copy have ? Million draft roots and `perf::unbundle` see a significant improvement. ### data-env-vars.name = mozilla-try-2023-03-22-zstd-sparse-revlog # benchmark.name = hg.perf.perf-unbundle # bin-env-vars.hg.flavor = no-rust # bin-env-vars.hg.py-re2-module = default # benchmark.variants.issue6528 = disabled # benchmark.variants.revs = last-1 before:: 1.746791 seconds after:: 1.278379 seconds (-26.82%) # benchmark.variants.revs = last-10 before:: 3.145774 seconds after:: 2.103735 seconds (-33.13%) # benchmark.variants.revs = last-100 before:: 3.487635 seconds after:: 2.446749 seconds (-29.85%) # benchmark.variants.revs = last-1000 before:: 5.007568 seconds after:: 3.989923 seconds (-20.32%)
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 20 Feb 2024 21:40:13 +0100
parents b01e7d97e167
children 3099f1c68afd
line wrap: on
line diff
--- a/rust/hg-cpython/src/revlog.rs	Tue Feb 20 21:40:08 2024 +0100
+++ b/rust/hg-cpython/src/revlog.rs	Tue Feb 20 21:40:13 2024 +0100
@@ -970,31 +970,16 @@
         py_roots: PyDict,
     ) -> PyResult<PyObject> {
         let index = &*self.index(py).borrow();
-        let opt = self.get_nodetree(py)?.borrow();
-        let nt = opt.as_ref().unwrap();
         let roots: Result<HashMap<Phase, Vec<Revision>>, PyErr> = py_roots
             .items_list(py)
             .iter(py)
             .map(|r| {
                 let phase = r.get_item(py, 0)?;
-                let nodes = r.get_item(py, 1)?;
-                // Transform the nodes from Python to revs here since we
-                // have access to the nodemap
-                let revs: Result<_, _> = nodes
-                    .iter(py)?
-                    .map(|node| match node?.extract::<PyBytes>(py) {
-                        Ok(py_bytes) => {
-                            let node = node_from_py_bytes(py, &py_bytes)?;
-                            nt.find_bin(index, node.into())
-                                .map_err(|e| nodemap_error(py, e))?
-                                .ok_or_else(|| revlog_error(py))
-                        }
-                        Err(e) => Err(e),
-                    })
-                    .collect();
+                let revs: Vec<_> =
+                    rev_pyiter_collect(py, &r.get_item(py, 1)?, index)?;
                 let phase = Phase::try_from(phase.extract::<usize>(py)?)
                     .map_err(|_| revlog_error(py));
-                Ok((phase?, revs?))
+                Ok((phase?, revs))
             })
             .collect();
         let (len, phase_maps) = index