diff rust/hg-cpython/src/parsers.rs @ 45377:27424779c5b8

hg-core: make parse_dirstate return references rather than update hashmaps Returing a vec is faster than updating a hashmap when the hashmap is not needed like in `hg files` which just list tracked files. Returning references avoid copying data when not needed improving performence for large repositories. Differential Revision: https://phab.mercurial-scm.org/D8861
author Antoine Cezar <antoine.cezar@octobus.net>
date Tue, 04 Aug 2020 10:59:43 +0200
parents 26114bd6ec60
children 496537c9c1b4
line wrap: on
line diff
--- a/rust/hg-cpython/src/parsers.rs	Fri Aug 07 18:01:48 2020 +0530
+++ b/rust/hg-cpython/src/parsers.rs	Tue Aug 04 10:59:43 2020 +0200
@@ -14,7 +14,7 @@
     PythonObject, ToPyObject,
 };
 use hg::{
-    pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf,
+    pack_dirstate, parse_dirstate, utils::hg_path::HgPathBuf, DirstateEntry,
     DirstatePackError, DirstateParents, DirstateParseError, FastHashMap,
     PARENT_SIZE,
 };
@@ -29,11 +29,17 @@
     copymap: PyDict,
     st: PyBytes,
 ) -> PyResult<PyTuple> {
-    let mut dirstate_map = FastHashMap::default();
-    let mut copies = FastHashMap::default();
+    match parse_dirstate(st.data(py)) {
+        Ok((parents, entries, copies)) => {
+            let dirstate_map: FastHashMap<HgPathBuf, DirstateEntry> = entries
+                .into_iter()
+                .map(|(path, entry)| (path.to_owned(), entry))
+                .collect();
+            let copy_map: FastHashMap<HgPathBuf, HgPathBuf> = copies
+                .into_iter()
+                .map(|(path, copy)| (path.to_owned(), copy.to_owned()))
+                .collect();
 
-    match parse_dirstate(&mut dirstate_map, &mut copies, st.data(py)) {
-        Ok(parents) => {
             for (filename, entry) in &dirstate_map {
                 dmap.set_item(
                     py,
@@ -41,7 +47,7 @@
                     make_dirstate_tuple(py, entry)?,
                 )?;
             }
-            for (path, copy_path) in copies {
+            for (path, copy_path) in copy_map {
                 copymap.set_item(
                     py,
                     PyBytes::new(py, path.as_bytes()),