Skip to content

Commit ee9764b

Browse files
author
Markus Westerlind
committed
Fix review comments
1 parent fac8c2d commit ee9764b

File tree

4 files changed

+222
-189
lines changed

4 files changed

+222
-189
lines changed

src/undo_log.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,21 @@
1111
/// A trait which allows actions (`T`) to be pushed which which allows the action to be undone at a
1212
/// later time if needed
1313
pub trait UndoLogs<T> {
14+
/// True if a snapshot has started, false otherwise
1415
fn in_snapshot(&self) -> bool {
1516
self.num_open_snapshots() > 0
1617
}
17-
fn num_open_snapshots(&self) -> usize {
18-
0
19-
}
18+
19+
/// How many open snapshots this undo log currently has
20+
fn num_open_snapshots(&self) -> usize;
21+
22+
/// Pushes a new "undo item" onto the undo log. This method is invoked when some action is taken
23+
/// (e.g., a variable is unified). It records the info needed to reverse that action should an
24+
/// enclosing snapshot be rolleod back.
2025
fn push(&mut self, undo: T);
26+
2127
fn clear(&mut self);
28+
2229
fn extend<I>(&mut self, undos: I)
2330
where
2431
Self: Sized,
@@ -78,24 +85,24 @@ where
7885
{
7986
type Snapshot = U::Snapshot;
8087
fn has_changes(&self, snapshot: &Self::Snapshot) -> bool {
81-
(**self).has_changes(snapshot)
88+
U::has_changes(self, snapshot)
8289
}
8390
fn actions_since_snapshot(&self, snapshot: &Self::Snapshot) -> &[T] {
84-
(**self).actions_since_snapshot(snapshot)
91+
U::actions_since_snapshot(self, snapshot)
8592
}
8693

8794
fn start_snapshot(&mut self) -> Self::Snapshot {
88-
(**self).start_snapshot()
95+
U::start_snapshot(self)
8996
}
9097
fn rollback_to<R>(&mut self, values: impl FnOnce() -> R, snapshot: Self::Snapshot)
9198
where
9299
R: Rollback<T>,
93100
{
94-
(**self).rollback_to(values, snapshot)
101+
U::rollback_to(self, values, snapshot)
95102
}
96103

97104
fn commit(&mut self, snapshot: Self::Snapshot) {
98-
(**self).commit(snapshot)
105+
U::commit(self, snapshot)
99106
}
100107
}
101108

src/unify/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub struct VarValue<K: UnifyKey> {
180180
/// - This implies that ordinary operations are quite a bit slower though.
181181
/// - Requires the `persistent` feature be selected in your Cargo.toml file.
182182
#[derive(Clone, Debug, Default)]
183-
pub struct UnificationTable<S> {
183+
pub struct UnificationTable<S: UnificationStoreBase> {
184184
/// Indicates the current value of each key.
185185
values: S,
186186
}
@@ -248,6 +248,8 @@ where
248248
K: UnifyKey,
249249
V: sv::VecLike<Delegate<K>>,
250250
{
251+
/// Creates a `UnificationTable` using an external `undo_log`, allowing mutating methods to be
252+
/// called if `L` does not implement `UndoLogs`
251253
pub fn with_log<'a, L2>(
252254
&'a mut self,
253255
undo_log: L2,
@@ -269,7 +271,7 @@ where
269271
// other type parameter U, and we have no way to say
270272
// Option<U>:LatticeValue.
271273

272-
impl<S: Default> UnificationTable<S> {
274+
impl<S: UnificationStoreBase + Default> UnificationTable<S> {
273275
pub fn new() -> Self {
274276
Self::default()
275277
}

src/unify/tests.rs

Lines changed: 1 addition & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,10 @@
1616
extern crate test;
1717
#[cfg(feature = "bench")]
1818
use self::test::Bencher;
19-
use snapshot_vec as sv;
2019
use std::cmp;
21-
use undo_log::{Rollback, Snapshots, UndoLogs};
2220
#[cfg(feature = "persistent")]
2321
use unify::Persistent;
24-
use unify::{
25-
self as ut, EqUnifyValue, InPlace, InPlaceUnificationTable, NoError, UnifyKey, UnifyValue,
26-
};
22+
use unify::{EqUnifyValue, InPlace, InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
2723
use unify::{UnificationStore, UnificationTable};
2824

2925
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
@@ -488,177 +484,3 @@ fn clone_table() {
488484
}
489485
}
490486
}
491-
492-
enum UndoLog {
493-
EqRelation(sv::UndoLog<ut::Delegate<IntKey>>),
494-
Values(sv::UndoLog<i32>),
495-
}
496-
497-
impl From<sv::UndoLog<ut::Delegate<IntKey>>> for UndoLog {
498-
fn from(l: sv::UndoLog<ut::Delegate<IntKey>>) -> Self {
499-
UndoLog::EqRelation(l)
500-
}
501-
}
502-
503-
impl From<sv::UndoLog<i32>> for UndoLog {
504-
fn from(l: sv::UndoLog<i32>) -> Self {
505-
UndoLog::Values(l)
506-
}
507-
}
508-
509-
impl Rollback<UndoLog> for TypeVariableStorage {
510-
fn reverse(&mut self, undo: UndoLog) {
511-
match undo {
512-
UndoLog::EqRelation(undo) => self.eq_relations.reverse(undo),
513-
UndoLog::Values(undo) => self.values.reverse(undo),
514-
}
515-
}
516-
}
517-
518-
#[derive(Default)]
519-
struct TypeVariableStorage {
520-
values: sv::SnapshotVecStorage<i32>,
521-
522-
eq_relations: ut::UnificationTableStorage<IntKey>,
523-
}
524-
525-
impl TypeVariableStorage {
526-
fn with_log<'a>(&'a mut self, undo_log: &'a mut TypeVariableUndoLogs) -> TypeVariableTable<'a> {
527-
TypeVariableTable {
528-
storage: self,
529-
undo_log,
530-
}
531-
}
532-
533-
fn len(&mut self) -> usize {
534-
assert_eq!(self.values.len(), self.eq_relations.len());
535-
self.values.len()
536-
}
537-
}
538-
539-
struct TypeVariableTable<'a> {
540-
storage: &'a mut TypeVariableStorage,
541-
542-
undo_log: &'a mut TypeVariableUndoLogs,
543-
}
544-
545-
impl TypeVariableTable<'_> {
546-
fn new(&mut self, i: i32) -> IntKey {
547-
self.storage.values.with_log(&mut self.undo_log).push(i);
548-
self.storage
549-
.eq_relations
550-
.with_log(&mut self.undo_log)
551-
.new_key(None)
552-
}
553-
}
554-
555-
struct Snapshot {
556-
undo_len: usize,
557-
}
558-
559-
struct TypeVariableUndoLogs {
560-
logs: Vec<UndoLog>,
561-
num_open_snapshots: usize,
562-
}
563-
564-
impl Default for TypeVariableUndoLogs {
565-
fn default() -> Self {
566-
Self {
567-
logs: Default::default(),
568-
num_open_snapshots: Default::default(),
569-
}
570-
}
571-
}
572-
573-
impl<T> UndoLogs<T> for TypeVariableUndoLogs
574-
where
575-
UndoLog: From<T>,
576-
{
577-
fn num_open_snapshots(&self) -> usize {
578-
self.num_open_snapshots
579-
}
580-
fn push(&mut self, undo: T) {
581-
if self.in_snapshot() {
582-
self.logs.push(undo.into())
583-
}
584-
}
585-
fn clear(&mut self) {
586-
self.logs.clear();
587-
self.num_open_snapshots = 0;
588-
}
589-
fn extend<J>(&mut self, undos: J)
590-
where
591-
Self: Sized,
592-
J: IntoIterator<Item = T>,
593-
{
594-
if self.in_snapshot() {
595-
self.logs.extend(undos.into_iter().map(UndoLog::from))
596-
}
597-
}
598-
}
599-
600-
impl Snapshots<UndoLog> for TypeVariableUndoLogs {
601-
type Snapshot = Snapshot;
602-
fn actions_since_snapshot(&self, snapshot: &Self::Snapshot) -> &[UndoLog] {
603-
&self.logs[snapshot.undo_len..]
604-
}
605-
606-
fn start_snapshot(&mut self) -> Self::Snapshot {
607-
self.num_open_snapshots += 1;
608-
Snapshot {
609-
undo_len: self.logs.len(),
610-
}
611-
}
612-
613-
fn rollback_to<R>(&mut self, values: impl FnOnce() -> R, snapshot: Self::Snapshot)
614-
where
615-
R: Rollback<UndoLog>,
616-
{
617-
debug!("rollback_to({})", snapshot.undo_len);
618-
619-
if self.logs.len() > snapshot.undo_len {
620-
let mut values = values();
621-
while self.logs.len() > snapshot.undo_len {
622-
values.reverse(self.logs.pop().unwrap());
623-
}
624-
}
625-
626-
if self.num_open_snapshots == 1 {
627-
// The root snapshot. It's safe to clear the undo log because
628-
// there's no snapshot further out that we might need to roll back
629-
// to.
630-
assert!(snapshot.undo_len == 0);
631-
self.logs.clear();
632-
}
633-
634-
self.num_open_snapshots -= 1;
635-
}
636-
637-
fn commit(&mut self, snapshot: Self::Snapshot) {
638-
debug!("commit({})", snapshot.undo_len);
639-
640-
if self.num_open_snapshots == 1 {
641-
// The root snapshot. It's safe to clear the undo log because
642-
// there's no snapshot further out that we might need to roll back
643-
// to.
644-
assert!(snapshot.undo_len == 0);
645-
self.logs.clear();
646-
}
647-
648-
self.num_open_snapshots -= 1;
649-
}
650-
}
651-
652-
#[test]
653-
fn separate_undo_log() {
654-
let mut storage = TypeVariableStorage::default();
655-
let mut undo_log = TypeVariableUndoLogs::default();
656-
657-
let snapshot = undo_log.start_snapshot();
658-
storage.with_log(&mut undo_log).new(1);
659-
storage.with_log(&mut undo_log).new(2);
660-
assert_eq!(storage.len(), 2);
661-
662-
undo_log.rollback_to(|| &mut storage, snapshot);
663-
assert_eq!(storage.len(), 0);
664-
}

0 commit comments

Comments
 (0)