timely/dataflow/operators/
capability.rs1use std::{borrow, error::Error, fmt::Display, ops::Deref};
25use std::rc::Rc;
26use std::cell::{OnceCell, RefCell};
27use std::fmt::{self, Debug};
28
29use crate::order::PartialOrder;
30use crate::progress::Timestamp;
31use crate::progress::ChangeBatch;
32use crate::progress::operate::PortConnectivity;
33use crate::scheduling::Activations;
34use crate::dataflow::channels::pullers::counter::ConsumedGuard;
35
36pub trait CapabilityTrait<T: Timestamp> {
38 fn time(&self) -> &T;
40 fn valid_for_output(&self, query_buffer: &Rc<RefCell<ChangeBatch<T>>>, port: usize) -> bool;
42}
43
44impl<T: Timestamp, C: CapabilityTrait<T>> CapabilityTrait<T> for &C {
45 fn time(&self) -> &T { (**self).time() }
46 fn valid_for_output(&self, query_buffer: &Rc<RefCell<ChangeBatch<T>>>, port: usize) -> bool {
47 (**self).valid_for_output(query_buffer, port)
48 }
49}
50impl<T: Timestamp, C: CapabilityTrait<T>> CapabilityTrait<T> for &mut C {
51 fn time(&self) -> &T { (**self).time() }
52 fn valid_for_output(&self, query_buffer: &Rc<RefCell<ChangeBatch<T>>>, port: usize) -> bool {
53 (**self).valid_for_output(query_buffer, port)
54 }
55}
56
57pub struct Capability<T: Timestamp> {
64 time: T,
65 internal: Rc<RefCell<ChangeBatch<T>>>,
66}
67
68impl<T: Timestamp> CapabilityTrait<T> for Capability<T> {
69 fn time(&self) -> &T { &self.time }
70 fn valid_for_output(&self, query_buffer: &Rc<RefCell<ChangeBatch<T>>>, _port: usize) -> bool {
71 Rc::ptr_eq(&self.internal, query_buffer)
72 }
73}
74
75impl<T: Timestamp> Capability<T> {
76 pub(crate) fn new(time: T, internal: Rc<RefCell<ChangeBatch<T>>>) -> Self {
79 internal.borrow_mut().update(time.clone(), 1);
80
81 Self {
82 time,
83 internal,
84 }
85 }
86
87 pub fn time(&self) -> &T {
89 &self.time
90 }
91
92 pub fn delayed(&self, new_time: &T) -> Capability<T> {
97 #[cold]
101 #[inline(never)]
102 fn delayed_panic(capability: &dyn Debug, invalid_time: &dyn Debug) -> ! {
103 panic!(
106 "Attempted to delay {:?} to {:?}, which is not beyond the capability's time.",
107 capability,
108 invalid_time,
109 )
110 }
111
112 self.try_delayed(new_time)
113 .unwrap_or_else(|| delayed_panic(self, new_time))
114 }
115
116 pub fn try_delayed(&self, new_time: &T) -> Option<Capability<T>> {
121 if self.time.less_equal(new_time) {
122 Some(Self::new(new_time.clone(), Rc::clone(&self.internal)))
123 } else {
124 None
125 }
126 }
127
128 pub fn downgrade(&mut self, new_time: &T) {
132 #[cold]
136 #[inline(never)]
137 fn downgrade_panic(capability: &dyn Debug, invalid_time: &dyn Debug) -> ! {
138 panic!(
141 "Attempted to downgrade {:?} to {:?}, which is not beyond the capability's time.",
142 capability,
143 invalid_time,
144 )
145 }
146
147 self.try_downgrade(new_time)
148 .unwrap_or_else(|_| downgrade_panic(self, new_time))
149 }
150
151 pub fn try_downgrade(&mut self, new_time: &T) -> Result<(), DowngradeError> {
155 if let Some(new_capability) = self.try_delayed(new_time) {
156 *self = new_capability;
157 Ok(())
158 } else {
159 Err(DowngradeError(()))
160 }
161 }
162}
163
164impl<T: Timestamp> Drop for Capability<T> {
168 fn drop(&mut self) {
169 let time = ::std::mem::replace(&mut self.time, T::minimum());
170 self.internal.borrow_mut().update(time, -1);
171 }
172}
173
174impl<T: Timestamp> Clone for Capability<T> {
175 fn clone(&self) -> Capability<T> {
176 Self::new(self.time.clone(), Rc::clone(&self.internal))
177 }
178}
179
180impl<T: Timestamp> Deref for Capability<T> {
181 type Target = T;
182
183 fn deref(&self) -> &T {
184 &self.time
185 }
186}
187
188impl<T: Timestamp> Debug for Capability<T> {
189 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
190 f.debug_struct("Capability")
191 .field("time", &self.time)
192 .field("internal", &"...")
193 .finish()
194 }
195}
196
197impl<T: Timestamp> PartialEq for Capability<T> {
198 fn eq(&self, other: &Self) -> bool {
199 self.time() == other.time() && Rc::ptr_eq(&self.internal, &other.internal)
200 }
201}
202impl<T: Timestamp> Eq for Capability<T> { }
203
204impl<T: Timestamp> PartialOrder for Capability<T> {
205 fn less_equal(&self, other: &Self) -> bool {
206 self.time().less_equal(other.time()) && Rc::ptr_eq(&self.internal, &other.internal)
207 }
208}
209
210impl<T: Timestamp+::std::hash::Hash> ::std::hash::Hash for Capability<T> {
211 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
212 self.time.hash(state);
213 }
214}
215
216#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
219pub struct DowngradeError(());
220
221impl Display for DowngradeError {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 f.write_str("could not downgrade the given capability")
224 }
225}
226
227impl Error for DowngradeError {}
228
229type CapabilityUpdates<T> = Rc<RefCell<Vec<Rc<RefCell<ChangeBatch<T>>>>>>;
231
232pub struct InputCapability<T: Timestamp> {
240 internal: CapabilityUpdates<T>,
242 summaries: Rc<OnceCell<PortConnectivity<T::Summary>>>,
244 consumed_guard: ConsumedGuard<T>,
246}
247
248impl<T: Timestamp> CapabilityTrait<T> for InputCapability<T> {
249 fn time(&self) -> &T { self.time() }
250 fn valid_for_output(&self, query_buffer: &Rc<RefCell<ChangeBatch<T>>>, port: usize) -> bool {
251 let summaries_borrow = self.summaries.get().expect("connectivity frozen at operator build");
252 let internal_borrow = self.internal.borrow();
253 Rc::ptr_eq(&internal_borrow[port], query_buffer) &&
255 summaries_borrow.get(port).map_or(false, |path| path.elements() == [Default::default()])
256 }
257}
258
259impl<T: Timestamp> InputCapability<T> {
260 pub(crate) fn new(internal: CapabilityUpdates<T>, summaries: Rc<OnceCell<PortConnectivity<T::Summary>>>, guard: ConsumedGuard<T>) -> Self {
263 InputCapability {
264 internal,
265 summaries,
266 consumed_guard: guard,
267 }
268 }
269
270 #[inline]
272 pub fn time(&self) -> &T {
273 self.consumed_guard.time()
274 }
275
276 pub fn delayed(&self, new_time: &T, output_port: usize) -> Capability<T> {
283 use crate::progress::timestamp::PathSummary;
284 if let Some(path) = self.summaries.get().expect("connectivity frozen at operator build").get(output_port) {
285 if path.iter().flat_map(|summary| summary.results_in(self.time())).any(|time| time.less_equal(new_time)) {
286 Capability::new(new_time.clone(), Rc::clone(&self.internal.borrow()[output_port]))
287 } else {
288 panic!("Attempted to delay to a time ({:?}) not greater or equal to the operators input-output summary ({:?}) applied to the capabilities time ({:?})", new_time, path, self.time());
289 }
290 }
291 else {
292 panic!("Attempted to delay a capability for a disconnected output");
293 }
294 }
295
296 #[inline]
304 pub fn retain(&self, output_port: usize) -> Capability<T> {
305 self.delayed(self.time(), output_port)
306 }
307}
308
309impl<T: Timestamp> Deref for InputCapability<T> {
310 type Target = T;
311
312 fn deref(&self) -> &T {
313 self.time()
314 }
315}
316
317impl<T: Timestamp> Debug for InputCapability<T> {
318 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
319 f.debug_struct("InputCapability")
320 .field("time", self.time())
321 .field("internal", &"...")
322 .finish()
323 }
324}
325
326#[derive(Clone, Debug)]
328pub struct ActivateCapability<T: Timestamp> {
329 pub(crate) capability: Capability<T>,
330 pub(crate) address: Rc<[usize]>,
331 pub(crate) activations: Rc<RefCell<Activations>>,
332}
333
334impl<T: Timestamp> CapabilityTrait<T> for ActivateCapability<T> {
335 fn time(&self) -> &T { self.capability.time() }
336 fn valid_for_output(&self, query_buffer: &Rc<RefCell<ChangeBatch<T>>>, port: usize) -> bool {
337 self.capability.valid_for_output(query_buffer, port)
338 }
339}
340
341impl<T: Timestamp> ActivateCapability<T> {
342 pub fn new(capability: Capability<T>, address: Rc<[usize]>, activations: Rc<RefCell<Activations>>) -> Self {
344 Self {
345 capability,
346 address,
347 activations,
348 }
349 }
350
351 pub fn time(&self) -> &T {
353 self.capability.time()
354 }
355
356 pub fn delayed(&self, time: &T) -> Self {
358 ActivateCapability {
359 capability: self.capability.delayed(time),
360 address: Rc::clone(&self.address),
361 activations: Rc::clone(&self.activations),
362 }
363 }
364
365 pub fn downgrade(&mut self, time: &T) {
367 self.capability.downgrade(time);
368 self.activations.borrow_mut().activate(&self.address);
369 }
370}
371
372impl<T: Timestamp> Drop for ActivateCapability<T> {
373 fn drop(&mut self) {
374 self.activations.borrow_mut().activate(&self.address);
375 }
376}
377
378#[derive(Clone, Debug)]
380pub struct CapabilitySet<T: Timestamp> {
381 elements: Vec<Capability<T>>,
382}
383
384impl<T: Timestamp> CapabilitySet<T> {
385
386 pub fn new() -> Self {
388 Self { elements: Vec::new() }
389 }
390
391 pub fn with_capacity(capacity: usize) -> Self {
393 Self { elements: Vec::with_capacity(capacity) }
394 }
395
396 pub fn from_elem(cap: Capability<T>) -> Self {
427 Self { elements: vec![cap] }
428 }
429
430 pub fn insert(&mut self, capability: Capability<T>) {
432 if !self.elements.iter().any(|c| c.less_equal(&capability)) {
433 self.elements.retain(|c| !capability.less_equal(c));
434 self.elements.push(capability);
435 }
436 }
437
438 pub fn delayed(&self, time: &T) -> Capability<T> {
442 #[cold]
446 #[inline(never)]
447 fn delayed_panic(invalid_time: &dyn Debug) -> ! {
448 panic!(
451 "failed to create a delayed capability, the current set does not \
452 have an element less than or equal to {:?}",
453 invalid_time,
454 )
455 }
456
457 self.try_delayed(time)
458 .unwrap_or_else(|| delayed_panic(time))
459 }
460
461 pub fn try_delayed(&self, time: &T) -> Option<Capability<T>> {
465 self.elements
466 .iter()
467 .find(|capability| capability.time().less_equal(time))
468 .and_then(|capability| capability.try_delayed(time))
469 }
470
471 pub fn downgrade<B, F>(&mut self, frontier: F)
475 where
476 B: borrow::Borrow<T>,
477 F: IntoIterator<Item = B>,
478 {
479 #[cold]
483 #[inline(never)]
484 fn downgrade_panic() -> ! {
485 panic!(
488 "Attempted to downgrade a CapabilitySet with a frontier containing an element \
489 that was not beyond an element within the set"
490 )
491 }
492
493 self.try_downgrade(frontier)
494 .unwrap_or_else(|_| downgrade_panic())
495 }
496
497 pub fn try_downgrade<B, F>(&mut self, frontier: F) -> Result<(), DowngradeError>
505 where
506 B: borrow::Borrow<T>,
507 F: IntoIterator<Item = B>,
508 {
509 let count = self.elements.len();
510 for time in frontier.into_iter() {
511 let capability = self.try_delayed(time.borrow()).ok_or(DowngradeError(()))?;
512 self.elements.push(capability);
513 }
514 self.elements.drain(..count);
515
516 Ok(())
517 }
518}
519
520impl<T> From<Vec<Capability<T>>> for CapabilitySet<T>
521where
522 T: Timestamp,
523{
524 fn from(capabilities: Vec<Capability<T>>) -> Self {
525 let mut this = Self::with_capacity(capabilities.len());
526 for capability in capabilities {
527 this.insert(capability);
528 }
529
530 this
531 }
532}
533
534impl<T: Timestamp> Default for CapabilitySet<T> {
535 fn default() -> Self {
536 Self::new()
537 }
538}
539
540impl<T: Timestamp> Deref for CapabilitySet<T> {
541 type Target=[Capability<T>];
542
543 fn deref(&self) -> &[Capability<T>] {
544 &self.elements
545 }
546}