Mercurial > public > mercurial-scm > hg
comparison rust/hg-cpython/src/revlog.rs @ 51258:9088c6d65ef6
rust-index-cpython: cache the heads' PyList representation
This is the same optimization that the C index does, we just have more
separation of the Python and native sides.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 29 Nov 2023 23:22:51 -0500 |
parents | 8b89f7cc953a |
children | f20c4b307a5a |
comparison
equal
deleted
inserted
replaced
51257:c4f1a790bda8 | 51258:9088c6d65ef6 |
---|---|
94 data docket: RefCell<Option<PyObject>>; | 94 data docket: RefCell<Option<PyObject>>; |
95 // Holds a reference to the mmap'ed persistent nodemap data | 95 // Holds a reference to the mmap'ed persistent nodemap data |
96 data nodemap_mmap: RefCell<Option<PyBuffer>>; | 96 data nodemap_mmap: RefCell<Option<PyBuffer>>; |
97 // Holds a reference to the mmap'ed persistent index data | 97 // Holds a reference to the mmap'ed persistent index data |
98 data index_mmap: RefCell<Option<PyBuffer>>; | 98 data index_mmap: RefCell<Option<PyBuffer>>; |
99 data head_revs_py_list: RefCell<Option<PyList>>; | |
99 | 100 |
100 def __new__( | 101 def __new__( |
101 _cls, | 102 _cls, |
102 data: PyObject, | 103 data: PyObject, |
103 default_header: u32, | 104 default_header: u32, |
255 /// It is Python's responsibility to call `update_nodemap_data` again. | 256 /// It is Python's responsibility to call `update_nodemap_data` again. |
256 def clearcaches(&self) -> PyResult<PyObject> { | 257 def clearcaches(&self) -> PyResult<PyObject> { |
257 self.nt(py).borrow_mut().take(); | 258 self.nt(py).borrow_mut().take(); |
258 self.docket(py).borrow_mut().take(); | 259 self.docket(py).borrow_mut().take(); |
259 self.nodemap_mmap(py).borrow_mut().take(); | 260 self.nodemap_mmap(py).borrow_mut().take(); |
261 self.head_revs_py_list(py).borrow_mut().take(); | |
260 self.index(py).borrow().clear_caches(); | 262 self.index(py).borrow().clear_caches(); |
261 Ok(py.None()) | 263 Ok(py.None()) |
262 } | 264 } |
263 | 265 |
264 /// return the raw binary string representing a revision | 266 /// return the raw binary string representing a revision |
619 })?, | 621 })?, |
620 RefCell::new(None), | 622 RefCell::new(None), |
621 RefCell::new(None), | 623 RefCell::new(None), |
622 RefCell::new(None), | 624 RefCell::new(None), |
623 RefCell::new(Some(buf)), | 625 RefCell::new(Some(buf)), |
626 RefCell::new(None), | |
624 ) | 627 ) |
625 } | 628 } |
626 | 629 |
627 fn len(&self, py: Python) -> PyResult<usize> { | 630 fn len(&self, py: Python) -> PyResult<usize> { |
628 let rust_index_len = self.index(py).borrow().len(); | 631 let rust_index_len = self.index(py).borrow().len(); |
771 }) | 774 }) |
772 } | 775 } |
773 | 776 |
774 fn inner_headrevs(&self, py: Python) -> PyResult<PyObject> { | 777 fn inner_headrevs(&self, py: Python) -> PyResult<PyObject> { |
775 let index = &*self.index(py).borrow(); | 778 let index = &*self.index(py).borrow(); |
776 let as_vec: Vec<PyObject> = index | 779 if let Some(new_heads) = |
777 .head_revs() | 780 index.head_revs_shortcut().map_err(|e| graph_error(py, e))? |
778 .map_err(|e| graph_error(py, e))? | 781 { |
779 .iter() | 782 self.cache_new_heads_py_list(new_heads, py); |
780 .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) | 783 } |
781 .collect(); | 784 |
782 Ok(PyList::new(py, &as_vec).into_object()) | 785 Ok(self |
786 .head_revs_py_list(py) | |
787 .borrow() | |
788 .as_ref() | |
789 .expect("head revs should be cached") | |
790 .clone_ref(py) | |
791 .into_object()) | |
783 } | 792 } |
784 | 793 |
785 fn inner_headrevsfiltered( | 794 fn inner_headrevsfiltered( |
786 &self, | 795 &self, |
787 py: Python, | 796 py: Python, |
788 filtered_revs: &PyObject, | 797 filtered_revs: &PyObject, |
789 ) -> PyResult<PyObject> { | 798 ) -> PyResult<PyObject> { |
790 let index = &mut *self.index(py).borrow_mut(); | 799 let index = &mut *self.index(py).borrow_mut(); |
791 let filtered_revs = rev_pyiter_collect(py, filtered_revs, index)?; | 800 let filtered_revs = rev_pyiter_collect(py, filtered_revs, index)?; |
792 | 801 |
793 let as_vec: Vec<PyObject> = index | 802 if let Some(new_heads) = index |
794 .head_revs_filtered(&filtered_revs) | 803 .head_revs_filtered(&filtered_revs, true) |
795 .map_err(|e| graph_error(py, e))? | 804 .map_err(|e| graph_error(py, e))? |
805 { | |
806 self.cache_new_heads_py_list(new_heads, py); | |
807 } | |
808 | |
809 Ok(self | |
810 .head_revs_py_list(py) | |
811 .borrow() | |
812 .as_ref() | |
813 .expect("head revs should be cached") | |
814 .clone_ref(py) | |
815 .into_object()) | |
816 } | |
817 | |
818 fn cache_new_heads_py_list( | |
819 &self, | |
820 new_heads: Vec<Revision>, | |
821 py: Python<'_>, | |
822 ) -> PyList { | |
823 let as_vec: Vec<PyObject> = new_heads | |
796 .iter() | 824 .iter() |
797 .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) | 825 .map(|r| PyRevision::from(*r).into_py_object(py).into_object()) |
798 .collect(); | 826 .collect(); |
799 Ok(PyList::new(py, &as_vec).into_object()) | 827 let new_heads_py_list = PyList::new(py, &as_vec); |
828 *self.head_revs_py_list(py).borrow_mut() = | |
829 Some(new_heads_py_list.clone_ref(py)); | |
830 new_heads_py_list | |
800 } | 831 } |
801 | 832 |
802 fn inner_ancestors( | 833 fn inner_ancestors( |
803 &self, | 834 &self, |
804 py: Python, | 835 py: Python, |