1- use std:: ops:: Range ;
1+ use std:: { marker :: PhantomData , ops:: Range } ;
22
33use rustc_index:: vec:: Idx ;
44
55use crate :: modified_set as ms;
6+ use crate :: snapshot_vec as sv;
67use crate :: unify as ut;
78use 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+
9138pub 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
15145impl < 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
163308pub 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