diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-10-18 21:32:31 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-10-21 11:13:34 -0400 |
| commit | 974817d4932fd447f724c4527360a258952ffd48 (patch) | |
| tree | abf55340848ec3df65ca2773cbdd155dfc028a01 /src/librustc_data_structures/snapshot_map | |
| parent | da5b6467c33f7f86b4964b08b37726f7611a8f0c (diff) | |
| download | rust-974817d4932fd447f724c4527360a258952ffd48.tar.gz rust-974817d4932fd447f724c4527360a258952ffd48.zip | |
when pop skol, also remove from proj cache
Diffstat (limited to 'src/librustc_data_structures/snapshot_map')
| -rw-r--r-- | src/librustc_data_structures/snapshot_map/mod.rs | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index 0306066d6e7..23a67b3bd93 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -11,6 +11,7 @@ use fnv::FnvHashMap; use std::hash::Hash; use std::ops; +use std::mem; #[cfg(test)] mod test; @@ -31,6 +32,7 @@ enum UndoLog<K, V> { CommittedSnapshot, Inserted(K), Overwrite(K, V), + Noop, } impl<K, V> SnapshotMap<K, V> @@ -100,24 +102,29 @@ impl<K, V> SnapshotMap<K, V> } } + pub fn partial_rollback(&mut self, snapshot: &Snapshot) { + self.assert_open_snapshot(snapshot); + for i in (snapshot.len + 1..self.undo_log.len()).rev() { + let reverse = match self.undo_log[i] { + UndoLog::OpenSnapshot => false, + UndoLog::CommittedSnapshot => false, + UndoLog::Noop => false, + UndoLog::Inserted(..) => true, + UndoLog::Overwrite(..) => true, + }; + + if reverse { + let entry = mem::replace(&mut self.undo_log[i], UndoLog::Noop); + self.reverse(entry); + } + } + } + pub fn rollback_to(&mut self, snapshot: Snapshot) { self.assert_open_snapshot(&snapshot); while self.undo_log.len() > snapshot.len + 1 { - match self.undo_log.pop().unwrap() { - UndoLog::OpenSnapshot => { - panic!("cannot rollback an uncommitted snapshot"); - } - - UndoLog::CommittedSnapshot => {} - - UndoLog::Inserted(key) => { - self.map.remove(&key); - } - - UndoLog::Overwrite(key, old_value) => { - self.map.insert(key, old_value); - } - } + let entry = self.undo_log.pop().unwrap(); + self.reverse(entry); } let v = self.undo_log.pop().unwrap(); @@ -127,6 +134,26 @@ impl<K, V> SnapshotMap<K, V> }); assert!(self.undo_log.len() == snapshot.len); } + + fn reverse(&mut self, entry: UndoLog<K, V>) { + match entry { + UndoLog::OpenSnapshot => { + panic!("cannot rollback an uncommitted snapshot"); + } + + UndoLog::CommittedSnapshot => {} + + UndoLog::Inserted(key) => { + self.map.remove(&key); + } + + UndoLog::Overwrite(key, old_value) => { + self.map.insert(key, old_value); + } + + UndoLog::Noop => {} + } + } } impl<'k, K, V> ops::Index<&'k K> for SnapshotMap<K, V> |
