Skip to content

Commit 215714e

Browse files
authored
Thread-safe EGraph struct (egraphs-good#517)
* thread safe * simplify code
1 parent 9e6ecb6 commit 215714e

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

src/ast/parse.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,16 +217,19 @@ fn map_fallible<T>(
217217
.collect::<Result<_, _>>()
218218
}
219219

220-
pub trait Macro<T> {
220+
pub trait Macro<T>: Send + Sync {
221221
fn name(&self) -> Symbol;
222222
fn parse(&self, args: &[Sexp], span: Span, parser: &mut Parser) -> Result<T, ParseError>;
223223
}
224224

225-
pub struct SimpleMacro<T, F: Fn(&[Sexp], Span, &mut Parser) -> Result<T, ParseError>>(Symbol, F);
225+
pub struct SimpleMacro<T, F: Fn(&[Sexp], Span, &mut Parser) -> Result<T, ParseError> + Send + Sync>(
226+
Symbol,
227+
F,
228+
);
226229

227230
impl<T, F> SimpleMacro<T, F>
228231
where
229-
F: Fn(&[Sexp], Span, &mut Parser) -> Result<T, ParseError>,
232+
F: Fn(&[Sexp], Span, &mut Parser) -> Result<T, ParseError> + Send + Sync,
230233
{
231234
pub fn new(head: &str, f: F) -> Self {
232235
Self(head.into(), f)
@@ -235,7 +238,7 @@ where
235238

236239
impl<T, F> Macro<T> for SimpleMacro<T, F>
237240
where
238-
F: Fn(&[Sexp], Span, &mut Parser) -> Result<T, ParseError>,
241+
F: Fn(&[Sexp], Span, &mut Parser) -> Result<T, ParseError> + Send + Sync,
239242
{
240243
fn name(&self) -> Symbol {
241244
self.0

src/function/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct Function {
1717
pub merge: MergeFn,
1818
pub(crate) nodes: table::Table,
1919
sorts: HashSet<Symbol>,
20-
pub(crate) indexes: Vec<Rc<ColumnIndex>>,
20+
pub(crate) indexes: Vec<Arc<ColumnIndex>>,
2121
pub(crate) rebuild_indexes: Vec<Option<CompositeColumnIndex>>,
2222
index_updated_through: usize,
2323
updates: usize,
@@ -30,7 +30,7 @@ pub enum MergeFn {
3030
Union,
3131
// the rc is make sure it's cheaply clonable, since calling the merge fn
3232
// requires a clone
33-
Expr(Rc<Program>),
33+
Expr(Arc<Program>),
3434
}
3535

3636
/// All information we know determined by the input.
@@ -125,7 +125,7 @@ impl Function {
125125
let program = egraph
126126
.compile_expr(&binding, &actions, &target)
127127
.map_err(Error::TypeErrors)?;
128-
MergeFn::Expr(Rc::new(program))
128+
MergeFn::Expr(Arc::new(program))
129129
} else if decl.subtype == FunctionSubtype::Constructor {
130130
MergeFn::Union
131131
} else {
@@ -136,7 +136,7 @@ impl Function {
136136
input
137137
.iter()
138138
.chain(once(&output))
139-
.map(|x| Rc::new(ColumnIndex::new(x.name()))),
139+
.map(|x| Arc::new(ColumnIndex::new(x.name()))),
140140
);
141141

142142
let rebuild_indexes = Vec::from_iter(input.iter().chain(once(&output)).map(|x| {
@@ -179,7 +179,7 @@ impl Function {
179179
self.nodes.clear();
180180
self.indexes
181181
.iter_mut()
182-
.for_each(|x| Rc::make_mut(x).clear());
182+
.for_each(|x| Arc::make_mut(x).clear());
183183
self.rebuild_indexes.iter_mut().for_each(|x| {
184184
if let Some(x) = x {
185185
x.clear()
@@ -219,7 +219,7 @@ impl Function {
219219
&self,
220220
col: usize,
221221
timestamps: &Range<u32>,
222-
) -> Option<Rc<ColumnIndex>> {
222+
) -> Option<Arc<ColumnIndex>> {
223223
let range = self.nodes.transform_range(timestamps);
224224
if range.end > self.index_updated_through {
225225
return None;
@@ -250,7 +250,7 @@ impl Function {
250250
.zip(self.rebuild_indexes.iter_mut())
251251
.enumerate()
252252
{
253-
let as_mut = Rc::make_mut(index);
253+
let as_mut = Arc::make_mut(index);
254254
if col == self.schema.input.len() {
255255
for (slot, _, out) in self.nodes.iter_range(offsets.clone(), true) {
256256
as_mut.add(out.value, slot)
@@ -295,7 +295,7 @@ impl Function {
295295
for index in &mut self.indexes {
296296
// Everything works if we don't have a unique copy of the indexes,
297297
// but we ought to be able to avoid this copy.
298-
Rc::make_mut(index).clear();
298+
Arc::make_mut(index).clear();
299299
}
300300
for rebuild_index in self.rebuild_indexes.iter_mut().flatten() {
301301
rebuild_index.clear();

src/gj.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ type RowIdx = u32;
797797
#[derive(Debug)]
798798
enum LazyTrieInner {
799799
Borrowed {
800-
index: Rc<ColumnIndex>,
800+
index: Arc<ColumnIndex>,
801801
map: HashMap<Value, LazyTrie>,
802802
},
803803
Delayed(SmallVec<[RowIdx; 4]>),
@@ -822,7 +822,7 @@ impl LazyTrie {
822822
LazyTrieInner::Borrowed { index, .. } => index.len(),
823823
}
824824
}
825-
fn from_column_index(index: Rc<ColumnIndex>) -> LazyTrie {
825+
fn from_column_index(index: Arc<ColumnIndex>) -> LazyTrie {
826826
LazyTrie(UnsafeCell::new(LazyTrieInner::Borrowed {
827827
index,
828828
map: Default::default(),

src/lib.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,16 @@ use indexmap::map::Entry;
4545
use instant::{Duration, Instant};
4646
pub use serialize::{SerializeConfig, SerializedNode};
4747
use sort::*;
48+
use std::fmt::Debug;
4849
use std::fmt::{Display, Formatter};
4950
use std::fs::File;
5051
use std::hash::Hash;
5152
use std::io::Read;
5253
use std::iter::once;
5354
use std::ops::{Deref, Range};
5455
use std::path::PathBuf;
55-
use std::rc::Rc;
5656
use std::str::FromStr;
57-
use std::{fmt::Debug, sync::Arc};
57+
use std::sync::Arc;
5858
pub use termdag::{Term, TermDag, TermId};
5959
use thiserror::Error;
6060
pub use typechecking::TypeInfo;
@@ -292,7 +292,7 @@ impl RunReport {
292292
}
293293

294294
#[derive(Clone)]
295-
pub struct Primitive(Arc<dyn PrimitiveLike>);
295+
pub struct Primitive(Arc<dyn PrimitiveLike + Send + Sync>);
296296
impl Primitive {
297297
// Takes the full signature of a primitive (including input and output types)
298298
// Returns whether the primitive is compatible with this signature
@@ -344,7 +344,7 @@ impl Debug for Primitive {
344344
}
345345
}
346346

347-
impl<T: PrimitiveLike + 'static> From<T> for Primitive {
347+
impl<T: PrimitiveLike + 'static + Send + Sync> From<T> for Primitive {
348348
fn from(p: T) -> Self {
349349
Self(Arc::new(p))
350350
}
@@ -1585,7 +1585,9 @@ pub enum Error {
15851585

15861586
#[cfg(test)]
15871587
mod tests {
1588-
use std::sync::Arc;
1588+
use std::sync::{Arc, Mutex};
1589+
1590+
use lazy_static::lazy_static;
15891591

15901592
use crate::constraint::SimpleTypeConstraint;
15911593
use crate::sort::*;
@@ -1656,4 +1658,8 @@ mod tests {
16561658
)
16571659
.unwrap();
16581660
}
1661+
1662+
lazy_static! {
1663+
pub static ref RT: Mutex<EGraph> = Mutex::new(EGraph::default());
1664+
}
16591665
}

0 commit comments

Comments
 (0)