scopegraphs_lib/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::{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
12#[derive(Debug)]
13pub struct FutureCompleteness<LABEL> {
14 explicit_close: ExplicitClose<LABEL>,
15 wakers: RefCell<HashMap<Delay<LABEL>, Vec<Waker>>>,
16}
17
18impl<LABEL> Default for FutureCompleteness<LABEL> {
19 fn default() -> Self {
20 Self {
21 explicit_close: ExplicitClose::<LABEL>::default(),
22 wakers: RefCell::new(HashMap::default()),
23 }
24 }
25}
26
27impl<LABEL> Sealed for FutureCompleteness<LABEL> {}
28
29impl<LABEL: Hash + Eq + Label + Copy, DATA> Completeness<LABEL, DATA>
30 for FutureCompleteness<LABEL>
31{
32 fn cmpl_new_scope(&self, inner_scope_graph: &InnerScopeGraph<LABEL, DATA>, scope: Scope) {
33 self.explicit_close.cmpl_new_scope(inner_scope_graph, scope)
34 }
35
36 type NewEdgeResult = <ExplicitClose<LABEL> as Completeness<LABEL, DATA>>::NewEdgeResult;
37
38 fn cmpl_new_edge(
39 &self,
40 inner_scope_graph: &InnerScopeGraph<LABEL, DATA>,
41 src: Scope,
42 lbl: LABEL,
43 dst: Scope,
44 ) -> Self::NewEdgeResult {
45 self.explicit_close
46 .cmpl_new_edge(inner_scope_graph, src, lbl, dst)
47 }
48
49 type GetEdgesResult<'rslv> = FutureWrapper<'rslv, Vec<Scope>> where Self: 'rslv, LABEL: 'rslv, DATA: 'rslv;
50
51 fn cmpl_get_edges<'rslv>(
52 &'rslv self,
53 inner_scope_graph: &'rslv InnerScopeGraph<LABEL, DATA>,
54 src: Scope,
55 lbl: LABEL,
56 ) -> Self::GetEdgesResult<'rslv>
57 where
58 LABEL: 'rslv,
59 DATA: 'rslv,
60 {
61 FutureWrapper::new(poll_fn(move |cx| {
62 match self
63 .explicit_close
64 .cmpl_get_edges(inner_scope_graph, src, lbl)
65 {
66 Ok(scopes) => Poll::Ready(scopes),
67 Err(delay) => {
68 self.wakers
69 .borrow_mut()
70 .entry(delay)
71 .or_default()
72 .push(cx.waker().clone());
73 Poll::Pending
74 }
75 }
76 }))
77 }
78}
79
80impl<LABEL: Hash + Eq + Copy> FutureCompleteness<LABEL> {
81 pub(super) fn close(&self, scope: Scope, label: &LABEL) {
82 self.explicit_close.close(scope, label);
83 for waker in self
84 .wakers
85 .borrow()
86 .get(&Delay {
87 scope,
88 label: *label,
89 })
90 .into_iter()
91 .flatten()
92 {
93 waker.wake_by_ref()
94 }
95 }
96}
97
98impl<LABEL: Hash + Eq + Label + Copy, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
99 for FutureCompleteness<LABEL>
100{
101 fn init_scope_with(&self, open_edges: HashSet<LABEL>) {
102 <ExplicitClose<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
103 &self.explicit_close,
104 open_edges,
105 );
106 }
107}