Skip to content

Commit dcf84c5

Browse files
committed
introduce in-place vs persistent unification tables as an option
1 parent 5d93337 commit dcf84c5

File tree

6 files changed

+462
-214
lines changed

6 files changed

+462
-214
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ authors = ["Niko Matsakis <[email protected]>"]
1010
[features]
1111
congruence-closure = [ "petgraph" ]
1212
bench = [ ]
13+
persistent = [ "dogged" ]
1314

1415
[dependencies]
16+
dogged = { version = "0.2.0", optional = true }
1517
log = "0.3"
1618
petgraph = { version = "0.4.5", optional = true }

src/cc/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ use petgraph::graph::{Graph, NodeIndex};
99
use std::collections::HashMap;
1010
use std::fmt::Debug;
1111
use std::hash::Hash;
12-
use unify::{NoError, UnifyKey, UnifyValue, UnificationTable, UnionedKeys};
12+
use unify::{NoError, InPlace, InPlaceUnificationTable, UnifyKey, UnifyValue, UnionedKeys};
1313

1414
#[cfg(test)]
1515
mod test;
1616

1717
pub struct CongruenceClosure<K: Key> {
1818
map: HashMap<K, Token>,
19-
table: UnificationTable<Token>,
19+
table: InPlaceUnificationTable<Token>,
2020
graph: Graph<K, ()>,
2121
}
2222

@@ -110,7 +110,7 @@ impl<K: Key> CongruenceClosure<K> {
110110
pub fn new() -> CongruenceClosure<K> {
111111
CongruenceClosure {
112112
map: HashMap::new(),
113-
table: UnificationTable::new(),
113+
table: InPlaceUnificationTable::new(),
114114
graph: Graph::new(),
115115
}
116116
}
@@ -276,7 +276,7 @@ impl<K: Key> CongruenceClosure<K> {
276276

277277
pub struct MergedKeys<'cc, K: Key + 'cc> {
278278
graph: &'cc Graph<K, ()>,
279-
iterator: UnionedKeys<'cc, Token>,
279+
iterator: UnionedKeys<'cc, InPlace<Token>>,
280280
}
281281

282282
impl<'cc, K: Key> Iterator for MergedKeys<'cc, K> {
@@ -293,7 +293,7 @@ impl<'cc, K: Key> Iterator for MergedKeys<'cc, K> {
293293

294294
struct Algorithm<'a, K: Key + 'a> {
295295
graph: &'a Graph<K, ()>,
296-
table: &'a mut UnificationTable<Token>,
296+
table: &'a mut InPlaceUnificationTable<Token>,
297297
}
298298

299299
impl<'a, K: Key> Algorithm<'a, K> {

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
#[macro_use]
2121
extern crate log;
2222

23+
#[cfg(feature = "persistent")]
24+
extern crate dogged;
25+
2326
#[cfg(feature = "congruence-closure")]
2427
extern crate petgraph;
2528

src/unify/backing_vec.rs

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#[cfg(feature = "persistent")]
2+
use dogged::DVec;
3+
use snapshot_vec as sv;
4+
use std::ops;
5+
use std::marker::PhantomData;
6+
7+
use super::{VarValue, UnifyKey, UnifyValue};
8+
9+
#[allow(dead_code)] // rustc BUG
10+
type Key<S> = <S as UnificationStore>::Key;
11+
12+
pub trait UnificationStore: ops::Index<usize, Output = VarValue<Key<Self>>> + Clone {
13+
type Key: UnifyKey<Value = Self::Value>;
14+
type Value: UnifyValue;
15+
type Snapshot;
16+
17+
fn new() -> Self;
18+
19+
fn start_snapshot(&mut self) -> Self::Snapshot;
20+
21+
fn rollback_to(&mut self, snapshot: Self::Snapshot);
22+
23+
fn commit(&mut self, snapshot: Self::Snapshot);
24+
25+
fn len(&self) -> usize;
26+
27+
fn push(&mut self, value: VarValue<Self::Key>);
28+
29+
fn update<F>(&mut self, index: usize, op: F)
30+
where F: FnOnce(&mut VarValue<Self::Key>);
31+
32+
fn tag() -> &'static str {
33+
Self::Key::tag()
34+
}
35+
}
36+
37+
#[derive(Clone)]
38+
pub struct InPlace<K: UnifyKey> {
39+
values: sv::SnapshotVec<Delegate<K>>
40+
}
41+
42+
impl<K: UnifyKey> UnificationStore for InPlace<K> {
43+
type Key = K;
44+
type Value = K::Value;
45+
type Snapshot = sv::Snapshot;
46+
47+
fn new() -> Self {
48+
InPlace { values: sv::SnapshotVec::new() }
49+
}
50+
51+
fn start_snapshot(&mut self) -> Self::Snapshot {
52+
self.values.start_snapshot()
53+
}
54+
55+
fn rollback_to(&mut self, snapshot: Self::Snapshot) {
56+
self.values.rollback_to(snapshot);
57+
}
58+
59+
fn commit(&mut self, snapshot: Self::Snapshot) {
60+
self.values.commit(snapshot);
61+
}
62+
63+
fn len(&self) -> usize {
64+
self.values.len()
65+
}
66+
67+
fn push(&mut self, value: VarValue<Self::Key>) {
68+
self.values.push(value);
69+
}
70+
71+
fn update<F>(&mut self, index: usize, op: F)
72+
where F: FnOnce(&mut VarValue<Self::Key>)
73+
{
74+
self.values.update(index, op)
75+
}
76+
}
77+
78+
impl<K> ops::Index<usize> for InPlace<K>
79+
where K: UnifyKey
80+
{
81+
type Output = VarValue<K>;
82+
fn index(&self, index: usize) -> &VarValue<K> {
83+
&self.values[index]
84+
}
85+
}
86+
87+
#[derive(Copy, Clone)]
88+
struct Delegate<K>(PhantomData<K>);
89+
90+
impl<K: UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
91+
type Value = VarValue<K>;
92+
type Undo = ();
93+
94+
fn reverse(_: &mut Vec<VarValue<K>>, _: ()) {}
95+
}
96+
97+
#[cfg(feature = "persistent")]
98+
#[derive(Clone)]
99+
pub struct Persistent<K: UnifyKey> {
100+
values: DVec<VarValue<K>>
101+
}
102+
103+
impl<K: UnifyKey> UnificationStore for Persistent<K> {
104+
type Key = K;
105+
type Value = K::Value;
106+
type Snapshot = Self;
107+
108+
fn new() -> Self {
109+
Persistent { values: DVec::new() }
110+
}
111+
112+
fn start_snapshot(&mut self) -> Self::Snapshot {
113+
self.clone()
114+
}
115+
116+
fn rollback_to(&mut self, snapshot: Self::Snapshot) {
117+
*self = snapshot;
118+
}
119+
120+
fn commit(&mut self, _snapshot: Self::Snapshot) {
121+
}
122+
123+
fn len(&self) -> usize {
124+
self.values.len()
125+
}
126+
127+
fn push(&mut self, value: VarValue<Self::Key>) {
128+
self.values.push(value);
129+
}
130+
131+
fn update<F>(&mut self, index: usize, op: F)
132+
where F: FnOnce(&mut VarValue<Self::Key>)
133+
{
134+
let p = &mut self.values[index];
135+
op(p);
136+
}
137+
}
138+
139+
impl<K> ops::Index<usize> for Persistent<K>
140+
where K: UnifyKey
141+
{
142+
type Output = VarValue<K>;
143+
fn index(&self, index: usize) -> &VarValue<K> {
144+
&self.values[index]
145+
}
146+
}

0 commit comments

Comments
 (0)