##// END OF EJS Templates
rust-index: add support for `headrevsfiltered`...
Raphaël Gomès -
r52109:9f876765 default
parent child Browse files
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 if !self.head_revs.is_empty() {
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> = (0..self.len())
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 .collect();
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