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") |
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 /// |