Compare commits
	
		
			No commits in common. "f2a0b6230fe419e61710e6dee2a2b6f9554b560e" and "15c4839a819b9dd6ae92c8cc9aa10654e6b47d77" have entirely different histories. 
		
	
	
		
			f2a0b6230f
			...
			15c4839a81
		
	
		| 
						 | 
					@ -110,19 +110,20 @@ impl Delta {
 | 
				
			||||||
        out
 | 
					        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
 | 
					    /// The contribution of a delta in a given chain is defined as the parts of the state produced
 | 
				
			||||||
    /// overwritten by any of its following deltas.
 | 
					    /// 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<I>(deltas: I) -> Vec<State>
 | 
					    pub fn contributions<I>(deltas: I) -> Vec<State>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        I: IntoIterator,
 | 
					        I: IntoIterator,
 | 
				
			||||||
        I::IntoIter: DoubleEndedIterator,
 | 
					 | 
				
			||||||
        I::Item: Borrow<Delta>,
 | 
					        I::Item: Borrow<Delta>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let mut contributions: Vec<State> = Vec::new();
 | 
					        let mut contributions: Vec<State> = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut deltas = deltas.into_iter().rev();
 | 
					        let mut deltas = deltas.into_iter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let Some(first_delta) = deltas.next() {
 | 
					        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
 | 
					            // 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
 | 
					        contributions
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -240,56 +242,4 @@ mod tests {
 | 
				
			||||||
        let expected = Delta::default().with_added("dir_1", ["file1", "file2"]);
 | 
					        let expected = Delta::default().with_added("dir_1", ["file1", "file2"]);
 | 
				
			||||||
        assert_eq!(expected, b.union(&a));
 | 
					        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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,8 +229,9 @@ where
 | 
				
			||||||
                    .map(|_| ()),
 | 
					                    .map(|_| ()),
 | 
				
			||||||
                    // Incremental backups are exported one by one according to their contribution
 | 
					                    // Incremental backups are exported one by one according to their contribution
 | 
				
			||||||
                    BackupType::Incremental => {
 | 
					                    BackupType::Incremental => {
 | 
				
			||||||
                        let contributions =
 | 
					                        let contributions = Delta::contributions(
 | 
				
			||||||
                            Delta::contributions(chain.iter().take(index + 1).map(|b| &b.delta));
 | 
					                            chain.iter().take(index + 1).map(|b| &b.delta).rev(),
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        let tar_gz = OpenOptions::new()
 | 
					                        let tar_gz = OpenOptions::new()
 | 
				
			||||||
                            .write(true)
 | 
					                            .write(true)
 | 
				
			||||||
| 
						 | 
					@ -244,6 +245,7 @@ where
 | 
				
			||||||
                        // overwritten by their successors anyways.
 | 
					                        // overwritten by their successors anyways.
 | 
				
			||||||
                        for (contribution, backup) in contributions
 | 
					                        for (contribution, backup) in contributions
 | 
				
			||||||
                            .iter()
 | 
					                            .iter()
 | 
				
			||||||
 | 
					                            .rev()
 | 
				
			||||||
                            .zip(chain.iter().take(index + 1))
 | 
					                            .zip(chain.iter().take(index + 1))
 | 
				
			||||||
                            .filter(|(contribution, _)| !contribution.is_empty())
 | 
					                            .filter(|(contribution, _)| !contribution.is_empty())
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue