Show More
@@ -14,11 +14,12 b'' | |||
|
14 | 14 | |
|
15 | 15 | use crate::PyRevision; |
|
16 | 16 | use crate::{ |
|
17 |
|
|
|
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< |
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
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 |
|
|
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( |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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( |
|
|
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 |
|
|
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