##// END OF EJS Templates
rust-index: using `hg::index::Index` in discovery...
Georges Racinet -
r52138:0b81440e default
parent child Browse files
Show More
@@ -14,11 +14,12 b''
14 14
15 15 use crate::PyRevision;
16 16 use crate::{
17 cindex::Index, conversion::rev_pyiter_collect, exceptions::GraphError,
17 conversion::rev_pyiter_collect, exceptions::GraphError,
18 revlog::PySharedIndex,
18 19 };
19 20 use cpython::{
20 21 ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple,
21 Python, PythonObject, ToPyObject,
22 Python, PythonObject, ToPyObject, UnsafePyLeaked,
22 23 };
23 24 use hg::discovery::PartialDiscovery as CorePartialDiscovery;
24 25 use hg::Revision;
@@ -26,11 +27,11 b' use std::collections::HashSet;'
26 27
27 28 use std::cell::RefCell;
28 29
29 use crate::revlog::pyindex_to_graph;
30 use crate::revlog::py_rust_index_to_graph;
30 31
31 32 py_class!(pub class PartialDiscovery |py| {
32 data inner: RefCell<Box<CorePartialDiscovery<Index>>>;
33 data index: RefCell<Index>;
33 data inner: RefCell<UnsafePyLeaked<CorePartialDiscovery<PySharedIndex>>>;
34 data index: RefCell<UnsafePyLeaked<PySharedIndex>>;
34 35
35 36 // `_respectsize` is currently only here to replicate the Python API and
36 37 // will be used in future patches inside methods that are yet to be
@@ -58,15 +59,21 b' py_class!(pub class PartialDiscovery |py'
58 59 }
59 60
60 61 def hasinfo(&self) -> PyResult<bool> {
61 Ok(self.inner(py).borrow().has_info())
62 let leaked = self.inner(py).borrow();
63 let inner = unsafe { leaked.try_borrow(py)? };
64 Ok(inner.has_info())
62 65 }
63 66
64 67 def iscomplete(&self) -> PyResult<bool> {
65 Ok(self.inner(py).borrow().is_complete())
68 let leaked = self.inner(py).borrow();
69 let inner = unsafe { leaked.try_borrow(py)? };
70 Ok(inner.is_complete())
66 71 }
67 72
68 73 def stats(&self) -> PyResult<PyDict> {
69 let stats = self.inner(py).borrow().stats();
74 let leaked = self.inner(py).borrow();
75 let inner = unsafe { leaked.try_borrow(py)? };
76 let stats = inner.stats();
70 77 let as_dict: PyDict = PyDict::new(py);
71 78 as_dict.set_item(py, "undecided",
72 79 stats.undecided.map(
@@ -76,7 +83,9 b' py_class!(pub class PartialDiscovery |py'
76 83 }
77 84
78 85 def commonheads(&self) -> PyResult<HashSet<PyRevision>> {
79 let res = self.inner(py).borrow().common_heads()
86 let leaked = self.inner(py).borrow();
87 let inner = unsafe { leaked.try_borrow(py)? };
88 let res = inner.common_heads()
80 89 .map_err(|e| GraphError::pynew(py, e))?;
81 90 Ok(res.into_iter().map(Into::into).collect())
82 91 }
@@ -102,17 +111,27 b' impl PartialDiscovery {'
102 111 randomize: bool,
103 112 ) -> PyResult<Self> {
104 113 let index = repo.getattr(py, "changelog")?.getattr(py, "index")?;
105 let index = pyindex_to_graph(py, index)?;
106 let target_heads = rev_pyiter_collect(py, &targetheads, &index)?;
114 let cloned_index = py_rust_index_to_graph(py, index.clone_ref(py))?;
115 let index = py_rust_index_to_graph(py, index)?;
116
117 let target_heads = {
118 let borrowed_idx = unsafe { index.try_borrow(py)? };
119 rev_pyiter_collect(py, &targetheads, &*borrowed_idx)?
120 };
121 let lazy_disco = unsafe {
122 index.map(py, |idx| {
123 CorePartialDiscovery::new(
124 idx,
125 target_heads,
126 respectsize,
127 randomize,
128 )
129 })
130 };
107 131 Self::create_instance(
108 132 py,
109 RefCell::new(Box::new(CorePartialDiscovery::new(
110 index.clone_ref(py),
111 target_heads,
112 respectsize,
113 randomize,
114 ))),
115 RefCell::new(index),
133 RefCell::new(lazy_disco),
134 RefCell::new(cloned_index),
116 135 )
117 136 }
118 137
@@ -122,7 +141,8 b' impl PartialDiscovery {'
122 141 py: Python,
123 142 iter: &PyObject,
124 143 ) -> PyResult<Vec<Revision>> {
125 let index = self.index(py).borrow();
144 let leaked = self.index(py).borrow();
145 let index = unsafe { leaked.try_borrow(py)? };
126 146 rev_pyiter_collect(py, iter, &*index)
127 147 }
128 148
@@ -147,7 +167,8 b' impl PartialDiscovery {'
147 167 missing.push(rev);
148 168 }
149 169 }
150 let mut inner = self.inner(py).borrow_mut();
170 let mut leaked = self.inner(py).borrow_mut();
171 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
151 172 inner
152 173 .add_common_revisions(common)
153 174 .map_err(|e| GraphError::pynew(py, e))?;
@@ -163,7 +184,8 b' impl PartialDiscovery {'
163 184 commons: PyObject,
164 185 ) -> PyResult<PyObject> {
165 186 let commons_vec = self.pyiter_to_vec(py, &commons)?;
166 let mut inner = self.inner(py).borrow_mut();
187 let mut leaked = self.inner(py).borrow_mut();
188 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
167 189 inner
168 190 .add_common_revisions(commons_vec)
169 191 .map_err(|e| GraphError::pynew(py, e))?;
@@ -176,7 +198,8 b' impl PartialDiscovery {'
176 198 missings: PyObject,
177 199 ) -> PyResult<PyObject> {
178 200 let missings_vec = self.pyiter_to_vec(py, &missings)?;
179 let mut inner = self.inner(py).borrow_mut();
201 let mut leaked = self.inner(py).borrow_mut();
202 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
180 203 inner
181 204 .add_missing_revisions(missings_vec)
182 205 .map_err(|e| GraphError::pynew(py, e))?;
@@ -189,7 +212,8 b' impl PartialDiscovery {'
189 212 _headrevs: PyObject,
190 213 size: usize,
191 214 ) -> PyResult<PyObject> {
192 let mut inner = self.inner(py).borrow_mut();
215 let mut leaked = self.inner(py).borrow_mut();
216 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
193 217 let sample = inner
194 218 .take_full_sample(size)
195 219 .map_err(|e| GraphError::pynew(py, e))?;
@@ -207,7 +231,8 b' impl PartialDiscovery {'
207 231 size: usize,
208 232 ) -> PyResult<PyObject> {
209 233 let revsvec = self.pyiter_to_vec(py, &headrevs)?;
210 let mut inner = self.inner(py).borrow_mut();
234 let mut leaked = self.inner(py).borrow_mut();
235 let mut inner = unsafe { leaked.try_borrow_mut(py)? };
211 236 let sample = inner
212 237 .take_quick_sample(revsvec, size)
213 238 .map_err(|e| GraphError::pynew(py, e))?;
@@ -31,17 +31,6 b' use hg::{'
31 31 use std::{cell::RefCell, collections::HashMap};
32 32 use vcsgraph::graph::Graph as VCSGraph;
33 33
34 /// Return a Struct implementing the Graph trait
35 pub(crate) fn pyindex_to_graph(
36 py: Python,
37 index: PyObject,
38 ) -> PyResult<cindex::Index> {
39 match index.extract::<MixedIndex>(py) {
40 Ok(midx) => Ok(midx.clone_cindex(py)),
41 Err(_) => cindex::Index::new(py, index),
42 }
43 }
44
45 34 pub struct PySharedIndex {
46 35 /// The underlying hg-core index
47 36 pub(crate) inner: &'static hg::index::Index,
@@ -1,6 +1,7 b''
1 1 import unittest
2 2
3 3 from mercurial import policy
4 from mercurial.testing import revlog as revlogtesting
4 5
5 6 PartialDiscovery = policy.importrust('discovery', member='PartialDiscovery')
6 7
@@ -47,7 +48,7 b' class fakerepo:'
47 48 "rustext or the C Extension parsers module "
48 49 "discovery relies on is not available",
49 50 )
50 class rustdiscoverytest(unittest.TestCase):
51 class rustdiscoverytest(revlogtesting.RustRevlogBasedTestBase):
51 52 """Test the correctness of binding to Rust code.
52 53
53 54 This test is merely for the binding to Rust itself: extraction of
@@ -60,7 +61,7 b' class rustdiscoverytest(unittest.TestCas'
60 61 """
61 62
62 63 def parseindex(self):
63 return cparsers.parse_index2(data_non_inlined, False)[0]
64 return self.parserustindex(data=data_non_inlined)
64 65
65 66 def repo(self):
66 67 return fakerepo(self.parseindex())
General Comments 0
You need to be logged in to leave comments. Login now