comparison rust/hg-core/src/revlog/index.rs @ 51261: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 c4f1a790bda8
children 47a34afda7ad
comparison
equal deleted inserted replaced
51260:c4f1a790bda8 51261:9088c6d65ef6
542 } 542 }
543 } 543 }
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
558 .read() 567 .read()
559 .expect("RwLock on Index.head_revs should not be poisoned"); 568 .expect("RwLock on Index.head_revs should not be poisoned");
560 let self_head_revs = &guard.0; 569 let self_head_revs = &guard.0;
561 let self_filtered_revs = &guard.1; 570 let self_filtered_revs = &guard.1;
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
569 let as_vec = if self.is_empty() { 584 let as_vec = if self.is_empty() {
570 vec![NULL_REVISION] 585 vec![NULL_REVISION]
590 *self 605 *self
591 .head_revs 606 .head_revs
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.
599 /// 614 ///
600 /// `stop_rev` specifies a revision to stop at. If not specified, we 615 /// `stop_rev` specifies a revision to stop at. If not specified, we