From a0aef250a4d94c2591deda874a0bd0d26e0dad84 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Fri, 18 Mar 2022 13:23:31 +0100 Subject: [PATCH 1/8] remove transmute and fix rust warning while `()` is a ZST the potentially dangling reference is still undefined behaviour. Making it a static is a trivial fix. Signed-off-by: Petros Angelatos --- src/operators/arrange/arrangement.rs | 4 ++-- src/trace/implementations/ord.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/operators/arrange/arrangement.rs b/src/operators/arrange/arrangement.rs index 09a48e248..55ad69577 100644 --- a/src/operators/arrange/arrangement.rs +++ b/src/operators/arrange/arrangement.rs @@ -405,10 +405,10 @@ where // Determine new frontier on queries that may be issued. // TODO: This code looks very suspect; explain better or fix. - let frontier = std::array::IntoIter::new([ + let frontier = IntoIterator::into_iter([ capability.as_ref().map(|c| c.time().clone()), input1.frontier().frontier().get(0).cloned(), - ]).filter_map(|t| t).min(); + ]).flatten().min(); if let Some(frontier) = frontier { trace.as_mut().map(|t| t.set_logical_compaction(AntichainRef::new(&[frontier]))); diff --git a/src/trace/implementations/ord.rs b/src/trace/implementations/ord.rs index f394d2365..08575e102 100644 --- a/src/trace/implementations/ord.rs +++ b/src/trace/implementations/ord.rs @@ -419,7 +419,6 @@ where type Cursor = OrdKeyCursor; fn cursor(&self) -> Self::Cursor { OrdKeyCursor { - empty: (), valid: true, cursor: self.layer.cursor(), phantom: PhantomData @@ -629,12 +628,12 @@ where } } +static EMPTY: () = (); /// A cursor for navigating a single layer. #[derive(Debug)] pub struct OrdKeyCursor { valid: bool, - empty: (), cursor: OrderedCursor>, phantom: PhantomData } @@ -650,7 +649,7 @@ where type Storage = OrdKeyBatch; fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { &self.cursor.key(&storage.layer) } - fn val<'a>(&self, _storage: &'a Self::Storage) -> &'a () { unsafe { ::std::mem::transmute(&self.empty) } } + fn val<'a>(&self, _storage: &'a Self::Storage) -> &'a () { &EMPTY } fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { self.cursor.child.rewind(&storage.layer.vals); while self.cursor.child.valid(&storage.layer.vals) { From f411308cabce854464ece486c16d3e324e4aaa66 Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Thu, 17 Mar 2022 18:43:26 +0100 Subject: [PATCH 2/8] trace: define `BatchReader` with associated types The `TraceReader` trait uses associated types to define its `Key`, `Val`, `Time`, `Diff` but the `BatchReader` trait did not, even though they are very similar in nature. Usually the choice between asssociated types or generic parameters on a trait is determined by whether or not a particular type is expected to implement the same trait multiple times. My starting point was that these two trait should at the very least be consistent with respect to their structure and either both use generic parameters or both use associated types. All the uses in this repo (and also that I can imagine being useful) don't really need `BatchReader` to be polymorphic for a particular type and so I chose to change that one to make it consistent with `TraceReader`. The result is quite pleasing as in many cases a lot of generic parameters are erased. In order to keep this PR short I left the `Cursor` trait untouched, but I believe a similar transformation would be beneficial there too, simplifying further many type signatures. Signed-off-by: Petros Angelatos --- dogsdogsdogs/src/operators/count.rs | 3 +- dogsdogsdogs/src/operators/half_join.rs | 4 +- dogsdogsdogs/src/operators/lookup_map.rs | 3 +- dogsdogsdogs/src/operators/propose.rs | 4 +- dogsdogsdogs/src/operators/validate.rs | 3 +- src/algorithms/graphs/bfs.rs | 3 +- src/algorithms/graphs/bijkstra.rs | 1 - src/algorithms/graphs/propagate.rs | 1 - src/operators/arrange/agent.rs | 2 +- src/operators/arrange/arrangement.rs | 15 ++- src/operators/arrange/upsert.rs | 4 +- src/operators/arrange/writer.rs | 8 +- src/operators/count.rs | 1 - src/operators/join.rs | 8 -- src/operators/reduce.rs | 14 +-- src/operators/threshold.rs | 1 - src/trace/implementations/merge_batcher.rs | 4 +- src/trace/implementations/ord.rs | 20 +++- src/trace/implementations/spine_fueled.rs | 26 ++--- src/trace/mod.rs | 116 ++++++++++++--------- src/trace/wrappers/enter.rs | 50 ++++----- src/trace/wrappers/enter_at.rs | 51 ++++----- src/trace/wrappers/filter.rs | 48 ++++----- src/trace/wrappers/freeze.rs | 41 +++----- src/trace/wrappers/frontier.rs | 48 ++++----- tests/trace.rs | 2 +- 26 files changed, 219 insertions(+), 262 deletions(-) diff --git a/dogsdogsdogs/src/operators/count.rs b/dogsdogsdogs/src/operators/count.rs index bae14c7b3..bb75f26a9 100644 --- a/dogsdogsdogs/src/operators/count.rs +++ b/dogsdogsdogs/src/operators/count.rs @@ -4,7 +4,7 @@ use differential_dataflow::{ExchangeData, Collection, Hashable}; use differential_dataflow::difference::{Monoid, Multiply}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader, BatchReader}; +use differential_dataflow::trace::{Cursor, TraceReader}; /// Reports a number of extensions to a stream of prefixes. /// @@ -23,7 +23,6 @@ where G::Timestamp: Lattice, Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+Default, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, R: Monoid+Multiply+ExchangeData, F: Fn(&P)->Tr::Key+Clone+'static, diff --git a/dogsdogsdogs/src/operators/half_join.rs b/dogsdogsdogs/src/operators/half_join.rs index 8f6f4d0cf..482bbb570 100644 --- a/dogsdogsdogs/src/operators/half_join.rs +++ b/dogsdogsdogs/src/operators/half_join.rs @@ -42,7 +42,7 @@ use differential_dataflow::{ExchangeData, Collection, AsCollection, Hashable}; use differential_dataflow::difference::{Monoid, Semigroup}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader, BatchReader}; +use differential_dataflow::trace::{Cursor, TraceReader}; use differential_dataflow::consolidation::{consolidate, consolidate_updates}; /// A binary equijoin that responds to updates on only its first input. @@ -81,7 +81,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+ExchangeData, Tr::Val: Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, Tr::R: Monoid+ExchangeData, FF: Fn(&G::Timestamp) -> G::Timestamp + 'static, @@ -137,7 +136,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+ExchangeData, Tr::Val: Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, Tr::R: Monoid+ExchangeData, FF: Fn(&G::Timestamp) -> G::Timestamp + 'static, diff --git a/dogsdogsdogs/src/operators/lookup_map.rs b/dogsdogsdogs/src/operators/lookup_map.rs index 671e24921..081f17bc4 100644 --- a/dogsdogsdogs/src/operators/lookup_map.rs +++ b/dogsdogsdogs/src/operators/lookup_map.rs @@ -10,7 +10,7 @@ use differential_dataflow::{ExchangeData, Collection, AsCollection, Hashable}; use differential_dataflow::difference::{Semigroup, Monoid}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader, BatchReader}; +use differential_dataflow::trace::{Cursor, TraceReader}; /// Proposes extensions to a stream of prefixes. /// @@ -32,7 +32,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable, Tr::Val: Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, Tr::R: Monoid+ExchangeData, F: FnMut(&D, &mut Tr::Key)+Clone+'static, diff --git a/dogsdogsdogs/src/operators/propose.rs b/dogsdogsdogs/src/operators/propose.rs index cf7e793c8..105bcc340 100644 --- a/dogsdogsdogs/src/operators/propose.rs +++ b/dogsdogsdogs/src/operators/propose.rs @@ -4,7 +4,7 @@ use differential_dataflow::{ExchangeData, Collection, Hashable}; use differential_dataflow::difference::{Monoid, Multiply}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader, BatchReader}; +use differential_dataflow::trace::{Cursor, TraceReader}; /// Proposes extensions to a prefix stream. /// @@ -25,7 +25,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+Default, Tr::Val: Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, Tr::R: Monoid+Multiply+ExchangeData, F: Fn(&P)->Tr::Key+Clone+'static, @@ -58,7 +57,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+Default, Tr::Val: Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, Tr::R: Monoid+Multiply+ExchangeData, F: Fn(&P)->Tr::Key+Clone+'static, diff --git a/dogsdogsdogs/src/operators/validate.rs b/dogsdogsdogs/src/operators/validate.rs index 7152f1876..3ef2f1d63 100644 --- a/dogsdogsdogs/src/operators/validate.rs +++ b/dogsdogsdogs/src/operators/validate.rs @@ -6,7 +6,7 @@ use differential_dataflow::{ExchangeData, Collection}; use differential_dataflow::difference::{Monoid, Multiply}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader, BatchReader}; +use differential_dataflow::trace::{Cursor, TraceReader}; /// Proposes extensions to a stream of prefixes. /// @@ -24,7 +24,6 @@ where Tr: TraceReader+Clone+'static, K: Ord+Hash+Clone+Default, V: ExchangeData+Hash+Default, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, Tr::R: Monoid+Multiply+ExchangeData, F: Fn(&P)->K+Clone+'static, diff --git a/src/algorithms/graphs/bfs.rs b/src/algorithms/graphs/bfs.rs index 2931922a8..6e1a0a5f1 100644 --- a/src/algorithms/graphs/bfs.rs +++ b/src/algorithms/graphs/bfs.rs @@ -30,7 +30,6 @@ where G::Timestamp: Lattice+Ord, N: ExchangeData+Hash, Tr: TraceReader+Clone+'static, - Tr::Batch: crate::trace::BatchReader+'static, Tr::Cursor: crate::trace::Cursor+'static, { // initialize roots as reaching themselves at distance 0 @@ -46,4 +45,4 @@ where .concat(&nodes) .reduce(|_, s, t| t.push((s[0].0.clone(), 1))) }) -} \ No newline at end of file +} diff --git a/src/algorithms/graphs/bijkstra.rs b/src/algorithms/graphs/bijkstra.rs index 91e02dbde..54dea878e 100644 --- a/src/algorithms/graphs/bijkstra.rs +++ b/src/algorithms/graphs/bijkstra.rs @@ -46,7 +46,6 @@ where G::Timestamp: Lattice+Ord, N: ExchangeData+Hash, Tr: TraceReader+Clone+'static, - Tr::Batch: crate::trace::BatchReader+'static, Tr::Cursor: crate::trace::Cursor+'static, { forward diff --git a/src/algorithms/graphs/propagate.rs b/src/algorithms/graphs/propagate.rs index c94e49814..71eed8c9d 100644 --- a/src/algorithms/graphs/propagate.rs +++ b/src/algorithms/graphs/propagate.rs @@ -65,7 +65,6 @@ where R: From, L: ExchangeData, Tr: TraceReader+Clone+'static, - Tr::Batch: crate::trace::BatchReader+'static, Tr::Cursor: crate::trace::Cursor+'static, F: Fn(&L)->u64+Clone+'static, { diff --git a/src/operators/arrange/agent.rs b/src/operators/arrange/agent.rs index 13c3b02cd..8f5a469ef 100644 --- a/src/operators/arrange/agent.rs +++ b/src/operators/arrange/agent.rs @@ -92,7 +92,7 @@ where pub fn new(trace: Tr, operator: ::timely::dataflow::operators::generic::OperatorInfo, logging: Option<::logging::Logger>) -> (Self, TraceWriter) where Tr: Trace, - Tr::Batch: Batch, + Tr::Batch: Batch, { let trace = Rc::new(RefCell::new(TraceBox::new(trace))); let queues = Rc::new(RefCell::new(Vec::new())); diff --git a/src/operators/arrange/arrangement.rs b/src/operators/arrange/arrangement.rs index 55ad69577..286859c59 100644 --- a/src/operators/arrange/arrangement.rs +++ b/src/operators/arrange/arrangement.rs @@ -65,7 +65,6 @@ impl Clone for Arranged where G::Timestamp: Lattice+Ord, Tr: TraceReader + Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, { fn clone(&self) -> Self { @@ -83,7 +82,6 @@ impl Arranged where G::Timestamp: Lattice+Ord, Tr: TraceReader + Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, { /// Brings an arranged collection into a nested scope. @@ -425,7 +423,6 @@ impl<'a, G: Scope, Tr> Arranged, Tr> where G::Timestamp: Lattice+Ord, Tr: TraceReader + Clone, - Tr::Batch: BatchReader, Tr::Cursor: Cursor, { /// Brings an arranged collection out of a nested region. @@ -462,7 +459,7 @@ where V: ExchangeData, R: ExchangeData, Tr: Trace+TraceReader+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, Tr::Cursor: Cursor, { self.arrange_named("Arrange") @@ -479,7 +476,7 @@ where V: ExchangeData, R: ExchangeData, Tr: Trace+TraceReader+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, Tr::Cursor: Cursor, { let exchange = Exchange::new(move |update: &((K,V),G::Timestamp,R)| (update.0).0.hashed().into()); @@ -495,7 +492,7 @@ where where P: ParallelizationContract, Tr: Trace+TraceReader+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, Tr::Cursor: Cursor, ; } @@ -512,7 +509,7 @@ where where P: ParallelizationContract, Tr: Trace+TraceReader+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, Tr::Cursor: Cursor, { // The `Arrange` operator is tasked with reacting to an advancing input @@ -547,7 +544,7 @@ where }; // Where we will deposit received updates, and from which we extract batches. - let mut batcher = >::Batcher::new(); + let mut batcher = ::Batcher::new(); // Capabilities for the lower envelope of updates in `batcher`. let mut capabilities = Antichain::>::new(); @@ -684,7 +681,7 @@ where where P: ParallelizationContract, Tr: Trace+TraceReader+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, Tr::Cursor: Cursor, { self.map(|k| (k, ())) diff --git a/src/operators/arrange/upsert.rs b/src/operators/arrange/upsert.rs index 978d9596f..6a7aa6ba3 100644 --- a/src/operators/arrange/upsert.rs +++ b/src/operators/arrange/upsert.rs @@ -145,7 +145,7 @@ where Tr::Key: ExchangeData+Hashable+std::hash::Hash, Tr::Val: ExchangeData, Tr: Trace+TraceReader+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, Tr::Cursor: Cursor, { let mut reader: Option> = None; @@ -252,7 +252,7 @@ where // Prepare a cursor to the existing arrangement, and a batch builder for // new stuff that we add. let (mut trace_cursor, trace_storage) = reader_local.cursor(); - let mut builder = >::Builder::new(); + let mut builder = ::Builder::new(); for (key, mut list) in to_process.drain(..) { // The prior value associated with the key. diff --git a/src/operators/arrange/writer.rs b/src/operators/arrange/writer.rs index b6c4c5710..a42924b75 100644 --- a/src/operators/arrange/writer.rs +++ b/src/operators/arrange/writer.rs @@ -23,7 +23,7 @@ pub struct TraceWriter where Tr: Trace, Tr::Time: Lattice+Timestamp+Ord+Clone+std::fmt::Debug+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, { /// Current upper limit. upper: Antichain, @@ -37,7 +37,7 @@ impl TraceWriter where Tr: Trace, Tr::Time: Lattice+Timestamp+Ord+Clone+std::fmt::Debug+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, { /// Creates a new `TraceWriter`. pub fn new( @@ -96,7 +96,7 @@ where pub fn seal(&mut self, upper: Antichain) { if self.upper != upper { use trace::Builder; - let builder = >::Builder::new(); + let builder = ::Builder::new(); let batch = builder.done(self.upper.clone(), upper, Antichain::from_elem(Tr::Time::minimum())); self.insert(batch, None); } @@ -107,7 +107,7 @@ impl Drop for TraceWriter where Tr: Trace, Tr::Time: Lattice+Timestamp+Ord+Clone+std::fmt::Debug+'static, - Tr::Batch: Batch, + Tr::Batch: Batch, { fn drop(&mut self) { self.seal(Antichain::new()) diff --git a/src/operators/count.rs b/src/operators/count.rs index f119d648e..6b6a6bf4e 100644 --- a/src/operators/count.rs +++ b/src/operators/count.rs @@ -74,7 +74,6 @@ where T1: TraceReader+Clone+'static, T1::Key: ExchangeData, T1::R: ExchangeData+Semigroup, - T1::Batch: BatchReader, T1::Cursor: Cursor, { fn count_total_core>(&self) -> Collection { diff --git a/src/operators/join.rs b/src/operators/join.rs index ea72b32f6..67a6b21d5 100644 --- a/src/operators/join.rs +++ b/src/operators/join.rs @@ -190,7 +190,6 @@ where Tr::Key: Data+Hashable, Tr::Val: Data, Tr::R: Semigroup, - Tr::Batch: BatchReader+'static, Tr::Cursor: Cursor+'static, { fn join_map(&self, other: &Collection, mut logic: L) -> Collection>::Output> @@ -258,7 +257,6 @@ pub trait JoinCore where G::Time fn join_core (&self, stream2: &Arranged, result: L) -> Collection>::Output> where Tr2: TraceReader+Clone+'static, - Tr2::Batch: BatchReader+'static, Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, @@ -311,7 +309,6 @@ pub trait JoinCore where G::Time fn join_core_internal_unsafe (&self, stream2: &Arranged, result: L) -> Collection where Tr2: TraceReader+Clone+'static, - Tr2::Batch: BatchReader+'static, Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, @@ -334,7 +331,6 @@ where fn join_core (&self, stream2: &Arranged, result: L) -> Collection>::Output> where Tr2: TraceReader+Clone+'static, - Tr2::Batch: BatchReader+'static, Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, @@ -351,7 +347,6 @@ where fn join_core_internal_unsafe (&self, stream2: &Arranged, result: L) -> Collection where Tr2: TraceReader+Clone+'static, - Tr2::Batch: BatchReader+'static, Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, @@ -374,14 +369,12 @@ impl JoinCore for Arranged T1::Key: Ord+Debug+'static, T1::Val: Ord+Clone+Debug+'static, T1::R: Semigroup, - T1::Batch: BatchReader+'static, T1::Cursor: Cursor+'static, { fn join_core(&self, other: &Arranged, mut result: L) -> Collection>::Output> where Tr2::Val: Ord+Clone+Debug+'static, Tr2: TraceReader+Clone+'static, - Tr2::Batch: BatchReader+'static, Tr2::Cursor: Cursor+'static, Tr2::R: Semigroup, T1::R: Multiply, @@ -401,7 +394,6 @@ impl JoinCore for Arranged fn join_core_internal_unsafe (&self, other: &Arranged, mut result: L) -> Collection where Tr2: TraceReader+Clone+'static, - Tr2::Batch: BatchReader+'static, Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, diff --git a/src/operators/reduce.rs b/src/operators/reduce.rs index f8d9edeb1..a2e8d58cc 100644 --- a/src/operators/reduce.rs +++ b/src/operators/reduce.rs @@ -90,7 +90,6 @@ impl Reduce for Arrang where G::Timestamp: Lattice+Ord, T1: TraceReader+Clone+'static, - T1::Batch: BatchReader, T1::Cursor: Cursor, { fn reduce_named(&self, name: &str, logic: L) -> Collection @@ -179,7 +178,6 @@ impl Threshold for Arranged+Clone+'static, - T1::Batch: BatchReader, T1::Cursor: Cursor, { fn threshold_namedR2+'static>(&self, name: &str, mut thresh: F) -> Collection { @@ -236,7 +234,6 @@ impl Count for Arranged where G::Timestamp: Lattice+Ord, T1: TraceReader+Clone+'static, - T1::Batch: BatchReader, T1::Cursor: Cursor, { fn count_core>(&self) -> Collection { @@ -282,7 +279,7 @@ pub trait ReduceCore where G::Timestam T2: Trace+TraceReader+'static, T2::Val: Data, T2::R: Abelian, - T2::Batch: Batch, + T2::Batch: Batch, T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val, T2::R)>)+'static, { @@ -305,7 +302,7 @@ pub trait ReduceCore where G::Timestam T2: Trace+TraceReader+'static, T2::Val: Data, T2::R: Semigroup, - T2::Batch: Batch, + T2::Batch: Batch, T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val,T2::R)>, &mut Vec<(T2::Val,T2::R)>)+'static ; @@ -324,7 +321,7 @@ where T2::Val: Data, T2::R: Semigroup, T2: Trace+TraceReader+'static, - T2::Batch: Batch, + T2::Batch: Batch, T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val,T2::R)>, &mut Vec<(T2::Val, T2::R)>)+'static { @@ -337,7 +334,6 @@ impl ReduceCore for Ar where G::Timestamp: Lattice+Ord, T1: TraceReader+Clone+'static, - T1::Batch: BatchReader, T1::Cursor: Cursor, { fn reduce_core(&self, name: &str, mut logic: L) -> Arranged> @@ -345,7 +341,7 @@ where T2: Trace+TraceReader+'static, T2::Val: Data, T2::R: Semigroup, - T2::Batch: Batch, + T2::Batch: Batch, T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val,T2::R)>, &mut Vec<(T2::Val, T2::R)>)+'static { @@ -488,7 +484,7 @@ where let mut builders = Vec::new(); for i in 0 .. capabilities.len() { buffers.push((capabilities[i].time().clone(), Vec::new())); - builders.push(>::Builder::new()); + builders.push(::Builder::new()); } // cursors for navigating input and output traces. diff --git a/src/operators/threshold.rs b/src/operators/threshold.rs index 427093a04..939211bc5 100644 --- a/src/operators/threshold.rs +++ b/src/operators/threshold.rs @@ -108,7 +108,6 @@ where T1: TraceReader+Clone+'static, T1::Key: ExchangeData, T1::R: ExchangeData+Semigroup, - T1::Batch: BatchReader, T1::Cursor: Cursor, { fn threshold_semigroup(&self, mut thresh: F) -> Collection diff --git a/src/trace/implementations/merge_batcher.rs b/src/trace/implementations/merge_batcher.rs index 14ccc0f3a..e281ca6c7 100644 --- a/src/trace/implementations/merge_batcher.rs +++ b/src/trace/implementations/merge_batcher.rs @@ -8,7 +8,7 @@ use lattice::Lattice; use trace::{Batch, Batcher, Builder}; /// Creates batches from unordered tuples. -pub struct MergeBatcher> { +pub struct MergeBatcher> { sorter: MergeSorter<(K, V), T, R>, lower: Antichain, frontier: Antichain, @@ -21,7 +21,7 @@ where V: Ord+Clone, T: Lattice+timely::progress::Timestamp+Ord+Clone, R: Semigroup, - B: Batch, + B: Batch, { fn new() -> Self { MergeBatcher { diff --git a/src/trace/implementations/ord.rs b/src/trace/implementations/ord.rs index 08575e102..4e7f8523a 100644 --- a/src/trace/implementations/ord.rs +++ b/src/trace/implementations/ord.rs @@ -62,7 +62,7 @@ where pub desc: Description, } -impl BatchReader for OrdValBatch +impl BatchReader for OrdValBatch where K: Ord+Clone+'static, V: Ord+Clone+'static, @@ -70,13 +70,18 @@ where R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { + type Key = K; + type Val = V; + type Time = T; + type R = R; + type Cursor = OrdValCursor; fn cursor(&self) -> Self::Cursor { OrdValCursor { cursor: self.layer.cursor() } } fn len(&self) -> usize { , O>, O> as Trie>::tuples(&self.layer) } fn description(&self) -> &Description { &self.desc } } -impl Batch for OrdValBatch +impl Batch for OrdValBatch where K: Ord+Clone+'static, V: Ord+Clone+'static, @@ -409,13 +414,18 @@ where pub desc: Description, } -impl BatchReader for OrdKeyBatch +impl BatchReader for OrdKeyBatch where K: Ord+Clone+'static, T: Lattice+Ord+Clone+'static, R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { + type Key = K; + type Val = (); + type Time = T; + type R = R; + type Cursor = OrdKeyCursor; fn cursor(&self) -> Self::Cursor { OrdKeyCursor { @@ -425,10 +435,10 @@ where } } fn len(&self) -> usize { , O> as Trie>::tuples(&self.layer) } - fn description(&self) -> &Description { &self.desc } + fn description(&self) -> &Description { &self.desc } } -impl Batch for OrdKeyBatch +impl Batch for OrdKeyBatch where K: Ord+Clone+'static, T: Lattice+timely::progress::Timestamp+Ord+Clone+'static, diff --git a/src/trace/implementations/spine_fueled.rs b/src/trace/implementations/spine_fueled.rs index 8624247e6..5acb3e7e5 100644 --- a/src/trace/implementations/spine_fueled.rs +++ b/src/trace/implementations/spine_fueled.rs @@ -87,7 +87,7 @@ use ::timely::order::PartialOrder; /// A spine maintains a small number of immutable collections of update tuples, merging the collections when /// two have similar sizes. In this way, it allows the addition of more tuples, which may then be merged with /// other immutable collections. -pub struct Spine> { +pub struct Spine> { operator: OperatorInfo, logger: Option, phantom: ::std::marker::PhantomData<(K, V, R)>, @@ -106,7 +106,7 @@ where V: Ord+Clone, // Clone is required by `batch::advance_*` (in-place could remove). T: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, R: Semigroup, - B: Batch+Clone+'static, + B: Batch+Clone+'static, { type Key = K; type Val = V; @@ -114,7 +114,7 @@ where type R = R; type Batch = B; - type Cursor = CursorList>::Cursor>; + type Cursor = CursorList::Cursor>; fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { @@ -248,7 +248,7 @@ where V: Ord+Clone, T: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, R: Semigroup, - B: Batch+Clone+'static, + B: Batch+Clone+'static, { fn new( info: ::timely::dataflow::operators::generic::OperatorInfo, @@ -322,7 +322,7 @@ impl Drop for Spine where T: Lattice+Ord, R: Semigroup, - B: Batch, + B: Batch, { fn drop(&mut self) { self.drop_batches(); @@ -334,7 +334,7 @@ impl Spine where T: Lattice+Ord, R: Semigroup, - B: Batch, + B: Batch, { /// Drops and logs batches. Used in `set_logical_compaction` and drop. fn drop_batches(&mut self) { @@ -382,7 +382,7 @@ where V: Ord+Clone, T: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, R: Semigroup, - B: Batch, + B: Batch, { /// True iff there is at most one non-empty batch in `self.merging`. /// @@ -766,7 +766,7 @@ where /// /// A layer can be empty, contain a single batch, or contain a pair of batches /// that are in the process of merging into a batch for the next layer. -enum MergeState> { +enum MergeState> { /// An empty layer, containing no updates. Vacant, /// A layer containing a single batch. @@ -778,7 +778,7 @@ enum MergeState> { Double(MergeVariant), } -impl> MergeState { +impl> MergeState { /// The number of actual updates contained in the level. fn len(&self) -> usize { @@ -864,7 +864,7 @@ impl> MergeState { match (batch1, batch2) { (Some(batch1), Some(batch2)) => { assert!(batch1.upper() == batch2.lower()); - let begin_merge = >::begin_merge(&batch1, &batch2, compaction_frontier); + let begin_merge = ::begin_merge(&batch1, &batch2, compaction_frontier); MergeVariant::InProgress(batch1, batch2, begin_merge) } (None, Some(x)) => MergeVariant::Complete(Some((x, None))), @@ -876,14 +876,14 @@ impl> MergeState { } } -enum MergeVariant> { +enum MergeVariant> { /// Describes an actual in-progress merge between two non-trivial batches. - InProgress(B, B, >::Merger), + InProgress(B, B, ::Merger), /// A merge that requires no further work. May or may not represent a non-trivial batch. Complete(Option<(B, Option<(B, B)>)>), } -impl> MergeVariant { +impl> MergeVariant { /// Completes and extracts the batch, unless structurally empty. /// diff --git a/src/trace/mod.rs b/src/trace/mod.rs index 45961491d..ad07f8a39 100644 --- a/src/trace/mod.rs +++ b/src/trace/mod.rs @@ -41,7 +41,6 @@ pub use self::description::Description; /// to update the contents of the trace. These methods are used to examine the contents, and to update the reader's /// capabilities (which may release restrictions on the mutations to the underlying trace and cause work to happen). pub trait TraceReader { - /// Key by which updates are indexed. type Key; /// Values associated with keys. @@ -52,7 +51,7 @@ pub trait TraceReader { type R; /// The type of an immutable collection of updates. - type Batch: BatchReader+Clone+'static; + type Batch: BatchReader+Clone+'static; /// The type used to enumerate the collections contents. type Cursor: Cursor; @@ -196,9 +195,7 @@ pub trait TraceReader { /// /// The trace must be constructable from, and navigable by the `Key`, `Val`, `Time` types, but does not need /// to return them. -pub trait Trace : TraceReader -where ::Batch: Batch { - +pub trait Trace: TraceReader { /// Allocates a new empty trace. fn new( info: ::timely::dataflow::operators::generic::OperatorInfo, @@ -232,12 +229,21 @@ where ::Batch: Batch +pub trait BatchReader where Self: ::std::marker::Sized, { + /// Key by which updates are indexed. + type Key; + /// Values associated with keys. + type Val; + /// Timestamps associated with updates + type Time; + /// Associated update. + type R; + /// The type used to enumerate the batch's contents. - type Cursor: Cursor; + type Cursor: Cursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor; /// The number of updates in the batch. @@ -245,39 +251,39 @@ where /// True if the batch is empty. fn is_empty(&self) -> bool { self.len() == 0 } /// Describes the times of the updates in the batch. - fn description(&self) -> &Description; + fn description(&self) -> &Description; /// All times in the batch are greater or equal to an element of `lower`. - fn lower(&self) -> &Antichain { self.description().lower() } + fn lower(&self) -> &Antichain { self.description().lower() } /// All times in the batch are not greater or equal to any element of `upper`. - fn upper(&self) -> &Antichain { self.description().upper() } + fn upper(&self) -> &Antichain { self.description().upper() } } /// An immutable collection of updates. -pub trait Batch : BatchReader where Self: ::std::marker::Sized { +pub trait Batch: BatchReader where Self: ::std::marker::Sized { /// A type used to assemble batches from disordered updates. - type Batcher: Batcher; + type Batcher: Batcher; /// A type used to assemble batches from ordered update sequences. - type Builder: Builder; + type Builder: Builder; /// A type used to progressively merge batches. - type Merger: Merger; + type Merger: Merger; /// Initiates the merging of consecutive batches. /// /// The result of this method can be exercised to eventually produce the same result /// that a call to `self.merge(other)` would produce, but it can be done in a measured /// fashion. This can help to avoid latency spikes where a large merge needs to happen. - fn begin_merge(&self, other: &Self, compaction_frontier: Option>) -> Self::Merger { + fn begin_merge(&self, other: &Self, compaction_frontier: Option>) -> Self::Merger { Self::Merger::new(self, other, compaction_frontier) } /// Creates an empty batch with the stated bounds. - fn empty(lower: Antichain, upper: Antichain, since: Antichain) -> Self { + fn empty(lower: Antichain, upper: Antichain, since: Antichain) -> Self { ::new().done(lower, upper, since) } } /// Functionality for collecting and batching updates. -pub trait Batcher> { +pub trait Batcher> { /// Allocates a new empty batcher. fn new() -> Self; /// Adds an unordered batch of elements to the batcher. @@ -289,7 +295,7 @@ pub trait Batcher> { } /// Functionality for building batches from ordered update sequences. -pub trait Builder> { +pub trait Builder> { /// Allocates an empty builder. fn new() -> Self; /// Allocates an empty builder with some capacity. @@ -305,7 +311,7 @@ pub trait Builder> { } /// Represents a merge in progress. -pub trait Merger> { +pub trait Merger> { /// Creates a new merger to merge the supplied batches, optionally compacting /// up to the supplied frontier. fn new(source1: &Output, source2: &Output, compaction_frontier: Option>) -> Self; @@ -331,10 +337,14 @@ pub mod rc_blanket_impls { use timely::progress::{Antichain, frontier::AntichainRef}; use super::{Batch, BatchReader, Batcher, Builder, Merger, Cursor, Description}; - impl> BatchReader for Rc { + impl BatchReader for Rc { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; /// The type used to enumerate the batch's contents. - type Cursor = RcBatchCursor; + type Cursor = RcBatchCursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor { RcBatchCursor::new((&**self).cursor()) @@ -343,16 +353,16 @@ pub mod rc_blanket_impls { /// The number of updates in the batch. fn len(&self) -> usize { (&**self).len() } /// Describes the times of the updates in the batch. - fn description(&self) -> &Description { (&**self).description() } + fn description(&self) -> &Description { (&**self).description() } } /// Wrapper to provide cursor to nested scope. - pub struct RcBatchCursor> { + pub struct RcBatchCursor> { phantom: ::std::marker::PhantomData<(K, V, T, R)>, cursor: B::Cursor, } - impl> RcBatchCursor { + impl> RcBatchCursor { fn new(cursor: B::Cursor) -> Self { RcBatchCursor { cursor, @@ -361,7 +371,7 @@ pub mod rc_blanket_impls { } } - impl> Cursor for RcBatchCursor { + impl> Cursor for RcBatchCursor { type Storage = Rc; @@ -387,17 +397,17 @@ pub mod rc_blanket_impls { } /// An immutable collection of updates. - impl> Batch for Rc { - type Batcher = RcBatcher; - type Builder = RcBuilder; - type Merger = RcMerger; + impl Batch for Rc { + type Batcher = RcBatcher; + type Builder = RcBuilder; + type Merger = RcMerger; } /// Wrapper type for batching reference counted batches. - pub struct RcBatcher> { batcher: B::Batcher } + pub struct RcBatcher> { batcher: B::Batcher } /// Functionality for collecting and batching updates. - impl> Batcher> for RcBatcher { + impl> Batcher> for RcBatcher { fn new() -> Self { RcBatcher { batcher: >::new() } } fn push_batch(&mut self, batch: &mut Vec<((K, V), T, R)>) { self.batcher.push_batch(batch) } fn seal(&mut self, upper: Antichain) -> Rc { Rc::new(self.batcher.seal(upper)) } @@ -405,10 +415,10 @@ pub mod rc_blanket_impls { } /// Wrapper type for building reference counted batches. - pub struct RcBuilder> { builder: B::Builder } + pub struct RcBuilder> { builder: B::Builder } /// Functionality for building batches from ordered update sequences. - impl> Builder> for RcBuilder { + impl> Builder> for RcBuilder { fn new() -> Self { RcBuilder { builder: >::new() } } fn with_capacity(cap: usize) -> Self { RcBuilder { builder: >::with_capacity(cap) } } fn push(&mut self, element: (K, V, T, R)) { self.builder.push(element) } @@ -416,10 +426,10 @@ pub mod rc_blanket_impls { } /// Wrapper type for merging reference counted batches. - pub struct RcMerger> { merger: B::Merger } + pub struct RcMerger> { merger: B::Merger } /// Represents a merge in progress. - impl> Merger> for RcMerger { + impl> Merger> for RcMerger { fn new(source1: &Rc, source2: &Rc, compaction_frontier: Option>) -> Self { RcMerger { merger: B::begin_merge(source1, source2, compaction_frontier) } } fn work(&mut self, source1: &Rc, source2: &Rc, fuel: &mut isize) { self.merger.work(source1, source2, fuel) } fn done(self) -> Rc { Rc::new(self.merger.done()) } @@ -438,10 +448,14 @@ pub mod abomonated_blanket_impls { use super::{Batch, BatchReader, Batcher, Builder, Merger, Cursor, Description}; - impl+Abomonation> BatchReader for Abomonated> { + impl BatchReader for Abomonated> { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; /// The type used to enumerate the batch's contents. - type Cursor = AbomonatedBatchCursor; + type Cursor = AbomonatedBatchCursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor { AbomonatedBatchCursor::new((&**self).cursor()) @@ -450,16 +464,16 @@ pub mod abomonated_blanket_impls { /// The number of updates in the batch. fn len(&self) -> usize { (&**self).len() } /// Describes the times of the updates in the batch. - fn description(&self) -> &Description { (&**self).description() } + fn description(&self) -> &Description { (&**self).description() } } /// Wrapper to provide cursor to nested scope. - pub struct AbomonatedBatchCursor> { + pub struct AbomonatedBatchCursor> { phantom: ::std::marker::PhantomData<(K, V, T, R)>, cursor: B::Cursor, } - impl> AbomonatedBatchCursor { + impl> AbomonatedBatchCursor { fn new(cursor: B::Cursor) -> Self { AbomonatedBatchCursor { cursor, @@ -468,7 +482,7 @@ pub mod abomonated_blanket_impls { } } - impl+Abomonation> Cursor for AbomonatedBatchCursor { + impl+Abomonation> Cursor for AbomonatedBatchCursor { type Storage = Abomonated>; @@ -494,17 +508,17 @@ pub mod abomonated_blanket_impls { } /// An immutable collection of updates. - impl+Abomonation> Batch for Abomonated> { - type Batcher = AbomonatedBatcher; - type Builder = AbomonatedBuilder; - type Merger = AbomonatedMerger; + impl Batch for Abomonated> { + type Batcher = AbomonatedBatcher; + type Builder = AbomonatedBuilder; + type Merger = AbomonatedMerger; } /// Wrapper type for batching reference counted batches. - pub struct AbomonatedBatcher> { batcher: B::Batcher } + pub struct AbomonatedBatcher> { batcher: B::Batcher } /// Functionality for collecting and batching updates. - impl+Abomonation> Batcher>> for AbomonatedBatcher { + impl+Abomonation> Batcher>> for AbomonatedBatcher { fn new() -> Self { AbomonatedBatcher { batcher: >::new() } } fn push_batch(&mut self, batch: &mut Vec<((K, V), T, R)>) { self.batcher.push_batch(batch) } fn seal(&mut self, upper: Antichain) -> Abomonated> { @@ -517,10 +531,10 @@ pub mod abomonated_blanket_impls { } /// Wrapper type for building reference counted batches. - pub struct AbomonatedBuilder> { builder: B::Builder } + pub struct AbomonatedBuilder> { builder: B::Builder } /// Functionality for building batches from ordered update sequences. - impl+Abomonation> Builder>> for AbomonatedBuilder { + impl+Abomonation> Builder>> for AbomonatedBuilder { fn new() -> Self { AbomonatedBuilder { builder: >::new() } } fn with_capacity(cap: usize) -> Self { AbomonatedBuilder { builder: >::with_capacity(cap) } } fn push(&mut self, element: (K, V, T, R)) { self.builder.push(element) } @@ -533,10 +547,10 @@ pub mod abomonated_blanket_impls { } /// Wrapper type for merging reference counted batches. - pub struct AbomonatedMerger> { merger: B::Merger } + pub struct AbomonatedMerger> { merger: B::Merger } /// Represents a merge in progress. - impl+Abomonation> Merger>> for AbomonatedMerger { + impl+Abomonation> Merger>> for AbomonatedMerger { fn new(source1: &Abomonated>, source2: &Abomonated>, compaction_frontier: Option>) -> Self { AbomonatedMerger { merger: B::begin_merge(source1, source2, compaction_frontier) } } diff --git a/src/trace/wrappers/enter.rs b/src/trace/wrappers/enter.rs index c1d28fd92..410b8d642 100644 --- a/src/trace/wrappers/enter.rs +++ b/src/trace/wrappers/enter.rs @@ -47,7 +47,7 @@ where type Time = TInner; type R = Tr::R; - type Batch = BatchEnter; + type Batch = BatchEnter; type Cursor = CursorEnter; fn map_batches(&self, mut f: F) { @@ -113,42 +113,37 @@ where /// Wrapper to provide batch to nested scope. -pub struct BatchEnter { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, +#[derive(Clone)] +pub struct BatchEnter { batch: B, description: Description, } -impl Clone for BatchEnter { - fn clone(&self) -> Self { - BatchEnter { - phantom: ::std::marker::PhantomData, - batch: self.batch.clone(), - description: self.description.clone(), - } - } -} - -impl BatchReader for BatchEnter +impl BatchReader for BatchEnter where - B: BatchReader, - T: Timestamp, - TInner: Refines+Lattice, + B: BatchReader, + B::Time: Timestamp, + TInner: Refines+Lattice, { - type Cursor = BatchCursorEnter; + type Key = B::Key; + type Val = B::Val; + type Time = TInner; + type R = B::R; + + type Cursor = BatchCursorEnter; fn cursor(&self) -> Self::Cursor { BatchCursorEnter::new(self.batch.cursor()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { &self.description } + fn description(&self) -> &Description { &self.description } } -impl BatchEnter +impl BatchEnter where - B: BatchReader, - T: Timestamp, - TInner: Refines+Lattice, + B: BatchReader, + B::Time: Timestamp, + TInner: Refines+Lattice, { /// Makes a new batch wrapper pub fn make_from(batch: B) -> Self { @@ -157,7 +152,6 @@ where let since: Vec<_> = batch.description().since().elements().iter().map(|x| TInner::to_inner(x.clone())).collect(); BatchEnter { - phantom: ::std::marker::PhantomData, batch: batch, description: Description::new(Antichain::from(lower), Antichain::from(upper), Antichain::from(since)) } @@ -213,12 +207,12 @@ where /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorEnter, TInner> { +pub struct BatchCursorEnter, TInner> { phantom: ::std::marker::PhantomData<(K, V, R, TInner)>, cursor: B::Cursor, } -impl, TInner> BatchCursorEnter { +impl, TInner> BatchCursorEnter { fn new(cursor: B::Cursor) -> Self { BatchCursorEnter { phantom: ::std::marker::PhantomData, @@ -227,12 +221,12 @@ impl, TInner> BatchCursorEnter> Cursor for BatchCursorEnter +impl> Cursor for BatchCursorEnter where T: Timestamp, TInner: Refines+Lattice, { - type Storage = BatchEnter; + type Storage = BatchEnter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } diff --git a/src/trace/wrappers/enter_at.rs b/src/trace/wrappers/enter_at.rs index 9562fc90c..e95f885f1 100644 --- a/src/trace/wrappers/enter_at.rs +++ b/src/trace/wrappers/enter_at.rs @@ -62,7 +62,7 @@ where type Time = TInner; type R = Tr::R; - type Batch = BatchEnter; + type Batch = BatchEnter; type Cursor = CursorEnter; fn map_batches(&self, mut f: F2) { @@ -131,32 +131,26 @@ where /// Wrapper to provide batch to nested scope. -pub struct BatchEnter { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, +#[derive(Clone)] +pub struct BatchEnter { batch: B, description: Description, logic: F, } -impl Clone for BatchEnter { - fn clone(&self) -> Self { - BatchEnter { - phantom: ::std::marker::PhantomData, - batch: self.batch.clone(), - description: self.description.clone(), - logic: self.logic.clone(), - } - } -} - -impl BatchReader for BatchEnter +impl BatchReader for BatchEnter where - B: BatchReader, - T: Timestamp, - TInner: Refines+Lattice, - F: FnMut(&K, &V, &T)->TInner+Clone, + B: BatchReader, + B::Time: Timestamp, + TInner: Refines+Lattice, + F: FnMut(&B::Key, &B::Val, &B::Time)->TInner+Clone, { - type Cursor = BatchCursorEnter; + type Key = B::Key; + type Val = B::Val; + type Time = TInner; + type R = B::R; + + type Cursor = BatchCursorEnter; fn cursor(&self) -> Self::Cursor { BatchCursorEnter::new(self.batch.cursor(), self.logic.clone()) @@ -165,11 +159,11 @@ where fn description(&self) -> &Description { &self.description } } -impl BatchEnter +impl BatchEnter where - B: BatchReader, - T: Timestamp, - TInner: Refines+Lattice, + B: BatchReader, + B::Time: Timestamp, + TInner: Refines+Lattice, { /// Makes a new batch wrapper pub fn make_from(batch: B, logic: F) -> Self { @@ -178,7 +172,6 @@ where let since: Vec<_> = batch.description().since().elements().iter().map(|x| TInner::to_inner(x.clone())).collect(); BatchEnter { - phantom: ::std::marker::PhantomData, batch, description: Description::new(Antichain::from(lower), Antichain::from(upper), Antichain::from(since)), logic, @@ -241,13 +234,13 @@ where /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorEnter, TInner, F> { +pub struct BatchCursorEnter, TInner, F> { phantom: ::std::marker::PhantomData<(K, V, R, TInner)>, cursor: B::Cursor, logic: F, } -impl, TInner, F> BatchCursorEnter { +impl, TInner, F> BatchCursorEnter { fn new(cursor: B::Cursor, logic: F) -> Self { BatchCursorEnter { phantom: ::std::marker::PhantomData, @@ -257,13 +250,13 @@ impl, TInner, F> BatchCursorEnter, F> Cursor for BatchCursorEnter +impl, F> Cursor for BatchCursorEnter where T: Timestamp, TInner: Refines+Lattice, F: FnMut(&K, &V, &T)->TInner, { - type Storage = BatchEnter; + type Storage = BatchEnter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } diff --git a/src/trace/wrappers/filter.rs b/src/trace/wrappers/filter.rs index 0f1a531ab..b61994bc1 100644 --- a/src/trace/wrappers/filter.rs +++ b/src/trace/wrappers/filter.rs @@ -40,7 +40,7 @@ where type Time = Tr::Time; type R = Tr::R; - type Batch = BatchFilter; + type Batch = BatchFilter; type Cursor = CursorFilter; fn map_batches(&self, mut f: F2) { @@ -76,46 +76,36 @@ where /// Wrapper to provide batch to nested scope. -pub struct BatchFilter { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, +#[derive(Clone)] +pub struct BatchFilter { batch: B, logic: F, } -impl Clone for BatchFilter { - fn clone(&self) -> Self { - BatchFilter { - phantom: ::std::marker::PhantomData, - batch: self.batch.clone(), - logic: self.logic.clone(), - } - } -} - -impl BatchReader for BatchFilter +impl BatchReader for BatchFilter where - B: BatchReader, - T: Timestamp, - F: FnMut(&K, &V)->bool+Clone+'static + B: BatchReader, + B::Time: Timestamp, + F: FnMut(&B::Key, &B::Val)->bool+Clone+'static { - type Cursor = BatchCursorFilter; + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; + + type Cursor = BatchCursorFilter; fn cursor(&self) -> Self::Cursor { BatchCursorFilter::new(self.batch.cursor(), self.logic.clone()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { &self.batch.description() } + fn description(&self) -> &Description { &self.batch.description() } } -impl BatchFilter -where - B: BatchReader, - T: Timestamp, -{ +impl BatchFilter { /// Makes a new batch wrapper pub fn make_from(batch: B, logic: F) -> Self { BatchFilter { - phantom: ::std::marker::PhantomData, batch, logic, } @@ -175,13 +165,13 @@ where /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorFilter, F> { +pub struct BatchCursorFilter, F> { phantom: ::std::marker::PhantomData<(K, V, R)>, cursor: B::Cursor, logic: F, } -impl, F> BatchCursorFilter { +impl, F> BatchCursorFilter { fn new(cursor: B::Cursor, logic: F) -> Self { BatchCursorFilter { phantom: ::std::marker::PhantomData, @@ -191,12 +181,12 @@ impl, F> BatchCursorFilter, F> Cursor for BatchCursorFilter +impl, F> Cursor for BatchCursorFilter where T: Timestamp, F: FnMut(&K, &V)->bool+'static, { - type Storage = BatchFilter; + type Storage = BatchFilter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } diff --git a/src/trace/wrappers/freeze.rs b/src/trace/wrappers/freeze.rs index fa24b91d7..706d6a1a8 100644 --- a/src/trace/wrappers/freeze.rs +++ b/src/trace/wrappers/freeze.rs @@ -41,7 +41,6 @@ where T::Key: 'static, T::Val: 'static, T::R: 'static, - T::Batch: BatchReader, T::Cursor: Cursor, F: Fn(&G::Timestamp)->Option+'static, { @@ -93,7 +92,7 @@ where type Time = Tr::Time; type R = Tr::R; - type Batch = BatchFreeze; + type Batch = BatchFreeze; type Cursor = CursorFreeze; fn map_batches(&self, mut f: F2) { @@ -137,47 +136,39 @@ where /// Wrapper to provide batch to nested scope. -pub struct BatchFreeze { - phantom: ::std::marker::PhantomData<(K, V, R, T)>, +pub struct BatchFreeze { batch: B, func: Rc, } -impl Clone for BatchFreeze { +impl Clone for BatchFreeze { fn clone(&self) -> Self { BatchFreeze { - phantom: ::std::marker::PhantomData, batch: self.batch.clone(), func: self.func.clone(), } } } -impl BatchReader for BatchFreeze -where - B: BatchReader, - T: Clone, - F: Fn(&T)->Option, -{ - type Cursor = BatchCursorFreeze; +impl Option> BatchReader for BatchFreeze { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; + + type Cursor = BatchCursorFreeze; fn cursor(&self) -> Self::Cursor { BatchCursorFreeze::new(self.batch.cursor(), self.func.clone()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { self.batch.description() } + fn description(&self) -> &Description { self.batch.description() } } -impl BatchFreeze -where - B: BatchReader, - T: Clone, - F: Fn(&T)->Option -{ +impl Option> BatchFreeze { /// Makes a new batch wrapper pub fn make_from(batch: B, func: Rc) -> Self { BatchFreeze { - phantom: ::std::marker::PhantomData, batch: batch, func: func, } @@ -236,13 +227,13 @@ where /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorFreeze, F> { +pub struct BatchCursorFreeze, F> { phantom: ::std::marker::PhantomData<(K, V, R, T)>, cursor: B::Cursor, func: Rc, } -impl, F> BatchCursorFreeze { +impl, F> BatchCursorFreeze { fn new(cursor: B::Cursor, func: Rc) -> Self { BatchCursorFreeze { phantom: ::std::marker::PhantomData, @@ -252,12 +243,12 @@ impl, F> BatchCursorFreeze, F> Cursor for BatchCursorFreeze +impl, F> Cursor for BatchCursorFreeze where F: Fn(&T)->Option, { - type Storage = BatchFreeze; + type Storage = BatchFreeze; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } diff --git a/src/trace/wrappers/frontier.rs b/src/trace/wrappers/frontier.rs index 43ed2096b..d54c79beb 100644 --- a/src/trace/wrappers/frontier.rs +++ b/src/trace/wrappers/frontier.rs @@ -47,7 +47,7 @@ where type Time = Tr::Time; type R = Tr::R; - type Batch = BatchFrontier; + type Batch = BatchFrontier; type Cursor = CursorFrontier; fn map_batches(&self, mut f: F) { @@ -83,45 +83,37 @@ where /// Wrapper to provide batch to nested scope. -pub struct BatchFrontier { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, +#[derive(Clone)] +pub struct BatchFrontier { batch: B, - frontier: Antichain, + frontier: Antichain, } -impl Clone for BatchFrontier { - fn clone(&self) -> Self { - BatchFrontier { - phantom: ::std::marker::PhantomData, - batch: self.batch.clone(), - frontier: self.frontier.to_owned(), - } - } -} - -impl BatchReader for BatchFrontier +impl BatchReader for BatchFrontier where - B: BatchReader, - T: Timestamp+Lattice, + B::Time: Timestamp + Lattice { - type Cursor = BatchCursorFrontier; + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; + + type Cursor = BatchCursorFrontier; fn cursor(&self) -> Self::Cursor { BatchCursorFrontier::new(self.batch.cursor(), self.frontier.borrow()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { &self.batch.description() } + fn description(&self) -> &Description { &self.batch.description() } } -impl BatchFrontier +impl BatchFrontier where - B: BatchReader, - T: Timestamp+Lattice, + B::Time: Timestamp+Lattice { /// Makes a new batch wrapper - pub fn make_from(batch: B, frontier: AntichainRef) -> Self { + pub fn make_from(batch: B, frontier: AntichainRef) -> Self { BatchFrontier { - phantom: ::std::marker::PhantomData, batch, frontier: frontier.to_owned(), } @@ -182,13 +174,13 @@ where /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorFrontier> { +pub struct BatchCursorFrontier> { phantom: ::std::marker::PhantomData<(K, V, R)>, cursor: B::Cursor, frontier: Antichain, } -impl> BatchCursorFrontier { +impl> BatchCursorFrontier { fn new(cursor: B::Cursor, frontier: AntichainRef) -> Self { BatchCursorFrontier { phantom: ::std::marker::PhantomData, @@ -198,11 +190,11 @@ impl> BatchCursorFrontier> Cursor for BatchCursorFrontier +impl> Cursor for BatchCursorFrontier where T: Timestamp+Lattice, { - type Storage = BatchFrontier; + type Storage = BatchFrontier; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } diff --git a/tests/trace.rs b/tests/trace.rs index 1c22f4665..db4d5a90e 100644 --- a/tests/trace.rs +++ b/tests/trace.rs @@ -19,7 +19,7 @@ fn get_trace() -> Spine::Batch as Batch>::Batcher::new(); + let mut batcher = <::Batch as Batch>::Batcher::new(); batcher.push_batch(&mut vec![ ((1, 2), 0, 1), From 9d2da4c5377e7b0bb1283fe8070b53efa677435d Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Fri, 18 Mar 2022 14:51:12 +0100 Subject: [PATCH 3/8] trace: redefine Cursor with associated types Signed-off-by: Petros Angelatos --- dogsdogsdogs/src/operators/count.rs | 3 +- dogsdogsdogs/src/operators/half_join.rs | 2 - dogsdogsdogs/src/operators/lookup_map.rs | 1 - dogsdogsdogs/src/operators/propose.rs | 4 +- dogsdogsdogs/src/operators/validate.rs | 3 +- src/algorithms/graphs/bfs.rs | 1 - src/algorithms/graphs/bijkstra.rs | 1 - src/algorithms/graphs/propagate.rs | 1 - src/operators/arrange/agent.rs | 2 +- src/operators/arrange/arrangement.rs | 8 --- src/operators/arrange/upsert.rs | 1 - src/operators/count.rs | 1 - src/operators/join.rs | 16 ++--- src/operators/mod.rs | 24 +++++--- src/operators/reduce.rs | 20 ++----- src/operators/threshold.rs | 1 - src/trace/cursor/cursor_list.rs | 35 ++++++----- src/trace/cursor/cursor_pair.rs | 12 ++-- src/trace/cursor/mod.rs | 41 +++++++++---- src/trace/implementations/ord.rs | 32 +++++++--- src/trace/implementations/spine_fueled.rs | 4 +- src/trace/mod.rs | 58 +++++++++--------- src/trace/wrappers/enter.rs | 65 ++++++++++---------- src/trace/wrappers/enter_at.rs | 70 ++++++++++++---------- src/trace/wrappers/filter.rs | 61 +++++++++---------- src/trace/wrappers/freeze.rs | 70 +++++++++++----------- src/trace/wrappers/frontier.rs | 73 ++++++++++++----------- src/trace/wrappers/rc.rs | 4 +- 28 files changed, 324 insertions(+), 290 deletions(-) diff --git a/dogsdogsdogs/src/operators/count.rs b/dogsdogsdogs/src/operators/count.rs index bb75f26a9..d86fb5089 100644 --- a/dogsdogsdogs/src/operators/count.rs +++ b/dogsdogsdogs/src/operators/count.rs @@ -4,7 +4,7 @@ use differential_dataflow::{ExchangeData, Collection, Hashable}; use differential_dataflow::difference::{Monoid, Multiply}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader}; +use differential_dataflow::trace::TraceReader; /// Reports a number of extensions to a stream of prefixes. /// @@ -23,7 +23,6 @@ where G::Timestamp: Lattice, Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+Default, - Tr::Cursor: Cursor, R: Monoid+Multiply+ExchangeData, F: Fn(&P)->Tr::Key+Clone+'static, P: ExchangeData, diff --git a/dogsdogsdogs/src/operators/half_join.rs b/dogsdogsdogs/src/operators/half_join.rs index 482bbb570..338a994aa 100644 --- a/dogsdogsdogs/src/operators/half_join.rs +++ b/dogsdogsdogs/src/operators/half_join.rs @@ -81,7 +81,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+ExchangeData, Tr::Val: Clone, - Tr::Cursor: Cursor, Tr::R: Monoid+ExchangeData, FF: Fn(&G::Timestamp) -> G::Timestamp + 'static, CF: Fn(&G::Timestamp, &G::Timestamp) -> bool + 'static, @@ -136,7 +135,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+ExchangeData, Tr::Val: Clone, - Tr::Cursor: Cursor, Tr::R: Monoid+ExchangeData, FF: Fn(&G::Timestamp) -> G::Timestamp + 'static, CF: Fn(&G::Timestamp, &G::Timestamp) -> bool + 'static, diff --git a/dogsdogsdogs/src/operators/lookup_map.rs b/dogsdogsdogs/src/operators/lookup_map.rs index 081f17bc4..029e1f942 100644 --- a/dogsdogsdogs/src/operators/lookup_map.rs +++ b/dogsdogsdogs/src/operators/lookup_map.rs @@ -32,7 +32,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable, Tr::Val: Clone, - Tr::Cursor: Cursor, Tr::R: Monoid+ExchangeData, F: FnMut(&D, &mut Tr::Key)+Clone+'static, D: ExchangeData, diff --git a/dogsdogsdogs/src/operators/propose.rs b/dogsdogsdogs/src/operators/propose.rs index 105bcc340..2a5e6747a 100644 --- a/dogsdogsdogs/src/operators/propose.rs +++ b/dogsdogsdogs/src/operators/propose.rs @@ -4,7 +4,7 @@ use differential_dataflow::{ExchangeData, Collection, Hashable}; use differential_dataflow::difference::{Monoid, Multiply}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader}; +use differential_dataflow::trace::TraceReader; /// Proposes extensions to a prefix stream. /// @@ -25,7 +25,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+Default, Tr::Val: Clone, - Tr::Cursor: Cursor, Tr::R: Monoid+Multiply+ExchangeData, F: Fn(&P)->Tr::Key+Clone+'static, P: ExchangeData, @@ -57,7 +56,6 @@ where Tr: TraceReader+Clone+'static, Tr::Key: Ord+Hashable+Default, Tr::Val: Clone, - Tr::Cursor: Cursor, Tr::R: Monoid+Multiply+ExchangeData, F: Fn(&P)->Tr::Key+Clone+'static, P: ExchangeData, diff --git a/dogsdogsdogs/src/operators/validate.rs b/dogsdogsdogs/src/operators/validate.rs index 3ef2f1d63..41efa8df2 100644 --- a/dogsdogsdogs/src/operators/validate.rs +++ b/dogsdogsdogs/src/operators/validate.rs @@ -6,7 +6,7 @@ use differential_dataflow::{ExchangeData, Collection}; use differential_dataflow::difference::{Monoid, Multiply}; use differential_dataflow::lattice::Lattice; use differential_dataflow::operators::arrange::Arranged; -use differential_dataflow::trace::{Cursor, TraceReader}; +use differential_dataflow::trace::TraceReader; /// Proposes extensions to a stream of prefixes. /// @@ -24,7 +24,6 @@ where Tr: TraceReader+Clone+'static, K: Ord+Hash+Clone+Default, V: ExchangeData+Hash+Default, - Tr::Cursor: Cursor, Tr::R: Monoid+Multiply+ExchangeData, F: Fn(&P)->K+Clone+'static, P: ExchangeData, diff --git a/src/algorithms/graphs/bfs.rs b/src/algorithms/graphs/bfs.rs index 6e1a0a5f1..d80ad3c75 100644 --- a/src/algorithms/graphs/bfs.rs +++ b/src/algorithms/graphs/bfs.rs @@ -30,7 +30,6 @@ where G::Timestamp: Lattice+Ord, N: ExchangeData+Hash, Tr: TraceReader+Clone+'static, - Tr::Cursor: crate::trace::Cursor+'static, { // initialize roots as reaching themselves at distance 0 let nodes = roots.map(|x| (x, 0)); diff --git a/src/algorithms/graphs/bijkstra.rs b/src/algorithms/graphs/bijkstra.rs index 54dea878e..eb803f160 100644 --- a/src/algorithms/graphs/bijkstra.rs +++ b/src/algorithms/graphs/bijkstra.rs @@ -46,7 +46,6 @@ where G::Timestamp: Lattice+Ord, N: ExchangeData+Hash, Tr: TraceReader+Clone+'static, - Tr::Cursor: crate::trace::Cursor+'static, { forward .stream diff --git a/src/algorithms/graphs/propagate.rs b/src/algorithms/graphs/propagate.rs index 71eed8c9d..62bd92283 100644 --- a/src/algorithms/graphs/propagate.rs +++ b/src/algorithms/graphs/propagate.rs @@ -65,7 +65,6 @@ where R: From, L: ExchangeData, Tr: TraceReader+Clone+'static, - Tr::Cursor: crate::trace::Cursor+'static, F: Fn(&L)->u64+Clone+'static, { // Morally the code performs the following iterative computation. However, in the interest of a simplified diff --git a/src/operators/arrange/agent.rs b/src/operators/arrange/agent.rs index 8f5a469ef..8016c12cc 100644 --- a/src/operators/arrange/agent.rs +++ b/src/operators/arrange/agent.rs @@ -77,7 +77,7 @@ where fn get_physical_compaction(&mut self) -> AntichainRef { self.physical_compaction.borrow() } - fn cursor_through(&mut self, frontier: AntichainRef) -> Option<(Tr::Cursor, >::Storage)> { + fn cursor_through(&mut self, frontier: AntichainRef) -> Option<(Tr::Cursor, ::Storage)> { self.trace.borrow_mut().trace.cursor_through(frontier) } fn map_batches(&self, f: F) { self.trace.borrow().trace.map_batches(f) } diff --git a/src/operators/arrange/arrangement.rs b/src/operators/arrange/arrangement.rs index 286859c59..cf1f3a003 100644 --- a/src/operators/arrange/arrangement.rs +++ b/src/operators/arrange/arrangement.rs @@ -65,7 +65,6 @@ impl Clone for Arranged where G::Timestamp: Lattice+Ord, Tr: TraceReader + Clone, - Tr::Cursor: Cursor, { fn clone(&self) -> Self { Arranged { @@ -82,7 +81,6 @@ impl Arranged where G::Timestamp: Lattice+Ord, Tr: TraceReader + Clone, - Tr::Cursor: Cursor, { /// Brings an arranged collection into a nested scope. /// @@ -423,7 +421,6 @@ impl<'a, G: Scope, Tr> Arranged, Tr> where G::Timestamp: Lattice+Ord, Tr: TraceReader + Clone, - Tr::Cursor: Cursor, { /// Brings an arranged collection out of a nested region. /// @@ -460,7 +457,6 @@ where R: ExchangeData, Tr: Trace+TraceReader+'static, Tr::Batch: Batch, - Tr::Cursor: Cursor, { self.arrange_named("Arrange") } @@ -477,7 +473,6 @@ where R: ExchangeData, Tr: Trace+TraceReader+'static, Tr::Batch: Batch, - Tr::Cursor: Cursor, { let exchange = Exchange::new(move |update: &((K,V),G::Timestamp,R)| (update.0).0.hashed().into()); self.arrange_core(exchange, name) @@ -493,7 +488,6 @@ where P: ParallelizationContract, Tr: Trace+TraceReader+'static, Tr::Batch: Batch, - Tr::Cursor: Cursor, ; } @@ -510,7 +504,6 @@ where P: ParallelizationContract, Tr: Trace+TraceReader+'static, Tr::Batch: Batch, - Tr::Cursor: Cursor, { // The `Arrange` operator is tasked with reacting to an advancing input // frontier by producing the sequence of batches whose lower and upper @@ -682,7 +675,6 @@ where P: ParallelizationContract, Tr: Trace+TraceReader+'static, Tr::Batch: Batch, - Tr::Cursor: Cursor, { self.map(|k| (k, ())) .arrange_core(pact, name) diff --git a/src/operators/arrange/upsert.rs b/src/operators/arrange/upsert.rs index 6a7aa6ba3..468398ae6 100644 --- a/src/operators/arrange/upsert.rs +++ b/src/operators/arrange/upsert.rs @@ -146,7 +146,6 @@ where Tr::Val: ExchangeData, Tr: Trace+TraceReader+'static, Tr::Batch: Batch, - Tr::Cursor: Cursor, { let mut reader: Option> = None; diff --git a/src/operators/count.rs b/src/operators/count.rs index 6b6a6bf4e..47864622b 100644 --- a/src/operators/count.rs +++ b/src/operators/count.rs @@ -74,7 +74,6 @@ where T1: TraceReader+Clone+'static, T1::Key: ExchangeData, T1::R: ExchangeData+Semigroup, - T1::Cursor: Cursor, { fn count_total_core>(&self) -> Collection { diff --git a/src/operators/join.rs b/src/operators/join.rs index 67a6b21d5..6f5a383ba 100644 --- a/src/operators/join.rs +++ b/src/operators/join.rs @@ -190,7 +190,6 @@ where Tr::Key: Data+Hashable, Tr::Val: Data, Tr::R: Semigroup, - Tr::Cursor: Cursor+'static, { fn join_map(&self, other: &Collection, mut logic: L) -> Collection>::Output> where Tr::Key: ExchangeData, Tr::R: Multiply, >::Output: Semigroup, L: FnMut(&Tr::Key, &Tr::Val, &V2)->D+'static { @@ -257,7 +256,6 @@ pub trait JoinCore where G::Time fn join_core (&self, stream2: &Arranged, result: L) -> Collection>::Output> where Tr2: TraceReader+Clone+'static, - Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, R: Multiply, @@ -309,7 +307,6 @@ pub trait JoinCore where G::Time fn join_core_internal_unsafe (&self, stream2: &Arranged, result: L) -> Collection where Tr2: TraceReader+Clone+'static, - Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, D: Data, @@ -331,7 +328,6 @@ where fn join_core (&self, stream2: &Arranged, result: L) -> Collection>::Output> where Tr2: TraceReader+Clone+'static, - Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, R: Multiply, @@ -347,7 +343,6 @@ where fn join_core_internal_unsafe (&self, stream2: &Arranged, result: L) -> Collection where Tr2: TraceReader+Clone+'static, - Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, R: Semigroup, @@ -369,13 +364,11 @@ impl JoinCore for Arranged T1::Key: Ord+Debug+'static, T1::Val: Ord+Clone+Debug+'static, T1::R: Semigroup, - T1::Cursor: Cursor+'static, { fn join_core(&self, other: &Arranged, mut result: L) -> Collection>::Output> where Tr2::Val: Ord+Clone+Debug+'static, Tr2: TraceReader+Clone+'static, - Tr2::Cursor: Cursor+'static, Tr2::R: Semigroup, T1::R: Multiply, >::Output: Semigroup, @@ -394,7 +387,6 @@ impl JoinCore for Arranged fn join_core_internal_unsafe (&self, other: &Arranged, mut result: L) -> Collection where Tr2: TraceReader+Clone+'static, - Tr2::Cursor: Cursor+'static, Tr2::Val: Ord+Clone+Debug+'static, Tr2::R: Semigroup, D: Data, @@ -651,8 +643,8 @@ where R1: Semigroup, R2: Semigroup, R3: Semigroup, - C1: Cursor, - C2: Cursor, + C1: Cursor, + C2: Cursor, D: Ord+Clone+Data, { phant: ::std::marker::PhantomData<(K, V1, V2, R1, R2)>, @@ -674,8 +666,8 @@ where R1: Semigroup, R2: Semigroup, R3: Semigroup, - C1: Cursor, - C2: Cursor, + C1: Cursor, + C2: Cursor, D: Clone+Data, { fn new(trace: C1, trace_storage: C1::Storage, batch: C2, batch_storage: C2::Storage, capability: Capability) -> Self { diff --git a/src/operators/mod.rs b/src/operators/mod.rs index 967370e85..1363ac36c 100644 --- a/src/operators/mod.rs +++ b/src/operators/mod.rs @@ -39,8 +39,13 @@ impl<'a, V:'a, T, R> EditList<'a, V, T, R> where T: Ord+Clone, R: Semigroup { } } /// Loads the contents of a cursor. - fn load(&mut self, cursor: &mut C, storage: &'a C::Storage, logic: L) - where K: Eq, V: Clone, C: Cursor, L: Fn(&T)->T { + fn load(&mut self, cursor: &mut C, storage: &'a C::Storage, logic: L) + where + C: Cursor, + L: Fn(&T)->T, + C::Key: Eq, + V: Clone, + { self.clear(); while cursor.val_valid(storage) { cursor.map_times(storage, |time1, diff1| self.push(logic(time1), diff1.clone())); @@ -102,22 +107,27 @@ impl<'storage, V: Ord+Clone+'storage, T: Lattice+Ord+Clone, R: Semigroup> ValueH self.history.clear(); self.buffer.clear(); } - fn load(&mut self, cursor: &mut C, storage: &'storage C::Storage, logic: L) - where K: Eq, C: Cursor, L: Fn(&T)->T { + fn load(&mut self, cursor: &mut C, storage: &'storage C::Storage, logic: L) + where C: Cursor, + C::Key: Eq, + L: Fn(&T)->T, + { self.edits.load(cursor, storage, logic); } /// Loads and replays a specified key. /// /// If the key is absent, the replayed history will be empty. - fn replay_key<'history, K, C, L>( + fn replay_key<'history, C, L>( &'history mut self, cursor: &mut C, storage: &'storage C::Storage, - key: &K, + key: &C::Key, logic: L ) -> HistoryReplay<'storage, 'history, V, T, R> - where K: Eq, C: Cursor, L: Fn(&T)->T + where C: Cursor, + C::Key: Eq, + L: Fn(&T)->T, { self.clear(); cursor.seek_key(storage, key); diff --git a/src/operators/reduce.rs b/src/operators/reduce.rs index a2e8d58cc..b9bb400c3 100644 --- a/src/operators/reduce.rs +++ b/src/operators/reduce.rs @@ -90,7 +90,6 @@ impl Reduce for Arrang where G::Timestamp: Lattice+Ord, T1: TraceReader+Clone+'static, - T1::Cursor: Cursor, { fn reduce_named(&self, name: &str, logic: L) -> Collection where L: FnMut(&K, &[(&V, R)], &mut Vec<(V2, R2)>)+'static { @@ -178,7 +177,6 @@ impl Threshold for Arranged+Clone+'static, - T1::Cursor: Cursor, { fn threshold_namedR2+'static>(&self, name: &str, mut thresh: F) -> Collection { self.reduce_abelian::<_,DefaultKeyTrace<_,_,_>>(name, move |k,s,t| t.push(((), thresh(k, &s[0].1)))) @@ -234,7 +232,6 @@ impl Count for Arranged where G::Timestamp: Lattice+Ord, T1: TraceReader+Clone+'static, - T1::Cursor: Cursor, { fn count_core>(&self) -> Collection { self.reduce_abelian::<_,DefaultValTrace<_,_,_,_>>("Count", |_k,s,t| t.push((s[0].1.clone(), R2::from(1i8)))) @@ -280,7 +277,6 @@ pub trait ReduceCore where G::Timestam T2::Val: Data, T2::R: Abelian, T2::Batch: Batch, - T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val, T2::R)>)+'static, { self.reduce_core::<_,T2>(name, move |key, input, output, change| { @@ -303,7 +299,6 @@ pub trait ReduceCore where G::Timestam T2::Val: Data, T2::R: Semigroup, T2::Batch: Batch, - T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val,T2::R)>, &mut Vec<(T2::Val,T2::R)>)+'static ; } @@ -322,7 +317,6 @@ where T2::R: Semigroup, T2: Trace+TraceReader+'static, T2::Batch: Batch, - T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val,T2::R)>, &mut Vec<(T2::Val, T2::R)>)+'static { self.arrange_by_key_named(&format!("Arrange: {}", name)) @@ -334,7 +328,6 @@ impl ReduceCore for Ar where G::Timestamp: Lattice+Ord, T1: TraceReader+Clone+'static, - T1::Cursor: Cursor, { fn reduce_core(&self, name: &str, mut logic: L) -> Arranged> where @@ -342,7 +335,6 @@ where T2::Val: Data, T2::R: Semigroup, T2::Batch: Batch, - T2::Cursor: Cursor, L: FnMut(&K, &[(&V, R)], &mut Vec<(T2::Val,T2::R)>, &mut Vec<(T2::Val, T2::R)>)+'static { let mut result_trace = None; @@ -678,9 +670,9 @@ where new_interesting: &mut Vec) -> (usize, usize) where K: Eq+Clone, - C1: Cursor, - C2: Cursor, - C3: Cursor, + C1: Cursor, + C2: Cursor, + C3: Cursor, L: FnMut(&K, &[(&V1, R1)], &mut Vec<(V2, R2)>, &mut Vec<(V2, R2)>); } @@ -756,9 +748,9 @@ mod history_replay { new_interesting: &mut Vec) -> (usize, usize) where K: Eq+Clone, - C1: Cursor, - C2: Cursor, - C3: Cursor, + C1: Cursor, + C2: Cursor, + C3: Cursor, L: FnMut(&K, &[(&V1, R1)], &mut Vec<(V2, R2)>, &mut Vec<(V2, R2)>) { diff --git a/src/operators/threshold.rs b/src/operators/threshold.rs index 939211bc5..cbe1b8d8f 100644 --- a/src/operators/threshold.rs +++ b/src/operators/threshold.rs @@ -108,7 +108,6 @@ where T1: TraceReader+Clone+'static, T1::Key: ExchangeData, T1::R: ExchangeData+Semigroup, - T1::Cursor: Cursor, { fn threshold_semigroup(&self, mut thresh: F) -> Collection where diff --git a/src/trace/cursor/cursor_list.rs b/src/trace/cursor/cursor_list.rs index a7685c6f1..15d2fa9d0 100644 --- a/src/trace/cursor/cursor_list.rs +++ b/src/trace/cursor/cursor_list.rs @@ -7,19 +7,20 @@ use super::Cursor; /// The `CursorList` tracks the indices of cursors with the minimum key, and the the indices of cursors with /// the minimum key and minimum value. It performs no clever management of these sets otherwise. #[derive(Debug)] -pub struct CursorList> { - _phantom: ::std::marker::PhantomData<(K, V, T, R)>, +pub struct CursorList { cursors: Vec, min_key: Vec, min_val: Vec, } -impl> CursorList where K: Ord, V: Ord { +impl CursorList +where C::Key: Ord, + C::Val: Ord +{ /// Creates a new cursor list from pre-existing cursors. pub fn new(cursors: Vec, storage: &[C::Storage]) -> Self { let mut result = CursorList { - _phantom: ::std::marker::PhantomData, cursors, min_key: Vec::new(), min_val: Vec::new(), @@ -43,7 +44,7 @@ impl> CursorList where K: Ord, self.min_key.clear(); // Determine the index of the cursor with minimum key. - let mut min_key_opt: Option<&K> = None; + let mut min_key_opt: Option<&C::Key> = None; for (index, cursor) in self.cursors.iter().enumerate() { let key = cursor.get_key(&storage[index]); if key.is_some() { @@ -71,7 +72,7 @@ impl> CursorList where K: Ord, self.min_val.clear(); // Determine the index of the cursor with minimum value. - let mut min_val: Option<&V> = None; + let mut min_val: Option<&C::Val> = None; for &index in self.min_key.iter() { let val = self.cursors[index].get_val(&storage[index]); if val.is_some() { @@ -87,11 +88,15 @@ impl> CursorList where K: Ord, } } -impl> Cursor for CursorList +impl Cursor for CursorList where - K: Ord, - V: Ord { - + C::Key: Ord, + C::Val: Ord +{ + type Key = C::Key; + type Val = C::Val; + type Time = C::Time; + type R = C::R; type Storage = Vec; // validation methods @@ -102,20 +107,20 @@ where // accessors #[inline] - fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { + fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { debug_assert!(self.key_valid(storage)); debug_assert!(self.cursors[self.min_key[0]].key_valid(&storage[self.min_key[0]])); self.cursors[self.min_key[0]].key(&storage[self.min_key[0]]) } #[inline] - fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { + fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { debug_assert!(self.key_valid(storage)); debug_assert!(self.val_valid(storage)); debug_assert!(self.cursors[self.min_val[0]].val_valid(&storage[self.min_val[0]])); self.cursors[self.min_val[0]].val(&storage[self.min_val[0]]) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { for &index in self.min_val.iter() { self.cursors[index].map_times(&storage[index], |t,d| logic(t,d)); } @@ -130,7 +135,7 @@ where self.minimize_keys(storage); } #[inline] - fn seek_key(&mut self, storage: &Self::Storage, key: &K) { + fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { for index in 0 .. self.cursors.len() { self.cursors[index].seek_key(&storage[index], key); } @@ -146,7 +151,7 @@ where self.minimize_vals(storage); } #[inline] - fn seek_val(&mut self, storage: &Self::Storage, val: &V) { + fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { for &index in self.min_key.iter() { self.cursors[index].seek_val(&storage[index], val); } diff --git a/src/trace/cursor/cursor_pair.rs b/src/trace/cursor/cursor_pair.rs index 1ae361c7f..b55e7dd6d 100644 --- a/src/trace/cursor/cursor_pair.rs +++ b/src/trace/cursor/cursor_pair.rs @@ -15,13 +15,17 @@ pub struct CursorPair { val_order: Ordering, // Invalid vals are `Greater` than all other vals. `Equal` implies both valid. } -impl Cursor for CursorPair +impl Cursor for CursorPair where K: Ord, V: Ord, - C1: Cursor, - C2: Cursor, + C1: Cursor, + C2: Cursor, { + type Key = K; + type Val = V; + type Time = T; + type R = R; type Storage = (C1::Storage, C2::Storage); // validation methods @@ -131,4 +135,4 @@ where if self.key_order != Ordering::Greater { self.cursor1.rewind_vals(&storage.0); } if self.key_order != Ordering::Less { self.cursor2.rewind_vals(&storage.1); } } -} \ No newline at end of file +} diff --git a/src/trace/cursor/mod.rs b/src/trace/cursor/mod.rs index d76e7cab0..82175447e 100644 --- a/src/trace/cursor/mod.rs +++ b/src/trace/cursor/mod.rs @@ -12,8 +12,15 @@ pub mod cursor_list; pub use self::cursor_list::CursorList; /// A cursor for navigating ordered `(key, val, time, diff)` updates. -pub trait Cursor { - +pub trait Cursor { + /// Key by which updates are indexed. + type Key; + /// Values associated with keys. + type Val; + /// Timestamps associated with updates + type Time; + /// Associated update. + type R; /// Type the cursor addresses data in. type Storage; @@ -27,32 +34,32 @@ pub trait Cursor { fn val_valid(&self, storage: &Self::Storage) -> bool; /// A reference to the current key. Asserts if invalid. - fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K; + fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key; /// A reference to the current value. Asserts if invalid. - fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V; + fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val; /// Returns a reference to the current key, if valid. - fn get_key<'a>(&self, storage: &'a Self::Storage) -> Option<&'a K> { + fn get_key<'a>(&self, storage: &'a Self::Storage) -> Option<&'a Self::Key> { if self.key_valid(storage) { Some(self.key(storage)) } else { None } } /// Returns a reference to the current value, if valid. - fn get_val<'a>(&self, storage: &'a Self::Storage) -> Option<&'a V> { + fn get_val<'a>(&self, storage: &'a Self::Storage) -> Option<&'a Self::Val> { if self.val_valid(storage) { Some(self.val(storage)) } else { None } } /// Applies `logic` to each pair of time and difference. Intended for mutation of the /// closure's scope. - fn map_times(&mut self, storage: &Self::Storage, logic: L); + fn map_times(&mut self, storage: &Self::Storage, logic: L); /// Advances the cursor to the next key. fn step_key(&mut self, storage: &Self::Storage); /// Advances the cursor to the specified key. - fn seek_key(&mut self, storage: &Self::Storage, key: &K); + fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key); /// Advances the cursor to the next value. fn step_val(&mut self, storage: &Self::Storage); /// Advances the cursor to the specified value. - fn seek_val(&mut self, storage: &Self::Storage, val: &V); + fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val); /// Rewinds the cursor to the first key. fn rewind_keys(&mut self, storage: &Self::Storage); @@ -61,9 +68,14 @@ pub trait Cursor { } /// Debugging and testing utilities for Cursor. -pub trait CursorDebug : Cursor { +pub trait CursorDebug: Cursor +where Self::Key: Clone, + Self::Val: Clone, + Self::Time: Clone, + Self::R: Clone +{ /// Rewinds the cursor and outputs its contents to a Vec - fn to_vec(&mut self, storage: &Self::Storage) -> Vec<((K, V), Vec<(T, R)>)> { + fn to_vec(&mut self, storage: &Self::Storage) -> Vec<((Self::Key, Self::Val), Vec<(Self::Time, Self::R)>)> { let mut out = Vec::new(); self.rewind_keys(storage); self.rewind_vals(storage); @@ -82,4 +94,9 @@ pub trait CursorDebug : Cursor CursorDebug for C where C: Cursor { } +impl CursorDebug for C +where C::Key: Clone, + C::Val: Clone, + C::Time: Clone, + C::R: Clone +{ } diff --git a/src/trace/implementations/ord.rs b/src/trace/implementations/ord.rs index 4e7f8523a..a8117b5d1 100644 --- a/src/trace/implementations/ord.rs +++ b/src/trace/implementations/ord.rs @@ -75,8 +75,13 @@ where type Time = T; type R = R; - type Cursor = OrdValCursor; - fn cursor(&self) -> Self::Cursor { OrdValCursor { cursor: self.layer.cursor() } } + type Cursor = OrdValCursor; + fn cursor(&self) -> Self::Cursor { + OrdValCursor { + cursor: self.layer.cursor(), + phantom: PhantomData, + } + } fn len(&self) -> usize { , O>, O> as Trie>::tuples(&self.layer) } fn description(&self) -> &Description { &self.desc } } @@ -311,7 +316,7 @@ where /// A cursor for navigating a single layer. #[derive(Debug)] -pub struct OrdValCursor +pub struct OrdValCursor where V: Ord+Clone, T: Lattice+Ord+Clone, @@ -319,9 +324,10 @@ where O: OrdOffset, >::Error: Debug, >::Error: Debug { cursor: OrderedCursor, O>>, + phantom: PhantomData, } -impl Cursor for OrdValCursor +impl Cursor for OrdValCursor where K: Ord+Clone, V: Ord+Clone, @@ -329,6 +335,10 @@ where R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { + type Key = K; + type Val = V; + type Time = T; + type R = R; type Storage = OrdValBatch; fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { &self.cursor.key(&storage.layer) } @@ -426,7 +436,7 @@ where type Time = T; type R = R; - type Cursor = OrdKeyCursor; + type Cursor = OrdKeyCursor; fn cursor(&self) -> Self::Cursor { OrdKeyCursor { valid: true, @@ -642,13 +652,13 @@ static EMPTY: () = (); /// A cursor for navigating a single layer. #[derive(Debug)] -pub struct OrdKeyCursor { +pub struct OrdKeyCursor { valid: bool, cursor: OrderedCursor>, - phantom: PhantomData + phantom: PhantomData<(K, O)> } -impl Cursor for OrdKeyCursor +impl Cursor for OrdKeyCursor where K: Ord+Clone, T: Lattice+Ord+Clone, @@ -656,6 +666,12 @@ where O: OrdOffset, >::Error: Debug, >::Error: Debug { + type Key = K; + type Val = (); + type Time = T; + type R = R; + + type Storage = OrdKeyBatch; fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { &self.cursor.key(&storage.layer) } diff --git a/src/trace/implementations/spine_fueled.rs b/src/trace/implementations/spine_fueled.rs index 5acb3e7e5..218332908 100644 --- a/src/trace/implementations/spine_fueled.rs +++ b/src/trace/implementations/spine_fueled.rs @@ -114,9 +114,9 @@ where type R = R; type Batch = B; - type Cursor = CursorList::Cursor>; + type Cursor = CursorList<::Cursor>; - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { // If `upper` is the minimum frontier, we can return an empty cursor. // This can happen with operators that are written to expect the ability to acquire cursors diff --git a/src/trace/mod.rs b/src/trace/mod.rs index ad07f8a39..85d9e30ee 100644 --- a/src/trace/mod.rs +++ b/src/trace/mod.rs @@ -54,10 +54,10 @@ pub trait TraceReader { type Batch: BatchReader+Clone+'static; /// The type used to enumerate the collections contents. - type Cursor: Cursor; + type Cursor: Cursor; /// Provides a cursor over updates contained in the trace. - fn cursor(&mut self) -> (Self::Cursor, >::Storage) { + fn cursor(&mut self) -> (Self::Cursor, ::Storage) { if let Some(cursor) = self.cursor_through(Antichain::new().borrow()) { cursor } @@ -73,7 +73,7 @@ pub trait TraceReader { /// the trace, and (ii) the trace has not been advanced beyond `upper`. Practically, the implementation should /// be expected to look for a "clean cut" using `upper`, and if it finds such a cut can return a cursor. This /// should allow `upper` such as `&[]` as used by `self.cursor()`, though it is difficult to imagine other uses. - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)>; + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)>; /// Advances the frontier that constrains logical compaction. /// @@ -243,7 +243,7 @@ where type R; /// The type used to enumerate the batch's contents. - type Cursor: Cursor; + type Cursor: Cursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor; /// The number of updates in the batch. @@ -344,7 +344,7 @@ pub mod rc_blanket_impls { type R = B::R; /// The type used to enumerate the batch's contents. - type Cursor = RcBatchCursor; + type Cursor = RcBatchCursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor { RcBatchCursor::new((&**self).cursor()) @@ -357,40 +357,41 @@ pub mod rc_blanket_impls { } /// Wrapper to provide cursor to nested scope. - pub struct RcBatchCursor> { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, + pub struct RcBatchCursor { cursor: B::Cursor, } - impl> RcBatchCursor { + impl RcBatchCursor { fn new(cursor: B::Cursor) -> Self { RcBatchCursor { cursor, - phantom: ::std::marker::PhantomData, } } } - impl> Cursor for RcBatchCursor { - + impl Cursor for RcBatchCursor { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; type Storage = Rc; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, logic: L) { + fn map_times(&mut self, storage: &Self::Storage, logic: L) { self.cursor.map_times(storage, logic) } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } @@ -455,7 +456,7 @@ pub mod abomonated_blanket_impls { type R = B::R; /// The type used to enumerate the batch's contents. - type Cursor = AbomonatedBatchCursor; + type Cursor = AbomonatedBatchCursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor { AbomonatedBatchCursor::new((&**self).cursor()) @@ -468,40 +469,41 @@ pub mod abomonated_blanket_impls { } /// Wrapper to provide cursor to nested scope. - pub struct AbomonatedBatchCursor> { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, + pub struct AbomonatedBatchCursor { cursor: B::Cursor, } - impl> AbomonatedBatchCursor { + impl AbomonatedBatchCursor { fn new(cursor: B::Cursor) -> Self { AbomonatedBatchCursor { cursor, - phantom: ::std::marker::PhantomData, } } } - impl+Abomonation> Cursor for AbomonatedBatchCursor { - + impl Cursor for AbomonatedBatchCursor { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; type Storage = Abomonated>; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, logic: L) { + fn map_times(&mut self, storage: &Self::Storage, logic: L) { self.cursor.map_times(storage, logic) } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } diff --git a/src/trace/wrappers/enter.rs b/src/trace/wrappers/enter.rs index 410b8d642..877891fe7 100644 --- a/src/trace/wrappers/enter.rs +++ b/src/trace/wrappers/enter.rs @@ -48,7 +48,7 @@ where type R = Tr::R; type Batch = BatchEnter; - type Cursor = CursorEnter; + type Cursor = CursorEnter; fn map_batches(&self, mut f: F) { self.trace.map_batches(|batch| { @@ -86,7 +86,7 @@ where self.stash2.borrow() } - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { self.stash1.clear(); for time in upper.iter() { self.stash1.insert(time.clone().to_outer()); @@ -130,7 +130,7 @@ where type Time = TInner; type R = B::R; - type Cursor = BatchCursorEnter; + type Cursor = BatchCursorEnter; fn cursor(&self) -> Self::Cursor { BatchCursorEnter::new(self.batch.cursor()) @@ -152,67 +152,68 @@ where let since: Vec<_> = batch.description().since().elements().iter().map(|x| TInner::to_inner(x.clone())).collect(); BatchEnter { - batch: batch, + batch, description: Description::new(Antichain::from(lower), Antichain::from(upper), Antichain::from(since)) } } } /// Wrapper to provide cursor to nested scope. -pub struct CursorEnter, TInner> { - phantom: ::std::marker::PhantomData<(K, V, T, R, TInner)>, +pub struct CursorEnter { + phantom: ::std::marker::PhantomData, cursor: C, } -impl, TInner> CursorEnter { +impl CursorEnter { fn new(cursor: C) -> Self { CursorEnter { phantom: ::std::marker::PhantomData, - cursor: cursor, + cursor, } } } -impl Cursor for CursorEnter +impl Cursor for CursorEnter where - C: Cursor, - T: Timestamp, - TInner: Refines+Lattice, + C::Time: Timestamp, + TInner: Refines+Lattice, { + type Key = C::Key; + type Val = C::Val; + type Time = TInner; + type R = C::R; type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { self.cursor.map_times(storage, |time, diff| { logic(&TInner::to_inner(time.clone()), diff) }) } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } - - /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorEnter, TInner> { - phantom: ::std::marker::PhantomData<(K, V, R, TInner)>, +pub struct BatchCursorEnter { + phantom: ::std::marker::PhantomData, cursor: B::Cursor, } -impl, TInner> BatchCursorEnter { +impl BatchCursorEnter { fn new(cursor: B::Cursor) -> Self { BatchCursorEnter { phantom: ::std::marker::PhantomData, @@ -221,31 +222,35 @@ impl, TInner> BatchCursorE } } -impl> Cursor for BatchCursorEnter +impl Cursor for BatchCursorEnter where - T: Timestamp, - TInner: Refines+Lattice, + B::Time: Timestamp, + TInner: Refines+Lattice, { + type Key = B::Key; + type Val = B::Val; + type Time = TInner; + type R = B::R; type Storage = BatchEnter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(&storage.batch) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(&storage.batch) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(&storage.batch) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(&storage.batch) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { self.cursor.map_times(&storage.batch, |time, diff| { logic(&TInner::to_inner(time.clone()), diff) }) } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(&storage.batch) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(&storage.batch, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(&storage.batch, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(&storage.batch) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(&storage.batch, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(&storage.batch, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(&storage.batch) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(&storage.batch) } diff --git a/src/trace/wrappers/enter_at.rs b/src/trace/wrappers/enter_at.rs index e95f885f1..3aa2b6952 100644 --- a/src/trace/wrappers/enter_at.rs +++ b/src/trace/wrappers/enter_at.rs @@ -62,8 +62,8 @@ where type Time = TInner; type R = Tr::R; - type Batch = BatchEnter; - type Cursor = CursorEnter; + type Batch = BatchEnter; + type Cursor = CursorEnter; fn map_batches(&self, mut f: F2) { let logic = self.logic.clone(); @@ -102,7 +102,7 @@ where self.stash2.borrow() } - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { self.stash1.clear(); for time in upper.iter() { self.stash1.insert(time.clone().to_outer()); @@ -120,7 +120,7 @@ where /// Makes a new trace wrapper pub fn make_from(trace: Tr, logic: F, prior: G) -> Self { TraceEnter { - trace: trace, + trace, stash1: Antichain::new(), stash2: Antichain::new(), logic, @@ -150,7 +150,7 @@ where type Time = TInner; type R = B::R; - type Cursor = BatchCursorEnter; + type Cursor = BatchCursorEnter; fn cursor(&self) -> Self::Cursor { BatchCursorEnter::new(self.batch.cursor(), self.logic.clone()) @@ -180,13 +180,13 @@ where } /// Wrapper to provide cursor to nested scope. -pub struct CursorEnter, TInner, F> { - phantom: ::std::marker::PhantomData<(K, V, T, R, TInner)>, +pub struct CursorEnter { + phantom: ::std::marker::PhantomData, cursor: C, logic: F, } -impl, TInner, F> CursorEnter { +impl CursorEnter { fn new(cursor: C, logic: F) -> Self { CursorEnter { phantom: ::std::marker::PhantomData, @@ -196,23 +196,27 @@ impl, TInner, F> CursorEnter Cursor for CursorEnter +impl Cursor for CursorEnter where - C: Cursor, - T: Timestamp, - TInner: Refines+Lattice, - F: FnMut(&K, &V, &T)->TInner, + C: Cursor, + C::Time: Timestamp, + TInner: Refines+Lattice, + F: FnMut(&C::Key, &C::Val, &C::Time)->TInner, { + type Key = C::Key; + type Val = C::Val; + type Time = TInner; + type R = C::R; type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let key = self.key(storage); let val = self.val(storage); let logic2 = &mut self.logic; @@ -222,25 +226,23 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } - - /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorEnter, TInner, F> { - phantom: ::std::marker::PhantomData<(K, V, R, TInner)>, +pub struct BatchCursorEnter { + phantom: ::std::marker::PhantomData, cursor: B::Cursor, logic: F, } -impl, TInner, F> BatchCursorEnter { +impl BatchCursorEnter { fn new(cursor: B::Cursor, logic: F) -> Self { BatchCursorEnter { phantom: ::std::marker::PhantomData, @@ -250,22 +252,26 @@ impl, TInner, F> BatchCurs } } -impl, F> Cursor for BatchCursorEnter +impl Cursor for BatchCursorEnter where - T: Timestamp, - TInner: Refines+Lattice, - F: FnMut(&K, &V, &T)->TInner, + B::Time: Timestamp, + TInner: Refines+Lattice, + F: FnMut(&B::Key, &B::Val, &B::Time)->TInner, { + type Key = B::Key; + type Val = B::Val; + type Time = TInner; + type R = B::R; type Storage = BatchEnter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(&storage.batch) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(&storage.batch) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(&storage.batch) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(&storage.batch) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let key = self.key(storage); let val = self.val(storage); let logic2 = &mut self.logic; @@ -275,10 +281,10 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(&storage.batch) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(&storage.batch, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(&storage.batch, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(&storage.batch) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(&storage.batch, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(&storage.batch, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(&storage.batch) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(&storage.batch) } diff --git a/src/trace/wrappers/filter.rs b/src/trace/wrappers/filter.rs index b61994bc1..4b502fbc5 100644 --- a/src/trace/wrappers/filter.rs +++ b/src/trace/wrappers/filter.rs @@ -41,7 +41,7 @@ where type R = Tr::R; type Batch = BatchFilter; - type Cursor = CursorFilter; + type Cursor = CursorFilter; fn map_batches(&self, mut f: F2) { let logic = self.logic.clone(); @@ -55,7 +55,7 @@ where fn set_physical_compaction(&mut self, frontier: AntichainRef) { self.trace.set_physical_compaction(frontier) } fn get_physical_compaction(&mut self) -> AntichainRef { self.trace.get_physical_compaction() } - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { self.trace.cursor_through(upper).map(|(x,y)| (CursorFilter::new(x, self.logic.clone()), y)) } } @@ -93,7 +93,7 @@ where type Time = B::Time; type R = B::R; - type Cursor = BatchCursorFilter; + type Cursor = BatchCursorFilter; fn cursor(&self) -> Self::Cursor { BatchCursorFilter::new(self.batch.cursor(), self.logic.clone()) @@ -113,38 +113,39 @@ impl BatchFilter { } /// Wrapper to provide cursor to nested scope. -pub struct CursorFilter, F> { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, +pub struct CursorFilter { cursor: C, logic: F, } -impl, F> CursorFilter { +impl CursorFilter { fn new(cursor: C, logic: F) -> Self { CursorFilter { - phantom: ::std::marker::PhantomData, cursor, logic, } } } -impl Cursor for CursorFilter +impl Cursor for CursorFilter where - C: Cursor, - T: Timestamp, - F: FnMut(&K, &V)->bool+'static + C: Cursor, + F: FnMut(&C::Key, &C::Val)->bool+'static { + type Key = C::Key; + type Val = C::Val; + type Time = C::Time; + type R = C::R; type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, logic: L) { + fn map_times(&mut self, storage: &Self::Storage, logic: L) { let key = self.key(storage); let val = self.val(storage); if (self.logic)(key, val) { @@ -153,49 +154,49 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } - - /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorFilter, F> { - phantom: ::std::marker::PhantomData<(K, V, R)>, +pub struct BatchCursorFilter { cursor: B::Cursor, logic: F, } -impl, F> BatchCursorFilter { +impl BatchCursorFilter { fn new(cursor: B::Cursor, logic: F) -> Self { BatchCursorFilter { - phantom: ::std::marker::PhantomData, cursor, logic, } } } -impl, F> Cursor for BatchCursorFilter +impl Cursor for BatchCursorFilter where - T: Timestamp, - F: FnMut(&K, &V)->bool+'static, + B::Time: Timestamp, + F: FnMut(&B::Key, &B::Val)->bool+'static, { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; type Storage = BatchFilter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(&storage.batch) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(&storage.batch) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(&storage.batch) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(&storage.batch) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, logic: L) { + fn map_times(&mut self, storage: &Self::Storage, logic: L) { let key = self.key(storage); let val = self.val(storage); if (self.logic)(key, val) { @@ -204,10 +205,10 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(&storage.batch) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(&storage.batch, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(&storage.batch, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(&storage.batch) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(&storage.batch, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(&storage.batch, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(&storage.batch) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(&storage.batch) } diff --git a/src/trace/wrappers/freeze.rs b/src/trace/wrappers/freeze.rs index 706d6a1a8..0391ca208 100644 --- a/src/trace/wrappers/freeze.rs +++ b/src/trace/wrappers/freeze.rs @@ -41,7 +41,6 @@ where T::Key: 'static, T::Val: 'static, T::R: 'static, - T::Cursor: Cursor, F: Fn(&G::Timestamp)->Option+'static, { let func1 = Rc::new(func); @@ -93,7 +92,7 @@ where type R = Tr::R; type Batch = BatchFreeze; - type Cursor = CursorFreeze; + type Cursor = CursorFreeze; fn map_batches(&self, mut f: F2) { let func = &self.func; @@ -108,7 +107,7 @@ where fn set_physical_compaction(&mut self, frontier: AntichainRef) { self.trace.set_physical_compaction(frontier) } fn get_physical_compaction(&mut self) -> AntichainRef { self.trace.get_physical_compaction() } - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { let func = &self.func; self.trace.cursor_through(upper) .map(|(cursor, storage)| (CursorFreeze::new(cursor, func.clone()), storage)) @@ -128,8 +127,8 @@ where /// Makes a new trace wrapper pub fn make_from(trace: Tr, func: Rc) -> Self { TraceFreeze { - trace: trace, - func: func, + trace, + func, } } } @@ -156,7 +155,7 @@ impl Option> BatchReader for BatchFr type Time = B::Time; type R = B::R; - type Cursor = BatchCursorFreeze; + type Cursor = BatchCursorFreeze; fn cursor(&self) -> Self::Cursor { BatchCursorFreeze::new(self.batch.cursor(), self.func.clone()) @@ -169,44 +168,44 @@ impl Option> BatchFreeze { /// Makes a new batch wrapper pub fn make_from(batch: B, func: Rc) -> Self { BatchFreeze { - batch: batch, - func: func, + batch, + func, } } } /// Wrapper to provide cursor to nested scope. -pub struct CursorFreeze, F> { - phantom: ::std::marker::PhantomData<(K, V, R, T)>, +pub struct CursorFreeze { cursor: C, func: Rc, } -impl, F> CursorFreeze { +impl CursorFreeze { fn new(cursor: C, func: Rc) -> Self { CursorFreeze { - phantom: ::std::marker::PhantomData, - cursor: cursor, - func: func, + cursor, + func, } } } -impl Cursor for CursorFreeze +impl Cursor for CursorFreeze where - C: Cursor, - F: Fn(&T)->Option, + F: Fn(&C::Time)->Option, { - + type Key = C::Key; + type Val = C::Val; + type Time = C::Time; + type R = C::R; type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } - #[inline] fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + #[inline] fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let func = &self.func; self.cursor.map_times(storage, |time, diff| { if let Some(time) = func(time) { @@ -216,10 +215,10 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } @@ -227,36 +226,37 @@ where /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorFreeze, F> { - phantom: ::std::marker::PhantomData<(K, V, R, T)>, +pub struct BatchCursorFreeze { cursor: B::Cursor, func: Rc, } -impl, F> BatchCursorFreeze { +impl BatchCursorFreeze { fn new(cursor: B::Cursor, func: Rc) -> Self { BatchCursorFreeze { - phantom: ::std::marker::PhantomData, cursor: cursor, func: func, } } } -impl, F> Cursor for BatchCursorFreeze +impl Cursor for BatchCursorFreeze where - F: Fn(&T)->Option, + F: Fn(&B::Time)->Option, { - + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; type Storage = BatchFreeze; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(&storage.batch) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(&storage.batch) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(&storage.batch) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(&storage.batch) } - #[inline] fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + #[inline] fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let func = &self.func; self.cursor.map_times(&storage.batch, |time, diff| { if let Some(time) = func(time) { @@ -266,10 +266,10 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(&storage.batch) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(&storage.batch, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(&storage.batch, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(&storage.batch) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(&storage.batch, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(&storage.batch, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(&storage.batch) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(&storage.batch) } diff --git a/src/trace/wrappers/frontier.rs b/src/trace/wrappers/frontier.rs index d54c79beb..385af9637 100644 --- a/src/trace/wrappers/frontier.rs +++ b/src/trace/wrappers/frontier.rs @@ -48,7 +48,7 @@ where type R = Tr::R; type Batch = BatchFrontier; - type Cursor = CursorFrontier; + type Cursor = CursorFrontier; fn map_batches(&self, mut f: F) { let frontier = self.frontier.borrow(); @@ -61,7 +61,7 @@ where fn set_physical_compaction(&mut self, frontier: AntichainRef) { self.trace.set_physical_compaction(frontier) } fn get_physical_compaction(&mut self) -> AntichainRef { self.trace.get_physical_compaction() } - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, >::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { let frontier = self.frontier.borrow(); self.trace.cursor_through(upper).map(|(x,y)| (CursorFrontier::new(x, frontier), y)) } @@ -98,7 +98,7 @@ where type Time = B::Time; type R = B::R; - type Cursor = BatchCursorFrontier; + type Cursor = BatchCursorFrontier; fn cursor(&self) -> Self::Cursor { BatchCursorFrontier::new(self.batch.cursor(), self.frontier.borrow()) @@ -121,39 +121,42 @@ where } /// Wrapper to provide cursor to nested scope. -pub struct CursorFrontier> { - phantom: ::std::marker::PhantomData<(K, V, T, R)>, +pub struct CursorFrontier { cursor: C, - frontier: Antichain, + frontier: Antichain, } -impl> CursorFrontier { - fn new(cursor: C, frontier: AntichainRef) -> Self { +impl CursorFrontier +where C::Time: Clone, +{ + fn new(cursor: C, frontier: AntichainRef) -> Self { CursorFrontier { - phantom: ::std::marker::PhantomData, cursor, frontier: frontier.to_owned(), } } } -impl Cursor for CursorFrontier +impl Cursor for CursorFrontier where - C: Cursor, - T: Timestamp+Lattice, + C::Time: Timestamp+Lattice, { + type Key = C::Key; + type Val = C::Val; + type Time = C::Time; + type R = C::R; type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(storage) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(storage) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(storage) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(storage) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(storage) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let frontier = self.frontier.borrow(); - let mut temp: T = ::minimum(); + let mut temp = ::minimum(); self.cursor.map_times(storage, |time, diff| { temp.clone_from(time); temp.advance_by(frontier); @@ -162,50 +165,52 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(storage) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(storage, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(storage, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(storage) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(storage, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(storage, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(storage) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } - - /// Wrapper to provide cursor to nested scope. -pub struct BatchCursorFrontier> { - phantom: ::std::marker::PhantomData<(K, V, R)>, +pub struct BatchCursorFrontier { cursor: B::Cursor, - frontier: Antichain, + frontier: Antichain, } -impl> BatchCursorFrontier { - fn new(cursor: B::Cursor, frontier: AntichainRef) -> Self { +impl BatchCursorFrontier +where B::Time: Clone, +{ + fn new(cursor: B::Cursor, frontier: AntichainRef) -> Self { BatchCursorFrontier { - phantom: ::std::marker::PhantomData, cursor, frontier: frontier.to_owned(), } } } -impl> Cursor for BatchCursorFrontier +impl Cursor for BatchCursorFrontier where - T: Timestamp+Lattice, + B::Time: Timestamp+Lattice, { + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; type Storage = BatchFrontier; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } #[inline] fn val_valid(&self, storage: &Self::Storage) -> bool { self.cursor.val_valid(&storage.batch) } - #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { self.cursor.key(&storage.batch) } - #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V { self.cursor.val(&storage.batch) } + #[inline] fn key<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Key { self.cursor.key(&storage.batch) } + #[inline] fn val<'a>(&self, storage: &'a Self::Storage) -> &'a Self::Val { self.cursor.val(&storage.batch) } #[inline] - fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { + fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let frontier = self.frontier.borrow(); - let mut temp: T = ::minimum(); + let mut temp = ::minimum(); self.cursor.map_times(&storage.batch, |time, diff| { temp.clone_from(time); temp.advance_by(frontier); @@ -214,10 +219,10 @@ where } #[inline] fn step_key(&mut self, storage: &Self::Storage) { self.cursor.step_key(&storage.batch) } - #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &K) { self.cursor.seek_key(&storage.batch, key) } + #[inline] fn seek_key(&mut self, storage: &Self::Storage, key: &Self::Key) { self.cursor.seek_key(&storage.batch, key) } #[inline] fn step_val(&mut self, storage: &Self::Storage) { self.cursor.step_val(&storage.batch) } - #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &V) { self.cursor.seek_val(&storage.batch, val) } + #[inline] fn seek_val(&mut self, storage: &Self::Storage, val: &Self::Val) { self.cursor.seek_val(&storage.batch, val) } #[inline] fn rewind_keys(&mut self, storage: &Self::Storage) { self.cursor.rewind_keys(&storage.batch) } #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(&storage.batch) } diff --git a/src/trace/wrappers/rc.rs b/src/trace/wrappers/rc.rs index 17796d12b..f1d66949c 100644 --- a/src/trace/wrappers/rc.rs +++ b/src/trace/wrappers/rc.rs @@ -120,7 +120,7 @@ where } fn get_physical_compaction(&mut self) -> AntichainRef { self.physical_compaction.borrow() } /// Creates a new cursor over the wrapped trace. - fn cursor_through(&mut self, frontier: AntichainRef) -> Option<(Tr::Cursor, >::Storage)> { + fn cursor_through(&mut self, frontier: AntichainRef) -> Option<(Tr::Cursor, ::Storage)> { ::std::cell::RefCell::borrow_mut(&self.wrapper).trace.cursor_through(frontier) } @@ -177,4 +177,4 @@ where self.logical_compaction = Antichain::new(); self.physical_compaction = Antichain::new(); } -} \ No newline at end of file +} From c44766194863bdfd52d3c23f28b9f1cf34285e3c Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Fri, 18 Mar 2022 13:23:31 +0100 Subject: [PATCH 4/8] remove transmute and fix rust warning while `()` is a ZST the potentially dangling reference is still undefined behaviour. Making it a static is a trivial fix. Signed-off-by: Petros Angelatos --- src/trace/implementations/ord.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/trace/implementations/ord.rs b/src/trace/implementations/ord.rs index a8117b5d1..618b1f490 100644 --- a/src/trace/implementations/ord.rs +++ b/src/trace/implementations/ord.rs @@ -648,8 +648,6 @@ where } } -static EMPTY: () = (); - /// A cursor for navigating a single layer. #[derive(Debug)] pub struct OrdKeyCursor { @@ -675,7 +673,7 @@ where type Storage = OrdKeyBatch; fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { &self.cursor.key(&storage.layer) } - fn val<'a>(&self, _storage: &'a Self::Storage) -> &'a () { &EMPTY } + fn val<'a>(&self, _storage: &'a Self::Storage) -> &'a () { &() } fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { self.cursor.child.rewind(&storage.layer.vals); while self.cursor.child.valid(&storage.layer.vals) { From 7e6f60d2a24116613c05931cb416924f3cf51f27 Mon Sep 17 00:00:00 2001 From: Frank McSherry Date: Mon, 23 May 2022 11:56:29 +0200 Subject: [PATCH 5/8] simplify generics of batch related traits --- src/trace/implementations/merge_batcher.rs | 32 +++---- src/trace/implementations/ord.rs | 31 +++--- src/trace/implementations/spine_fueled.rs | 106 ++++++++++----------- src/trace/mod.rs | 102 ++++++++++---------- tests/trace.rs | 6 +- 5 files changed, 135 insertions(+), 142 deletions(-) diff --git a/src/trace/implementations/merge_batcher.rs b/src/trace/implementations/merge_batcher.rs index e281ca6c7..f1f2264ff 100644 --- a/src/trace/implementations/merge_batcher.rs +++ b/src/trace/implementations/merge_batcher.rs @@ -8,32 +8,32 @@ use lattice::Lattice; use trace::{Batch, Batcher, Builder}; /// Creates batches from unordered tuples. -pub struct MergeBatcher> { - sorter: MergeSorter<(K, V), T, R>, - lower: Antichain, - frontier: Antichain, +pub struct MergeBatcher where B::Key: Ord, B::Val: Ord, B::Time: Ord, B::R: Semigroup { + sorter: MergeSorter<(B::Key, B::Val), B::Time, B::R>, + lower: Antichain, + frontier: Antichain, phantom: ::std::marker::PhantomData, } -impl Batcher for MergeBatcher +impl Batcher for MergeBatcher where - K: Ord+Clone, - V: Ord+Clone, - T: Lattice+timely::progress::Timestamp+Ord+Clone, - R: Semigroup, - B: Batch, + B: Batch, + B::Key: Ord+Clone, + B::Val: Ord+Clone, + B::Time: Lattice+timely::progress::Timestamp+Ord+Clone, + B::R: Semigroup, { fn new() -> Self { MergeBatcher { sorter: MergeSorter::new(), frontier: Antichain::new(), - lower: Antichain::from_elem(T::minimum()), + lower: Antichain::from_elem(::minimum()), phantom: ::std::marker::PhantomData, } } #[inline(never)] - fn push_batch(&mut self, batch: &mut Vec<((K,V),T,R)>) { + fn push_batch(&mut self, batch: &mut Vec<((B::Key,B::Val),B::Time,B::R)>) { self.sorter.push(batch); } @@ -42,7 +42,7 @@ where // which we call `lower`, by assumption that after sealing a batcher we receive no more // updates with times not greater or equal to `upper`. #[inline(never)] - fn seal(&mut self, upper: Antichain) -> B { + fn seal(&mut self, upper: Antichain) -> B { let mut builder = B::Builder::new(); @@ -92,18 +92,18 @@ where let mut buffer = Vec::new(); self.sorter.push(&mut buffer); // We recycle buffers with allocations (capacity, and not zero-sized). - while buffer.capacity() > 0 && std::mem::size_of::<((K,V),T,R)>() > 0 { + while buffer.capacity() > 0 && std::mem::size_of::<((B::Key,B::Val),B::Time,B::R)>() > 0 { buffer = Vec::new(); self.sorter.push(&mut buffer); } - let seal = builder.done(self.lower.clone(), upper.clone(), Antichain::from_elem(T::minimum())); + let seal = builder.done(self.lower.clone(), upper.clone(), Antichain::from_elem(::minimum())); self.lower = upper; seal } // the frontier of elements remaining after the most recent call to `self.seal`. - fn frontier(&mut self) -> timely::progress::frontier::AntichainRef { + fn frontier(&mut self) -> timely::progress::frontier::AntichainRef { self.frontier.borrow() } } diff --git a/src/trace/implementations/ord.rs b/src/trace/implementations/ord.rs index 618b1f490..d05e508c6 100644 --- a/src/trace/implementations/ord.rs +++ b/src/trace/implementations/ord.rs @@ -35,16 +35,16 @@ use super::merge_batcher::MergeBatcher; use abomonation::abomonated::Abomonated; /// A trace implementation using a spine of ordered lists. -pub type OrdValSpine = Spine>>; +pub type OrdValSpine = Spine>>; /// A trace implementation using a spine of abomonated ordered lists. -pub type OrdValSpineAbom = Spine, Vec>>>; +pub type OrdValSpineAbom = Spine, Vec>>>; /// A trace implementation for empty values using a spine of ordered lists. -pub type OrdKeySpine = Spine>>; +pub type OrdKeySpine = Spine>>; /// A trace implementation for empty values using a spine of abomonated ordered lists. -pub type OrdKeySpineAbom = Spine, Vec>>>; +pub type OrdKeySpineAbom = Spine, Vec>>>; /// An immutable collection of update tuples, from a contiguous interval of logical times. @@ -76,12 +76,7 @@ where type R = R; type Cursor = OrdValCursor; - fn cursor(&self) -> Self::Cursor { - OrdValCursor { - cursor: self.layer.cursor(), - phantom: PhantomData, - } - } + fn cursor(&self) -> Self::Cursor { OrdValCursor { cursor: self.layer.cursor(), phantom: std::marker::PhantomData } } fn len(&self) -> usize { , O>, O> as Trie>::tuples(&self.layer) } fn description(&self) -> &Description { &self.desc } } @@ -94,7 +89,7 @@ where R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { - type Batcher = MergeBatcher; + type Batcher = MergeBatcher; type Builder = OrdValBuilder; type Merger = OrdValMerger; @@ -225,7 +220,7 @@ where should_compact: bool, } -impl Merger> for OrdValMerger +impl Merger> for OrdValMerger where K: Ord+Clone+'static, V: Ord+Clone+'static, @@ -323,8 +318,8 @@ where R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { + phantom: std::marker::PhantomData, cursor: OrderedCursor, O>>, - phantom: PhantomData, } impl Cursor for OrdValCursor @@ -373,7 +368,7 @@ where builder: OrderedBuilder, O>, O>, } -impl Builder> for OrdValBuilder +impl Builder> for OrdValBuilder where K: Ord+Clone+'static, V: Ord+Clone+'static, @@ -445,7 +440,7 @@ where } } fn len(&self) -> usize { , O> as Trie>::tuples(&self.layer) } - fn description(&self) -> &Description { &self.desc } + fn description(&self) -> &Description { &self.desc } } impl Batch for OrdKeyBatch @@ -455,7 +450,7 @@ where R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { - type Batcher = MergeBatcher; + type Batcher = MergeBatcher; type Builder = OrdKeyBuilder; type Merger = OrdKeyMerger; @@ -554,7 +549,7 @@ where should_compact: bool, } -impl Merger> for OrdKeyMerger +impl Merger> for OrdKeyMerger where K: Ord+Clone+'static, T: Lattice+timely::progress::Timestamp+Ord+Clone+'static, @@ -703,7 +698,7 @@ where builder: OrderedBuilder, O>, } -impl Builder> for OrdKeyBuilder +impl Builder> for OrdKeyBuilder where K: Ord+Clone+'static, T: Lattice+timely::progress::Timestamp+Ord+Clone+'static, diff --git a/src/trace/implementations/spine_fueled.rs b/src/trace/implementations/spine_fueled.rs index 218332908..ba737293b 100644 --- a/src/trace/implementations/spine_fueled.rs +++ b/src/trace/implementations/spine_fueled.rs @@ -87,41 +87,40 @@ use ::timely::order::PartialOrder; /// A spine maintains a small number of immutable collections of update tuples, merging the collections when /// two have similar sizes. In this way, it allows the addition of more tuples, which may then be merged with /// other immutable collections. -pub struct Spine> { +pub struct Spine where B::Time: Lattice+Ord, B::R: Semigroup { operator: OperatorInfo, logger: Option, - phantom: ::std::marker::PhantomData<(K, V, R)>, - logical_frontier: Antichain, // Times after which the trace must accumulate correctly. - physical_frontier: Antichain, // Times after which the trace must be able to subset its inputs. - merging: Vec>,// Several possibly shared collections of updates. - pending: Vec, // Batches at times in advance of `frontier`. - upper: Antichain, + logical_frontier: Antichain, // Times after which the trace must accumulate correctly. + physical_frontier: Antichain, // Times after which the trace must be able to subset its inputs. + merging: Vec>, // Several possibly shared collections of updates. + pending: Vec, // Batches at times in advance of `frontier`. + upper: Antichain, effort: usize, activator: Option, } -impl TraceReader for Spine +impl TraceReader for Spine where - K: Ord+Clone, // Clone is required by `batch::advance_*` (in-place could remove). - V: Ord+Clone, // Clone is required by `batch::advance_*` (in-place could remove). - T: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, - R: Semigroup, - B: Batch+Clone+'static, + B: Batch+Clone+'static, + B::Key: Ord+Clone, // Clone is required by `batch::advance_*` (in-place could remove). + B::Val: Ord+Clone, // Clone is required by `batch::advance_*` (in-place could remove). + B::Time: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, + B::R: Semigroup, { - type Key = K; - type Val = V; - type Time = T; - type R = R; + type Key = B::Key; + type Val = B::Val; + type Time = B::Time; + type R = B::R; type Batch = B; type Cursor = CursorList<::Cursor>; - fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { + fn cursor_through(&mut self, upper: AntichainRef) -> Option<(Self::Cursor, ::Storage)> { // If `upper` is the minimum frontier, we can return an empty cursor. // This can happen with operators that are written to expect the ability to acquire cursors // for their prior frontiers, and which start at `[T::minimum()]`, such as `Reduce`, sadly. - if upper.less_equal(&T::minimum()) { + if upper.less_equal(&::minimum()) { let cursors = Vec::new(); let storage = Vec::new(); return Some((CursorList::new(cursors, &storage), storage)); @@ -211,19 +210,19 @@ where Some((CursorList::new(cursors, &storage), storage)) } - fn set_logical_compaction(&mut self, frontier: AntichainRef) { + fn set_logical_compaction(&mut self, frontier: AntichainRef) { self.logical_frontier.clear(); self.logical_frontier.extend(frontier.iter().cloned()); } - fn get_logical_compaction(&mut self) -> AntichainRef { self.logical_frontier.borrow() } - fn set_physical_compaction(&mut self, frontier: AntichainRef) { + fn get_logical_compaction(&mut self) -> AntichainRef { self.logical_frontier.borrow() } + fn set_physical_compaction(&mut self, frontier: AntichainRef) { // We should never request to rewind the frontier. debug_assert!(PartialOrder::less_equal(&self.physical_frontier.borrow(), &frontier), "FAIL\tthrough frontier !<= new frontier {:?} {:?}\n", self.physical_frontier, frontier); self.physical_frontier.clear(); self.physical_frontier.extend(frontier.iter().cloned()); self.consider_merges(); } - fn get_physical_compaction(&mut self) -> AntichainRef { self.physical_frontier.borrow() } + fn get_physical_compaction(&mut self) -> AntichainRef { self.physical_frontier.borrow() } fn map_batches(&self, mut f: F) { for batch in self.merging.iter().rev() { @@ -242,13 +241,13 @@ where // A trace implementation for any key type that can be borrowed from or converted into `Key`. // TODO: Almost all this implementation seems to be generic with respect to the trace and batch types. -impl Trace for Spine +impl Trace for Spine where - K: Ord+Clone, - V: Ord+Clone, - T: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, - R: Semigroup, - B: Batch+Clone+'static, + B: Batch+Clone+'static, + B::Key: Ord+Clone, + B::Val: Ord+Clone, + B::Time: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, + B::R: Semigroup, { fn new( info: ::timely::dataflow::operators::generic::OperatorInfo, @@ -311,18 +310,18 @@ where if !self.upper.borrow().is_empty() { use trace::Builder; let builder = B::Builder::new(); - let batch = builder.done(self.upper.clone(), Antichain::new(), Antichain::from_elem(T::minimum())); + let batch = builder.done(self.upper.clone(), Antichain::new(), Antichain::from_elem(::minimum())); self.insert(batch); } } } // Drop implementation allows us to log batch drops, to zero out maintained totals. -impl Drop for Spine +impl Drop for Spine where - T: Lattice+Ord, - R: Semigroup, - B: Batch, + B: Batch, + B::Time: Lattice+Ord, + B::R: Semigroup, { fn drop(&mut self) { self.drop_batches(); @@ -330,11 +329,11 @@ where } -impl Spine +impl Spine where - T: Lattice+Ord, - R: Semigroup, - B: Batch, + B: Batch, + B::Time: Lattice+Ord, + B::R: Semigroup, { /// Drops and logs batches. Used in `set_logical_compaction` and drop. fn drop_batches(&mut self) { @@ -376,13 +375,13 @@ where } } -impl Spine +impl Spine where - K: Ord+Clone, - V: Ord+Clone, - T: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, - R: Semigroup, - B: Batch, + B: Batch, + B::Key: Ord+Clone, + B::Val: Ord+Clone, + B::Time: Lattice+timely::progress::Timestamp+Ord+Clone+Debug, + B::R: Semigroup, { /// True iff there is at most one non-empty batch in `self.merging`. /// @@ -432,12 +431,11 @@ where Spine { operator, logger, - phantom: ::std::marker::PhantomData, - logical_frontier: Antichain::from_elem(::minimum()), - physical_frontier: Antichain::from_elem(::minimum()), + logical_frontier: Antichain::from_elem(::minimum()), + physical_frontier: Antichain::from_elem(::minimum()), merging: Vec::new(), pending: Vec::new(), - upper: Antichain::from_elem(::minimum()), + upper: Antichain::from_elem(::minimum()), effort, activator, } @@ -766,7 +764,7 @@ where /// /// A layer can be empty, contain a single batch, or contain a pair of batches /// that are in the process of merging into a batch for the next layer. -enum MergeState> { +enum MergeState { /// An empty layer, containing no updates. Vacant, /// A layer containing a single batch. @@ -775,10 +773,10 @@ enum MergeState> { /// to ensure the progress of maintenance work. Single(Option), /// A layer containing two batches, in the process of merging. - Double(MergeVariant), + Double(MergeVariant), } -impl> MergeState { +impl MergeState where B::Time: Eq { /// The number of actual updates contained in the level. fn len(&self) -> usize { @@ -859,7 +857,7 @@ impl> MergeState, batch2: Option, compaction_frontier: Option>) -> MergeState { + fn begin_merge(batch1: Option, batch2: Option, compaction_frontier: Option>) -> MergeState { let variant = match (batch1, batch2) { (Some(batch1), Some(batch2)) => { @@ -876,14 +874,14 @@ impl> MergeState> { +enum MergeVariant { /// Describes an actual in-progress merge between two non-trivial batches. InProgress(B, B, ::Merger), /// A merge that requires no further work. May or may not represent a non-trivial batch. Complete(Option<(B, Option<(B, B)>)>), } -impl> MergeVariant { +impl MergeVariant { /// Completes and extracts the batch, unless structurally empty. /// diff --git a/src/trace/mod.rs b/src/trace/mod.rs index 85d9e30ee..a4102d579 100644 --- a/src/trace/mod.rs +++ b/src/trace/mod.rs @@ -260,13 +260,13 @@ where } /// An immutable collection of updates. -pub trait Batch: BatchReader where Self: ::std::marker::Sized { +pub trait Batch : BatchReader where Self: ::std::marker::Sized { /// A type used to assemble batches from disordered updates. - type Batcher: Batcher; + type Batcher: Batcher; /// A type used to assemble batches from ordered update sequences. - type Builder: Builder; + type Builder: Builder; /// A type used to progressively merge batches. - type Merger: Merger; + type Merger: Merger; /// Initiates the merging of consecutive batches. /// @@ -283,38 +283,38 @@ pub trait Batch: BatchReader where Self: ::std::marker::Sized { } /// Functionality for collecting and batching updates. -pub trait Batcher> { +pub trait Batcher { /// Allocates a new empty batcher. fn new() -> Self; /// Adds an unordered batch of elements to the batcher. - fn push_batch(&mut self, batch: &mut Vec<((K, V), T, R)>); + fn push_batch(&mut self, batch: &mut Vec<((Output::Key, Output::Val), Output::Time, Output::R)>); /// Returns all updates not greater or equal to an element of `upper`. - fn seal(&mut self, upper: Antichain) -> Output; + fn seal(&mut self, upper: Antichain) -> Output; /// Returns the lower envelope of contained update times. - fn frontier(&mut self) -> timely::progress::frontier::AntichainRef; + fn frontier(&mut self) -> timely::progress::frontier::AntichainRef; } /// Functionality for building batches from ordered update sequences. -pub trait Builder> { +pub trait Builder { /// Allocates an empty builder. fn new() -> Self; /// Allocates an empty builder with some capacity. fn with_capacity(cap: usize) -> Self; /// Adds an element to the batch. - fn push(&mut self, element: (K, V, T, R)); + fn push(&mut self, element: (Output::Key, Output::Val, Output::Time, Output::R)); /// Adds an ordered sequence of elements to the batch. - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { for item in iter { self.push(item); } } /// Completes building and returns the batch. - fn done(self, lower: Antichain, upper: Antichain, since: Antichain) -> Output; + fn done(self, lower: Antichain, upper: Antichain, since: Antichain) -> Output; } /// Represents a merge in progress. -pub trait Merger> { +pub trait Merger { /// Creates a new merger to merge the supplied batches, optionally compacting /// up to the supplied frontier. - fn new(source1: &Output, source2: &Output, compaction_frontier: Option>) -> Self; + fn new(source1: &Output, source2: &Output, compaction_frontier: Option>) -> Self; /// Perform some amount of work, decrementing `fuel`. /// /// If `fuel` is non-zero after the call, the merging is complete and @@ -399,39 +399,39 @@ pub mod rc_blanket_impls { /// An immutable collection of updates. impl Batch for Rc { - type Batcher = RcBatcher; - type Builder = RcBuilder; - type Merger = RcMerger; + type Batcher = RcBatcher; + type Builder = RcBuilder; + type Merger = RcMerger; } /// Wrapper type for batching reference counted batches. - pub struct RcBatcher> { batcher: B::Batcher } + pub struct RcBatcher { batcher: B::Batcher } /// Functionality for collecting and batching updates. - impl> Batcher> for RcBatcher { - fn new() -> Self { RcBatcher { batcher: >::new() } } - fn push_batch(&mut self, batch: &mut Vec<((K, V), T, R)>) { self.batcher.push_batch(batch) } - fn seal(&mut self, upper: Antichain) -> Rc { Rc::new(self.batcher.seal(upper)) } - fn frontier(&mut self) -> timely::progress::frontier::AntichainRef { self.batcher.frontier() } + impl Batcher> for RcBatcher { + fn new() -> Self { RcBatcher { batcher: >::new() } } + fn push_batch(&mut self, batch: &mut Vec<((B::Key, B::Val), B::Time, B::R)>) { self.batcher.push_batch(batch) } + fn seal(&mut self, upper: Antichain) -> Rc { Rc::new(self.batcher.seal(upper)) } + fn frontier(&mut self) -> timely::progress::frontier::AntichainRef { self.batcher.frontier() } } /// Wrapper type for building reference counted batches. - pub struct RcBuilder> { builder: B::Builder } + pub struct RcBuilder { builder: B::Builder } /// Functionality for building batches from ordered update sequences. - impl> Builder> for RcBuilder { - fn new() -> Self { RcBuilder { builder: >::new() } } - fn with_capacity(cap: usize) -> Self { RcBuilder { builder: >::with_capacity(cap) } } - fn push(&mut self, element: (K, V, T, R)) { self.builder.push(element) } - fn done(self, lower: Antichain, upper: Antichain, since: Antichain) -> Rc { Rc::new(self.builder.done(lower, upper, since)) } + impl Builder> for RcBuilder { + fn new() -> Self { RcBuilder { builder: >::new() } } + fn with_capacity(cap: usize) -> Self { RcBuilder { builder: >::with_capacity(cap) } } + fn push(&mut self, element: (B::Key, B::Val, B::Time, B::R)) { self.builder.push(element) } + fn done(self, lower: Antichain, upper: Antichain, since: Antichain) -> Rc { Rc::new(self.builder.done(lower, upper, since)) } } /// Wrapper type for merging reference counted batches. - pub struct RcMerger> { merger: B::Merger } + pub struct RcMerger { merger: B::Merger } /// Represents a merge in progress. - impl> Merger> for RcMerger { - fn new(source1: &Rc, source2: &Rc, compaction_frontier: Option>) -> Self { RcMerger { merger: B::begin_merge(source1, source2, compaction_frontier) } } + impl Merger> for RcMerger { + fn new(source1: &Rc, source2: &Rc, compaction_frontier: Option>) -> Self { RcMerger { merger: B::begin_merge(source1, source2, compaction_frontier) } } fn work(&mut self, source1: &Rc, source2: &Rc, fuel: &mut isize) { self.merger.work(source1, source2, fuel) } fn done(self) -> Rc { Rc::new(self.merger.done()) } } @@ -510,37 +510,37 @@ pub mod abomonated_blanket_impls { } /// An immutable collection of updates. - impl Batch for Abomonated> { - type Batcher = AbomonatedBatcher; - type Builder = AbomonatedBuilder; - type Merger = AbomonatedMerger; + impl Batch for Abomonated> { + type Batcher = AbomonatedBatcher; + type Builder = AbomonatedBuilder; + type Merger = AbomonatedMerger; } /// Wrapper type for batching reference counted batches. - pub struct AbomonatedBatcher> { batcher: B::Batcher } + pub struct AbomonatedBatcher { batcher: B::Batcher } /// Functionality for collecting and batching updates. - impl+Abomonation> Batcher>> for AbomonatedBatcher { - fn new() -> Self { AbomonatedBatcher { batcher: >::new() } } - fn push_batch(&mut self, batch: &mut Vec<((K, V), T, R)>) { self.batcher.push_batch(batch) } - fn seal(&mut self, upper: Antichain) -> Abomonated> { + impl Batcher>> for AbomonatedBatcher { + fn new() -> Self { AbomonatedBatcher { batcher: >::new() } } + fn push_batch(&mut self, batch: &mut Vec<((B::Key, B::Val), B::Time, B::R)>) { self.batcher.push_batch(batch) } + fn seal(&mut self, upper: Antichain) -> Abomonated> { let batch = self.batcher.seal(upper); let mut bytes = Vec::with_capacity(measure(&batch)); unsafe { abomonation::encode(&batch, &mut bytes).unwrap() }; unsafe { Abomonated::::new(bytes).unwrap() } } - fn frontier(&mut self) -> timely::progress::frontier::AntichainRef { self.batcher.frontier() } + fn frontier(&mut self) -> timely::progress::frontier::AntichainRef { self.batcher.frontier() } } /// Wrapper type for building reference counted batches. - pub struct AbomonatedBuilder> { builder: B::Builder } + pub struct AbomonatedBuilder { builder: B::Builder } /// Functionality for building batches from ordered update sequences. - impl+Abomonation> Builder>> for AbomonatedBuilder { - fn new() -> Self { AbomonatedBuilder { builder: >::new() } } - fn with_capacity(cap: usize) -> Self { AbomonatedBuilder { builder: >::with_capacity(cap) } } - fn push(&mut self, element: (K, V, T, R)) { self.builder.push(element) } - fn done(self, lower: Antichain, upper: Antichain, since: Antichain) -> Abomonated> { + impl Builder>> for AbomonatedBuilder { + fn new() -> Self { AbomonatedBuilder { builder: >::new() } } + fn with_capacity(cap: usize) -> Self { AbomonatedBuilder { builder: >::with_capacity(cap) } } + fn push(&mut self, element: (B::Key, B::Val, B::Time, B::R)) { self.builder.push(element) } + fn done(self, lower: Antichain, upper: Antichain, since: Antichain) -> Abomonated> { let batch = self.builder.done(lower, upper, since); let mut bytes = Vec::with_capacity(measure(&batch)); unsafe { abomonation::encode(&batch, &mut bytes).unwrap() }; @@ -549,11 +549,11 @@ pub mod abomonated_blanket_impls { } /// Wrapper type for merging reference counted batches. - pub struct AbomonatedMerger> { merger: B::Merger } + pub struct AbomonatedMerger { merger: B::Merger } /// Represents a merge in progress. - impl+Abomonation> Merger>> for AbomonatedMerger { - fn new(source1: &Abomonated>, source2: &Abomonated>, compaction_frontier: Option>) -> Self { + impl Merger>> for AbomonatedMerger { + fn new(source1: &Abomonated>, source2: &Abomonated>, compaction_frontier: Option>) -> Self { AbomonatedMerger { merger: B::begin_merge(source1, source2, compaction_frontier) } } fn work(&mut self, source1: &Abomonated>, source2: &Abomonated>, fuel: &mut isize) { diff --git a/tests/trace.rs b/tests/trace.rs index db4d5a90e..f87ffa33e 100644 --- a/tests/trace.rs +++ b/tests/trace.rs @@ -8,14 +8,14 @@ use timely::progress::{Antichain, frontier::AntichainRef}; use differential_dataflow::trace::implementations::ord::OrdValBatch; use differential_dataflow::trace::{Trace, TraceReader, Batch, Batcher}; -use differential_dataflow::trace::cursor::CursorDebug; +use differential_dataflow::trace::cursor::Cursor; use differential_dataflow::trace::implementations::spine_fueled::Spine; -pub type OrdValSpine = Spine>>; +pub type OrdValSpine = Spine>>; type IntegerTrace = OrdValSpine; -fn get_trace() -> Spine>> { +fn get_trace() -> Spine>> { let op_info = OperatorInfo::new(0, 0, &[]); let mut trace = IntegerTrace::new(op_info, None, None); { From a16889e57d02d8af798751b6fe71483e2d53a64b Mon Sep 17 00:00:00 2001 From: Frank McSherry Date: Mon, 23 May 2022 11:58:42 +0200 Subject: [PATCH 6/8] simplify generics of join's deferred struct --- src/operators/join.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/operators/join.rs b/src/operators/join.rs index 6f5a383ba..2db2560e1 100644 --- a/src/operators/join.rs +++ b/src/operators/join.rs @@ -635,39 +635,39 @@ impl JoinCore for Arranged /// The structure wraps cursors which allow us to play out join computation at whatever rate we like. /// This allows us to avoid producing and buffering massive amounts of data, without giving the timely /// dataflow system a chance to run operators that can consume and aggregate the data. -struct Deferred +struct Deferred where - V1: Ord+Clone, - V2: Ord+Clone, T: Timestamp+Lattice+Ord+Debug, - R1: Semigroup, - R2: Semigroup, - R3: Semigroup, - C1: Cursor, - C2: Cursor, + R: Semigroup, + C1: Cursor, + C2: Cursor, + C1::Val: Ord+Clone, + C2::Val: Ord+Clone, + C1::R: Semigroup, + C2::R: Semigroup, D: Ord+Clone+Data, { - phant: ::std::marker::PhantomData<(K, V1, V2, R1, R2)>, + phant: ::std::marker::PhantomData, trace: C1, trace_storage: C1::Storage, batch: C2, batch_storage: C2::Storage, capability: Capability, done: bool, - temp: Vec<((D, T), R3)>, + temp: Vec<((D, T), R)>, } -impl Deferred +impl Deferred where K: Ord+Debug+Eq, - V1: Ord+Clone+Debug, - V2: Ord+Clone+Debug, + C1: Cursor, + C2: Cursor, + C1::Val: Ord+Clone+Debug, + C2::Val: Ord+Clone+Debug, + C1::R: Semigroup, + C2::R: Semigroup, T: Timestamp+Lattice+Ord+Debug, - R1: Semigroup, - R2: Semigroup, - R3: Semigroup, - C1: Cursor, - C2: Cursor, + R: Semigroup, D: Clone+Data, { fn new(trace: C1, trace_storage: C1::Storage, batch: C2, batch_storage: C2::Storage, capability: Capability) -> Self { @@ -689,8 +689,8 @@ where /// Process keys until at least `fuel` output tuples produced, or the work is exhausted. #[inline(never)] - fn work(&mut self, output: &mut OutputHandle>, mut logic: L, fuel: &mut usize) - where I: IntoIterator, L: FnMut(&K, &V1, &V2, &T, &R1, &R2)->I { + fn work(&mut self, output: &mut OutputHandle>, mut logic: L, fuel: &mut usize) + where I: IntoIterator, L: FnMut(&K, &C1::Val, &C2::Val, &T, &C1::R, &C2::R)->I { let meet = self.capability.time(); From 8605f3b4e29872bf7939b8665c753d1208a24db1 Mon Sep 17 00:00:00 2001 From: Frank McSherry Date: Mon, 23 May 2022 12:01:03 +0200 Subject: [PATCH 7/8] merge CursorDebug trait methods into Cursor --- examples/cursors.rs | 2 +- src/trace/cursor/mod.rs | 23 +++++++---------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/examples/cursors.rs b/examples/cursors.rs index 29e9ddc00..5ab55b5e6 100644 --- a/examples/cursors.rs +++ b/examples/cursors.rs @@ -43,7 +43,7 @@ use timely::progress::frontier::AntichainRef; use differential_dataflow::input::Input; use differential_dataflow::operators::arrange::ArrangeByKey; use differential_dataflow::operators::*; -use differential_dataflow::trace::cursor::CursorDebug; +use differential_dataflow::trace::cursor::Cursor; use differential_dataflow::trace::TraceReader; type Node = u32; diff --git a/src/trace/cursor/mod.rs b/src/trace/cursor/mod.rs index 82175447e..e34ac19a8 100644 --- a/src/trace/cursor/mod.rs +++ b/src/trace/cursor/mod.rs @@ -65,17 +65,15 @@ pub trait Cursor { fn rewind_keys(&mut self, storage: &Self::Storage); /// Rewinds the cursor to the first value for current key. fn rewind_vals(&mut self, storage: &Self::Storage); -} -/// Debugging and testing utilities for Cursor. -pub trait CursorDebug: Cursor -where Self::Key: Clone, - Self::Val: Clone, - Self::Time: Clone, - Self::R: Clone -{ /// Rewinds the cursor and outputs its contents to a Vec - fn to_vec(&mut self, storage: &Self::Storage) -> Vec<((Self::Key, Self::Val), Vec<(Self::Time, Self::R)>)> { + fn to_vec(&mut self, storage: &Self::Storage) -> Vec<((Self::Key, Self::Val), Vec<(Self::Time, Self::R)>)> + where + Self::Key: Clone, + Self::Val: Clone, + Self::Time: Clone, + Self::R: Clone, + { let mut out = Vec::new(); self.rewind_keys(storage); self.rewind_vals(storage); @@ -93,10 +91,3 @@ where Self::Key: Clone, out } } - -impl CursorDebug for C -where C::Key: Clone, - C::Val: Clone, - C::Time: Clone, - C::R: Clone -{ } From d4679beb0ad47122106914001ea29facf8a9e36c Mon Sep 17 00:00:00 2001 From: Frank McSherry Date: Mon, 23 May 2022 12:01:33 +0200 Subject: [PATCH 8/8] various code style changes --- src/algorithms/graphs/bfs.rs | 2 +- src/operators/arrange/arrangement.rs | 2 +- src/operators/mod.rs | 16 +++---------- src/operators/reduce.rs | 12 +++++----- src/trace/cursor/cursor_list.rs | 12 ++++------ src/trace/cursor/cursor_pair.rs | 7 +++--- src/trace/cursor/mod.rs | 2 ++ src/trace/implementations/ord.rs | 4 ++-- src/trace/mod.rs | 16 +++++++++---- src/trace/wrappers/enter.rs | 15 ++++++++---- src/trace/wrappers/enter_at.rs | 12 ++++++---- src/trace/wrappers/filter.rs | 13 +++++++++-- src/trace/wrappers/freeze.rs | 35 +++++++++++++++++++--------- src/trace/wrappers/frontier.rs | 29 ++++++++++++----------- src/trace/wrappers/rc.rs | 2 +- 15 files changed, 106 insertions(+), 73 deletions(-) diff --git a/src/algorithms/graphs/bfs.rs b/src/algorithms/graphs/bfs.rs index d80ad3c75..6774f535f 100644 --- a/src/algorithms/graphs/bfs.rs +++ b/src/algorithms/graphs/bfs.rs @@ -44,4 +44,4 @@ where .concat(&nodes) .reduce(|_, s, t| t.push((s[0].0.clone(), 1))) }) -} +} \ No newline at end of file diff --git a/src/operators/arrange/arrangement.rs b/src/operators/arrange/arrangement.rs index cf1f3a003..d452c7113 100644 --- a/src/operators/arrange/arrangement.rs +++ b/src/operators/arrange/arrangement.rs @@ -404,7 +404,7 @@ where let frontier = IntoIterator::into_iter([ capability.as_ref().map(|c| c.time().clone()), input1.frontier().frontier().get(0).cloned(), - ]).flatten().min(); + ]).filter_map(|t| t).min(); if let Some(frontier) = frontier { trace.as_mut().map(|t| t.set_logical_compaction(AntichainRef::new(&[frontier]))); diff --git a/src/operators/mod.rs b/src/operators/mod.rs index 1363ac36c..96f0acc93 100644 --- a/src/operators/mod.rs +++ b/src/operators/mod.rs @@ -40,12 +40,7 @@ impl<'a, V:'a, T, R> EditList<'a, V, T, R> where T: Ord+Clone, R: Semigroup { } /// Loads the contents of a cursor. fn load(&mut self, cursor: &mut C, storage: &'a C::Storage, logic: L) - where - C: Cursor, - L: Fn(&T)->T, - C::Key: Eq, - V: Clone, - { + where V: Clone, C: Cursor, C::Key: Eq, L: Fn(&T)->T { self.clear(); while cursor.val_valid(storage) { cursor.map_times(storage, |time1, diff1| self.push(logic(time1), diff1.clone())); @@ -108,10 +103,7 @@ impl<'storage, V: Ord+Clone+'storage, T: Lattice+Ord+Clone, R: Semigroup> ValueH self.buffer.clear(); } fn load(&mut self, cursor: &mut C, storage: &'storage C::Storage, logic: L) - where C: Cursor, - C::Key: Eq, - L: Fn(&T)->T, - { + where C: Cursor, C::Key: Eq, L: Fn(&T)->T { self.edits.load(cursor, storage, logic); } @@ -125,9 +117,7 @@ impl<'storage, V: Ord+Clone+'storage, T: Lattice+Ord+Clone, R: Semigroup> ValueH key: &C::Key, logic: L ) -> HistoryReplay<'storage, 'history, V, T, R> - where C: Cursor, - C::Key: Eq, - L: Fn(&T)->T, + where C: Cursor, C::Key: Eq, L: Fn(&T)->T { self.clear(); cursor.seek_key(storage, key); diff --git a/src/operators/reduce.rs b/src/operators/reduce.rs index b9bb400c3..2b5ea9aa2 100644 --- a/src/operators/reduce.rs +++ b/src/operators/reduce.rs @@ -670,9 +670,9 @@ where new_interesting: &mut Vec) -> (usize, usize) where K: Eq+Clone, - C1: Cursor, - C2: Cursor, - C3: Cursor, + C1: Cursor, + C2: Cursor, + C3: Cursor, L: FnMut(&K, &[(&V1, R1)], &mut Vec<(V2, R2)>, &mut Vec<(V2, R2)>); } @@ -748,9 +748,9 @@ mod history_replay { new_interesting: &mut Vec) -> (usize, usize) where K: Eq+Clone, - C1: Cursor, - C2: Cursor, - C3: Cursor, + C1: Cursor, + C2: Cursor, + C3: Cursor, L: FnMut(&K, &[(&V1, R1)], &mut Vec<(V2, R2)>, &mut Vec<(V2, R2)>) { diff --git a/src/trace/cursor/cursor_list.rs b/src/trace/cursor/cursor_list.rs index 15d2fa9d0..a7adf8cc1 100644 --- a/src/trace/cursor/cursor_list.rs +++ b/src/trace/cursor/cursor_list.rs @@ -13,10 +13,7 @@ pub struct CursorList { min_val: Vec, } -impl CursorList -where C::Key: Ord, - C::Val: Ord -{ +impl CursorList where C::Key: Ord, C::Val: Ord { /// Creates a new cursor list from pre-existing cursors. pub fn new(cursors: Vec, storage: &[C::Storage]) -> Self { @@ -44,7 +41,7 @@ where C::Key: Ord, self.min_key.clear(); // Determine the index of the cursor with minimum key. - let mut min_key_opt: Option<&C::Key> = None; + let mut min_key_opt = None; for (index, cursor) in self.cursors.iter().enumerate() { let key = cursor.get_key(&storage[index]); if key.is_some() { @@ -72,7 +69,7 @@ where C::Key: Ord, self.min_val.clear(); // Determine the index of the cursor with minimum value. - let mut min_val: Option<&C::Val> = None; + let mut min_val = None; for &index in self.min_key.iter() { let val = self.cursors[index].get_val(&storage[index]); if val.is_some() { @@ -91,12 +88,13 @@ where C::Key: Ord, impl Cursor for CursorList where C::Key: Ord, - C::Val: Ord + C::Val: Ord, { type Key = C::Key; type Val = C::Val; type Time = C::Time; type R = C::R; + type Storage = Vec; // validation methods diff --git a/src/trace/cursor/cursor_pair.rs b/src/trace/cursor/cursor_pair.rs index b55e7dd6d..c34f03abb 100644 --- a/src/trace/cursor/cursor_pair.rs +++ b/src/trace/cursor/cursor_pair.rs @@ -19,13 +19,14 @@ impl Cursor for CursorPair where K: Ord, V: Ord, - C1: Cursor, - C2: Cursor, + C1: Cursor, + C2: Cursor, { type Key = K; type Val = V; type Time = T; type R = R; + type Storage = (C1::Storage, C2::Storage); // validation methods @@ -135,4 +136,4 @@ where if self.key_order != Ordering::Greater { self.cursor1.rewind_vals(&storage.0); } if self.key_order != Ordering::Less { self.cursor2.rewind_vals(&storage.1); } } -} +} \ No newline at end of file diff --git a/src/trace/cursor/mod.rs b/src/trace/cursor/mod.rs index e34ac19a8..a71ca2dad 100644 --- a/src/trace/cursor/mod.rs +++ b/src/trace/cursor/mod.rs @@ -13,6 +13,7 @@ pub use self::cursor_list::CursorList; /// A cursor for navigating ordered `(key, val, time, diff)` updates. pub trait Cursor { + /// Key by which updates are indexed. type Key; /// Values associated with keys. @@ -21,6 +22,7 @@ pub trait Cursor { type Time; /// Associated update. type R; + /// Type the cursor addresses data in. type Storage; diff --git a/src/trace/implementations/ord.rs b/src/trace/implementations/ord.rs index d05e508c6..a7c4fcae1 100644 --- a/src/trace/implementations/ord.rs +++ b/src/trace/implementations/ord.rs @@ -334,6 +334,7 @@ where type Val = V; type Time = T; type R = R; + type Storage = OrdValBatch; fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { &self.cursor.key(&storage.layer) } @@ -643,6 +644,7 @@ where } } + /// A cursor for navigating a single layer. #[derive(Debug)] pub struct OrdKeyCursor { @@ -658,13 +660,11 @@ where R: Semigroup, O: OrdOffset, >::Error: Debug, >::Error: Debug { - type Key = K; type Val = (); type Time = T; type R = R; - type Storage = OrdKeyBatch; fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K { &self.cursor.key(&storage.layer) } diff --git a/src/trace/mod.rs b/src/trace/mod.rs index a4102d579..f1775050f 100644 --- a/src/trace/mod.rs +++ b/src/trace/mod.rs @@ -41,6 +41,7 @@ pub use self::description::Description; /// to update the contents of the trace. These methods are used to examine the contents, and to update the reader's /// capabilities (which may release restrictions on the mutations to the underlying trace and cause work to happen). pub trait TraceReader { + /// Key by which updates are indexed. type Key; /// Values associated with keys. @@ -51,10 +52,10 @@ pub trait TraceReader { type R; /// The type of an immutable collection of updates. - type Batch: BatchReader+Clone+'static; + type Batch: BatchReader+Clone+'static; /// The type used to enumerate the collections contents. - type Cursor: Cursor; + type Cursor: Cursor; /// Provides a cursor over updates contained in the trace. fn cursor(&mut self) -> (Self::Cursor, ::Storage) { @@ -195,7 +196,9 @@ pub trait TraceReader { /// /// The trace must be constructable from, and navigable by the `Key`, `Val`, `Time` types, but does not need /// to return them. -pub trait Trace: TraceReader { +pub trait Trace : TraceReader +where ::Batch: Batch { + /// Allocates a new empty trace. fn new( info: ::timely::dataflow::operators::generic::OperatorInfo, @@ -243,7 +246,7 @@ where type R; /// The type used to enumerate the batch's contents. - type Cursor: Cursor; + type Cursor: Cursor; /// Acquires a cursor to the batch's contents. fn cursor(&self) -> Self::Cursor; /// The number of updates in the batch. @@ -370,10 +373,12 @@ pub mod rc_blanket_impls { } impl Cursor for RcBatchCursor { + type Key = B::Key; type Val = B::Val; type Time = B::Time; type R = B::R; + type Storage = Rc; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } @@ -450,6 +455,7 @@ pub mod abomonated_blanket_impls { use super::{Batch, BatchReader, Batcher, Builder, Merger, Cursor, Description}; impl BatchReader for Abomonated> { + type Key = B::Key; type Val = B::Val; type Time = B::Time; @@ -482,10 +488,12 @@ pub mod abomonated_blanket_impls { } impl Cursor for AbomonatedBatchCursor { + type Key = B::Key; type Val = B::Val; type Time = B::Time; type R = B::R; + type Storage = Abomonated>; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } diff --git a/src/trace/wrappers/enter.rs b/src/trace/wrappers/enter.rs index 877891fe7..1b4316dc4 100644 --- a/src/trace/wrappers/enter.rs +++ b/src/trace/wrappers/enter.rs @@ -136,7 +136,7 @@ where BatchCursorEnter::new(self.batch.cursor()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { &self.description } + fn description(&self) -> &Description { &self.description } } impl BatchEnter @@ -152,7 +152,7 @@ where let since: Vec<_> = batch.description().since().elements().iter().map(|x| TInner::to_inner(x.clone())).collect(); BatchEnter { - batch, + batch: batch, description: Description::new(Antichain::from(lower), Antichain::from(upper), Antichain::from(since)) } } @@ -168,13 +168,14 @@ impl CursorEnter { fn new(cursor: C) -> Self { CursorEnter { phantom: ::std::marker::PhantomData, - cursor, + cursor: cursor, } } } -impl Cursor for CursorEnter +impl Cursor for CursorEnter where + C: Cursor, C::Time: Timestamp, TInner: Refines+Lattice, { @@ -182,6 +183,7 @@ where type Val = C::Val; type Time = TInner; type R = C::R; + type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } @@ -207,6 +209,8 @@ where #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } + + /// Wrapper to provide cursor to nested scope. pub struct BatchCursorEnter { phantom: ::std::marker::PhantomData, @@ -222,7 +226,7 @@ impl BatchCursorEnter { } } -impl Cursor for BatchCursorEnter +impl Cursor for BatchCursorEnter where B::Time: Timestamp, TInner: Refines+Lattice, @@ -231,6 +235,7 @@ where type Val = B::Val; type Time = TInner; type R = B::R; + type Storage = BatchEnter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } diff --git a/src/trace/wrappers/enter_at.rs b/src/trace/wrappers/enter_at.rs index 3aa2b6952..e5c5419ed 100644 --- a/src/trace/wrappers/enter_at.rs +++ b/src/trace/wrappers/enter_at.rs @@ -62,8 +62,8 @@ where type Time = TInner; type R = Tr::R; - type Batch = BatchEnter; - type Cursor = CursorEnter; + type Batch = BatchEnter; + type Cursor = CursorEnter; fn map_batches(&self, mut f: F2) { let logic = self.logic.clone(); @@ -120,7 +120,7 @@ where /// Makes a new trace wrapper pub fn make_from(trace: Tr, logic: F, prior: G) -> Self { TraceEnter { - trace, + trace: trace, stash1: Antichain::new(), stash2: Antichain::new(), logic, @@ -207,6 +207,7 @@ where type Val = C::Val; type Time = TInner; type R = C::R; + type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } @@ -235,6 +236,8 @@ where #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } + + /// Wrapper to provide cursor to nested scope. pub struct BatchCursorEnter { phantom: ::std::marker::PhantomData, @@ -252,7 +255,7 @@ impl BatchCursorEnter { } } -impl Cursor for BatchCursorEnter +impl Cursor for BatchCursorEnter where B::Time: Timestamp, TInner: Refines+Lattice, @@ -262,6 +265,7 @@ where type Val = B::Val; type Time = TInner; type R = B::R; + type Storage = BatchEnter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } diff --git a/src/trace/wrappers/filter.rs b/src/trace/wrappers/filter.rs index 4b502fbc5..3fdf29603 100644 --- a/src/trace/wrappers/filter.rs +++ b/src/trace/wrappers/filter.rs @@ -99,10 +99,14 @@ where BatchCursorFilter::new(self.batch.cursor(), self.logic.clone()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { &self.batch.description() } + fn description(&self) -> &Description { &self.batch.description() } } -impl BatchFilter { +impl BatchFilter +where + B: BatchReader, + B::Time: Timestamp, +{ /// Makes a new batch wrapper pub fn make_from(batch: B, logic: F) -> Self { BatchFilter { @@ -130,12 +134,14 @@ impl CursorFilter { impl Cursor for CursorFilter where C: Cursor, + C::Time: Timestamp, F: FnMut(&C::Key, &C::Val)->bool+'static { type Key = C::Key; type Val = C::Val; type Time = C::Time; type R = C::R; + type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } @@ -163,6 +169,8 @@ where #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } + + /// Wrapper to provide cursor to nested scope. pub struct BatchCursorFilter { cursor: B::Cursor, @@ -187,6 +195,7 @@ where type Val = B::Val; type Time = B::Time; type R = B::R; + type Storage = BatchFilter; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } diff --git a/src/trace/wrappers/freeze.rs b/src/trace/wrappers/freeze.rs index 0391ca208..ed5965266 100644 --- a/src/trace/wrappers/freeze.rs +++ b/src/trace/wrappers/freeze.rs @@ -127,8 +127,8 @@ where /// Makes a new trace wrapper pub fn make_from(trace: Tr, func: Rc) -> Self { TraceFreeze { - trace, - func, + trace: trace, + func: func, } } } @@ -149,7 +149,12 @@ impl Clone for BatchFreeze { } } -impl Option> BatchReader for BatchFreeze { +impl BatchReader for BatchFreeze +where + B: BatchReader, + B::Time: Clone, + F: Fn(&B::Time)->Option, +{ type Key = B::Key; type Val = B::Val; type Time = B::Time; @@ -161,21 +166,26 @@ impl Option> BatchReader for BatchFr BatchCursorFreeze::new(self.batch.cursor(), self.func.clone()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { self.batch.description() } + fn description(&self) -> &Description { self.batch.description() } } -impl Option> BatchFreeze { +impl BatchFreeze +where + B: BatchReader, + B::Time: Clone, + F: Fn(&B::Time)->Option +{ /// Makes a new batch wrapper pub fn make_from(batch: B, func: Rc) -> Self { BatchFreeze { - batch, - func, + batch: batch, + func: func, } } } /// Wrapper to provide cursor to nested scope. -pub struct CursorFreeze { +pub struct CursorFreeze { cursor: C, func: Rc, } @@ -183,20 +193,22 @@ pub struct CursorFreeze { impl CursorFreeze { fn new(cursor: C, func: Rc) -> Self { CursorFreeze { - cursor, - func, + cursor: cursor, + func: func, } } } -impl Cursor for CursorFreeze +impl Cursor for CursorFreeze where + C: Cursor, F: Fn(&C::Time)->Option, { type Key = C::Key; type Val = C::Val; type Time = C::Time; type R = C::R; + type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } @@ -248,6 +260,7 @@ where type Val = B::Val; type Time = B::Time; type R = B::R; + type Storage = BatchFreeze; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } diff --git a/src/trace/wrappers/frontier.rs b/src/trace/wrappers/frontier.rs index 385af9637..ec321b71e 100644 --- a/src/trace/wrappers/frontier.rs +++ b/src/trace/wrappers/frontier.rs @@ -91,7 +91,8 @@ pub struct BatchFrontier { impl BatchReader for BatchFrontier where - B::Time: Timestamp + Lattice + B: BatchReader, + B::Time: Timestamp+Lattice, { type Key = B::Key; type Val = B::Val; @@ -104,12 +105,13 @@ where BatchCursorFrontier::new(self.batch.cursor(), self.frontier.borrow()) } fn len(&self) -> usize { self.batch.len() } - fn description(&self) -> &Description { &self.batch.description() } + fn description(&self) -> &Description { &self.batch.description() } } -impl BatchFrontier +impl BatchFrontier where - B::Time: Timestamp+Lattice + B: BatchReader, + B::Time: Timestamp+Lattice, { /// Makes a new batch wrapper pub fn make_from(batch: B, frontier: AntichainRef) -> Self { @@ -126,9 +128,7 @@ pub struct CursorFrontier { frontier: Antichain, } -impl CursorFrontier -where C::Time: Clone, -{ +impl CursorFrontier where C::Time: Clone { fn new(cursor: C, frontier: AntichainRef) -> Self { CursorFrontier { cursor, @@ -137,14 +137,16 @@ where C::Time: Clone, } } -impl Cursor for CursorFrontier +impl Cursor for CursorFrontier where + C: Cursor, C::Time: Timestamp+Lattice, { type Key = C::Key; type Val = C::Val; type Time = C::Time; type R = C::R; + type Storage = C::Storage; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(storage) } @@ -156,7 +158,7 @@ where #[inline] fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let frontier = self.frontier.borrow(); - let mut temp = ::minimum(); + let mut temp: C::Time = ::minimum(); self.cursor.map_times(storage, |time, diff| { temp.clone_from(time); temp.advance_by(frontier); @@ -174,15 +176,15 @@ where #[inline] fn rewind_vals(&mut self, storage: &Self::Storage) { self.cursor.rewind_vals(storage) } } + + /// Wrapper to provide cursor to nested scope. pub struct BatchCursorFrontier { cursor: B::Cursor, frontier: Antichain, } -impl BatchCursorFrontier -where B::Time: Clone, -{ +impl BatchCursorFrontier where B::Time: Clone { fn new(cursor: B::Cursor, frontier: AntichainRef) -> Self { BatchCursorFrontier { cursor, @@ -199,6 +201,7 @@ where type Val = B::Val; type Time = B::Time; type R = B::R; + type Storage = BatchFrontier; #[inline] fn key_valid(&self, storage: &Self::Storage) -> bool { self.cursor.key_valid(&storage.batch) } @@ -210,7 +213,7 @@ where #[inline] fn map_times(&mut self, storage: &Self::Storage, mut logic: L) { let frontier = self.frontier.borrow(); - let mut temp = ::minimum(); + let mut temp: B::Time = ::minimum(); self.cursor.map_times(&storage.batch, |time, diff| { temp.clone_from(time); temp.advance_by(frontier); diff --git a/src/trace/wrappers/rc.rs b/src/trace/wrappers/rc.rs index f1d66949c..b31f8779e 100644 --- a/src/trace/wrappers/rc.rs +++ b/src/trace/wrappers/rc.rs @@ -177,4 +177,4 @@ where self.logical_compaction = Antichain::new(); self.physical_compaction = Antichain::new(); } -} +} \ No newline at end of file