Skip to main content

delta/algorithm/
mod.rs

1pub mod greedy;
2pub mod onepass;
3pub mod correcting;
4
5use crate::types::{Algorithm, Command, DiffOptions};
6
7/// Print shared verbose statistics for diff algorithm output.
8pub(crate) fn print_command_stats(commands: &[Command]) {
9    let mut copy_lens: Vec<usize> = Vec::new();
10    let mut total_copy: usize = 0;
11    let mut total_add: usize = 0;
12    let mut num_copies: usize = 0;
13    let mut num_adds: usize = 0;
14    for cmd in commands {
15        match cmd {
16            Command::Copy { length, .. } => {
17                total_copy += length;
18                num_copies += 1;
19                copy_lens.push(*length);
20            }
21            Command::Add { data } => {
22                total_add += data.len();
23                num_adds += 1;
24            }
25        }
26    }
27    let total_out = total_copy + total_add;
28    let copy_pct = if total_out > 0 {
29        total_copy as f64 / total_out as f64 * 100.0
30    } else {
31        0.0
32    };
33    eprintln!(
34        "  result: {} copies ({} bytes), {} adds ({} bytes)\n  \
35         result: copy coverage {:.1}%, output {} bytes",
36        num_copies, total_copy, num_adds, total_add, copy_pct, total_out
37    );
38    if !copy_lens.is_empty() {
39        copy_lens.sort();
40        let mean = total_copy as f64 / copy_lens.len() as f64;
41        let median = copy_lens[copy_lens.len() / 2];
42        eprintln!(
43            "  copies: {} regions, min={} max={} mean={:.1} median={} bytes",
44            copy_lens.len(),
45            copy_lens.first().unwrap(),
46            copy_lens.last().unwrap(),
47            mean,
48            median
49        );
50    }
51}
52
53/// Dispatch to the appropriate differencing algorithm.
54pub fn diff(
55    algorithm: Algorithm,
56    r: &[u8],
57    v: &[u8],
58    opts: &DiffOptions,
59) -> Vec<Command> {
60    match algorithm {
61        Algorithm::Greedy => greedy::diff_greedy(r, v, opts),
62        Algorithm::Onepass => onepass::diff_onepass(r, v, opts),
63        Algorithm::Correcting => correcting::diff_correcting(r, v, opts),
64    }
65}
66
67/// Dispatch with default parameters.
68pub fn diff_default(algorithm: Algorithm, r: &[u8], v: &[u8]) -> Vec<Command> {
69    diff(algorithm, r, v, &DiffOptions::default())
70}