rust/hg-cpython/src/revlog.rs
changeset 51236 7eea2e4109ae
parent 51232 456e0fe702e8
child 51242 0b81440e2a73
equal deleted inserted replaced
51235:633408a0f2e2 51236:7eea2e4109ae
    14 use cpython::{
    14 use cpython::{
    15     buffer::{Element, PyBuffer},
    15     buffer::{Element, PyBuffer},
    16     exc::{IndexError, ValueError},
    16     exc::{IndexError, ValueError},
    17     ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyInt, PyList,
    17     ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyInt, PyList,
    18     PyModule, PyObject, PyResult, PySet, PyString, PyTuple, Python,
    18     PyModule, PyObject, PyResult, PySet, PyString, PyTuple, Python,
    19     PythonObject, ToPyObject,
    19     PythonObject, ToPyObject, UnsafePyLeaked,
    20 };
    20 };
    21 use hg::{
    21 use hg::{
    22     errors::HgError,
    22     errors::HgError,
    23     index::{
    23     index::{
    24         IndexHeader, Phase, RevisionDataParams, SnapshotsCache,
    24         IndexHeader, Phase, RevisionDataParams, SnapshotsCache,
    25         INDEX_ENTRY_SIZE,
    25         INDEX_ENTRY_SIZE,
    26     },
    26     },
    27     nodemap::{Block, NodeMapError, NodeTree},
    27     nodemap::{Block, NodeMapError, NodeTree},
    28     revlog::{nodemap::NodeMap, NodePrefix, RevlogError, RevlogIndex},
    28     revlog::{nodemap::NodeMap, Graph, NodePrefix, RevlogError, RevlogIndex},
    29     BaseRevision, Revision, UncheckedRevision, NULL_REVISION,
    29     BaseRevision, Node, Revision, UncheckedRevision, NULL_REVISION,
    30 };
    30 };
    31 use std::{cell::RefCell, collections::HashMap};
    31 use std::{cell::RefCell, collections::HashMap};
       
    32 use vcsgraph::graph::Graph as VCSGraph;
    32 
    33 
    33 /// Return a Struct implementing the Graph trait
    34 /// Return a Struct implementing the Graph trait
    34 pub(crate) fn pyindex_to_graph(
    35 pub(crate) fn pyindex_to_graph(
    35     py: Python,
    36     py: Python,
    36     index: PyObject,
    37     index: PyObject,
    39         Ok(midx) => Ok(midx.clone_cindex(py)),
    40         Ok(midx) => Ok(midx.clone_cindex(py)),
    40         Err(_) => cindex::Index::new(py, index),
    41         Err(_) => cindex::Index::new(py, index),
    41     }
    42     }
    42 }
    43 }
    43 
    44 
       
    45 pub struct PySharedIndex {
       
    46     /// The underlying hg-core index
       
    47     pub(crate) inner: &'static hg::index::Index,
       
    48 }
       
    49 
       
    50 /// Return a Struct implementing the Graph trait
       
    51 pub(crate) fn py_rust_index_to_graph(
       
    52     py: Python,
       
    53     index: PyObject,
       
    54 ) -> PyResult<UnsafePyLeaked<PySharedIndex>> {
       
    55     let midx = index.extract::<MixedIndex>(py)?;
       
    56     let leaked = midx.index(py).leak_immutable();
       
    57     Ok(unsafe { leaked.map(py, |idx| PySharedIndex { inner: idx }) })
       
    58 }
       
    59 
       
    60 impl Clone for PySharedIndex {
       
    61     fn clone(&self) -> Self {
       
    62         Self { inner: self.inner }
       
    63     }
       
    64 }
       
    65 
       
    66 impl Graph for PySharedIndex {
       
    67     fn parents(&self, rev: Revision) -> Result<[Revision; 2], hg::GraphError> {
       
    68         self.inner.parents(rev)
       
    69     }
       
    70 }
       
    71 
       
    72 impl VCSGraph for PySharedIndex {
       
    73     fn parents(
       
    74         &self,
       
    75         rev: BaseRevision,
       
    76     ) -> Result<vcsgraph::graph::Parents, vcsgraph::graph::GraphReadError>
       
    77     {
       
    78         // FIXME This trait should be reworked to decide between Revision
       
    79         // and UncheckedRevision, get better errors names, etc.
       
    80         match Graph::parents(self, Revision(rev)) {
       
    81             Ok(parents) => {
       
    82                 Ok(vcsgraph::graph::Parents([parents[0].0, parents[1].0]))
       
    83             }
       
    84             Err(hg::GraphError::ParentOutOfRange(rev)) => {
       
    85                 Err(vcsgraph::graph::GraphReadError::KeyedInvalidKey(rev.0))
       
    86             }
       
    87         }
       
    88     }
       
    89 }
       
    90 
       
    91 impl RevlogIndex for PySharedIndex {
       
    92     fn len(&self) -> usize {
       
    93         self.inner.len()
       
    94     }
       
    95     fn node(&self, rev: Revision) -> Option<&Node> {
       
    96         self.inner.node(rev)
       
    97     }
       
    98 }
       
    99 
    44 py_class!(pub class MixedIndex |py| {
   100 py_class!(pub class MixedIndex |py| {
    45     data cindex: RefCell<cindex::Index>;
   101     data cindex: RefCell<cindex::Index>;
    46     data index: RefCell<hg::index::Index>;
   102     @shared data index: hg::index::Index;
    47     data nt: RefCell<Option<NodeTree>>;
   103     data nt: RefCell<Option<NodeTree>>;
    48     data docket: RefCell<Option<PyObject>>;
   104     data docket: RefCell<Option<PyObject>>;
    49     // Holds a reference to the mmap'ed persistent nodemap data
   105     // Holds a reference to the mmap'ed persistent nodemap data
    50     data nodemap_mmap: RefCell<Option<PyBuffer>>;
   106     data nodemap_mmap: RefCell<Option<PyBuffer>>;
    51     // Holds a reference to the mmap'ed persistent index data
   107     // Holds a reference to the mmap'ed persistent index data
   666         let (buf, bytes) = unsafe { mmap_keeparound(py, data)? };
   722         let (buf, bytes) = unsafe { mmap_keeparound(py, data)? };
   667 
   723 
   668         Self::create_instance(
   724         Self::create_instance(
   669             py,
   725             py,
   670             RefCell::new(cindex::Index::new(py, cindex)?),
   726             RefCell::new(cindex::Index::new(py, cindex)?),
   671             RefCell::new(
   727             hg::index::Index::new(
   672                 hg::index::Index::new(
   728                 bytes,
   673                     bytes,
   729                 IndexHeader::parse(&header.to_be_bytes())
   674                     IndexHeader::parse(&header.to_be_bytes())
   730                     .expect("default header is broken")
   675                         .expect("default header is broken")
   731                     .unwrap(),
   676                         .unwrap(),
   732             )
   677                 )
   733             .map_err(|e| {
   678                 .map_err(|e| {
   734                 revlog_error_with_msg(py, e.to_string().as_bytes())
   679                     revlog_error_with_msg(py, e.to_string().as_bytes())
   735             })?,
   680                 })?,
       
   681             ),
       
   682             RefCell::new(None),
   736             RefCell::new(None),
   683             RefCell::new(None),
   737             RefCell::new(None),
   684             RefCell::new(None),
   738             RefCell::new(None),
   685             RefCell::new(Some(buf)),
   739             RefCell::new(Some(buf)),
   686         )
   740         )