Compare commits
	
		
			2 Commits 
		
	
	
		
			15c4839a81
			...
			f2a0b6230f
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						f2a0b6230f | |
| 
							
							
								
									
								
								 | 
						5f43d7b8b1 | 
| 
						 | 
					@ -110,20 +110,19 @@ impl Delta {
 | 
				
			||||||
        out
 | 
					        out
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Given a chain of deltas, ordered from last to first, calculate the "contribution" for each
 | 
					    /// Given a chain of deltas, calculate the "contribution" for each state.
 | 
				
			||||||
    /// state.
 | 
					 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// The contribution of a delta in a given chain is defined as the parts of the state produced
 | 
					    /// For each delta, its contribution is the part of its added and removed files that isn't
 | 
				
			||||||
    /// by this chain that are actually provided by this delta. This comes down to calculating the
 | 
					    /// overwritten by any of its following deltas.
 | 
				
			||||||
    /// 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();
 | 
					        let mut deltas = deltas.into_iter().rev();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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
 | 
				
			||||||
| 
						 | 
					@ -138,8 +137,7 @@ impl Delta {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // contributions.reverse();
 | 
					        contributions.reverse();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        contributions
 | 
					        contributions
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,4 +240,56 @@ 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,9 +229,8 @@ 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 = Delta::contributions(
 | 
					                        let contributions =
 | 
				
			||||||
                            chain.iter().take(index + 1).map(|b| &b.delta).rev(),
 | 
					                            Delta::contributions(chain.iter().take(index + 1).map(|b| &b.delta));
 | 
				
			||||||
                        );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        let tar_gz = OpenOptions::new()
 | 
					                        let tar_gz = OpenOptions::new()
 | 
				
			||||||
                            .write(true)
 | 
					                            .write(true)
 | 
				
			||||||
| 
						 | 
					@ -245,7 +244,6 @@ 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