use antichain::Lattice;
use antichain_intervals::IntervalSetLattice;
fn main() {
println!("=== Backfill-with-gaps convergence demo ===\n");
println!("Three workers re-process blocks [0, 1000) from a distributed log.");
println!("Blocks arrive out of order. Gaps block safe acknowledgement.\n");
let mut w0 = IntervalSetLattice::new();
w0.insert(0u64, 300); w0.insert(350, 700);
let mut w1 = IntervalSetLattice::new();
w1.insert(0u64, 600);
let mut w2 = IntervalSetLattice::new();
w2.insert(200u64, 800);
print_state("Initial state", &w0, &w1, &w2);
let safe_r1 = w0.meet(&w1).meet(&w2);
println!("Round 1 — safe to ack (meet of all workers):");
println!(" {:?}", safe_r1.intervals());
println!(" → Only ranges covered by all three workers: [200,300) and [350,600).\n");
println!("--- Worker 0 fills gap [300, 350) ---\n");
w0.insert(300u64, 350);
let union_r2 = w0.join(&w1).join(&w2);
println!("Union coverage (optimistic, any worker):");
println!(" {:?}", union_r2.intervals());
let safe_r2 = w0.meet(&w1).meet(&w2);
println!("Safe to ack (meet of all workers):");
println!(" {:?}", safe_r2.intervals());
println!(" → [200, 600) is now confirmed by all three workers.\n");
println!("--- All workers cover [0, 1000) ---\n");
w0.insert(700u64, 1000); w1.insert(600u64, 1000); w2.insert(0u64, 200); w2.insert(800u64, 1000);
print_state("Final state", &w0, &w1, &w2);
let safe_final = w0.meet(&w1).meet(&w2);
println!("Final safe to ack (meet of all workers):");
println!(" {:?}", safe_final.intervals());
let expected = [(0u64, 1000u64)];
if safe_final.intervals() == expected {
println!("\n✓ All blocks [0, 1000) are safely acknowledged by all workers.");
} else {
eprintln!("\n✗ Unexpected coverage: {:?}", safe_final.intervals());
std::process::exit(1);
}
println!("\n--- Using IntervalSetLattice as a Frontier value type ---\n");
use antichain::Frontier;
let shard_0_progress: IntervalSetLattice<u64> = {
let mut s = IntervalSetLattice::new();
s.insert(0u64, 500);
s
};
let shard_1_progress: IntervalSetLattice<u64> = {
let mut s = IntervalSetLattice::new();
s.insert(0u64, 750);
s
};
let f0 = Frontier::from_elem(shard_0_progress);
let f1 = Frontier::from_elem(shard_1_progress);
let global = f0.meet(&f1);
let safe_intervals = global.elements();
println!("Global frontier element count: {}", safe_intervals.len());
println!("Safe intervals: {:?}", safe_intervals[0].intervals());
println!("✓ Frontier<IntervalSetLattice> composes correctly.");
}
fn print_state(
label: &str,
w0: &IntervalSetLattice<u64>,
w1: &IntervalSetLattice<u64>,
w2: &IntervalSetLattice<u64>,
) {
println!("{label}:");
println!(" Worker 0: {:?}", w0.intervals());
println!(" Worker 1: {:?}", w1.intervals());
println!(" Worker 2: {:?}", w2.intervals());
println!();
}