use timely::order::PartialOrder;
pub trait Lattice : PartialOrder {
fn minimum() -> Self;
fn join(&self, &Self) -> Self;
fn join_assign(&mut self, other: &Self) where Self: Sized {
*self = self.join(other);
}
fn meet(&self, &Self) -> Self;
fn meet_assign(&mut self, other: &Self) where Self: Sized {
*self = self.meet(other);
}
#[inline(always)]
fn advance_by(&mut self, frontier: &[Self]) where Self: Sized {
if let Some(first) = frontier.get(0) {
let mut result = self.join(first);
for f in &frontier[1..] {
result.meet_assign(&self.join(f));
}
*self = result;
}
}
}
use timely::order::Product;
impl<T1: Lattice, T2: Lattice> Lattice for Product<T1, T2> {
#[inline(always)]
fn minimum() -> Self { Product::new(T1::minimum(), T2::minimum()) }
#[inline(always)]
fn join(&self, other: &Product<T1, T2>) -> Product<T1, T2> {
Product {
outer: self.outer.join(&other.outer),
inner: self.inner.join(&other.inner),
}
}
#[inline(always)]
fn meet(&self, other: &Product<T1, T2>) -> Product<T1, T2> {
Product {
outer: self.outer.meet(&other.outer),
inner: self.inner.meet(&other.inner),
}
}
}
macro_rules! implement_lattice {
($index_type:ty, $minimum:expr) => (
impl Lattice for $index_type {
#[inline(always)] fn minimum() -> Self { $minimum }
#[inline(always)] fn join(&self, other: &Self) -> Self { ::std::cmp::max(*self, *other) }
#[inline(always)] fn meet(&self, other: &Self) -> Self { ::std::cmp::min(*self, *other) }
}
)
}
use std::time::Duration;
implement_lattice!(Duration, Duration::new(0, 0));
implement_lattice!(usize, usize::min_value());
implement_lattice!(u64, u64::min_value());
implement_lattice!(u32, u32::min_value());
implement_lattice!(i32, i32::min_value());
implement_lattice!((), ());