Skip to content

Commit 31fb673

Browse files
author
Markus Westerlind
committed
Start reading where ModifiedSet currently is
1 parent aa4595a commit 31fb673

File tree

4 files changed

+242
-139
lines changed

4 files changed

+242
-139
lines changed
Lines changed: 184 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,145 @@
1-
use std::ops::Range;
1+
use std::{marker::PhantomData, ops::Range};
22

33
use rustc_index::vec::Idx;
44

55
use crate::modified_set as ms;
6+
use crate::snapshot_vec as sv;
67
use crate::unify as ut;
78
use crate::unify_log as ul;
89

10+
use ena::undo_log::{Rollback, Snapshots, UndoLogs};
11+
12+
enum UndoLog<K: ut::UnifyKey, I> {
13+
Relation(sv::UndoLog<ut::Delegate<K>>),
14+
UnifyLog(ul::Undo<I>),
15+
ModifiedSet(ms::Undo),
16+
}
17+
18+
impl<K: ut::UnifyKey, I> From<sv::UndoLog<ut::Delegate<K>>> for UndoLog<K, I> {
19+
fn from(l: sv::UndoLog<ut::Delegate<K>>) -> Self {
20+
UndoLog::Relation(l)
21+
}
22+
}
23+
24+
impl<K: ut::UnifyKey, I> From<ul::Undo<I>> for UndoLog<K, I> {
25+
fn from(l: ul::Undo<I>) -> Self {
26+
UndoLog::UnifyLog(l)
27+
}
28+
}
29+
30+
impl<K: ut::UnifyKey, I> From<ms::Undo> for UndoLog<K, I> {
31+
fn from(l: ms::Undo) -> Self {
32+
UndoLog::ModifiedSet(l)
33+
}
34+
}
35+
36+
struct Logs<K: ut::UnifyKey, I> {
37+
logs: Vec<UndoLog<K, I>>,
38+
num_open_snapshots: usize,
39+
}
40+
41+
impl<K: ut::UnifyKey, I> Default for Logs<K, I> {
42+
fn default() -> Self {
43+
Self { logs: Default::default(), num_open_snapshots: Default::default() }
44+
}
45+
}
46+
47+
impl<T, K: ut::UnifyKey, I> UndoLogs<T> for Logs<K, I>
48+
where
49+
UndoLog<K, I>: From<T>,
50+
{
51+
fn num_open_snapshots(&self) -> usize {
52+
self.num_open_snapshots
53+
}
54+
fn push(&mut self, undo: T) {
55+
if self.in_snapshot() {
56+
self.logs.push(undo.into())
57+
}
58+
}
59+
fn extend<J>(&mut self, undos: J)
60+
where
61+
Self: Sized,
62+
J: IntoIterator<Item = T>,
63+
{
64+
if self.in_snapshot() {
65+
self.logs.extend(undos.into_iter().map(UndoLog::from))
66+
}
67+
}
68+
}
69+
70+
struct RollbackView<'a, K: ut::UnifyKey, I: Idx> {
71+
relations: &'a mut ut::UnificationStorage<K>,
72+
unify_log: &'a mut ul::UnifyLog<I>,
73+
modified_set: &'a mut ms::ModifiedSet<I>,
74+
}
75+
76+
impl<K: ut::UnifyKey, I: Idx> Rollback<UndoLog<K, I>> for RollbackView<'_, K, I> {
77+
fn reverse(&mut self, undo: UndoLog<K, I>) {
78+
match undo {
79+
UndoLog::Relation(undo) => self.relations.reverse(undo),
80+
UndoLog::UnifyLog(undo) => self.unify_log.reverse(undo),
81+
UndoLog::ModifiedSet(undo) => self.modified_set.reverse(undo),
82+
}
83+
}
84+
}
85+
86+
impl<K: ut::UnifyKey, I: Idx> Snapshots<UndoLog<K, I>> for Logs<K, I> {
87+
type Snapshot = Snapshot<K, I>;
88+
fn actions_since_snapshot(&self, snapshot: &Self::Snapshot) -> &[UndoLog<K, I>] {
89+
&self.logs[snapshot.undo_len..]
90+
}
91+
92+
fn start_snapshot(&mut self) -> Self::Snapshot {
93+
unreachable!()
94+
}
95+
96+
fn rollback_to(&mut self, values: &mut impl Rollback<UndoLog<K, I>>, snapshot: Self::Snapshot) {
97+
debug!("rollback_to({})", snapshot.undo_len);
98+
self.assert_open_snapshot(&snapshot);
99+
100+
while self.logs.len() > snapshot.undo_len {
101+
values.reverse(self.logs.pop().unwrap());
102+
}
103+
104+
if self.num_open_snapshots == 1 {
105+
// The root snapshot. It's safe to clear the undo log because
106+
// there's no snapshot further out that we might need to roll back
107+
// to.
108+
assert!(snapshot.undo_len == 0);
109+
self.logs.clear();
110+
}
111+
112+
self.num_open_snapshots -= 1;
113+
}
114+
115+
fn commit(&mut self, snapshot: Self::Snapshot) {
116+
debug!("commit({})", snapshot.undo_len);
117+
118+
if self.num_open_snapshots == 1 {
119+
// The root snapshot. It's safe to clear the undo log because
120+
// there's no snapshot further out that we might need to roll back
121+
// to.
122+
assert!(snapshot.undo_len == 0);
123+
self.logs.clear();
124+
}
125+
126+
self.num_open_snapshots -= 1;
127+
}
128+
}
129+
130+
impl<K: ut::UnifyKey, I: Idx> Logs<K, I> {
131+
fn assert_open_snapshot(&self, snapshot: &Snapshot<K, I>) {
132+
// Failures here may indicate a failure to follow a stack discipline.
133+
assert!(self.logs.len() >= snapshot.undo_len);
134+
assert!(self.num_open_snapshots > 0);
135+
}
136+
}
137+
9138
pub struct LoggedUnificationTable<K: ut::UnifyKey, I: Idx = K> {
10-
relations: ut::UnificationTable<ut::InPlace<K>>,
139+
relations: ut::UnificationStorage<K>,
11140
unify_log: ul::UnifyLog<I>,
12141
modified_set: ms::ModifiedSet<I>,
142+
undo_log: Logs<K, I>,
13143
}
14144

15145
impl<K, I> LoggedUnificationTable<K, I>
@@ -19,12 +149,19 @@ where
19149
{
20150
pub fn new() -> Self {
21151
Self {
22-
relations: ut::UnificationTable::new(),
152+
relations: Default::default(),
23153
unify_log: ul::UnifyLog::new(),
24154
modified_set: ms::ModifiedSet::new(),
155+
undo_log: Logs::default(),
25156
}
26157
}
27158

159+
fn relations(
160+
&mut self,
161+
) -> ut::UnificationTable<ut::InPlace<K, &mut ut::UnificationStorage<K>, &mut Logs<K, I>>> {
162+
ut::UnificationTable::with_log(&mut self.relations, &mut self.undo_log)
163+
}
164+
28165
pub fn unify(&mut self, a: I, b: I)
29166
where
30167
K::Value: ut::UnifyValue<Error = ut::NoError>,
@@ -38,17 +175,18 @@ where
38175
{
39176
if self.unify_log.needs_log(vid) {
40177
warn!("ModifiedSet {:?} => {:?}", vid, ty);
41-
self.modified_set.set(vid);
178+
self.modified_set.set(&mut self.undo_log, vid);
42179
}
43180
let vid = vid.into();
44-
debug_assert!(self.relations.find(vid) == vid);
45-
self.relations.union_value(vid, ty);
181+
let mut relations = self.relations();
182+
debug_assert!(relations.find(vid) == vid);
183+
relations.union_value(vid, ty);
46184

47185
vid
48186
}
49187

50188
pub fn find(&mut self, vid: I) -> K {
51-
self.relations.find(vid)
189+
self.relations().find(vid)
52190
}
53191

54192
pub fn unify_var_value(
@@ -58,24 +196,25 @@ where
58196
) -> Result<(), <K::Value as ut::UnifyValue>::Error> {
59197
let vid = self.find(vid).into();
60198
if self.unify_log.needs_log(vid) {
61-
self.modified_set.set(vid);
199+
self.modified_set.set(&mut self.undo_log, vid);
62200
}
63-
self.relations.unify_var_value(vid, value)
201+
self.relations().unify_var_value(vid, value)
64202
}
65203

66204
pub fn unify_var_var(&mut self, a: I, b: I) -> Result<(), <K::Value as ut::UnifyValue>::Error> {
67-
let a = self.relations.find(a);
68-
let b = self.relations.find(b);
205+
let mut relations = self.relations();
206+
let a = relations.find(a);
207+
let b = relations.find(b);
69208
if a == b {
70209
return Ok(());
71210
}
72211

73-
self.relations.unify_var_var(a, b)?;
212+
relations.unify_var_var(a, b)?;
74213

75-
if a == self.relations.find(a) {
76-
self.unify_log.unify(a.into(), b.into());
214+
if a == relations.find(a) {
215+
self.unify_log.unify(&mut self.undo_log, a.into(), b.into());
77216
} else {
78-
self.unify_log.unify(b.into(), a.into());
217+
self.unify_log.unify(&mut self.undo_log, b.into(), a.into());
79218
}
80219
Ok(())
81220
}
@@ -89,46 +228,52 @@ where
89228
}
90229

91230
pub fn probe_value(&mut self, vid: I) -> K::Value {
92-
self.relations.probe_value(vid)
231+
self.relations().probe_value(vid)
93232
}
94233

95234
#[inline(always)]
96235
pub fn inlined_probe_value(&mut self, vid: I) -> K::Value {
97-
self.relations.inlined_probe_value(vid)
236+
self.relations().inlined_probe_value(vid)
98237
}
99238

100239
pub fn new_key(&mut self, value: K::Value) -> K {
101-
self.relations.new_key(value)
240+
self.relations().new_key(value)
102241
}
103242

104243
pub fn len(&self) -> usize {
105244
self.relations.len()
106245
}
107246

247+
pub fn vars_since_snapshot(&mut self, s: &Snapshot<K, I>) -> Range<K> {
248+
K::from(I::new(s.value_count))..K::from(I::new(self.relations().len()))
249+
}
250+
108251
pub fn snapshot(&mut self) -> Snapshot<K, I> {
252+
self.undo_log.num_open_snapshots += 1;
109253
Snapshot {
110-
snapshot: self.relations.snapshot(),
111-
unify_log_snapshot: self.unify_log.snapshot(),
112-
modified_snapshot: self.modified_set.snapshot(),
254+
undo_len: self.undo_log.logs.len(),
255+
value_count: self.relations().len(),
256+
_marker: PhantomData,
113257
}
114258
}
115259

116-
pub fn rollback_to(&mut self, s: Snapshot<K, I>) {
117-
let Snapshot { snapshot, unify_log_snapshot, modified_snapshot } = s;
118-
self.relations.rollback_to(snapshot);
119-
self.unify_log.rollback_to(unify_log_snapshot);
120-
self.modified_set.rollback_to(modified_snapshot);
121-
}
260+
pub fn rollback_to(&mut self, snapshot: Snapshot<K, I>) {
261+
let Self { relations, unify_log, modified_set, .. } = self;
262+
263+
self.undo_log
264+
.rollback_to(&mut RollbackView { relations, unify_log, modified_set }, snapshot);
122265

123-
pub fn commit(&mut self, s: Snapshot<K, I>) {
124-
let Snapshot { snapshot, unify_log_snapshot, modified_snapshot } = s;
125-
self.relations.commit(snapshot);
126-
self.unify_log.commit(unify_log_snapshot);
127-
self.modified_set.commit(modified_snapshot);
266+
if self.undo_log.num_open_snapshots == 0 {
267+
self.modified_set.clear();
268+
}
128269
}
129270

130-
pub fn vars_since_snapshot(&mut self, s: &Snapshot<K, I>) -> Range<K> {
131-
self.relations.vars_since_snapshot(&s.snapshot)
271+
pub fn commit(&mut self, snapshot: Snapshot<K, I>) {
272+
self.undo_log.commit(snapshot);
273+
274+
if self.undo_log.num_open_snapshots == 0 {
275+
self.modified_set.clear();
276+
}
132277
}
133278

134279
pub fn register(&mut self) -> ms::Offset<I> {
@@ -140,7 +285,7 @@ where
140285
}
141286

142287
pub fn watch_variable(&mut self, index: I) {
143-
debug_assert!(index == self.relations.find(index).into());
288+
debug_assert!(index == self.relations().find(index).into());
144289
self.unify_log.watch_variable(index)
145290
}
146291

@@ -150,7 +295,7 @@ where
150295

151296
pub fn drain_modified_set(&mut self, offset: &ms::Offset<I>, mut f: impl FnMut(I) -> bool) {
152297
let unify_log = &self.unify_log;
153-
self.modified_set.drain(offset, |vid| {
298+
self.modified_set.drain(&mut self.undo_log, offset, |vid| {
154299
for &unified_vid in unify_log.get(vid) {
155300
f(unified_vid);
156301
}
@@ -161,7 +306,7 @@ where
161306
}
162307

163308
pub struct Snapshot<K: ut::UnifyKey, I: Idx = K> {
164-
snapshot: ut::Snapshot<ut::InPlace<K>>,
165-
unify_log_snapshot: ul::Snapshot<I>,
166-
modified_snapshot: ms::Snapshot<I>,
309+
undo_len: usize,
310+
value_count: usize,
311+
_marker: PhantomData<(K, I)>,
167312
}

0 commit comments

Comments
 (0)