rust/hg-cpython/src/revlog.rs
changeset 50990 4c5f6e95df84
parent 50988 1928b770e3e7
child 51118 532e74ad3ff6
equal deleted inserted replaced
50989:27e773aa607d 50990:4c5f6e95df84
     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