#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::print_stdout,
clippy::indexing_slicing,
clippy::arithmetic_side_effects,
clippy::default_numeric_fallback,
clippy::cast_precision_loss,
clippy::as_conversions,
clippy::cast_possible_truncation,
clippy::missing_panics_doc
)]
use bitcut::{apply_patch, make_patch_stats, Op, PatchStats};
use std::time::Instant;
fn noise(seed: u64, len: usize) -> Vec<u8> {
let mut x = seed | 1;
(0..len)
.map(|_| {
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
(x.wrapping_mul(0x2545_F491_4F6C_DD1D) >> 33) as u8
})
.collect()
}
struct Measured {
patch_len: usize,
literal_bytes: usize,
stats: PatchStats,
}
fn measure(name: &str, old: &[u8], new: &[u8]) -> Measured {
let start = Instant::now();
let (patch, stats) = make_patch_stats(old, new).unwrap();
let build = start.elapsed();
assert_eq!(apply_patch(old, &patch).unwrap(), new, "{name}: roundtrip");
let literal_bytes = Op::iter(&patch)
.map(|op| match op.unwrap() {
Op::Add(bytes) => bytes.len(),
Op::Copy { .. } => 0,
})
.sum();
println!(
"{name}\n {} KiB base, build {build:?}\n patch {} B, literal {} B ({:.2}% of base)\n {stats:?}\n",
old.len() / 1024,
patch.len(),
literal_bytes,
100.0 * literal_bytes as f64 / old.len() as f64,
);
Measured {
patch_len: patch.len(),
literal_bytes,
stats,
}
}
#[test]
fn a_local_edit_never_escalates() {
let base = noise(1, 2 << 20);
let mut edited = base.clone();
edited.splice(1_000_000..1_000_000, b"INSERTED".iter().copied());
let m = measure("local edit", &base, &edited);
assert_eq!(m.stats.escalations, 0);
assert_eq!(m.stats.restarts, 0);
assert!(m.patch_len < 256, "patch is {} B", m.patch_len);
assert!(
m.stats.old_bytes_scanned < 1 << 16,
"scanned {} bytes of a 2 MiB base",
m.stats.old_bytes_scanned
);
}
#[test]
fn a_relocated_block_does_not_leak_into_literals() {
let head = noise(1, 1 << 20);
let tail = noise(999, 1 << 20);
let old: Vec<u8> = head.iter().chain(tail.iter()).copied().collect();
let new: Vec<u8> = tail.iter().chain(head.iter()).copied().collect();
let m = measure("halves swapped", &old, &new);
assert!(
m.stats.escalations > 0,
"expected escalation: {:?}",
m.stats
);
assert_eq!(m.stats.restarts, 1, "the blind prefix must be redone");
assert_eq!(
m.literal_bytes, 0,
"every byte of `new` exists in `old`, so nothing should be literal"
);
assert!(m.patch_len < 256, "patch is {} B", m.patch_len);
}
#[test]
fn a_moved_prefix_does_not_leak_into_literals() {
let base = noise(7, 2 << 20);
let mut moved = base.clone();
let prefix: Vec<u8> = moved.drain(..64 * 1024).collect();
moved.extend_from_slice(&prefix);
let m = measure("prefix moved to the end", &base, &moved);
assert_eq!(m.stats.restarts, 1);
assert_eq!(m.literal_bytes, 0);
assert!(m.patch_len < 256, "patch is {} B", m.patch_len);
}
#[test]
fn unrelated_documents_cost_one_literal() {
let old = noise(3, 512 * 1024);
let new = noise(4, 512 * 1024);
let m = measure("unrelated documents", &old, &new);
assert_eq!(m.literal_bytes, new.len());
assert!(
m.patch_len < new.len() + 1024,
"patch {} for new {}",
m.patch_len,
new.len()
);
}