comparison rust/hg-cpython/src/revlog.rs @ 51250:96e05f1a99bd

rust-index: stop instantiating a C Index The only missing piece was the `cache` to be returned from `revlog.parse_index_v1_mixed`, and it really seems that it is essentially repetition of the input, if `inline` is `True`. Not worth a Rust implementation (C implementation is probably there for historical reasons).
author Georges Racinet <georges.racinet@octobus.net>
date Sun, 29 Oct 2023 23:54:05 +0100
parents 0409bd6ba663
children f94c10334bcb
comparison
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();