@@ -15,7 +15,6 @@ use crate::hashable::Hashable;
15
15
use crate :: collection:: AsCollection ;
16
16
use crate :: operators:: arrange:: { Arranged , ArrangeBySelf } ;
17
17
use crate :: trace:: { BatchReader , Cursor , TraceReader } ;
18
- use crate :: trace:: cursor:: IntoOwned ;
19
18
20
19
/// Extension trait for the `distinct` differential dataflow method.
21
20
pub trait ThresholdTotal < G : Scope , K : ExchangeData , R : ExchangeData +Semigroup > where G :: Timestamp : TotalOrder +Lattice +Ord {
@@ -117,66 +116,85 @@ where
117
116
118
117
self . stream . unary_frontier ( Pipeline , "ThresholdTotal" , move |_, _| {
119
118
120
- // tracks the upper limit of known-complete timestamps.
119
+ // tracks the lower and upper limit of received batches.
120
+ let mut lower_limit = timely:: progress:: frontier:: Antichain :: from_elem ( <G :: Timestamp as timely:: progress:: Timestamp >:: minimum ( ) ) ;
121
121
let mut upper_limit = timely:: progress:: frontier:: Antichain :: from_elem ( <G :: Timestamp as timely:: progress:: Timestamp >:: minimum ( ) ) ;
122
122
123
123
move |input, output| {
124
124
125
+ let mut batch_cursors = Vec :: new ( ) ;
126
+ let mut batch_storage = Vec :: new ( ) ;
127
+
128
+ // Downgrde previous upper limit to be current lower limit.
129
+ lower_limit. clear ( ) ;
130
+ lower_limit. extend ( upper_limit. borrow ( ) . iter ( ) . cloned ( ) ) ;
131
+
132
+ let mut cap = None ;
125
133
input. for_each ( |capability, batches| {
134
+ if cap. is_none ( ) { // NB: Assumes batches are in-order
135
+ cap = Some ( capability. retain ( ) ) ;
136
+ }
126
137
batches. swap ( & mut buffer) ;
127
- let mut session = output. session ( & capability) ;
128
138
for batch in buffer. drain ( ..) {
139
+ upper_limit. clone_from ( batch. upper ( ) ) ; // NB: Assumes batches are in-order
140
+ batch_cursors. push ( batch. cursor ( ) ) ;
141
+ batch_storage. push ( batch) ;
142
+ }
143
+ } ) ;
129
144
130
- let mut batch_cursor = batch . cursor ( ) ;
131
- let ( mut trace_cursor , trace_storage ) = trace . cursor_through ( batch . lower ( ) . borrow ( ) ) . unwrap ( ) ;
145
+ use crate :: trace :: cursor:: IntoOwned ;
146
+ if let Some ( capability ) = cap {
132
147
133
- upper_limit . clone_from ( batch . upper ( ) ) ;
148
+ let mut session = output . session ( & capability ) ;
134
149
135
- while let Some ( key) = batch_cursor. get_key ( & batch) {
136
- let mut count: Option < T1 :: Diff > = None ;
150
+ use crate :: trace:: cursor:: CursorList ;
151
+ let mut batch_cursor = CursorList :: new ( batch_cursors, & batch_storage) ;
152
+ let ( mut trace_cursor, trace_storage) = trace. cursor_through ( lower_limit. borrow ( ) ) . unwrap ( ) ;
137
153
138
- // Compute the multiplicity of this key before the current batch.
139
- trace_cursor. seek_key ( & trace_storage, key) ;
140
- if trace_cursor. get_key ( & trace_storage) == Some ( key) {
141
- trace_cursor. map_times ( & trace_storage, |_, diff| {
142
- count. as_mut ( ) . map ( |c| c. plus_equals ( & diff) ) ;
143
- if count. is_none ( ) { count = Some ( diff. into_owned ( ) ) ; }
144
- } ) ;
145
- }
154
+ while let Some ( key) = batch_cursor. get_key ( & batch_storage) {
155
+ let mut count: Option < T1 :: Diff > = None ;
146
156
147
- // Apply `thresh` both before and after `diff` is applied to `count`.
148
- // If the result is non-zero, send it along.
149
- batch_cursor. map_times ( & batch, |time, diff| {
150
-
151
- let difference =
152
- match & count {
153
- Some ( old) => {
154
- let mut temp = old. clone ( ) ;
155
- temp. plus_equals ( & diff) ;
156
- thresh ( key, & temp, Some ( old) )
157
- } ,
158
- None => { thresh ( key, & diff. into_owned ( ) , None ) } ,
159
- } ;
160
-
161
- // Either add or assign `diff` to `count`.
162
- if let Some ( count) = & mut count {
163
- count. plus_equals ( & diff) ;
164
- }
165
- else {
166
- count = Some ( diff. into_owned ( ) ) ;
167
- }
157
+ // Compute the multiplicity of this key before the current batch.
158
+ trace_cursor. seek_key ( & trace_storage, key) ;
159
+ if trace_cursor. get_key ( & trace_storage) == Some ( key) {
160
+ trace_cursor. map_times ( & trace_storage, |_, diff| {
161
+ count. as_mut ( ) . map ( |c| c. plus_equals ( & diff) ) ;
162
+ if count. is_none ( ) { count = Some ( diff. into_owned ( ) ) ; }
163
+ } ) ;
164
+ }
165
+
166
+ // Apply `thresh` both before and after `diff` is applied to `count`.
167
+ // If the result is non-zero, send it along.
168
+ batch_cursor. map_times ( & batch_storage, |time, diff| {
169
+
170
+ let difference =
171
+ match & count {
172
+ Some ( old) => {
173
+ let mut temp = old. clone ( ) ;
174
+ temp. plus_equals ( & diff) ;
175
+ thresh ( key, & temp, Some ( old) )
176
+ } ,
177
+ None => { thresh ( key, & diff. into_owned ( ) , None ) } ,
178
+ } ;
179
+
180
+ // Either add or assign `diff` to `count`.
181
+ if let Some ( count) = & mut count {
182
+ count. plus_equals ( & diff) ;
183
+ }
184
+ else {
185
+ count = Some ( diff. into_owned ( ) ) ;
186
+ }
168
187
169
- if let Some ( difference) = difference {
170
- if !difference. is_zero ( ) {
171
- session. give ( ( key. clone ( ) , time. into_owned ( ) , difference) ) ;
172
- }
188
+ if let Some ( difference) = difference {
189
+ if !difference. is_zero ( ) {
190
+ session. give ( ( key. clone ( ) , time. into_owned ( ) , difference) ) ;
173
191
}
174
- } ) ;
192
+ }
193
+ } ) ;
175
194
176
- batch_cursor. step_key ( & batch) ;
177
- }
195
+ batch_cursor. step_key ( & batch_storage) ;
178
196
}
179
- } ) ;
197
+ }
180
198
181
199
// tidy up the shared input trace.
182
200
trace. advance_upper ( & mut upper_limit) ;
0 commit comments