rust/hg-core/src/revlog/index.rs
changeset 51396 b01e7d97e167
parent 51292 c4cbb515b006
child 51423 7c6d0b9dde37
equal deleted inserted replaced
51395:3f37d80d3ab4 51396:b01e7d97e167
   552     /// Python-specific shortcut to save on PyList creation
   552     /// Python-specific shortcut to save on PyList creation
   553     pub fn head_revs_shortcut(
   553     pub fn head_revs_shortcut(
   554         &self,
   554         &self,
   555     ) -> Result<Option<Vec<Revision>>, GraphError> {
   555     ) -> Result<Option<Vec<Revision>>, GraphError> {
   556         self.head_revs_filtered(&HashSet::new(), true)
   556         self.head_revs_filtered(&HashSet::new(), true)
       
   557     }
       
   558 
       
   559     /// Return the heads removed and added by advancing from `begin` to `end`.
       
   560     /// In revset language, we compute:
       
   561     /// - `heads(:begin)-heads(:end)`
       
   562     /// - `heads(:end)-heads(:begin)`
       
   563     pub fn head_revs_diff(
       
   564         &self,
       
   565         begin: Revision,
       
   566         end: Revision,
       
   567     ) -> Result<(Vec<Revision>, Vec<Revision>), GraphError> {
       
   568         let mut heads_added = vec![];
       
   569         let mut heads_removed = vec![];
       
   570 
       
   571         let mut acc = HashSet::new();
       
   572         let Revision(begin) = begin;
       
   573         let Revision(end) = end;
       
   574         let mut i = end;
       
   575 
       
   576         while i > begin {
       
   577             // acc invariant:
       
   578             // `j` is in the set iff `j <= i` and it has children
       
   579             // among `i+1..end` (inclusive)
       
   580             if !acc.remove(&i) {
       
   581                 heads_added.push(Revision(i));
       
   582             }
       
   583             for Revision(parent) in self.parents(Revision(i))? {
       
   584                 acc.insert(parent);
       
   585             }
       
   586             i -= 1;
       
   587         }
       
   588 
       
   589         // At this point `acc` contains old revisions that gained new children.
       
   590         // We need to check if they had any children before. If not, those
       
   591         // revisions are the removed heads.
       
   592         while !acc.is_empty() {
       
   593             // acc invariant:
       
   594             // `j` is in the set iff `j <= i` and it has children
       
   595             // among `begin+1..end`, but not among `i+1..begin` (inclusive)
       
   596 
       
   597             assert!(i >= -1); // yes, `-1` can also be a head if the repo is empty
       
   598             if acc.remove(&i) {
       
   599                 heads_removed.push(Revision(i));
       
   600             }
       
   601             for Revision(parent) in self.parents(Revision(i))? {
       
   602                 acc.remove(&parent);
       
   603             }
       
   604             i -= 1;
       
   605         }
       
   606 
       
   607         Ok((heads_removed, heads_added))
   557     }
   608     }
   558 
   609 
   559     /// Return the head revisions of this index
   610     /// Return the head revisions of this index
   560     pub fn head_revs_filtered(
   611     pub fn head_revs_filtered(
   561         &self,
   612         &self,