scopegraphs_lib/completeness/
future.rs

1use 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}