Skip to content

Commit 3c5e8b4

Browse files
authored
Merge pull request #10 from rust-lang-nursery/ndm-reset-unifications
add `reset_unifications` API
2 parents d9314f5 + 8308f38 commit 3c5e8b4

File tree

4 files changed

+79
-1
lines changed

4 files changed

+79
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description = "Union-find, congruence closure, and other unification code. Based
44
license = "MIT/Apache-2.0"
55
homepage = "https://github.com/nikomatsakis/ena"
66
repository = "https://github.com/nikomatsakis/ena"
7-
version = "0.9.2"
7+
version = "0.9.3"
88
authors = ["Niko Matsakis <[email protected]>"]
99
readme = "README.md"
1010
keywords = ["unification", "union-find"]

src/snapshot_vec.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ impl<D: SnapshotVecDelegate> SnapshotVec<D> {
119119
&self.values[index]
120120
}
121121

122+
/// Reserve space for new values, just like an ordinary vec.
123+
pub fn reserve(&mut self, additional: usize) {
124+
// This is not affected by snapshots or anything.
125+
self.values.reserve(additional);
126+
}
127+
122128
/// Returns a mutable pointer into the vec; whatever changes you make here cannot be undone
123129
/// automatically, so you should be sure call `record()` with some sort of suitable undo
124130
/// action.
@@ -135,6 +141,20 @@ impl<D: SnapshotVecDelegate> SnapshotVec<D> {
135141
}
136142
}
137143

144+
/// Updates all elements. Potentially more efficient -- but
145+
/// otherwise equivalent to -- invoking `set` for each element.
146+
pub fn set_all(&mut self, mut new_elems: impl FnMut(usize) -> D::Value) {
147+
if !self.in_snapshot() {
148+
for (slot, index) in self.values.iter_mut().zip(0..) {
149+
*slot = new_elems(index);
150+
}
151+
} else {
152+
for i in 0..self.values.len() {
153+
self.set(i, new_elems(i));
154+
}
155+
}
156+
}
157+
138158
pub fn update<OP>(&mut self, index: usize, op: OP)
139159
where
140160
OP: FnOnce(&mut D::Value),

src/unify/backing_vec.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,17 @@ pub trait UnificationStore: ops::Index<usize, Output = VarValue<Key<Self>>> + Cl
2525

2626
fn commit(&mut self, snapshot: Self::Snapshot);
2727

28+
fn reset_unifications(
29+
&mut self,
30+
value: impl FnMut(u32) -> VarValue<Self::Key>,
31+
);
32+
2833
fn len(&self) -> usize;
2934

3035
fn push(&mut self, value: VarValue<Self::Key>);
3136

37+
fn reserve(&mut self, num_new_values: usize);
38+
3239
fn update<F>(&mut self, index: usize, op: F)
3340
where F: FnOnce(&mut VarValue<Self::Key>);
3441

@@ -69,6 +76,14 @@ impl<K: UnifyKey> UnificationStore for InPlace<K> {
6976
self.values.commit(snapshot);
7077
}
7178

79+
#[inline]
80+
fn reset_unifications(
81+
&mut self,
82+
mut value: impl FnMut(u32) -> VarValue<Self::Key>,
83+
) {
84+
self.values.set_all(|i| value(i as u32));
85+
}
86+
7287
#[inline]
7388
fn len(&self) -> usize {
7489
self.values.len()
@@ -79,6 +94,11 @@ impl<K: UnifyKey> UnificationStore for InPlace<K> {
7994
self.values.push(value);
8095
}
8196

97+
#[inline]
98+
fn reserve(&mut self, num_new_values: usize) {
99+
self.values.reserve(num_new_values);
100+
}
101+
82102
#[inline]
83103
fn update<F>(&mut self, index: usize, op: F)
84104
where F: FnOnce(&mut VarValue<Self::Key>)
@@ -137,6 +157,19 @@ impl<K: UnifyKey> UnificationStore for Persistent<K> {
137157
fn commit(&mut self, _snapshot: Self::Snapshot) {
138158
}
139159

160+
#[inline]
161+
fn reset_unifications(
162+
&mut self,
163+
mut value: impl FnMut(u32) -> VarValue<Self::Key>,
164+
) {
165+
// Without extending dogged, there isn't obviously a more
166+
// efficient way to do this. But it's pretty dumb. Maybe
167+
// dogged needs a `map`.
168+
for i in 0 .. self.values.len() {
169+
self.values[i] = value(i as u32);
170+
}
171+
}
172+
140173
#[inline]
141174
fn len(&self) -> usize {
142175
self.values.len()
@@ -147,6 +180,11 @@ impl<K: UnifyKey> UnificationStore for Persistent<K> {
147180
self.values.push(value);
148181
}
149182

183+
#[inline]
184+
fn reserve(&mut self, _num_new_values: usize) {
185+
// not obviously relevant to DVec.
186+
}
187+
150188
#[inline]
151189
fn update<F>(&mut self, index: usize, op: F)
152190
where F: FnOnce(&mut VarValue<Self::Key>)

src/unify/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,26 @@ impl<S: UnificationStore> UnificationTable<S> {
274274
key
275275
}
276276

277+
/// Reserve memory for `num_new_keys` to be created. Does not
278+
/// actually create the new keys; you must then invoke `new_key`.
279+
pub fn reserve(&mut self, num_new_keys: usize) {
280+
self.values.reserve(num_new_keys);
281+
}
282+
283+
/// Clears all unifications that have been performed, resetting to
284+
/// the initial state. The values of each variable are given by
285+
/// the closure.
286+
pub fn reset_unifications(
287+
&mut self,
288+
mut value: impl FnMut(S::Key) -> S::Value,
289+
) {
290+
self.values.reset_unifications(|i| {
291+
let key = UnifyKey::from_index(i as u32);
292+
let value = value(key);
293+
VarValue::new_var(key, value)
294+
});
295+
}
296+
277297
/// Returns the number of keys created so far.
278298
pub fn len(&self) -> usize {
279299
self.values.len()

0 commit comments

Comments
 (0)