scopegraphs/completeness/
future.rs1use crate::completeness::private::Sealed;
2use crate::completeness::{Completeness, CriticalEdgeBasedCompleteness, Delay, ExplicitClose};
3use crate::future_wrapper::FutureWrapper;
4use crate::label::Label;
5use crate::scopegraph::{InnerScopeGraph, Scope};
6use std::cell::RefCell;
7use std::collections::{HashMap, HashSet};
8use std::future::poll_fn;
9use std::hash::Hash;
10use std::task::{Poll, Waker};
11
12use super::{UserClosed, Witness};
13
14#[derive(Debug)]
25pub struct FutureCompleteness<LABEL: Label> {
26 explicit_close: ExplicitClose<LABEL>,
27 wakers: RefCell<HashMap<Delay<LABEL>, Vec<Waker>>>,
28}
29
30impl<LABEL: Label> Default for FutureCompleteness<LABEL> {
31 fn default() -> Self {
32 Self {
33 explicit_close: ExplicitClose::<LABEL>::default(),
34 wakers: RefCell::new(HashMap::default()),
35 }
36 }
37}
38
39impl<LABEL: Label> Sealed for FutureCompleteness<LABEL> {}
40
41impl<LABEL: Hash + Label + Copy, DATA> Completeness<LABEL, DATA> for FutureCompleteness<LABEL> {
42 fn cmpl_new_scope(&self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {
43 self.explicit_close.cmpl_new_scope(inner_scope_graph, scope)
44 }
45
46 fn cmpl_new_complete_scope(&self, _: &InnerScopeGraph<LABEL, DATA>, _: Scope) {
47 <FutureCompleteness<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
48 self,
49 HashSet::new(), )
51 }
52
53 type NewEdgeResult = <ExplicitClose<LABEL> as Completeness<LABEL, DATA>>::NewEdgeResult;
54
55 fn cmpl_new_edge(
56 &self,
57 inner_scope_graph: &InnerScopeGraph<LABEL, DATA>,
58 src: Scope,
59 lbl: LABEL,
60 dst: Scope,
61 ) -> Self::NewEdgeResult {
62 self.explicit_close
63 .cmpl_new_edge(inner_scope_graph, src, lbl, dst)
64 }
65
66 type GetEdgesResult<'rslv>
67 = FutureWrapper<'rslv, Vec<Scope>>
68 where
69 Self: 'rslv,
70 LABEL: 'rslv,
71 DATA: 'rslv;
72
73 fn cmpl_get_edges<'rslv>(
74 &'rslv self,
75 inner_scope_graph: &'rslv InnerScopeGraph<LABEL, DATA>,
76 src: Scope,
77 lbl: LABEL,
78 ) -> Self::GetEdgesResult<'rslv>
79 where
80 LABEL: 'rslv,
81 DATA: 'rslv,
82 {
83 FutureWrapper::new(poll_fn(move |cx| {
84 match self
85 .explicit_close
86 .cmpl_get_edges(inner_scope_graph, src, lbl)
87 {
88 Ok(scopes) => Poll::Ready(scopes),
89 Err(delay) => {
90 self.wakers
91 .borrow_mut()
92 .entry(delay)
93 .or_default()
94 .push(cx.waker().clone());
95 Poll::Pending
96 }
97 }
98 }))
99 }
100}
101
102impl<LABEL: Hash + Label + Copy, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
103 for FutureCompleteness<LABEL>
104{
105 fn init_scope_with(&self, open_edges: HashSet<LABEL>) {
106 <ExplicitClose<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
107 &self.explicit_close,
108 open_edges,
109 );
110 }
111}
112
113impl<LABEL: Hash + Label + Copy, DATA> UserClosed<LABEL, DATA> for FutureCompleteness<LABEL> {
114 fn close(&self, scope: Scope, label: &LABEL, _witness: Witness) {
117 UserClosed::<_, DATA>::close(&self.explicit_close, scope, label, _witness);
118 for waker in self
119 .wakers
120 .borrow()
121 .get(&Delay {
122 scope,
123 label: *label,
124 })
125 .into_iter()
126 .flatten()
127 {
128 waker.wake_by_ref()
129 }
130 }
131}