##// END OF EJS Templates
rust-index-cpython: cache the heads' PyList representation...
Raphaël Gomès -
r52154:9088c6d6 default
parent child Browse files
Show More
@@ -544,14 +544,23 b' impl Index {'
544
544
545 /// Return the head revisions of this index
545 /// Return the head revisions of this index
546 pub fn head_revs(&self) -> Result<Vec<Revision>, GraphError> {
546 pub fn head_revs(&self) -> Result<Vec<Revision>, GraphError> {
547 self.head_revs_filtered(&HashSet::new())
547 self.head_revs_filtered(&HashSet::new(), false)
548 .map(|h| h.unwrap())
549 }
550
551 /// Python-specific shortcut to save on PyList creation
552 pub fn head_revs_shortcut(
553 &self,
554 ) -> Result<Option<Vec<Revision>>, GraphError> {
555 self.head_revs_filtered(&HashSet::new(), true)
548 }
556 }
549
557
550 /// Return the head revisions of this index
558 /// Return the head revisions of this index
551 pub fn head_revs_filtered(
559 pub fn head_revs_filtered(
552 &self,
560 &self,
553 filtered_revs: &HashSet<Revision>,
561 filtered_revs: &HashSet<Revision>,
554 ) -> Result<Vec<Revision>, GraphError> {
562 py_shortcut: bool,
563 ) -> Result<Option<Vec<Revision>>, GraphError> {
555 {
564 {
556 let guard = self
565 let guard = self
557 .head_revs
566 .head_revs
@@ -562,7 +571,13 b' impl Index {'
562 if !self_head_revs.is_empty()
571 if !self_head_revs.is_empty()
563 && filtered_revs == self_filtered_revs
572 && filtered_revs == self_filtered_revs
564 {
573 {
565 return Ok(self_head_revs.to_owned());
574 if py_shortcut {
575 // Don't copy the revs since we've already cached them
576 // on the Python side.
577 return Ok(None);
578 } else {
579 return Ok(Some(self_head_revs.to_owned()));
580 }
566 }
581 }
567 }
582 }
568
583
@@ -592,7 +607,7 b' impl Index {'
592 .write()
607 .write()
593 .expect("RwLock on Index.head_revs should not be poisoned") =
608 .expect("RwLock on Index.head_revs should not be poisoned") =
594 (as_vec.to_owned(), filtered_revs.to_owned());
609 (as_vec.to_owned(), filtered_revs.to_owned());
595 Ok(as_vec)
610 Ok(Some(as_vec))
596 }
611 }
597
612
598 /// Obtain the delta chain for a revision.
613 /// Obtain the delta chain for a revision.
@@ -96,6 +96,7 b' py_class!(pub class Index |py| {'
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,
@@ -257,6 +258,7 b' py_class!(pub class Index |py| {'
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 }
@@ -621,6 +623,7 b' impl Index {'
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
@@ -773,13 +776,19 b' impl Index {'
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(
@@ -790,13 +799,35 b' impl Index {'
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(
General Comments 0
You need to be logged in to leave comments. Login now