rust/hg-cpython/src/revlog.rs
changeset 51250 96e05f1a99bd
parent 51248 0409bd6ba663
child 51251 f94c10334bcb
equal deleted inserted replaced
51249:fd1aa5e18f75 51250:96e05f1a99bd
     4 //
     4 //
     5 // This software may be used and distributed according to the terms of the
     5 // This software may be used and distributed according to the terms of the
     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,
       
    10     conversion::{rev_pyiter_collect, rev_pyiter_collect_or_else},
     9     conversion::{rev_pyiter_collect, rev_pyiter_collect_or_else},
    11     utils::{node_from_py_bytes, node_from_py_object},
    10     utils::{node_from_py_bytes, node_from_py_object},
    12     PyRevision,
    11     PyRevision,
    13 };
    12 };
    14 use cpython::{
    13 use cpython::{
    85         self.inner.node(rev)
    84         self.inner.node(rev)
    86     }
    85     }
    87 }
    86 }
    88 
    87 
    89 py_class!(pub class MixedIndex |py| {
    88 py_class!(pub class MixedIndex |py| {
    90     data cindex: RefCell<cindex::Index>;
       
    91     @shared data index: hg::index::Index;
    89     @shared data index: hg::index::Index;
    92     data nt: RefCell<Option<CoreNodeTree>>;
    90     data nt: RefCell<Option<CoreNodeTree>>;
    93     data docket: RefCell<Option<PyObject>>;
    91     data docket: RefCell<Option<PyObject>>;
    94     // Holds a reference to the mmap'ed persistent nodemap data
    92     // Holds a reference to the mmap'ed persistent nodemap data
    95     data nodemap_mmap: RefCell<Option<PyBuffer>>;
    93     data nodemap_mmap: RefCell<Option<PyBuffer>>;
    96     // Holds a reference to the mmap'ed persistent index data
    94     // Holds a reference to the mmap'ed persistent index data
    97     data index_mmap: RefCell<Option<PyBuffer>>;
    95     data index_mmap: RefCell<Option<PyBuffer>>;
    98 
    96 
    99     def __new__(
    97     def __new__(
   100         _cls,
    98         _cls,
   101         cindex: PyObject,
       
   102         data: PyObject,
    99         data: PyObject,
   103         default_header: u32,
   100         default_header: u32,
   104     ) -> PyResult<MixedIndex> {
   101     ) -> PyResult<MixedIndex> {
   105         Self::new(py, cindex, data, default_header)
   102         Self::new(py, data, default_header)
   106     }
   103     }
   107 
   104 
   108     /// Compatibility layer used for Python consumers needing access to the C index
   105     /// Compatibility layer used for Python consumers needing access to the C index
   109     ///
   106     ///
   110     /// Only use case so far is `scmutil.shortesthexnodeidprefix`,
   107     /// Only use case so far is `scmutil.shortesthexnodeidprefix`,
   111     /// that may need to build a custom `nodetree`, based on a specified revset.
   108     /// that may need to build a custom `nodetree`, based on a specified revset.
   112     /// With a Rust implementation of the nodemap, we will be able to get rid of
   109     /// With a Rust implementation of the nodemap, we will be able to get rid of
   113     /// this, by exposing our own standalone nodemap class,
   110     /// this, by exposing our own standalone nodemap class,
   114     /// ready to accept `MixedIndex`.
   111     /// ready to accept `Index`.
   115     def get_cindex(&self) -> PyResult<PyObject> {
   112 /*    def get_cindex(&self) -> PyResult<PyObject> {
   116         Ok(self.cindex(py).borrow().inner().clone_ref(py))
   113         Ok(self.cindex(py).borrow().inner().clone_ref(py))
   117     }
   114     }
   118 
   115 */
   119     // Index API involving nodemap, as defined in mercurial/pure/parsers.py
   116     // Index API involving nodemap, as defined in mercurial/pure/parsers.py
   120 
   117 
   121     /// Return Revision if found, raises a bare `error.RevlogError`
   118     /// Return Revision if found, raises a bare `error.RevlogError`
   122     /// in case of ambiguity, same as C version does
   119     /// in case of ambiguity, same as C version does
   123     def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> {
   120     def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> {
   600         })
   597         })
   601     }
   598     }
   602 }
   599 }
   603 
   600 
   604 impl MixedIndex {
   601 impl MixedIndex {
   605     fn new(
   602     fn new(py: Python, data: PyObject, header: u32) -> PyResult<MixedIndex> {
   606         py: Python,
       
   607         cindex: PyObject,
       
   608         data: PyObject,
       
   609         header: u32,
       
   610     ) -> PyResult<MixedIndex> {
       
   611         // Safety: we keep the buffer around inside the class as `index_mmap`
   603         // Safety: we keep the buffer around inside the class as `index_mmap`
   612         let (buf, bytes) = unsafe { mmap_keeparound(py, data)? };
   604         let (buf, bytes) = unsafe { mmap_keeparound(py, data)? };
   613 
   605 
   614         Self::create_instance(
   606         Self::create_instance(
   615             py,
   607             py,
   616             RefCell::new(cindex::Index::new(py, cindex)?),
       
   617             hg::index::Index::new(
   608             hg::index::Index::new(
   618                 bytes,
   609                 bytes,
   619                 IndexHeader::parse(&header.to_be_bytes())
   610                 IndexHeader::parse(&header.to_be_bytes())
   620                     .expect("default header is broken")
   611                     .expect("default header is broken")
   621                     .unwrap(),
   612                     .unwrap(),
   662             let mut nt = CoreNodeTree::load_bytes(readonly, 0);
   653             let mut nt = CoreNodeTree::load_bytes(readonly, 0);
   663             self.fill_nodemap(py, &mut nt)?;
   654             self.fill_nodemap(py, &mut nt)?;
   664             self.nt(py).borrow_mut().replace(nt);
   655             self.nt(py).borrow_mut().replace(nt);
   665         }
   656         }
   666         Ok(self.nt(py))
   657         Ok(self.nt(py))
   667     }
       
   668 
       
   669     pub fn clone_cindex(&self, py: Python) -> cindex::Index {
       
   670         self.cindex(py).borrow().clone_ref(py)
       
   671     }
   658     }
   672 
   659 
   673     /// Returns the full nodemap bytes to be written as-is to disk
   660     /// Returns the full nodemap bytes to be written as-is to disk
   674     fn inner_nodemap_data_all(&self, py: Python) -> PyResult<PyBytes> {
   661     fn inner_nodemap_data_all(&self, py: Python) -> PyResult<PyBytes> {
   675         let nodemap = self.get_nodetree(py)?.borrow_mut().take().unwrap();
   662         let nodemap = self.get_nodetree(py)?.borrow_mut().take().unwrap();