Skip to content

Commit

Permalink
Merge pull request #21 from varkor/vars_since_snapshot
Browse files Browse the repository at this point in the history
Add a `vars_since_snapshot` method to `UnificationTable`
  • Loading branch information
nikomatsakis authored Mar 22, 2019
2 parents 38fcb1c + e7ad85c commit 7ad2655
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 43 deletions.
22 changes: 13 additions & 9 deletions src/snapshot_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ impl<D> fmt::Debug for SnapshotVec<D>

// Snapshots are tokens that should be created/consumed linearly.
pub struct Snapshot {
// Number of values at the time the snapshot was taken.
pub(crate) value_count: usize,
// Length of the undo log at the time the snapshot was taken.
pub(crate) length: usize,
undo_len: usize,
}

pub trait SnapshotVecDelegate {
Expand Down Expand Up @@ -173,27 +175,29 @@ impl<D: SnapshotVecDelegate> SnapshotVec<D> {
}

pub fn start_snapshot(&mut self) -> Snapshot {
let length = self.undo_log.len();
self.num_open_snapshots += 1;
Snapshot { length: length }
Snapshot {
value_count: self.values.len(),
undo_len: self.undo_log.len(),
}
}

pub fn actions_since_snapshot(&self, snapshot: &Snapshot) -> &[UndoLog<D>] {
&self.undo_log[snapshot.length..]
&self.undo_log[snapshot.undo_len..]
}

fn assert_open_snapshot(&self, snapshot: &Snapshot) {
// Failures here may indicate a failure to follow a stack discipline.
assert!(self.undo_log.len() >= snapshot.length);
assert!(self.undo_log.len() >= snapshot.undo_len);
assert!(self.num_open_snapshots > 0);
}

pub fn rollback_to(&mut self, snapshot: Snapshot) {
debug!("rollback_to({})", snapshot.length);
debug!("rollback_to({})", snapshot.undo_len);

self.assert_open_snapshot(&snapshot);

while self.undo_log.len() > snapshot.length {
while self.undo_log.len() > snapshot.undo_len {
match self.undo_log.pop().unwrap() {
NewElem(i) => {
self.values.pop();
Expand All @@ -216,15 +220,15 @@ impl<D: SnapshotVecDelegate> SnapshotVec<D> {
/// Commits all changes since the last snapshot. Of course, they
/// can still be undone if there is a snapshot further out.
pub fn commit(&mut self, snapshot: Snapshot) {
debug!("commit({})", snapshot.length);
debug!("commit({})", snapshot.undo_len);

self.assert_open_snapshot(&snapshot);

if self.num_open_snapshots == 1 {
// The root snapshot. It's safe to clear the undo log because
// there's no snapshot further out that we might need to roll back
// to.
assert!(snapshot.length == 0);
assert!(snapshot.undo_len == 0);
self.undo_log.clear();
}

Expand Down
58 changes: 24 additions & 34 deletions src/unify/backing_vec.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#[cfg(feature = "persistent")]
use dogged::DVec;
use snapshot_vec as sv;
use std::ops;
use std::ops::RangeInclusive;
use std::ops::{self, Range};
use std::marker::PhantomData;

use super::{VarValue, UnifyKey, UnifyValue};
Expand All @@ -11,35 +10,31 @@ use super::{VarValue, UnifyKey, UnifyValue};
#[allow(type_alias_bounds)]
type Key<S: UnificationStore> = <S as UnificationStore>::Key;

pub trait Measurable {
fn len(&self) -> usize;
}

/// Largely internal trait implemented by the unification table
/// backing store types. The most common such type is `InPlace`,
/// which indicates a standard, mutable unification table.
pub trait UnificationStore:
ops::Index<usize, Output = VarValue<Key<Self>>> + Measurable + Clone + Default
ops::Index<usize, Output = VarValue<Key<Self>>> + Clone + Default
{
type Key: UnifyKey<Value = Self::Value>;
type Value: UnifyValue;
type Snapshot: Measurable;
type Snapshot;

fn start_snapshot(&mut self) -> Self::Snapshot;

fn rollback_to(&mut self, snapshot: Self::Snapshot);

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

fn values_since_snapshot(&mut self, snapshot: &Self::Snapshot) -> RangeInclusive<usize> {
snapshot.len()..=self.len()
}
fn values_since_snapshot(&self, snapshot: &Self::Snapshot) -> Range<usize>;

fn reset_unifications(
&mut self,
value: impl FnMut(u32) -> VarValue<Self::Key>,
);

fn len(&self) -> usize;

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

fn reserve(&mut self, num_new_values: usize);
Expand All @@ -66,20 +61,6 @@ impl<K: UnifyKey> Default for InPlace<K> {
}
}

impl Measurable for sv::Snapshot {
#[inline]
fn len(&self) -> usize {
self.length
}
}

impl<K: UnifyKey> Measurable for InPlace<K> {
#[inline]
fn len(&self) -> usize {
self.values.len()
}
}

impl<K: UnifyKey> UnificationStore for InPlace<K> {
type Key = K;
type Value = K::Value;
Expand All @@ -100,6 +81,11 @@ impl<K: UnifyKey> UnificationStore for InPlace<K> {
self.values.commit(snapshot);
}

#[inline]
fn values_since_snapshot(&self, snapshot: &Self::Snapshot) -> Range<usize> {
snapshot.value_count..self.len()
}

#[inline]
fn reset_unifications(
&mut self,
Expand All @@ -108,6 +94,10 @@ impl<K: UnifyKey> UnificationStore for InPlace<K> {
self.values.set_all(|i| value(i as u32));
}

fn len(&self) -> usize {
self.values.len()
}

#[inline]
fn push(&mut self, value: VarValue<Self::Key>) {
self.values.push(value);
Expand Down Expand Up @@ -159,14 +149,6 @@ impl<K: UnifyKey> Default for Persistent<K> {
}
}

#[cfg(feature = "persistent")]
impl<K: UnifyKey> Measurable for Persistent<K> {
#[inline]
fn len(&self) -> usize {
self.values.len()
}
}

#[cfg(feature = "persistent")]
impl<K: UnifyKey> UnificationStore for Persistent<K> {
type Key = K;
Expand All @@ -184,7 +166,11 @@ impl<K: UnifyKey> UnificationStore for Persistent<K> {
}

#[inline]
fn commit(&mut self, _snapshot: Self::Snapshot) {
fn commit(&mut self, _snapshot: Self::Snapshot) {}

#[inline]
fn values_since_snapshot(&self, snapshot: &Self::Snapshot) -> Range<usize> {
snapshot.len()..self.len()
}

#[inline]
Expand All @@ -200,6 +186,10 @@ impl<K: UnifyKey> UnificationStore for Persistent<K> {
}
}

fn len(&self) -> usize {
self.values.len()
}

#[inline]
fn push(&mut self, value: VarValue<Self::Key>) {
self.values.push(value);
Expand Down
10 changes: 10 additions & 0 deletions src/unify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

use std::marker;
use std::fmt::Debug;
use std::ops::Range;

mod backing_vec;
pub use self::backing_vec::{InPlace, UnificationStore};
Expand Down Expand Up @@ -299,6 +300,15 @@ impl<S: UnificationStore> UnificationTable<S> {
self.values.len()
}

/// Returns the keys of all variables created since the `snapshot`.
pub fn vars_since_snapshot(
&self,
snapshot: &Snapshot<S>,
) -> Range<S::Key> {
let range = self.values.values_since_snapshot(&snapshot.snapshot);
S::Key::from_index(range.start as u32)..S::Key::from_index(range.end as u32)
}

/// Obtains the current value for a particular key.
/// Not for end-users; they can use `probe_value`.
fn value(&self, key: S::Key) -> &VarValue<S::Key> {
Expand Down

0 comments on commit 7ad2655

Please sign in to comment.