(repo: &impl Repo, segments: &[u64], offset: u64)
| 703 | } |
| 704 | |
| 705 | fn reset_to_internal(repo: &impl Repo, segments: &[u64], offset: u64) -> io::Result<()> { |
| 706 | for segment in segments.iter().copied().rev() { |
| 707 | if segment > offset { |
| 708 | // Segment is outside the offset, so remove it wholesale. |
| 709 | debug!("removing segment {segment}"); |
| 710 | repo.remove_segment(segment)?; |
| 711 | } else { |
| 712 | // Read commit-wise until we find the byte offset. |
| 713 | let mut reader = repo::open_segment_reader(repo, DEFAULT_LOG_FORMAT_VERSION, segment)?; |
| 714 | |
| 715 | let (index_file, mut byte_offset) = try_seek_using_offset_index(repo, &mut reader, offset) |
| 716 | .map(|(index_file, byte_offset)| (Some(index_file), byte_offset)) |
| 717 | .unwrap_or((None, segment::Header::LEN as u64)); |
| 718 | |
| 719 | let commits = reader.commits(); |
| 720 | |
| 721 | for commit in commits { |
| 722 | let commit = commit?; |
| 723 | if commit.min_tx_offset > offset { |
| 724 | break; |
| 725 | } |
| 726 | byte_offset += Commit::from(commit).encoded_len() as u64; |
| 727 | } |
| 728 | |
| 729 | if byte_offset == segment::Header::LEN as u64 { |
| 730 | // Segment is empty, just remove it. |
| 731 | repo.remove_segment(segment)?; |
| 732 | } else { |
| 733 | debug!("truncating segment {segment} to {offset} at {byte_offset}"); |
| 734 | let mut file = repo.open_segment_writer(segment)?; |
| 735 | |
| 736 | if let Some(mut index_file) = index_file { |
| 737 | let index_file = index_file.as_mut(); |
| 738 | // Note: The offset index truncates equal or greater, |
| 739 | // inclusive. We'd like to retain `offset` in the index, as |
| 740 | // the commit is also retained in the log. |
| 741 | index_file.ftruncate(offset + 1, byte_offset).map_err(|e| { |
| 742 | io::Error::new( |
| 743 | io::ErrorKind::InvalidData, |
| 744 | format!("Failed to truncate offset index: {e}"), |
| 745 | ) |
| 746 | })?; |
| 747 | index_file.async_flush()?; |
| 748 | } |
| 749 | |
| 750 | file.ftruncate(offset, byte_offset)?; |
| 751 | // Some filesystems require fsync after ftruncate. |
| 752 | file.fsync()?; |
| 753 | break; |
| 754 | } |
| 755 | } |
| 756 | } |
| 757 | |
| 758 | Ok(()) |
| 759 | } |
| 760 | |
| 761 | pub struct Segments<R> { |
| 762 | repo: R, |
no test coverage detected
searching dependent graphs…