##// 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 use crate::PyRevision;
15 use crate::PyRevision;
16 use crate::{
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 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<Box<CorePartialDiscovery<Index>>>;
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 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 def iscomplete(&self) -> PyResult<bool> {
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 def stats(&self) -> PyResult<PyDict> {
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 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 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 .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(Box::new(CorePartialDiscovery::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 index = self.index(py).borrow();
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 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 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 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 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 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 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 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 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 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 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(unittest.TestCase):
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 cparsers.parse_index2(data_non_inlined, False)[0]
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