Skip to content

Commit 3af2ba4

Browse files
authored
Document the collection invariant (#384)
* Document the collection invariant * must_use on the lattice operations
1 parent b27c8ab commit 3af2ba4

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

differential-dataflow/src/collection.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ pub struct Collection<G: Scope, D, R = isize, C = Vec<(D, <G as ScopeParent>::Ti
4444
///
4545
/// This field is exposed to support direct timely dataflow manipulation when required, but it is
4646
/// not intended to be the idiomatic way to work with the collection.
47+
///
48+
/// The timestamp in the data is required to always be at least the timestamp _of_ the data, in
49+
/// the timely-dataflow sense. If this invariant is not upheld, differential operators may behave
50+
/// unexpectedly.
4751
pub inner: timely::dataflow::StreamCore<G, C>,
4852
/// Phantom data for unreferenced `D` and `R` types.
4953
phantom: std::marker::PhantomData<(D, R)>,
@@ -56,6 +60,9 @@ impl<G: Scope, D, R, C> Collection<G, D, R, C> {
5660
/// idiomatic approach to convert timely streams to collections. Also, the `input::Input` trait
5761
/// provides a `new_collection` method which will create a new collection for you without exposing
5862
/// the underlying timely stream at all.
63+
///
64+
/// This stream should satisfy the timestamp invariant as documented on [Collection]; this
65+
/// method does not check it.
5966
pub fn new(stream: StreamCore<G, C>) -> Collection<G, D, R, C> {
6067
Collection { inner: stream, phantom: std::marker::PhantomData }
6168
}
@@ -433,8 +440,9 @@ impl<G: Scope, D: Clone+'static, R: Clone+'static> Collection<G, D, R> {
433440
///
434441
/// It is assumed that `func` only advances timestamps; this is not verified, and things may go horribly
435442
/// wrong if that assumption is incorrect. It is also critical that `func` be monotonic: if two times are
436-
/// ordered, they should have the same order once `func` is applied to them (this is because we advance the
437-
/// timely capability with the same logic, and it must remain `less_equal` to all of the data timestamps).
443+
/// ordered, they should have the same order or compare equal once `func` is applied to them (this
444+
/// is because we advance the timely capability with the same logic, and it must remain `less_equal`
445+
/// to all of the data timestamps).
438446
pub fn delay<F>(&self, func: F) -> Collection<G, D, R>
439447
where F: FnMut(&G::Timestamp) -> G::Timestamp + Clone + 'static {
440448

@@ -446,6 +454,7 @@ impl<G: Scope, D: Clone+'static, R: Clone+'static> Collection<G, D, R> {
446454
.map_in_place(move |x| x.1 = func2(&x.1))
447455
.as_collection()
448456
}
457+
449458
/// Applies a supplied function to each update.
450459
///
451460
/// This method is most commonly used to report information back to the user, often for debugging purposes.
@@ -622,6 +631,10 @@ pub trait AsCollection<G: Scope, D, R, C> {
622631
}
623632

624633
impl<G: Scope, D, R, C: Clone> AsCollection<G, D, R, C> for StreamCore<G, C> {
634+
/// Converts the type to a differential dataflow collection.
635+
///
636+
/// By calling this method, you guarantee that the timestamp invariant (as documented on
637+
/// [Collection]) is upheld. This method will not check it.
625638
fn as_collection(&self) -> Collection<G, D, R, C> {
626639
Collection::<G,D,R,C>::new(self.clone())
627640
}

differential-dataflow/src/lattice.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub trait Lattice : PartialOrder {
2727
/// assert_eq!(join, Product::new(4, 7));
2828
/// # }
2929
/// ```
30+
#[must_use]
3031
fn join(&self, other: &Self) -> Self;
3132

3233
/// Updates `self` to the smallest element greater than or equal to both arguments.
@@ -67,6 +68,7 @@ pub trait Lattice : PartialOrder {
6768
/// assert_eq!(meet, Product::new(3, 6));
6869
/// # }
6970
/// ```
71+
#[must_use]
7072
fn meet(&self, other: &Self) -> Self;
7173

7274
/// Updates `self` to the largest element less than or equal to both arguments.

0 commit comments

Comments
 (0)