Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions timely/src/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
/// This trait is distinct from Rust's `PartialOrd` trait, because the implementation
/// of that trait precludes a distinct `Ord` implementation. We need an independent
/// trait if we want to have a partially ordered type that can also be sorted.
pub trait PartialOrder : Eq {
pub trait PartialOrder<Rhs: ?Sized = Self>: PartialEq<Rhs> {
/// Returns true iff one element is strictly less than the other.
fn less_than(&self, other: &Self) -> bool {
fn less_than(&self, other: &Rhs) -> bool {
self.less_equal(other) && self != other
}
/// Returns true iff one element is less than or equal to the other.
fn less_equal(&self, other: &Self) -> bool;
fn less_equal(&self, other: &Rhs) -> bool;
}

/// A type that is totally ordered.
Expand Down Expand Up @@ -97,9 +97,14 @@ mod product {
}

use super::PartialOrder;
impl<TOuter: PartialOrder, TInner: PartialOrder> PartialOrder for Product<TOuter, TInner> {
impl<TOuter, TOuter2, TInner, TInner2> PartialOrder<Product<TOuter2, TInner2>> for Product<TOuter, TInner>
where
TOuter: PartialOrder<TOuter2>,
TInner: PartialOrder<TInner2>,
Self: PartialEq<Product<TOuter2, TInner2>>,
{
#[inline]
fn less_equal(&self, other: &Self) -> bool {
fn less_equal(&self, other: &Product<TOuter2, TInner2>) -> bool {
self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner)
}
}
Expand Down Expand Up @@ -189,9 +194,14 @@ mod product {
mod tuple {

use super::PartialOrder;
impl<TOuter: PartialOrder, TInner: PartialOrder> PartialOrder for (TOuter, TInner) {
impl<TOuter, TOuter2, TInner, TInner2> PartialOrder<(TOuter2, TInner2)> for (TOuter, TInner)
where
TOuter: PartialOrder<TOuter2>,
TInner: PartialOrder<TInner2>,
(TOuter, TInner): PartialEq<(TOuter2, TInner2)>,
{
#[inline]
fn less_equal(&self, other: &Self) -> bool {
fn less_equal(&self, other: &(TOuter2, TInner2)) -> bool {
// We avoid Rust's `PartialOrd` implementation, for reasons of correctness.
self.0.less_than(&other.0) || (self.0.eq(&other.0) && self.1.less_equal(&other.1))
}
Expand Down
44 changes: 35 additions & 9 deletions timely/src/progress/frontier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,32 @@ impl<T: PartialOrder> Antichain<T> {
}
}

/// Updates the `Antichain` if the element is not greater than or equal to some present element.
/// If the antichain needs updating, it uses the `to_owned` closure to convert the element into
/// a `T`.
///
/// Returns true if element is added to the set
///
/// # Examples
///
///```
/// use timely::progress::frontier::Antichain;
///
/// let mut frontier = Antichain::new();
/// assert!(frontier.insert_with(&2, |x| *x));
/// assert!(!frontier.insert(3));
///```
pub fn insert_with<O: PartialOrder<T>, F: FnOnce(&O) -> T>(&mut self, element: &O, to_owned: F) -> bool where T: PartialOrder<O> {
if !self.elements.iter().any(|x| x.less_equal(element)) {
self.elements.retain(|x| !element.less_equal(x));
self.elements.push(to_owned(element));
true
}
else {
false
}
}

/// Reserves capacity for at least additional more elements to be inserted in the given `Antichain`
pub fn reserve(&mut self, additional: usize) {
self.elements.reserve(additional);
Expand Down Expand Up @@ -450,9 +476,9 @@ impl<T> MutableAntichain<T> {
/// assert!(frontier.less_than(&2));
///```
#[inline]
pub fn less_than(&self, time: &T) -> bool
pub fn less_than<O>(&self, time: &O) -> bool
where
T: PartialOrder,
T: PartialOrder<O>,
{
self.frontier().less_than(time)
}
Expand All @@ -470,9 +496,9 @@ impl<T> MutableAntichain<T> {
/// assert!(frontier.less_equal(&2));
///```
#[inline]
pub fn less_equal(&self, time: &T) -> bool
pub fn less_equal<O>(&self, time: &O) -> bool
where
T: PartialOrder,
T: PartialOrder<O>,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar as above; is one constraint unnecessary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

{
self.frontier().less_equal(time)
}
Expand Down Expand Up @@ -549,9 +575,9 @@ impl<T> MutableAntichain<T> {
}

/// Reports the count for a queried time.
pub fn count_for(&self, query_time: &T) -> i64
pub fn count_for<O>(&self, query_time: &O) -> i64
where
T: Ord,
T: PartialEq<O>,
{
self.updates
.unstable_internal_updates()
Expand Down Expand Up @@ -679,7 +705,7 @@ impl<'a, T: 'a> AntichainRef<'a, T> {
}
}

impl<'a, T: 'a+PartialOrder> AntichainRef<'a, T> {
impl<T> AntichainRef<'_, T> {

/// Returns true if any item in the `AntichainRef` is strictly less than the argument.
///
Expand All @@ -694,7 +720,7 @@ impl<'a, T: 'a+PartialOrder> AntichainRef<'a, T> {
/// assert!(frontier.less_than(&2));
///```
#[inline]
pub fn less_than(&self, time: &T) -> bool {
pub fn less_than<O>(&self, time: &O) -> bool where T: PartialOrder<O> {
self.iter().any(|x| x.less_than(time))
}

Expand All @@ -711,7 +737,7 @@ impl<'a, T: 'a+PartialOrder> AntichainRef<'a, T> {
/// assert!(frontier.less_equal(&1));
/// assert!(frontier.less_equal(&2));
///```
pub fn less_equal(&self, time: &T) -> bool {
pub fn less_equal<O>(&self, time: &O) -> bool where T: PartialOrder<O> {
self.iter().any(|x| x.less_equal(time))
}
}
Expand Down