Show More
@@ -263,6 +263,9 b' pub struct Index {' | |||||
263 | /// Cache of the head revisions in this index, kept in sync. Should |
|
263 | /// Cache of the head revisions in this index, kept in sync. Should | |
264 | /// be accessed via the [`Self::head_revs`] method. |
|
264 | /// be accessed via the [`Self::head_revs`] method. | |
265 | head_revs: Vec<Revision>, |
|
265 | head_revs: Vec<Revision>, | |
|
266 | /// Cache of the last filtered revisions in this index, used to make sure | |||
|
267 | /// we haven't changed filters when returning the cached `head_revs`. | |||
|
268 | filtered_revs: HashSet<Revision>, | |||
266 | } |
|
269 | } | |
267 |
|
270 | |||
268 | impl Debug for Index { |
|
271 | impl Debug for Index { | |
@@ -363,6 +366,7 b' impl Index {' | |||||
363 | uses_generaldelta, |
|
366 | uses_generaldelta, | |
364 | is_inline: true, |
|
367 | is_inline: true, | |
365 | head_revs: vec![], |
|
368 | head_revs: vec![], | |
|
369 | filtered_revs: HashSet::new(), | |||
366 | }) |
|
370 | }) | |
367 | } else { |
|
371 | } else { | |
368 | Err(HgError::corrupted("unexpected inline revlog length")) |
|
372 | Err(HgError::corrupted("unexpected inline revlog length")) | |
@@ -374,6 +378,7 b' impl Index {' | |||||
374 | uses_generaldelta, |
|
378 | uses_generaldelta, | |
375 | is_inline: false, |
|
379 | is_inline: false, | |
376 | head_revs: vec![], |
|
380 | head_revs: vec![], | |
|
381 | filtered_revs: HashSet::new(), | |||
377 | }) |
|
382 | }) | |
378 | } |
|
383 | } | |
379 | } |
|
384 | } | |
@@ -520,13 +525,36 b' impl Index {' | |||||
520 |
|
525 | |||
521 | /// Return the head revisions of this index |
|
526 | /// Return the head revisions of this index | |
522 | pub fn head_revs(&mut self) -> Result<Vec<Revision>, GraphError> { |
|
527 | pub fn head_revs(&mut self) -> Result<Vec<Revision>, GraphError> { | |
523 |
|
|
528 | self.head_revs_filtered(&HashSet::new()) | |
|
529 | } | |||
|
530 | ||||
|
531 | /// Return the head revisions of this index | |||
|
532 | pub fn head_revs_filtered( | |||
|
533 | &mut self, | |||
|
534 | filtered_revs: &HashSet<Revision>, | |||
|
535 | ) -> Result<Vec<Revision>, GraphError> { | |||
|
536 | if !self.head_revs.is_empty() && filtered_revs == &self.filtered_revs { | |||
524 | return Ok(self.head_revs.to_owned()); |
|
537 | return Ok(self.head_revs.to_owned()); | |
525 | } |
|
538 | } | |
526 |
let mut revs: HashSet<Revision, RandomState> = |
|
539 | let mut revs: HashSet<Revision, RandomState> = | |
527 | .into_iter() |
|
540 | if filtered_revs.is_empty() { | |
528 | .map(|i| Revision(i as BaseRevision)) |
|
541 | (0..self.len()) | |
529 |
. |
|
542 | .into_iter() | |
|
543 | .map(|i| Revision(i as BaseRevision)) | |||
|
544 | .collect() | |||
|
545 | } else { | |||
|
546 | (0..self.len()) | |||
|
547 | .into_iter() | |||
|
548 | .filter_map(|i| { | |||
|
549 | let r = Revision(i as BaseRevision); | |||
|
550 | if filtered_revs.contains(&r) { | |||
|
551 | None | |||
|
552 | } else { | |||
|
553 | Some(r) | |||
|
554 | } | |||
|
555 | }) | |||
|
556 | .collect() | |||
|
557 | }; | |||
530 | dagops::retain_heads(self, &mut revs)?; |
|
558 | dagops::retain_heads(self, &mut revs)?; | |
531 | if self.is_empty() { |
|
559 | if self.is_empty() { | |
532 | revs.insert(NULL_REVISION); |
|
560 | revs.insert(NULL_REVISION); | |
@@ -535,6 +563,7 b' impl Index {' | |||||
535 | revs.into_iter().map(Into::into).collect(); |
|
563 | revs.into_iter().map(Into::into).collect(); | |
536 | as_vec.sort_unstable(); |
|
564 | as_vec.sort_unstable(); | |
537 | self.head_revs = as_vec.to_owned(); |
|
565 | self.head_revs = as_vec.to_owned(); | |
|
566 | self.filtered_revs = filtered_revs.to_owned(); | |||
538 | Ok(as_vec) |
|
567 | Ok(as_vec) | |
539 | } |
|
568 | } | |
540 |
|
569 |
@@ -7,6 +7,8 b'' | |||||
7 |
|
7 | |||
8 | use crate::{ |
|
8 | use crate::{ | |
9 | cindex, |
|
9 | cindex, | |
|
10 | conversion::rev_pyiter_collect, | |||
|
11 | exceptions::GraphError, | |||
10 | utils::{node_from_py_bytes, node_from_py_object}, |
|
12 | utils::{node_from_py_bytes, node_from_py_object}, | |
11 | PyRevision, |
|
13 | PyRevision, | |
12 | }; |
|
14 | }; | |
@@ -259,7 +261,20 b' py_class!(pub class MixedIndex |py| {' | |||||
259 |
|
261 | |||
260 | /// get filtered head revisions |
|
262 | /// get filtered head revisions | |
261 | def headrevsfiltered(&self, *args, **kw) -> PyResult<PyObject> { |
|
263 | def headrevsfiltered(&self, *args, **kw) -> PyResult<PyObject> { | |
262 | self.call_cindex(py, "headrevsfiltered", args, kw) |
|
264 | let rust_res = self.inner_headrevsfiltered(py, &args.get_item(py, 0))?; | |
|
265 | let c_res = self.call_cindex(py, "headrevsfiltered", args, kw)?; | |||
|
266 | assert_eq!( | |||
|
267 | rust_res.len(), | |||
|
268 | c_res.len(py)?, | |||
|
269 | "filtered heads differ {:?} {}", | |||
|
270 | rust_res, | |||
|
271 | c_res | |||
|
272 | ); | |||
|
273 | for (index, rev) in rust_res.iter().enumerate() { | |||
|
274 | let c_rev: BaseRevision = c_res.get_item(py, index)?.extract(py)?; | |||
|
275 | assert_eq!(c_rev, rev.0); | |||
|
276 | } | |||
|
277 | Ok(c_res) | |||
263 | } |
|
278 | } | |
264 |
|
279 | |||
265 | /// True if the object is a snapshot |
|
280 | /// True if the object is a snapshot | |
@@ -797,6 +812,19 b' impl MixedIndex {' | |||||
797 | .collect(); |
|
812 | .collect(); | |
798 | Ok(PyList::new(py, &as_vec).into_object()) |
|
813 | Ok(PyList::new(py, &as_vec).into_object()) | |
799 | } |
|
814 | } | |
|
815 | ||||
|
816 | fn inner_headrevsfiltered( | |||
|
817 | &self, | |||
|
818 | py: Python, | |||
|
819 | filtered_revs: &PyObject, | |||
|
820 | ) -> PyResult<Vec<Revision>> { | |||
|
821 | let index = &mut *self.index(py).borrow_mut(); | |||
|
822 | let filtered_revs = rev_pyiter_collect(py, filtered_revs, index)?; | |||
|
823 | ||||
|
824 | index | |||
|
825 | .head_revs_filtered(&filtered_revs) | |||
|
826 | .map_err(|e| GraphError::pynew(py, e)) | |||
|
827 | } | |||
800 | } |
|
828 | } | |
801 |
|
829 | |||
802 | fn revlog_error(py: Python) -> PyErr { |
|
830 | fn revlog_error(py: Python) -> PyErr { |
General Comments 0
You need to be logged in to leave comments.
Login now