rust/hg-core/src/revlog/index.rs
changeset 51216 9f876765cbe2
parent 51215 a7bba7df9189
child 51218 0112803e6c01
equal deleted inserted replaced
51215:a7bba7df9189 51216:9f876765cbe2
   261     uses_generaldelta: bool,
   261     uses_generaldelta: bool,
   262     is_inline: bool,
   262     is_inline: bool,
   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 {
   269     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
   272     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
   270         f.debug_struct("Index")
   273         f.debug_struct("Index")
   361                     bytes: IndexData::new(bytes),
   364                     bytes: IndexData::new(bytes),
   362                     offsets: RwLock::new(Some(offsets)),
   365                     offsets: RwLock::new(Some(offsets)),
   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"))
   369             }
   373             }
   370         } else {
   374         } else {
   372                 bytes: IndexData::new(bytes),
   376                 bytes: IndexData::new(bytes),
   373                 offsets: RwLock::new(None),
   377                 offsets: RwLock::new(None),
   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     }
   380 
   385 
   381     pub fn uses_generaldelta(&self) -> bool {
   386     pub fn uses_generaldelta(&self) -> bool {
   518         }
   523         }
   519     }
   524     }
   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);
   533         }
   561         }
   534         let mut as_vec: Vec<Revision> =
   562         let mut as_vec: Vec<Revision> =
   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 
   541     /// Obtain the delta chain for a revision.
   570     /// Obtain the delta chain for a revision.
   542     ///
   571     ///