diff --git a/backup/src/delta.rs b/backup/src/delta.rs index 95ec391..cc831ac 100644 --- a/backup/src/delta.rs +++ b/backup/src/delta.rs @@ -110,19 +110,20 @@ impl Delta { out } - /// Given a chain of deltas, calculate the "contribution" for each state. + /// Given a chain of deltas, ordered from last to first, calculate the "contribution" for each + /// state. /// - /// For each delta, its contribution is the part of its added and removed files that isn't - /// overwritten by any of its following deltas. + /// The contribution of a delta in a given chain is defined as the parts of the state produced + /// by this chain that are actually provided by this delta. This comes down to calculating the + /// strict difference of this delta and all of its successive deltas. pub fn contributions(deltas: I) -> Vec where I: IntoIterator, - I::IntoIter: DoubleEndedIterator, I::Item: Borrow, { let mut contributions: Vec = Vec::new(); - let mut deltas = deltas.into_iter().rev(); + let mut deltas = deltas.into_iter(); if let Some(first_delta) = deltas.next() { // From last to first, we calculate the strict difference of the delta with the union of all its @@ -137,7 +138,8 @@ impl Delta { } } - contributions.reverse(); + // contributions.reverse(); + contributions } @@ -240,56 +242,4 @@ mod tests { let expected = Delta::default().with_added("dir_1", ["file1", "file2"]); assert_eq!(expected, b.union(&a)); } - - #[test] - fn test_difference() { - let a = Delta::default() - .with_added("dir1", ["file1", "file2"]) - .with_removed("dir1", ["file3", "file4"]); - let b = Delta::default() - .with_added("dir1", ["file1"]) - .with_removed("dir1", ["file3"]); - let expected = Delta::default() - .with_added("dir1", ["file2"]) - .with_removed("dir1", ["file4"]); - - assert_eq!(a.difference(&b), expected); - assert_eq!(b.difference(&a), Delta::default()); - } - - #[test] - fn test_strict_difference() { - let a = Delta::default() - .with_added("dir1", ["file1", "file2"]) - .with_removed("dir1", ["file3", "file4"]); - let b = Delta::default() - .with_added("dir1", ["file1", "file4"]) - .with_removed("dir1", ["file3"]); - let expected = Delta::default().with_added("dir1", ["file2"]); - - assert_eq!(a.strict_difference(&b), expected); - assert_eq!(b.strict_difference(&a), Delta::default()); - } - - #[test] - fn test_contributions() { - let deltas = [ - Delta::default().with_added("dir1", ["file4"]), - Delta::default().with_added("dir1", ["file1", "file2"]), - Delta::default() - .with_added("dir1", ["file1"]) - .with_added("dir2", ["file3"]), - Delta::default() - .with_added("dir1", ["file2"]) - .with_removed("dir2", ["file3"]), - ]; - let expected = [ - State::default().with_dir("dir1", ["file4"]), - State::default(), - State::default().with_dir("dir1", ["file1"]), - State::default().with_dir("dir1", ["file2"]), - ]; - - assert_eq!(Delta::contributions(deltas), expected); - } } diff --git a/backup/src/manager/mod.rs b/backup/src/manager/mod.rs index f13c69f..f8bbc73 100644 --- a/backup/src/manager/mod.rs +++ b/backup/src/manager/mod.rs @@ -229,8 +229,9 @@ where .map(|_| ()), // Incremental backups are exported one by one according to their contribution BackupType::Incremental => { - let contributions = - Delta::contributions(chain.iter().take(index + 1).map(|b| &b.delta)); + let contributions = Delta::contributions( + chain.iter().take(index + 1).map(|b| &b.delta).rev(), + ); let tar_gz = OpenOptions::new() .write(true) @@ -244,6 +245,7 @@ where // overwritten by their successors anyways. for (contribution, backup) in contributions .iter() + .rev() .zip(chain.iter().take(index + 1)) .filter(|(contribution, _)| !contribution.is_empty()) {