1//! A lexicographically ordered pair of timestamps.
2//!
3//! Two timestamps (s1, t1) and (s2, t2) are ordered either if
4//! s1 and s2 are ordered, or if s1 equals s2 and t1 and t2 are
5//! ordered.
6//!
7//! The join of two timestamps should have as its first coordinate
8//! the join of the first coordinates, and for its second coordinate
9//! the join of the second coordinates for elements whose first
10//! coordinate equals the computed join. That may be the minimum
11//! element of the second lattice, if neither first element equals
12//! the join.
1314use serde::{Deserialize, Serialize};
1516/// A pair of timestamps, partially ordered by the product order.
17#[derive(Debug, Hash, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
18pub struct AltNeu<T> {
19pub time: T,
20pub neu: bool, // alt < neu in timestamp comparisons.
21}
2223impl<T> AltNeu<T> {
24pub fn alt(time: T) -> Self { AltNeu { time, neu: false } }
25pub fn neu(time: T) -> Self { AltNeu { time, neu: true } }
26}
2728// Implement timely dataflow's `PartialOrder` trait.
29use timely::order::PartialOrder;
30impl<T: PartialOrder> PartialOrder for AltNeu<T> {
31fn less_equal(&self, other: &Self) -> bool {
32if self.time.eq(&other.time) {
33self.neu <= other.neu
34 }
35else {
36self.time.less_equal(&other.time)
37 }
38 }
39}
4041// Implement timely dataflow's `PathSummary` trait.
42// This is preparation for the `Timestamp` implementation below.
43use timely::progress::PathSummary;
44impl<T: Timestamp> PathSummary<AltNeu<T>> for () {
45fn results_in(&self, timestamp: &AltNeu<T>) -> Option<AltNeu<T>> {
46Some(timestamp.clone())
47 }
48fn followed_by(&self, other: &Self) -> Option<Self> {
49Some(other.clone())
50 }
51}
5253// Implement timely dataflow's `Timestamp` trait.
54use timely::progress::Timestamp;
55impl<T: Timestamp> Timestamp for AltNeu<T> {
56type Summary = ();
57fn minimum() -> Self { AltNeu::alt(T::minimum()) }
58}
5960use timely::progress::timestamp::Refines;
6162impl<T: Timestamp> Refines<T> for AltNeu<T> {
63fn to_inner(other: T) -> Self {
64 AltNeu::alt(other)
65 }
66fn to_outer(self: AltNeu<T>) -> T {
67self.time
68 }
69fn summarize(_path: ()) -> <T as Timestamp>::Summary {
70 Default::default()
71 }
72}
7374// Implement differential dataflow's `Lattice` trait.
75// This extends the `PartialOrder` implementation with additional structure.
76use differential_dataflow::lattice::Lattice;
77impl<T: Lattice> Lattice for AltNeu<T> {
78fn join(&self, other: &Self) -> Self {
79let time = self.time.join(&other.time);
80let mut neu = false;
81if time == self.time {
82 neu = neu || self.neu;
83 }
84if time == other.time {
85 neu = neu || other.neu;
86 }
87 AltNeu { time, neu }
88 }
89fn meet(&self, other: &Self) -> Self {
90let time = self.time.meet(&other.time);
91let mut neu = true;
92if time == self.time {
93 neu = neu && self.neu;
94 }
95if time == other.time {
96 neu = neu && other.neu;
97 }
98 AltNeu { time, neu }
99 }
100}