Skip to content

Commit

Permalink
Change API to rely on scope_ext drop when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
AZWN committed Jun 6, 2024
1 parent 07b2979 commit 587b6b6
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 353 deletions.
117 changes: 0 additions & 117 deletions scopegraphs/src/completeness/drop.rs

This file was deleted.

190 changes: 6 additions & 184 deletions scopegraphs/src/completeness/explicit.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::completeness::private::Sealed;
use crate::completeness::{
Completeness, CriticalEdgeBasedCompleteness, CriticalEdgeSet, Delay, EdgeClosedError,
EdgesOrDelay, FutureCompleteness,
EdgesOrDelay,
};
use crate::scopegraph::{InnerScopeGraph, Scope, ScopeGraph};
use crate::scopegraph::{InnerScopeGraph, Scope};
use crate::Label;
use std::{collections::HashSet, hash::Hash};

use super::{UserClosed, Witness};

/// Critical-edge based [`Completeness`] implementation.
///
/// Unlike [`ImplicitClose`](super::ImplicitClose), this implementation shifts responsibility of closing edges to the
Expand Down Expand Up @@ -101,190 +103,10 @@ impl<LABEL: Hash + Eq + Label, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
}
}

impl<LABEL: Hash + Eq> ExplicitClose<LABEL> {
impl<LABEL: Hash + Eq + Label, DATA> UserClosed<LABEL, DATA> for ExplicitClose<LABEL> {
/// Close a scope for a certain label
/// // TODO: link to "closing" in concepts
pub fn close(&self, scope: Scope, label: &LABEL) {
fn close(&self, scope: Scope, label: &LABEL, _witness: Witness) {
self.critical_edges.close(scope, label);
}
}

impl<'sg, LABEL: Hash + Eq, DATA> ScopeGraph<'sg, LABEL, DATA, ExplicitClose<LABEL>> {
// TODO: fix this sentence
/// Closes an edge, (i.e., prohibit future new
///
/// For example, the following program will return an error.
/// ```
/// # use scopegraphs::completeness::ExplicitClose;
/// # use scopegraphs::Label;
/// # use scopegraphs::Storage;
/// # use scopegraphs::ScopeGraph;
///
/// # #[derive(Eq, Hash, PartialEq, Label)] enum Lbl { Def }
/// # use Lbl::*;
/// let storage = Storage::new();
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(&storage, ExplicitClose::default());
///
/// let s1 = sg.add_scope_with(0, [Def]);
/// let s2 = sg.add_scope_closed(42);
///
/// sg.close(s1, &Def);
/// sg.add_edge(s1, Def, s2).expect_err("cannot add edge after closing edge");
/// ```
///
/// Closing is required to permit queries to traverse these edges:
/// ```
///
/// # use scopegraphs::completeness::ExplicitClose;
/// # use scopegraphs::ScopeGraph;
/// # use scopegraphs::resolve::{DefaultDataEquivalence, DefaultLabelOrder, EdgeOrData, Resolve};
/// # use scopegraphs_macros::{compile_regex, Label};
/// # use scopegraphs::Storage;
/// #
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
/// # enum Lbl { Def }
/// # use Lbl::*;
/// # type LblD = EdgeOrData<Lbl>;
/// #
/// # compile_regex!(type Regex<Lbl> = Def);
/// let storage = Storage::new();
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(&storage, ExplicitClose::default());
///
/// let s1 = sg.add_scope_with(0, [Def]);
/// let s2 = sg.add_scope_closed(42);
///
/// // Note: not calling `sg.close(s1, &Def)`
///
/// let query_result = sg.query()
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
/// .resolve(s1);
///
/// query_result.expect_err("require s1/Def to be closed");
/// ```
///
/// Closing allows queries to resolve:
/// ```
///
/// # use scopegraphs::completeness::ExplicitClose;
/// # use scopegraphs::ScopeGraph;
/// # use scopegraphs::resolve::{DefaultDataEquivalence, DefaultLabelOrder, EdgeOrData, Resolve};
/// # use scopegraphs_macros::{compile_regex, Label};
/// # use scopegraphs::Storage;
/// #
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
/// # enum Lbl { Def }
/// # use Lbl::*;
/// # type LblD = EdgeOrData<Lbl>;
/// #
/// # compile_regex!(type Regex<Lbl> = Def);
/// let storage = Storage::new();
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(&storage, ExplicitClose::default());
///
/// let s1 = sg.add_scope_with(0, [Def]);
/// let s2 = sg.add_scope_closed(42);
///
/// // Note: closing the edge *after* creating all edges, *before* doing the query
/// sg.close(s1, &Def);
///
/// let query_result = sg.query()
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
/// .resolve(s1);
///
/// query_result.expect("query should return result");
/// ```
pub fn close(&self, scope: Scope, label: &LABEL) {
self.completeness.close(scope, label)
}
}

impl<'sg, LABEL: Hash + Eq + Copy, DATA> ScopeGraph<'sg, LABEL, DATA, FutureCompleteness<LABEL>> {
// TODO: update this example to use futures
// TODO: fix this sentence
/// Closes an edge, (i.e., prohibit future new
///
/// For example, the following program will return an error.
/// ```
/// # use scopegraphs::completeness::ExplicitClose;
/// # use scopegraphs::ScopeGraph;
/// # use scopegraphs_macros::Label;
/// # use scopegraphs::Storage;
/// # #[derive(Eq, Hash, PartialEq, Label)] enum Lbl { Def }
/// # use Lbl::*;
/// let storage = Storage::new();
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(&storage, ExplicitClose::default());
///
/// let s1 = sg.add_scope_with(0, [Def]);
/// let s2 = sg.add_scope_closed(42);
///
/// sg.close(s1, &Def);
/// sg.add_edge(s1, Def, s2).expect_err("cannot add edge after closing edge");
/// ```
///
/// Closing is required to permit queries to traverse these edges:
/// ```
///
/// # use scopegraphs::completeness::ExplicitClose;
/// # use scopegraphs::ScopeGraph;
/// # use scopegraphs::resolve::{DefaultDataEquivalence, DefaultLabelOrder, EdgeOrData, Resolve};
/// # use scopegraphs_macros::{compile_regex, Label};
/// # use scopegraphs::Storage;
/// #
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
/// # enum Lbl { Def }
/// # use Lbl::*;
/// # type LblD = EdgeOrData<Lbl>;
/// #
/// # compile_regex!(type Regex<Lbl> = Def);
/// let storage = Storage::new();
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(&storage, ExplicitClose::default());
///
/// let s1 = sg.add_scope_with(0, [Def]);
/// let s2 = sg.add_scope_closed(42);
///
/// // Note: not calling `sg.close(s1, &Def)`
///
/// let query_result = sg.query()
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
/// .resolve(s1);
///
/// query_result.expect_err("require s1/Def to be closed");
/// ```
///
/// Closing allows queries to resolve:
/// ```
///
/// # use scopegraphs::completeness::ExplicitClose;
/// # use scopegraphs::ScopeGraph;
/// # use scopegraphs::resolve::{DefaultDataEquivalence, DefaultLabelOrder, EdgeOrData, Resolve};
/// # use scopegraphs_macros::{compile_regex, Label};
/// # use scopegraphs::Storage;
/// #
/// # #[derive(Eq, Hash, PartialEq, Label, Debug, Copy, Clone)]
/// # enum Lbl { Def }
/// # use Lbl::*;
/// # type LblD = EdgeOrData<Lbl>;
/// #
/// # compile_regex!(type Regex<Lbl> = Def);
/// let storage = Storage::new();
/// let mut sg = ScopeGraph::<Lbl, usize, _>::new(&storage, ExplicitClose::default());
///
/// let s1 = sg.add_scope_with(0, [Def]);
/// let s2 = sg.add_scope_closed(42);
///
/// // Note: closing the edge *after* creating all edges, *before* doing the query
/// sg.close(s1, &Def);
///
/// let query_result = sg.query()
/// .with_path_wellformedness(Regex::new()) // regex: `Def`
/// .with_data_wellformedness(|x: &usize| *x == 42) // match `42`
/// .resolve(s1);
///
/// query_result.expect("query should return result");
/// ```
pub fn close(&self, scope: Scope, label: &LABEL) {
self.completeness.close(scope, label)
}
}
32 changes: 18 additions & 14 deletions scopegraphs/src/completeness/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use std::future::poll_fn;
use std::hash::Hash;
use std::task::{Poll, Waker};

use super::{UserClosed, Witness};

/// A completeness strategy that makes queries return a [`Future`](std::future::Future)
/// in case one of the scopes that the query runs over was not yet closed.
/// The future resolves once all such scopes *are* closed.
Expand Down Expand Up @@ -94,9 +96,22 @@ impl<LABEL: Hash + Eq + Label + Copy, DATA> Completeness<LABEL, DATA>
}
}

impl<LABEL: Hash + Eq + Copy> FutureCompleteness<LABEL> {
pub(crate) fn close(&self, scope: Scope, label: &LABEL) {
self.explicit_close.close(scope, label);
impl<LABEL: Hash + Eq + Label + Copy, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
for FutureCompleteness<LABEL>
{
fn init_scope_with(&self, open_edges: HashSet<LABEL>) {
<ExplicitClose<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
&self.explicit_close,
open_edges,
);
}
}

impl<LABEL: Hash + Eq + Label + Copy, DATA> UserClosed<LABEL, DATA> for FutureCompleteness<LABEL> {
/// Close a scope for a certain label
/// // TODO: link to "closing" in concepts
fn close(&self, scope: Scope, label: &LABEL, _witness: Witness) {
UserClosed::<_, DATA>::close(&self.explicit_close, scope, label, _witness);
for waker in self
.wakers
.borrow()
Expand All @@ -111,14 +126,3 @@ impl<LABEL: Hash + Eq + Copy> FutureCompleteness<LABEL> {
}
}
}

impl<LABEL: Hash + Eq + Label + Copy, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
for FutureCompleteness<LABEL>
{
fn init_scope_with(&self, open_edges: HashSet<LABEL>) {
<ExplicitClose<LABEL> as CriticalEdgeBasedCompleteness<LABEL, DATA>>::init_scope_with(
&self.explicit_close,
open_edges,
);
}
}
4 changes: 4 additions & 0 deletions scopegraphs/src/completeness/implicit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use crate::Label;
use std::collections::HashSet;
use std::hash::Hash;

use super::Implicit;

/// Critical-edge based [`Completeness`] implementation.
///
/// Unlike [`ExplicitClose`](crate::completeness::ExplicitClose), this implementation will implicitly close edges once traversed.
Expand Down Expand Up @@ -93,3 +95,5 @@ impl<LABEL: Hash + Eq + Label, DATA> CriticalEdgeBasedCompleteness<LABEL, DATA>
self.critical_edges.init_scope(open_labels)
}
}

impl<LABEL: Hash + Eq + Label, DATA> Implicit<LABEL, DATA> for ImplicitClose<LABEL> {}
Loading

0 comments on commit 587b6b6

Please sign in to comment.