diff rust/hg-pyo3/src/revlog/mod.rs @ 52805:a8debfd85d55

rust-pyo3-revlog: _index_deltachain Again, we could let go of some copying.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Tue, 24 Dec 2024 00:25:49 +0100
parents 6c6cfb89a4f1
children 0a0ed46ef6d6
line wrap: on
line diff
--- a/rust/hg-pyo3/src/revlog/mod.rs	Mon Dec 23 23:51:29 2024 +0100
+++ b/rust/hg-pyo3/src/revlog/mod.rs	Tue Dec 24 00:25:49 2024 +0100
@@ -11,7 +11,9 @@
 use pyo3::conversion::IntoPyObject;
 use pyo3::exceptions::{PyIndexError, PyTypeError, PyValueError};
 use pyo3::prelude::*;
-use pyo3::types::{PyBytes, PyBytesMethods, PyDict, PyList, PySet, PyTuple};
+use pyo3::types::{
+    PyBool, PyBytes, PyBytesMethods, PyDict, PyList, PySet, PyTuple,
+};
 use pyo3_sharedref::{PyShareable, SharedByPyObject};
 
 use std::collections::HashSet;
@@ -566,6 +568,42 @@
         Ok(())
     }
 
+    /// determine revisions with deltas to reconstruct fulltext
+    #[pyo3(signature = (rev, stop_rev, using_general_delta))]
+    fn _index_deltachain(
+        slf: &Bound<'_, Self>,
+        py: Python<'_>,
+        rev: PyRevision,
+        stop_rev: Option<PyRevision>,
+        using_general_delta: Option<u32>,
+    ) -> PyResult<Py<PyTuple>> {
+        let using_general_delta = using_general_delta.map(|i| i != 0);
+        let rev: UncheckedRevision = rev.into();
+        let stop_rev: Option<UncheckedRevision> = stop_rev.map(Into::into);
+
+        let (chain, stopped) = Self::with_index_read(slf, |idx| {
+            let rev = idx.check_revision(rev).ok_or_else(|| {
+                nodemap_error(NodeMapError::RevisionNotInIndex(rev))
+            })?;
+            let stop_rev = stop_rev
+                .map(|r| {
+                    idx.check_revision(r).ok_or_else(|| {
+                        nodemap_error(NodeMapError::RevisionNotInIndex(
+                            rev.into(),
+                        ))
+                    })
+                })
+                .transpose()?;
+            idx.delta_chain(rev, stop_rev, using_general_delta)
+                .map_err(|e| PyValueError::new_err(e.to_string()))
+        })?;
+
+        let py_chain = revs_py_list(py, chain)?.into_any();
+        let py_stopped =
+            PyBool::new(py, stopped).to_owned().unbind().into_any();
+        Ok((py_chain, py_stopped).into_pyobject(py)?.unbind())
+    }
+
     fn _index___len__(slf: &Bound<'_, Self>) -> PyResult<usize> {
         Self::with_index_read(slf, |idx| Ok(idx.len()))
     }