use vulture::manual::SimpleTimetable;
use vulture::{SecondOfDay, Timetable};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum S {
A,
B,
}
fn main() {
let trips: Vec<(u16, Vec<(SecondOfDay, SecondOfDay)>)> = (0..5)
.map(|i| {
let dep = SecondOfDay::hms(9, 0, 0) + vulture::Duration(i * 120);
let arr = dep + vulture::Duration(60);
(i as u16, vec![(dep, dep), (arr, arr)])
})
.collect();
let trip_args: Vec<(u16, &[(SecondOfDay, SecondOfDay)])> = trips
.iter()
.map(|(t, sched)| (*t, sched.as_slice()))
.collect();
let tt = SimpleTimetable::new().route(0u8, &[S::A, S::B], &trip_args);
let a = tt.stop_idx_of(&S::A);
let b = tt.stop_idx_of(&S::B);
let departures: Vec<SecondOfDay> = (0..3)
.map(|i| SecondOfDay::hms(8, 59, 30) + vulture::Duration(i * 60))
.collect();
let serial = tt
.query()
.from(a)
.to(b)
.max_transfers(1)
.depart_in_window(departures.iter().copied())
.run();
let parallel = tt
.query()
.from(a)
.to(b)
.max_transfers(1)
.depart_in_window(departures.iter().copied())
.run_par();
println!("Serial rRAPTOR ({} entries):", serial.len());
for rj in &serial {
println!(" depart {}, arrive {}", rj.depart, rj.journey.arrival(),);
}
println!("Parallel naive ({} entries):", parallel.len());
for rj in ¶llel {
println!(" depart {}, arrive {}", rj.depart, rj.journey.arrival(),);
}
let mut s_keys: Vec<(u32, u32)> = serial
.iter()
.map(|rj| (rj.depart.0, rj.journey.arrival().0))
.collect();
let mut p_keys: Vec<(u32, u32)> = parallel
.iter()
.map(|rj| (rj.depart.0, rj.journey.arrival().0))
.collect();
s_keys.sort();
p_keys.sort();
assert_eq!(
s_keys, p_keys,
"serial and parallel range queries should agree",
);
for rj in &serial {
let dep = rj.depart.0;
let next_trip_dep = (dep.div_ceil(120) * 120).max(SecondOfDay::hms(9, 0, 0).0);
assert_eq!(
rj.journey.arrival().0,
next_trip_dep + 60,
"expected to catch the next trip after depart {dep}",
);
}
}