6 // GNU General Public License version 2 or any later version. |
6 // GNU General Public License version 2 or any later version. |
7 |
7 |
8 use crate::{ |
8 use crate::{ |
9 cindex, |
9 cindex, |
10 utils::{node_from_py_bytes, node_from_py_object}, |
10 utils::{node_from_py_bytes, node_from_py_object}, |
|
11 PyRevision, |
11 }; |
12 }; |
12 use cpython::{ |
13 use cpython::{ |
13 buffer::{Element, PyBuffer}, |
14 buffer::{Element, PyBuffer}, |
14 exc::{IndexError, ValueError}, |
15 exc::{IndexError, ValueError}, |
15 ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyInt, PyModule, |
16 ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyInt, PyModule, |
16 PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject, |
17 PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject, |
17 }; |
18 }; |
18 use hg::{ |
19 use hg::{ |
19 nodemap::{Block, NodeMapError, NodeTree}, |
20 nodemap::{Block, NodeMapError, NodeTree}, |
20 revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex}, |
21 revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex}, |
21 Revision, UncheckedRevision, |
22 BaseRevision, Revision, UncheckedRevision, |
22 }; |
23 }; |
23 use std::cell::RefCell; |
24 use std::cell::RefCell; |
24 |
25 |
25 /// Return a Struct implementing the Graph trait |
26 /// Return a Struct implementing the Graph trait |
26 pub(crate) fn pyindex_to_graph( |
27 pub(crate) fn pyindex_to_graph( |
57 |
58 |
58 // Index API involving nodemap, as defined in mercurial/pure/parsers.py |
59 // Index API involving nodemap, as defined in mercurial/pure/parsers.py |
59 |
60 |
60 /// Return Revision if found, raises a bare `error.RevlogError` |
61 /// Return Revision if found, raises a bare `error.RevlogError` |
61 /// in case of ambiguity, same as C version does |
62 /// in case of ambiguity, same as C version does |
62 def get_rev(&self, node: PyBytes) -> PyResult<Option<Revision>> { |
63 def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> { |
63 let opt = self.get_nodetree(py)?.borrow(); |
64 let opt = self.get_nodetree(py)?.borrow(); |
64 let nt = opt.as_ref().unwrap(); |
65 let nt = opt.as_ref().unwrap(); |
65 let idx = &*self.cindex(py).borrow(); |
66 let idx = &*self.cindex(py).borrow(); |
66 let node = node_from_py_bytes(py, &node)?; |
67 let node = node_from_py_bytes(py, &node)?; |
67 nt.find_bin(idx, node.into()).map_err(|e| nodemap_error(py, e)) |
68 let res = nt.find_bin(idx, node.into()); |
|
69 Ok(res.map_err(|e| nodemap_error(py, e))?.map(Into::into)) |
68 } |
70 } |
69 |
71 |
70 /// same as `get_rev()` but raises a bare `error.RevlogError` if node |
72 /// same as `get_rev()` but raises a bare `error.RevlogError` if node |
71 /// is not found. |
73 /// is not found. |
72 /// |
74 /// |
73 /// No need to repeat `node` in the exception, `mercurial/revlog.py` |
75 /// No need to repeat `node` in the exception, `mercurial/revlog.py` |
74 /// will catch and rewrap with it |
76 /// will catch and rewrap with it |
75 def rev(&self, node: PyBytes) -> PyResult<Revision> { |
77 def rev(&self, node: PyBytes) -> PyResult<PyRevision> { |
76 self.get_rev(py, node)?.ok_or_else(|| revlog_error(py)) |
78 self.get_rev(py, node)?.ok_or_else(|| revlog_error(py)) |
77 } |
79 } |
78 |
80 |
79 /// return True if the node exist in the index |
81 /// return True if the node exist in the index |
80 def has_node(&self, node: PyBytes) -> PyResult<bool> { |
82 def has_node(&self, node: PyBytes) -> PyResult<bool> { |
129 } |
131 } |
130 let node_bytes = tup.get_item(py, 7).extract(py)?; |
132 let node_bytes = tup.get_item(py, 7).extract(py)?; |
131 let node = node_from_py_object(py, &node_bytes)?; |
133 let node = node_from_py_object(py, &node_bytes)?; |
132 |
134 |
133 let mut idx = self.cindex(py).borrow_mut(); |
135 let mut idx = self.cindex(py).borrow_mut(); |
134 let rev = idx.len() as Revision; |
136 |
135 |
137 // This is ok since we will just add the revision to the index |
|
138 let rev = Revision(idx.len() as BaseRevision); |
136 idx.append(py, tup)?; |
139 idx.append(py, tup)?; |
|
140 |
137 self.get_nodetree(py)?.borrow_mut().as_mut().unwrap() |
141 self.get_nodetree(py)?.borrow_mut().as_mut().unwrap() |
138 .insert(&*idx, &node, rev) |
142 .insert(&*idx, &node, rev) |
139 .map_err(|e| nodemap_error(py, e))?; |
143 .map_err(|e| nodemap_error(py, e))?; |
140 Ok(py.None()) |
144 Ok(py.None()) |
141 } |
145 } |
268 // this is an equivalent implementation of the index_contains() |
272 // this is an equivalent implementation of the index_contains() |
269 // defined in revlog.c |
273 // defined in revlog.c |
270 let cindex = self.cindex(py).borrow(); |
274 let cindex = self.cindex(py).borrow(); |
271 match item.extract::<i32>(py) { |
275 match item.extract::<i32>(py) { |
272 Ok(rev) => { |
276 Ok(rev) => { |
273 Ok(rev >= -1 && rev < cindex.inner().len(py)? as Revision) |
277 Ok(rev >= -1 && rev < cindex.inner().len(py)? as BaseRevision) |
274 } |
278 } |
275 Err(_) => { |
279 Err(_) => { |
276 cindex.inner().call_method( |
280 cindex.inner().call_method( |
277 py, |
281 py, |
278 "has_node", |
282 "has_node", |
329 py: Python, |
333 py: Python, |
330 nt: &mut NodeTree, |
334 nt: &mut NodeTree, |
331 ) -> PyResult<PyObject> { |
335 ) -> PyResult<PyObject> { |
332 let index = self.cindex(py).borrow(); |
336 let index = self.cindex(py).borrow(); |
333 for r in 0..index.len() { |
337 for r in 0..index.len() { |
334 let rev = r as Revision; |
338 let rev = Revision(r as BaseRevision); |
335 // in this case node() won't ever return None |
339 // in this case node() won't ever return None |
336 nt.insert(&*index, index.node(rev).unwrap(), rev) |
340 nt.insert(&*index, index.node(rev).unwrap(), rev) |
337 .map_err(|e| nodemap_error(py, e))? |
341 .map_err(|e| nodemap_error(py, e))? |
338 } |
342 } |
339 Ok(py.None()) |
343 Ok(py.None()) |
445 // pointer. |
449 // pointer. |
446 self.mmap(py).borrow_mut().replace(buf); |
450 self.mmap(py).borrow_mut().replace(buf); |
447 |
451 |
448 let mut nt = NodeTree::load_bytes(Box::new(bytes), len); |
452 let mut nt = NodeTree::load_bytes(Box::new(bytes), len); |
449 |
453 |
450 let data_tip = |
454 let data_tip = docket |
451 docket.getattr(py, "tip_rev")?.extract::<i32>(py)?.into(); |
455 .getattr(py, "tip_rev")? |
|
456 .extract::<BaseRevision>(py)? |
|
457 .into(); |
452 self.docket(py).borrow_mut().replace(docket.clone_ref(py)); |
458 self.docket(py).borrow_mut().replace(docket.clone_ref(py)); |
453 let idx = self.cindex(py).borrow(); |
459 let idx = self.cindex(py).borrow(); |
454 let data_tip = idx.check_revision(data_tip).ok_or_else(|| { |
460 let data_tip = idx.check_revision(data_tip).ok_or_else(|| { |
455 nodemap_error(py, NodeMapError::RevisionNotInIndex(data_tip)) |
461 nodemap_error(py, NodeMapError::RevisionNotInIndex(data_tip)) |
456 })?; |
462 })?; |
457 let current_tip = idx.len(); |
463 let current_tip = idx.len(); |
458 |
464 |
459 for r in (data_tip + 1)..current_tip as Revision { |
465 for r in (data_tip.0 + 1)..current_tip as BaseRevision { |
460 let rev = r as Revision; |
466 let rev = Revision(r); |
461 // in this case node() won't ever return None |
467 // in this case node() won't ever return None |
462 nt.insert(&*idx, idx.node(rev).unwrap(), rev) |
468 nt.insert(&*idx, idx.node(rev).unwrap(), rev) |
463 .map_err(|e| nodemap_error(py, e))? |
469 .map_err(|e| nodemap_error(py, e))? |
464 } |
470 } |
465 |
471 |