Show More
@@ -14,11 +14,12 b'' | |||||
14 |
|
14 | |||
15 | use crate::PyRevision; |
|
15 | use crate::PyRevision; | |
16 | use crate::{ |
|
16 | use crate::{ | |
17 |
|
|
17 | conversion::rev_pyiter_collect, exceptions::GraphError, | |
|
18 | revlog::PySharedIndex, | |||
18 | }; |
|
19 | }; | |
19 | use cpython::{ |
|
20 | use cpython::{ | |
20 | ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple, |
|
21 | ObjectProtocol, PyClone, PyDict, PyModule, PyObject, PyResult, PyTuple, | |
21 | Python, PythonObject, ToPyObject, |
|
22 | Python, PythonObject, ToPyObject, UnsafePyLeaked, | |
22 | }; |
|
23 | }; | |
23 | use hg::discovery::PartialDiscovery as CorePartialDiscovery; |
|
24 | use hg::discovery::PartialDiscovery as CorePartialDiscovery; | |
24 | use hg::Revision; |
|
25 | use hg::Revision; | |
@@ -26,11 +27,11 b' use std::collections::HashSet;' | |||||
26 |
|
27 | |||
27 | use std::cell::RefCell; |
|
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 | py_class!(pub class PartialDiscovery |py| { |
|
32 | py_class!(pub class PartialDiscovery |py| { | |
32 |
data inner: RefCell< |
|
33 | data inner: RefCell<UnsafePyLeaked<CorePartialDiscovery<PySharedIndex>>>; | |
33 | data index: RefCell<Index>; |
|
34 | data index: RefCell<UnsafePyLeaked<PySharedIndex>>; | |
34 |
|
35 | |||
35 | // `_respectsize` is currently only here to replicate the Python API and |
|
36 | // `_respectsize` is currently only here to replicate the Python API and | |
36 | // will be used in future patches inside methods that are yet to be |
|
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 | def hasinfo(&self) -> PyResult<bool> { |
|
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 | def iscomplete(&self) -> PyResult<bool> { |
|
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 | def stats(&self) -> PyResult<PyDict> { |
|
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 | let as_dict: PyDict = PyDict::new(py); |
|
77 | let as_dict: PyDict = PyDict::new(py); | |
71 | as_dict.set_item(py, "undecided", |
|
78 | as_dict.set_item(py, "undecided", | |
72 | stats.undecided.map( |
|
79 | stats.undecided.map( | |
@@ -76,7 +83,9 b' py_class!(pub class PartialDiscovery |py' | |||||
76 | } |
|
83 | } | |
77 |
|
84 | |||
78 | def commonheads(&self) -> PyResult<HashSet<PyRevision>> { |
|
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 | .map_err(|e| GraphError::pynew(py, e))?; |
|
89 | .map_err(|e| GraphError::pynew(py, e))?; | |
81 | Ok(res.into_iter().map(Into::into).collect()) |
|
90 | Ok(res.into_iter().map(Into::into).collect()) | |
82 | } |
|
91 | } | |
@@ -102,17 +111,27 b' impl PartialDiscovery {' | |||||
102 | randomize: bool, |
|
111 | randomize: bool, | |
103 | ) -> PyResult<Self> { |
|
112 | ) -> PyResult<Self> { | |
104 | let index = repo.getattr(py, "changelog")?.getattr(py, "index")?; |
|
113 | let index = repo.getattr(py, "changelog")?.getattr(py, "index")?; | |
105 | let index = pyindex_to_graph(py, index)?; |
|
114 | let cloned_index = py_rust_index_to_graph(py, index.clone_ref(py))?; | |
106 | let target_heads = rev_pyiter_collect(py, &targetheads, &index)?; |
|
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 | Self::create_instance( |
|
131 | Self::create_instance( | |
108 | py, |
|
132 | py, | |
109 |
RefCell::new( |
|
133 | RefCell::new(lazy_disco), | |
110 | index.clone_ref(py), |
|
134 | RefCell::new(cloned_index), | |
111 | target_heads, |
|
|||
112 | respectsize, |
|
|||
113 | randomize, |
|
|||
114 | ))), |
|
|||
115 | RefCell::new(index), |
|
|||
116 | ) |
|
135 | ) | |
117 | } |
|
136 | } | |
118 |
|
137 | |||
@@ -122,7 +141,8 b' impl PartialDiscovery {' | |||||
122 | py: Python, |
|
141 | py: Python, | |
123 | iter: &PyObject, |
|
142 | iter: &PyObject, | |
124 | ) -> PyResult<Vec<Revision>> { |
|
143 | ) -> PyResult<Vec<Revision>> { | |
125 |
let |
|
144 | let leaked = self.index(py).borrow(); | |
|
145 | let index = unsafe { leaked.try_borrow(py)? }; | |||
126 | rev_pyiter_collect(py, iter, &*index) |
|
146 | rev_pyiter_collect(py, iter, &*index) | |
127 | } |
|
147 | } | |
128 |
|
148 | |||
@@ -147,7 +167,8 b' impl PartialDiscovery {' | |||||
147 | missing.push(rev); |
|
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 | inner |
|
172 | inner | |
152 | .add_common_revisions(common) |
|
173 | .add_common_revisions(common) | |
153 | .map_err(|e| GraphError::pynew(py, e))?; |
|
174 | .map_err(|e| GraphError::pynew(py, e))?; | |
@@ -163,7 +184,8 b' impl PartialDiscovery {' | |||||
163 | commons: PyObject, |
|
184 | commons: PyObject, | |
164 | ) -> PyResult<PyObject> { |
|
185 | ) -> PyResult<PyObject> { | |
165 | let commons_vec = self.pyiter_to_vec(py, &commons)?; |
|
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 | inner |
|
189 | inner | |
168 | .add_common_revisions(commons_vec) |
|
190 | .add_common_revisions(commons_vec) | |
169 | .map_err(|e| GraphError::pynew(py, e))?; |
|
191 | .map_err(|e| GraphError::pynew(py, e))?; | |
@@ -176,7 +198,8 b' impl PartialDiscovery {' | |||||
176 | missings: PyObject, |
|
198 | missings: PyObject, | |
177 | ) -> PyResult<PyObject> { |
|
199 | ) -> PyResult<PyObject> { | |
178 | let missings_vec = self.pyiter_to_vec(py, &missings)?; |
|
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 | inner |
|
203 | inner | |
181 | .add_missing_revisions(missings_vec) |
|
204 | .add_missing_revisions(missings_vec) | |
182 | .map_err(|e| GraphError::pynew(py, e))?; |
|
205 | .map_err(|e| GraphError::pynew(py, e))?; | |
@@ -189,7 +212,8 b' impl PartialDiscovery {' | |||||
189 | _headrevs: PyObject, |
|
212 | _headrevs: PyObject, | |
190 | size: usize, |
|
213 | size: usize, | |
191 | ) -> PyResult<PyObject> { |
|
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 | let sample = inner |
|
217 | let sample = inner | |
194 | .take_full_sample(size) |
|
218 | .take_full_sample(size) | |
195 | .map_err(|e| GraphError::pynew(py, e))?; |
|
219 | .map_err(|e| GraphError::pynew(py, e))?; | |
@@ -207,7 +231,8 b' impl PartialDiscovery {' | |||||
207 | size: usize, |
|
231 | size: usize, | |
208 | ) -> PyResult<PyObject> { |
|
232 | ) -> PyResult<PyObject> { | |
209 | let revsvec = self.pyiter_to_vec(py, &headrevs)?; |
|
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 | let sample = inner |
|
236 | let sample = inner | |
212 | .take_quick_sample(revsvec, size) |
|
237 | .take_quick_sample(revsvec, size) | |
213 | .map_err(|e| GraphError::pynew(py, e))?; |
|
238 | .map_err(|e| GraphError::pynew(py, e))?; |
@@ -31,17 +31,6 b' use hg::{' | |||||
31 | use std::{cell::RefCell, collections::HashMap}; |
|
31 | use std::{cell::RefCell, collections::HashMap}; | |
32 | use vcsgraph::graph::Graph as VCSGraph; |
|
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 | pub struct PySharedIndex { |
|
34 | pub struct PySharedIndex { | |
46 | /// The underlying hg-core index |
|
35 | /// The underlying hg-core index | |
47 | pub(crate) inner: &'static hg::index::Index, |
|
36 | pub(crate) inner: &'static hg::index::Index, |
@@ -1,6 +1,7 b'' | |||||
1 | import unittest |
|
1 | import unittest | |
2 |
|
2 | |||
3 | from mercurial import policy |
|
3 | from mercurial import policy | |
|
4 | from mercurial.testing import revlog as revlogtesting | |||
4 |
|
5 | |||
5 | PartialDiscovery = policy.importrust('discovery', member='PartialDiscovery') |
|
6 | PartialDiscovery = policy.importrust('discovery', member='PartialDiscovery') | |
6 |
|
7 | |||
@@ -47,7 +48,7 b' class fakerepo:' | |||||
47 | "rustext or the C Extension parsers module " |
|
48 | "rustext or the C Extension parsers module " | |
48 | "discovery relies on is not available", |
|
49 | "discovery relies on is not available", | |
49 | ) |
|
50 | ) | |
50 |
class rustdiscoverytest( |
|
51 | class rustdiscoverytest(revlogtesting.RustRevlogBasedTestBase): | |
51 | """Test the correctness of binding to Rust code. |
|
52 | """Test the correctness of binding to Rust code. | |
52 |
|
53 | |||
53 | This test is merely for the binding to Rust itself: extraction of |
|
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 | def parseindex(self): |
|
63 | def parseindex(self): | |
63 |
return |
|
64 | return self.parserustindex(data=data_non_inlined) | |
64 |
|
65 | |||
65 | def repo(self): |
|
66 | def repo(self): | |
66 | return fakerepo(self.parseindex()) |
|
67 | return fakerepo(self.parseindex()) |
General Comments 0
You need to be logged in to leave comments.
Login now