rust/hg-core/src/ancestors.rs
changeset 50990 4c5f6e95df84
parent 50003 e98fd81bb151
child 51495 b08c5fbe0e70
equal deleted inserted replaced
50989:27e773aa607d 50990:4c5f6e95df84
   245         while curr != NULL_REVISION && revs.len() > keepcount {
   245         while curr != NULL_REVISION && revs.len() > keepcount {
   246             if self.bases.contains(&curr) {
   246             if self.bases.contains(&curr) {
   247                 revs.remove(&curr);
   247                 revs.remove(&curr);
   248                 self.add_parents(curr)?;
   248                 self.add_parents(curr)?;
   249             }
   249             }
   250             curr -= 1;
   250             // We know this revision is safe because we've checked the bounds
       
   251             // before.
       
   252             curr = Revision(curr.0 - 1);
   251         }
   253         }
   252         Ok(())
   254         Ok(())
   253     }
   255     }
   254 
   256 
   255     /// Add the parents of `rev` to `self.bases`
   257     /// Add the parents of `rev` to `self.bases`
   295         let max_revs = revs_visit.iter().cloned().max().unwrap();
   297         let max_revs = revs_visit.iter().cloned().max().unwrap();
   296         let start = max(self.max_base, max_revs);
   298         let start = max(self.max_base, max_revs);
   297 
   299 
   298         // TODO heuristics for with_capacity()?
   300         // TODO heuristics for with_capacity()?
   299         let mut missing: Vec<Revision> = Vec::new();
   301         let mut missing: Vec<Revision> = Vec::new();
   300         for curr in (0..=start).rev() {
   302         for curr in (0..=start.0).rev() {
   301             if revs_visit.is_empty() {
   303             if revs_visit.is_empty() {
   302                 break;
   304                 break;
   303             }
   305             }
   304             if both_visit.remove(&curr) {
   306             if both_visit.remove(&Revision(curr)) {
   305                 // curr's parents might have made it into revs_visit through
   307                 // curr's parents might have made it into revs_visit through
   306                 // another path
   308                 // another path
   307                 for p in self.graph.parents(curr)?.iter().cloned() {
   309                 for p in self.graph.parents(Revision(curr))?.iter().cloned() {
   308                     if p == NULL_REVISION {
   310                     if p == NULL_REVISION {
   309                         continue;
   311                         continue;
   310                     }
   312                     }
   311                     revs_visit.remove(&p);
   313                     revs_visit.remove(&p);
   312                     bases_visit.insert(p);
   314                     bases_visit.insert(p);
   313                     both_visit.insert(p);
   315                     both_visit.insert(p);
   314                 }
   316                 }
   315             } else if revs_visit.remove(&curr) {
   317             } else if revs_visit.remove(&Revision(curr)) {
   316                 missing.push(curr);
   318                 missing.push(Revision(curr));
   317                 for p in self.graph.parents(curr)?.iter().cloned() {
   319                 for p in self.graph.parents(Revision(curr))?.iter().cloned() {
   318                     if p == NULL_REVISION {
   320                     if p == NULL_REVISION {
   319                         continue;
   321                         continue;
   320                     }
   322                     }
   321                     if bases_visit.contains(&p) {
   323                     if bases_visit.contains(&p) {
   322                         // p is already known to be an ancestor of revs_visit
   324                         // p is already known to be an ancestor of revs_visit
   329                     } else {
   331                     } else {
   330                         // visit later
   332                         // visit later
   331                         revs_visit.insert(p);
   333                         revs_visit.insert(p);
   332                     }
   334                     }
   333                 }
   335                 }
   334             } else if bases_visit.contains(&curr) {
   336             } else if bases_visit.contains(&Revision(curr)) {
   335                 for p in self.graph.parents(curr)?.iter().cloned() {
   337                 for p in self.graph.parents(Revision(curr))?.iter().cloned() {
   336                     if p == NULL_REVISION {
   338                     if p == NULL_REVISION {
   337                         continue;
   339                         continue;
   338                     }
   340                     }
   339                     if revs_visit.remove(&p) || both_visit.contains(&p) {
   341                     if revs_visit.remove(&p) || both_visit.contains(&p) {
   340                         // p is an ancestor of bases_visit, and is implicitly
   342                         // p is an ancestor of bases_visit, and is implicitly
   354 
   356 
   355 #[cfg(test)]
   357 #[cfg(test)]
   356 mod tests {
   358 mod tests {
   357 
   359 
   358     use super::*;
   360     use super::*;
   359     use crate::testing::{SampleGraph, VecGraph};
   361     use crate::{
       
   362         testing::{SampleGraph, VecGraph},
       
   363         BaseRevision,
       
   364     };
       
   365 
       
   366     impl From<BaseRevision> for Revision {
       
   367         fn from(value: BaseRevision) -> Self {
       
   368             if !cfg!(test) {
       
   369                 panic!("should only be used in tests")
       
   370             }
       
   371             Revision(value)
       
   372         }
       
   373     }
       
   374 
       
   375     impl PartialEq<BaseRevision> for Revision {
       
   376         fn eq(&self, other: &BaseRevision) -> bool {
       
   377             if !cfg!(test) {
       
   378                 panic!("should only be used in tests")
       
   379             }
       
   380             self.0.eq(other)
       
   381         }
       
   382     }
       
   383 
       
   384     impl PartialEq<u32> for Revision {
       
   385         fn eq(&self, other: &u32) -> bool {
       
   386             if !cfg!(test) {
       
   387                 panic!("should only be used in tests")
       
   388             }
       
   389             let check: Result<u32, _> = self.0.try_into();
       
   390             match check {
       
   391                 Ok(value) => value.eq(other),
       
   392                 Err(_) => false,
       
   393             }
       
   394         }
       
   395     }
   360 
   396 
   361     fn list_ancestors<G: Graph>(
   397     fn list_ancestors<G: Graph>(
   362         graph: G,
   398         graph: G,
   363         initrevs: Vec<Revision>,
   399         initrevs: Vec<Revision>,
   364         stoprev: Revision,
   400         stoprev: Revision,
   372 
   408 
   373     #[test]
   409     #[test]
   374     /// Same tests as test-ancestor.py, without membership
   410     /// Same tests as test-ancestor.py, without membership
   375     /// (see also test-ancestor.py.out)
   411     /// (see also test-ancestor.py.out)
   376     fn test_list_ancestor() {
   412     fn test_list_ancestor() {
   377         assert_eq!(list_ancestors(SampleGraph, vec![], 0, false), vec![]);
   413         assert_eq!(
   378         assert_eq!(
   414             list_ancestors(SampleGraph, vec![], 0.into(), false),
   379             list_ancestors(SampleGraph, vec![11, 13], 0, false),
   415             Vec::<Revision>::new()
       
   416         );
       
   417         assert_eq!(
       
   418             list_ancestors(
       
   419                 SampleGraph,
       
   420                 vec![11.into(), 13.into()],
       
   421                 0.into(),
       
   422                 false
       
   423             ),
   380             vec![8, 7, 4, 3, 2, 1, 0]
   424             vec![8, 7, 4, 3, 2, 1, 0]
   381         );
   425         );
   382         assert_eq!(
   426         assert_eq!(
   383             list_ancestors(SampleGraph, vec![1, 3], 0, false),
   427             list_ancestors(
       
   428                 SampleGraph,
       
   429                 vec![1.into(), 3.into()],
       
   430                 0.into(),
       
   431                 false
       
   432             ),
   384             vec![1, 0]
   433             vec![1, 0]
   385         );
   434         );
   386         assert_eq!(
   435         assert_eq!(
   387             list_ancestors(SampleGraph, vec![11, 13], 0, true),
   436             list_ancestors(
       
   437                 SampleGraph,
       
   438                 vec![11.into(), 13.into()],
       
   439                 0.into(),
       
   440                 true
       
   441             ),
   388             vec![13, 11, 8, 7, 4, 3, 2, 1, 0]
   442             vec![13, 11, 8, 7, 4, 3, 2, 1, 0]
   389         );
   443         );
   390         assert_eq!(
   444         assert_eq!(
   391             list_ancestors(SampleGraph, vec![11, 13], 6, false),
   445             list_ancestors(
       
   446                 SampleGraph,
       
   447                 vec![11.into(), 13.into()],
       
   448                 6.into(),
       
   449                 false
       
   450             ),
   392             vec![8, 7]
   451             vec![8, 7]
   393         );
   452         );
   394         assert_eq!(
   453         assert_eq!(
   395             list_ancestors(SampleGraph, vec![11, 13], 6, true),
   454             list_ancestors(
       
   455                 SampleGraph,
       
   456                 vec![11.into(), 13.into()],
       
   457                 6.into(),
       
   458                 true
       
   459             ),
   396             vec![13, 11, 8, 7]
   460             vec![13, 11, 8, 7]
   397         );
   461         );
   398         assert_eq!(
   462         assert_eq!(
   399             list_ancestors(SampleGraph, vec![11, 13], 11, true),
   463             list_ancestors(
       
   464                 SampleGraph,
       
   465                 vec![11.into(), 13.into()],
       
   466                 11.into(),
       
   467                 true
       
   468             ),
   400             vec![13, 11]
   469             vec![13, 11]
   401         );
   470         );
   402         assert_eq!(
   471         assert_eq!(
   403             list_ancestors(SampleGraph, vec![11, 13], 12, true),
   472             list_ancestors(
       
   473                 SampleGraph,
       
   474                 vec![11.into(), 13.into()],
       
   475                 12.into(),
       
   476                 true
       
   477             ),
   404             vec![13]
   478             vec![13]
   405         );
   479         );
   406         assert_eq!(
   480         assert_eq!(
   407             list_ancestors(SampleGraph, vec![10, 1], 0, true),
   481             list_ancestors(
       
   482                 SampleGraph,
       
   483                 vec![10.into(), 1.into()],
       
   484                 0.into(),
       
   485                 true
       
   486             ),
   408             vec![10, 5, 4, 2, 1, 0]
   487             vec![10, 5, 4, 2, 1, 0]
   409         );
   488         );
   410     }
   489     }
   411 
   490 
   412     #[test]
   491     #[test]
   413     /// Corner case that's not directly in test-ancestors.py, but
   492     /// Corner case that's not directly in test-ancestors.py, but
   414     /// that happens quite often, as demonstrated by running the whole
   493     /// that happens quite often, as demonstrated by running the whole
   415     /// suite.
   494     /// suite.
   416     /// For instance, run tests/test-obsolete-checkheads.t
   495     /// For instance, run tests/test-obsolete-checkheads.t
   417     fn test_nullrev_input() {
   496     fn test_nullrev_input() {
   418         let mut iter =
   497         let mut iter = AncestorsIterator::new(
   419             AncestorsIterator::new(SampleGraph, vec![-1], 0, false).unwrap();
   498             SampleGraph,
       
   499             vec![Revision(-1)],
       
   500             0.into(),
       
   501             false,
       
   502         )
       
   503         .unwrap();
   420         assert_eq!(iter.next(), None)
   504         assert_eq!(iter.next(), None)
   421     }
   505     }
   422 
   506 
   423     #[test]
   507     #[test]
   424     fn test_contains() {
   508     fn test_contains() {
   425         let mut lazy =
   509         let mut lazy = AncestorsIterator::new(
   426             AncestorsIterator::new(SampleGraph, vec![10, 1], 0, true).unwrap();
   510             SampleGraph,
   427         assert!(lazy.contains(1).unwrap());
   511             vec![10.into(), 1.into()],
   428         assert!(!lazy.contains(3).unwrap());
   512             0.into(),
   429 
   513             true,
   430         let mut lazy =
   514         )
   431             AncestorsIterator::new(SampleGraph, vec![0], 0, false).unwrap();
   515         .unwrap();
       
   516         assert!(lazy.contains(1.into()).unwrap());
       
   517         assert!(!lazy.contains(3.into()).unwrap());
       
   518 
       
   519         let mut lazy = AncestorsIterator::new(
       
   520             SampleGraph,
       
   521             vec![0.into()],
       
   522             0.into(),
       
   523             false,
       
   524         )
       
   525         .unwrap();
   432         assert!(!lazy.contains(NULL_REVISION).unwrap());
   526         assert!(!lazy.contains(NULL_REVISION).unwrap());
   433     }
   527     }
   434 
   528 
   435     #[test]
   529     #[test]
   436     fn test_peek() {
   530     fn test_peek() {
   437         let mut iter =
   531         let mut iter = AncestorsIterator::new(
   438             AncestorsIterator::new(SampleGraph, vec![10], 0, true).unwrap();
   532             SampleGraph,
       
   533             vec![10.into()],
       
   534             0.into(),
       
   535             true,
       
   536         )
       
   537         .unwrap();
   439         // peek() gives us the next value
   538         // peek() gives us the next value
   440         assert_eq!(iter.peek(), Some(10));
   539         assert_eq!(iter.peek(), Some(10.into()));
   441         // but it's not been consumed
   540         // but it's not been consumed
   442         assert_eq!(iter.next(), Some(Ok(10)));
   541         assert_eq!(iter.next(), Some(Ok(10.into())));
   443         // and iteration resumes normally
   542         // and iteration resumes normally
   444         assert_eq!(iter.next(), Some(Ok(5)));
   543         assert_eq!(iter.next(), Some(Ok(5.into())));
   445 
   544 
   446         // let's drain the iterator to test peek() at the end
   545         // let's drain the iterator to test peek() at the end
   447         while iter.next().is_some() {}
   546         while iter.next().is_some() {}
   448         assert_eq!(iter.peek(), None);
   547         assert_eq!(iter.peek(), None);
   449     }
   548     }
   450 
   549 
   451     #[test]
   550     #[test]
   452     fn test_empty() {
   551     fn test_empty() {
   453         let mut iter =
   552         let mut iter = AncestorsIterator::new(
   454             AncestorsIterator::new(SampleGraph, vec![10], 0, true).unwrap();
   553             SampleGraph,
       
   554             vec![10.into()],
       
   555             0.into(),
       
   556             true,
       
   557         )
       
   558         .unwrap();
   455         assert!(!iter.is_empty());
   559         assert!(!iter.is_empty());
   456         while iter.next().is_some() {}
   560         while iter.next().is_some() {}
   457         assert!(!iter.is_empty());
   561         assert!(!iter.is_empty());
   458 
   562 
   459         let iter =
   563         let iter = AncestorsIterator::new(SampleGraph, vec![], 0.into(), true)
   460             AncestorsIterator::new(SampleGraph, vec![], 0, true).unwrap();
   564             .unwrap();
   461         assert!(iter.is_empty());
   565         assert!(iter.is_empty());
   462 
   566 
   463         // case where iter.seen == {NULL_REVISION}
   567         // case where iter.seen == {NULL_REVISION}
   464         let iter =
   568         let iter = AncestorsIterator::new(
   465             AncestorsIterator::new(SampleGraph, vec![0], 0, false).unwrap();
   569             SampleGraph,
       
   570             vec![0.into()],
       
   571             0.into(),
       
   572             false,
       
   573         )
       
   574         .unwrap();
   466         assert!(iter.is_empty());
   575         assert!(iter.is_empty());
   467     }
   576     }
   468 
   577 
   469     /// A corrupted Graph, supporting error handling tests
   578     /// A corrupted Graph, supporting error handling tests
   470     #[derive(Clone, Debug)]
   579     #[derive(Clone, Debug)]
   471     struct Corrupted;
   580     struct Corrupted;
   472 
   581 
   473     impl Graph for Corrupted {
   582     impl Graph for Corrupted {
       
   583         // FIXME what to do about this? Are we just not supposed to get them
       
   584         // anymore?
   474         fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
   585         fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError> {
   475             match rev {
   586             match rev {
   476                 1 => Ok([0, -1]),
   587                 Revision(1) => Ok([0.into(), (-1).into()]),
   477                 r => Err(GraphError::ParentOutOfRange(r)),
   588                 r => Err(GraphError::ParentOutOfRange(r)),
   478             }
   589             }
   479         }
   590         }
   480     }
   591     }
   481 
   592 
   482     #[test]
   593     #[test]
   483     fn test_initrev_out_of_range() {
   594     fn test_initrev_out_of_range() {
   484         // inclusive=false looks up initrev's parents right away
   595         // inclusive=false looks up initrev's parents right away
   485         match AncestorsIterator::new(SampleGraph, vec![25], 0, false) {
   596         match AncestorsIterator::new(
       
   597             SampleGraph,
       
   598             vec![25.into()],
       
   599             0.into(),
       
   600             false,
       
   601         ) {
   486             Ok(_) => panic!("Should have been ParentOutOfRange"),
   602             Ok(_) => panic!("Should have been ParentOutOfRange"),
   487             Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25)),
   603             Err(e) => assert_eq!(e, GraphError::ParentOutOfRange(25.into())),
   488         }
   604         }
   489     }
   605     }
   490 
   606 
   491     #[test]
   607     #[test]
   492     fn test_next_out_of_range() {
   608     fn test_next_out_of_range() {
   493         // inclusive=false looks up initrev's parents right away
   609         // inclusive=false looks up initrev's parents right away
   494         let mut iter =
   610         let mut iter =
   495             AncestorsIterator::new(Corrupted, vec![1], 0, false).unwrap();
   611             AncestorsIterator::new(Corrupted, vec![1.into()], 0.into(), false)
   496         assert_eq!(iter.next(), Some(Err(GraphError::ParentOutOfRange(0))));
   612                 .unwrap();
       
   613         assert_eq!(
       
   614             iter.next(),
       
   615             Some(Err(GraphError::ParentOutOfRange(0.into())))
       
   616         );
   497     }
   617     }
   498 
   618 
   499     #[test]
   619     #[test]
   500     /// Test constructor, add/get bases and heads
   620     /// Test constructor, add/get bases and heads
   501     fn test_missing_bases() -> Result<(), GraphError> {
   621     fn test_missing_bases() -> Result<(), GraphError> {
   502         let mut missing_ancestors =
   622         let mut missing_ancestors = MissingAncestors::new(
   503             MissingAncestors::new(SampleGraph, [5, 3, 1, 3].iter().cloned());
   623             SampleGraph,
       
   624             [5.into(), 3.into(), 1.into(), 3.into()].iter().cloned(),
       
   625         );
   504         let mut as_vec: Vec<Revision> =
   626         let mut as_vec: Vec<Revision> =
   505             missing_ancestors.get_bases().iter().cloned().collect();
   627             missing_ancestors.get_bases().iter().cloned().collect();
   506         as_vec.sort_unstable();
   628         as_vec.sort_unstable();
   507         assert_eq!(as_vec, [1, 3, 5]);
   629         assert_eq!(as_vec, [1, 3, 5]);
   508         assert_eq!(missing_ancestors.max_base, 5);
   630         assert_eq!(missing_ancestors.max_base, 5);
   509 
   631 
   510         missing_ancestors.add_bases([3, 7, 8].iter().cloned());
   632         missing_ancestors
       
   633             .add_bases([3.into(), 7.into(), 8.into()].iter().cloned());
   511         as_vec = missing_ancestors.get_bases().iter().cloned().collect();
   634         as_vec = missing_ancestors.get_bases().iter().cloned().collect();
   512         as_vec.sort_unstable();
   635         as_vec.sort_unstable();
   513         assert_eq!(as_vec, [1, 3, 5, 7, 8]);
   636         assert_eq!(as_vec, [1, 3, 5, 7, 8]);
   514         assert_eq!(missing_ancestors.max_base, 8);
   637         assert_eq!(missing_ancestors.max_base, 8);
   515 
   638 
   518         assert_eq!(as_vec, [3, 5, 7, 8]);
   641         assert_eq!(as_vec, [3, 5, 7, 8]);
   519         Ok(())
   642         Ok(())
   520     }
   643     }
   521 
   644 
   522     fn assert_missing_remove(
   645     fn assert_missing_remove(
   523         bases: &[Revision],
   646         bases: &[BaseRevision],
   524         revs: &[Revision],
   647         revs: &[BaseRevision],
   525         expected: &[Revision],
   648         expected: &[BaseRevision],
   526     ) {
   649     ) {
   527         let mut missing_ancestors =
   650         let mut missing_ancestors = MissingAncestors::new(
   528             MissingAncestors::new(SampleGraph, bases.iter().cloned());
   651             SampleGraph,
   529         let mut revset: HashSet<Revision> = revs.iter().cloned().collect();
   652             bases.iter().map(|r| Revision(*r)),
       
   653         );
       
   654         let mut revset: HashSet<Revision> =
       
   655             revs.iter().map(|r| Revision(*r)).collect();
   530         missing_ancestors
   656         missing_ancestors
   531             .remove_ancestors_from(&mut revset)
   657             .remove_ancestors_from(&mut revset)
   532             .unwrap();
   658             .unwrap();
   533         let mut as_vec: Vec<Revision> = revset.into_iter().collect();
   659         let mut as_vec: Vec<Revision> = revset.into_iter().collect();
   534         as_vec.sort_unstable();
   660         as_vec.sort_unstable();
   545         assert_missing_remove(&[10], &[11, 12, 13, 14], &[11, 12, 13, 14]);
   671         assert_missing_remove(&[10], &[11, 12, 13, 14], &[11, 12, 13, 14]);
   546         assert_missing_remove(&[7], &[1, 2, 3, 4, 5], &[3, 5]);
   672         assert_missing_remove(&[7], &[1, 2, 3, 4, 5], &[3, 5]);
   547     }
   673     }
   548 
   674 
   549     fn assert_missing_ancestors(
   675     fn assert_missing_ancestors(
   550         bases: &[Revision],
   676         bases: &[BaseRevision],
   551         revs: &[Revision],
   677         revs: &[BaseRevision],
   552         expected: &[Revision],
   678         expected: &[BaseRevision],
   553     ) {
   679     ) {
   554         let mut missing_ancestors =
   680         let mut missing_ancestors = MissingAncestors::new(
   555             MissingAncestors::new(SampleGraph, bases.iter().cloned());
   681             SampleGraph,
       
   682             bases.iter().map(|r| Revision(*r)),
       
   683         );
   556         let missing = missing_ancestors
   684         let missing = missing_ancestors
   557             .missing_ancestors(revs.iter().cloned())
   685             .missing_ancestors(revs.iter().map(|r| Revision(*r)))
   558             .unwrap();
   686             .unwrap();
   559         assert_eq!(missing.as_slice(), expected);
   687         assert_eq!(missing.as_slice(), expected);
   560     }
   688     }
   561 
   689 
   562     #[test]
   690     #[test]
   573     /// failed this, yet none of the integration tests of the whole suite
   701     /// failed this, yet none of the integration tests of the whole suite
   574     /// catched it.
   702     /// catched it.
   575     #[allow(clippy::unnecessary_cast)]
   703     #[allow(clippy::unnecessary_cast)]
   576     #[test]
   704     #[test]
   577     fn test_remove_ancestors_from_case1() {
   705     fn test_remove_ancestors_from_case1() {
       
   706         const FAKE_NULL_REVISION: BaseRevision = -1;
       
   707         assert_eq!(FAKE_NULL_REVISION, NULL_REVISION.0);
   578         let graph: VecGraph = vec![
   708         let graph: VecGraph = vec![
   579             [NULL_REVISION, NULL_REVISION],
   709             [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
   580             [0, NULL_REVISION],
   710             [0, FAKE_NULL_REVISION],
   581             [1, 0],
   711             [1, 0],
   582             [2, 1],
   712             [2, 1],
   583             [3, NULL_REVISION],
   713             [3, FAKE_NULL_REVISION],
   584             [4, NULL_REVISION],
   714             [4, FAKE_NULL_REVISION],
   585             [5, 1],
   715             [5, 1],
   586             [2, NULL_REVISION],
   716             [2, FAKE_NULL_REVISION],
   587             [7, NULL_REVISION],
   717             [7, FAKE_NULL_REVISION],
   588             [8, NULL_REVISION],
   718             [8, FAKE_NULL_REVISION],
   589             [9, NULL_REVISION],
   719             [9, FAKE_NULL_REVISION],
   590             [10, 1],
   720             [10, 1],
   591             [3, NULL_REVISION],
   721             [3, FAKE_NULL_REVISION],
   592             [12, NULL_REVISION],
   722             [12, FAKE_NULL_REVISION],
   593             [13, NULL_REVISION],
   723             [13, FAKE_NULL_REVISION],
   594             [14, NULL_REVISION],
   724             [14, FAKE_NULL_REVISION],
   595             [4, NULL_REVISION],
   725             [4, FAKE_NULL_REVISION],
   596             [16, NULL_REVISION],
   726             [16, FAKE_NULL_REVISION],
   597             [17, NULL_REVISION],
   727             [17, FAKE_NULL_REVISION],
   598             [18, NULL_REVISION],
   728             [18, FAKE_NULL_REVISION],
   599             [19, 11],
   729             [19, 11],
   600             [20, NULL_REVISION],
   730             [20, FAKE_NULL_REVISION],
   601             [21, NULL_REVISION],
   731             [21, FAKE_NULL_REVISION],
   602             [22, NULL_REVISION],
   732             [22, FAKE_NULL_REVISION],
   603             [23, NULL_REVISION],
   733             [23, FAKE_NULL_REVISION],
   604             [2, NULL_REVISION],
   734             [2, FAKE_NULL_REVISION],
   605             [3, NULL_REVISION],
   735             [3, FAKE_NULL_REVISION],
   606             [26, 24],
   736             [26, 24],
   607             [27, NULL_REVISION],
   737             [27, FAKE_NULL_REVISION],
   608             [28, NULL_REVISION],
   738             [28, FAKE_NULL_REVISION],
   609             [12, NULL_REVISION],
   739             [12, FAKE_NULL_REVISION],
   610             [1, NULL_REVISION],
   740             [1, FAKE_NULL_REVISION],
   611             [1, 9],
   741             [1, 9],
   612             [32, NULL_REVISION],
   742             [32, FAKE_NULL_REVISION],
   613             [33, NULL_REVISION],
   743             [33, FAKE_NULL_REVISION],
   614             [34, 31],
   744             [34, 31],
   615             [35, NULL_REVISION],
   745             [35, FAKE_NULL_REVISION],
   616             [36, 26],
   746             [36, 26],
   617             [37, NULL_REVISION],
   747             [37, FAKE_NULL_REVISION],
   618             [38, NULL_REVISION],
   748             [38, FAKE_NULL_REVISION],
   619             [39, NULL_REVISION],
   749             [39, FAKE_NULL_REVISION],
   620             [40, NULL_REVISION],
   750             [40, FAKE_NULL_REVISION],
   621             [41, NULL_REVISION],
   751             [41, FAKE_NULL_REVISION],
   622             [42, 26],
   752             [42, 26],
   623             [0, NULL_REVISION],
   753             [0, FAKE_NULL_REVISION],
   624             [44, NULL_REVISION],
   754             [44, FAKE_NULL_REVISION],
   625             [45, 4],
   755             [45, 4],
   626             [40, NULL_REVISION],
   756             [40, FAKE_NULL_REVISION],
   627             [47, NULL_REVISION],
   757             [47, FAKE_NULL_REVISION],
   628             [36, 0],
   758             [36, 0],
   629             [49, NULL_REVISION],
   759             [49, FAKE_NULL_REVISION],
   630             [NULL_REVISION, NULL_REVISION],
   760             [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
   631             [51, NULL_REVISION],
   761             [51, FAKE_NULL_REVISION],
   632             [52, NULL_REVISION],
   762             [52, FAKE_NULL_REVISION],
   633             [53, NULL_REVISION],
   763             [53, FAKE_NULL_REVISION],
   634             [14, NULL_REVISION],
   764             [14, FAKE_NULL_REVISION],
   635             [55, NULL_REVISION],
   765             [55, FAKE_NULL_REVISION],
   636             [15, NULL_REVISION],
   766             [15, FAKE_NULL_REVISION],
   637             [23, NULL_REVISION],
   767             [23, FAKE_NULL_REVISION],
   638             [58, NULL_REVISION],
   768             [58, FAKE_NULL_REVISION],
   639             [59, NULL_REVISION],
   769             [59, FAKE_NULL_REVISION],
   640             [2, NULL_REVISION],
   770             [2, FAKE_NULL_REVISION],
   641             [61, 59],
   771             [61, 59],
   642             [62, NULL_REVISION],
   772             [62, FAKE_NULL_REVISION],
   643             [63, NULL_REVISION],
   773             [63, FAKE_NULL_REVISION],
   644             [NULL_REVISION, NULL_REVISION],
   774             [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
   645             [65, NULL_REVISION],
   775             [65, FAKE_NULL_REVISION],
   646             [66, NULL_REVISION],
   776             [66, FAKE_NULL_REVISION],
   647             [67, NULL_REVISION],
   777             [67, FAKE_NULL_REVISION],
   648             [68, NULL_REVISION],
   778             [68, FAKE_NULL_REVISION],
   649             [37, 28],
   779             [37, 28],
   650             [69, 25],
   780             [69, 25],
   651             [71, NULL_REVISION],
   781             [71, FAKE_NULL_REVISION],
   652             [72, NULL_REVISION],
   782             [72, FAKE_NULL_REVISION],
   653             [50, 2],
   783             [50, 2],
   654             [74, NULL_REVISION],
   784             [74, FAKE_NULL_REVISION],
   655             [12, NULL_REVISION],
   785             [12, FAKE_NULL_REVISION],
   656             [18, NULL_REVISION],
   786             [18, FAKE_NULL_REVISION],
   657             [77, NULL_REVISION],
   787             [77, FAKE_NULL_REVISION],
   658             [78, NULL_REVISION],
   788             [78, FAKE_NULL_REVISION],
   659             [79, NULL_REVISION],
   789             [79, FAKE_NULL_REVISION],
   660             [43, 33],
   790             [43, 33],
   661             [81, NULL_REVISION],
   791             [81, FAKE_NULL_REVISION],
   662             [82, NULL_REVISION],
   792             [82, FAKE_NULL_REVISION],
   663             [83, NULL_REVISION],
   793             [83, FAKE_NULL_REVISION],
   664             [84, 45],
   794             [84, 45],
   665             [85, NULL_REVISION],
   795             [85, FAKE_NULL_REVISION],
   666             [86, NULL_REVISION],
   796             [86, FAKE_NULL_REVISION],
   667             [NULL_REVISION, NULL_REVISION],
   797             [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
   668             [88, NULL_REVISION],
   798             [88, FAKE_NULL_REVISION],
   669             [NULL_REVISION, NULL_REVISION],
   799             [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
   670             [76, 83],
   800             [76, 83],
   671             [44, NULL_REVISION],
   801             [44, FAKE_NULL_REVISION],
   672             [92, NULL_REVISION],
   802             [92, FAKE_NULL_REVISION],
   673             [93, NULL_REVISION],
   803             [93, FAKE_NULL_REVISION],
   674             [9, NULL_REVISION],
   804             [9, FAKE_NULL_REVISION],
   675             [95, 67],
   805             [95, 67],
   676             [96, NULL_REVISION],
   806             [96, FAKE_NULL_REVISION],
   677             [97, NULL_REVISION],
   807             [97, FAKE_NULL_REVISION],
   678             [NULL_REVISION, NULL_REVISION],
   808             [FAKE_NULL_REVISION, FAKE_NULL_REVISION],
   679         ];
   809         ]
   680         let problem_rev = 28 as Revision;
   810         .into_iter()
   681         let problem_base = 70 as Revision;
   811         .map(|[a, b]| [Revision(a), Revision(b)])
       
   812         .collect();
       
   813         let problem_rev = 28.into();
       
   814         let problem_base = 70.into();
   682         // making the problem obvious: problem_rev is a parent of problem_base
   815         // making the problem obvious: problem_rev is a parent of problem_base
   683         assert_eq!(graph.parents(problem_base).unwrap()[1], problem_rev);
   816         assert_eq!(graph.parents(problem_base).unwrap()[1], problem_rev);
   684 
   817 
   685         let mut missing_ancestors: MissingAncestors<VecGraph> =
   818         let mut missing_ancestors: MissingAncestors<VecGraph> =
   686             MissingAncestors::new(
   819             MissingAncestors::new(
   687                 graph,
   820                 graph,
   688                 [60, 26, 70, 3, 96, 19, 98, 49, 97, 47, 1, 6]
   821                 [60, 26, 70, 3, 96, 19, 98, 49, 97, 47, 1, 6]
   689                     .iter()
   822                     .iter()
   690                     .cloned(),
   823                     .map(|r| Revision(*r)),
   691             );
   824             );
   692         assert!(missing_ancestors.bases.contains(&problem_base));
   825         assert!(missing_ancestors.bases.contains(&problem_base));
   693 
   826 
   694         let mut revs: HashSet<Revision> =
   827         let mut revs: HashSet<Revision> =
   695             [4, 12, 41, 28, 68, 38, 1, 30, 56, 44]
   828             [4, 12, 41, 28, 68, 38, 1, 30, 56, 44]
   696                 .iter()
   829                 .iter()
   697                 .cloned()
   830                 .map(|r| Revision(*r))
   698                 .collect();
   831                 .collect();
   699         missing_ancestors.remove_ancestors_from(&mut revs).unwrap();
   832         missing_ancestors.remove_ancestors_from(&mut revs).unwrap();
   700         assert!(!revs.contains(&problem_rev));
   833         assert!(!revs.contains(&problem_rev));
   701     }
   834     }
   702 }
   835 }