Mercurial > hg
changeset 51241:578c049f0408
rust-index: using `hg::index::Index` in `hg-cpython::dagops`
Hooking `headrevs` to the Rust index is straightforward as long as
we go the `PySharedRef` way. Direct attempts of obtaining a reference
to the inner `hg::index::Index` fail for lifetime reasons: the reference
is bound to the GIL, yet the `as_set` local variable is considered to
be static (the borrow checker clearly does not realize or care that this
set only stores `Revision` values).
In `rank()`, the chosen solution is the simplest as far as `hg-cpython` is
concerned, but it has the defect of removing an implementation
that would be easily adaptable if the core index did implement `RankedGraph`
(returning the same error as long as only `REVLOGV1` is supported), but that
would introduce a direct dependency of `hg-core` on the ``vcsgraph` crate.
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Sun, 29 Oct 2023 10:47:54 +0100 |
parents | 59d81768ad6d |
children | 2e2832e00f6c |
files | rust/hg-cpython/src/dagops.rs tests/test-rust-ancestor.py |
diffstat | 2 files changed, 21 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-cpython/src/dagops.rs Sat Oct 28 22:50:10 2023 +0200 +++ b/rust/hg-cpython/src/dagops.rs Sun Oct 29 10:47:54 2023 +0100 @@ -15,10 +15,9 @@ use hg::dagops; use hg::Revision; use std::collections::HashSet; -use vcsgraph::ancestors::node_rank; -use vcsgraph::graph::{Parents, Rank}; +use vcsgraph::graph::Rank; -use crate::revlog::pyindex_to_graph; +use crate::revlog::py_rust_index_to_graph; /// Using the the `index`, return heads out of any Python iterable of Revisions /// @@ -28,23 +27,33 @@ index: PyObject, revs: PyObject, ) -> PyResult<HashSet<PyRevision>> { - let index = pyindex_to_graph(py, index)?; - let mut as_set: HashSet<Revision> = rev_pyiter_collect(py, &revs, &index)?; - dagops::retain_heads(&index, &mut as_set) + let py_leaked = py_rust_index_to_graph(py, index)?; + let index = &*unsafe { py_leaked.try_borrow(py)? }; + let mut as_set: HashSet<Revision> = rev_pyiter_collect(py, &revs, index)?; + dagops::retain_heads(index, &mut as_set) .map_err(|e| GraphError::pynew(py, e))?; Ok(as_set.into_iter().map(Into::into).collect()) } /// Computes the rank, i.e. the number of ancestors including itself, /// of a node represented by its parents. +/// +/// Currently, the pure Rust index supports only the REVLOGV1 format, hence +/// the only possible return value is that the rank is unknown. +/// +/// References: +/// - C implementation, function `index_fast_rank()`. +/// - `impl vcsgraph::graph::RankedGraph for Index` in `crate::cindex`. pub fn rank( py: Python, - index: PyObject, - p1r: PyRevision, - p2r: PyRevision, + _index: PyObject, + _p1r: PyRevision, + _p2r: PyRevision, ) -> PyResult<Rank> { - node_rank(&pyindex_to_graph(py, index)?, &Parents([p1r.0, p2r.0])) - .map_err(|e| GraphError::pynew_from_vcsgraph(py, e)) + Err(GraphError::pynew_from_vcsgraph( + py, + vcsgraph::graph::GraphReadError::InconsistentGraphData, + )) } /// Create the module, with `__package__` given from parent
--- a/tests/test-rust-ancestor.py Sat Oct 28 22:50:10 2023 +0200 +++ b/tests/test-rust-ancestor.py Sun Oct 29 10:47:54 2023 +0100 @@ -157,7 +157,7 @@ self.assertEqual(exc.args, ('InvalidRevision', wdirrev)) def testheadrevs(self): - idx = self.parseindex() + idx = self.parserustindex() self.assertEqual(dagop.headrevs(idx, [1, 2, 3]), {3})