@@ -2,12 +2,17 @@ use std::{collections::VecDeque, marker::PhantomData};
2
2
3
3
use rustc_index:: { bit_set:: BitSet , vec:: Idx } ;
4
4
5
+ #[ derive( Copy , Clone , Debug ) ]
6
+ enum Undo < T > {
7
+ Add ( T ) ,
8
+ Drain { index : usize , offset : usize } ,
9
+ }
10
+
5
11
#[ derive( Clone , Debug ) ]
6
12
pub struct ModifiedSet < T : Idx > {
7
- modified : VecDeque < T > ,
13
+ modified : VecDeque < Undo < T > > ,
8
14
snapshots : usize ,
9
15
modified_set : BitSet < T > ,
10
- undo_offsets : Vec < usize > ,
11
16
offsets : Vec < usize > ,
12
17
}
13
18
@@ -18,7 +23,6 @@ impl<T: Idx> Default for ModifiedSet<T> {
18
23
snapshots : 0 ,
19
24
modified_set : BitSet :: new_empty ( 0 ) ,
20
25
offsets : Vec :: new ( ) ,
21
- undo_offsets : Vec :: new ( ) ,
22
26
}
23
27
}
24
28
}
@@ -33,62 +37,59 @@ impl<T: Idx> ModifiedSet<T> {
33
37
self . modified_set . resize ( index. index ( ) + 1 ) ;
34
38
}
35
39
if self . modified_set . insert ( index) {
36
- self . modified . push_back ( index) ;
40
+ self . modified . push_back ( Undo :: Add ( index) ) ;
37
41
}
38
42
}
39
43
40
- pub fn drain ( & mut self , offset : & Offset < T > , mut f : impl FnMut ( T ) -> bool ) {
41
- let offset = & mut self . offsets [ offset. index ] ;
42
- for & index in self . modified . iter ( ) . skip ( * offset) {
43
- if f ( index) { }
44
+ pub fn drain ( & mut self , index : & Offset < T > , mut f : impl FnMut ( T ) -> bool ) {
45
+ let offset = & mut self . offsets [ index. index ] ;
46
+ if * offset < self . modified . len ( ) {
47
+ for & undo in self . modified . iter ( ) . skip ( * offset) {
48
+ if let Undo :: Add ( index) = undo {
49
+ f ( index) ;
50
+ }
51
+ }
52
+ self . modified . push_back ( Undo :: Drain { index : index. index , offset : * offset } ) ;
53
+ * offset = self . modified . len ( ) ;
44
54
}
45
- * offset = self . modified . len ( ) ;
46
55
}
47
56
48
57
pub fn snapshot ( & mut self ) -> Snapshot < T > {
49
58
self . snapshots += 1 ;
50
- let offsets_start = self . undo_offsets . len ( ) ;
51
- self . undo_offsets . extend_from_slice ( & self . offsets ) ;
52
- Snapshot {
53
- modified_len : self . modified . len ( ) ,
54
- offsets_start,
55
- offsets_len : self . offsets . len ( ) ,
56
- _marker : PhantomData ,
57
- }
59
+ Snapshot { modified_len : self . modified . len ( ) , _marker : PhantomData }
58
60
}
59
61
60
62
pub fn rollback_to ( & mut self , snapshot : Snapshot < T > ) {
61
63
self . snapshots -= 1 ;
62
- for & index in self . modified . iter ( ) . skip ( snapshot. modified_len ) {
63
- self . modified_set . remove ( index) ;
64
- }
65
- self . modified . truncate ( snapshot. modified_len ) ;
66
- let ( offsets, offsets_rest) = self . offsets . split_at_mut ( snapshot. offsets_len ) ;
67
- offsets. copy_from_slice (
68
- & self . undo_offsets
69
- [ snapshot. offsets_start ..snapshot. offsets_start + snapshot. offsets_len ] ,
70
- ) ;
71
- for offset in offsets_rest {
72
- * offset = self . modified . len ( ) . min ( * offset) ;
64
+ if snapshot. modified_len < self . modified . len ( ) {
65
+ for & undo in
66
+ self . modified . iter ( ) . rev ( ) . take ( self . modified . len ( ) - snapshot. modified_len )
67
+ {
68
+ match undo {
69
+ Undo :: Add ( index) => {
70
+ self . modified_set . remove ( index) ;
71
+ }
72
+ Undo :: Drain { index, offset } => {
73
+ if let Some ( o) = self . offsets . get_mut ( index) {
74
+ * o = offset;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ self . modified . truncate ( snapshot. modified_len ) ;
73
80
}
74
- self . undo_offsets . truncate ( snapshot. offsets_start ) ;
75
81
76
82
if self . snapshots == 0 {
77
83
let min = self . offsets . iter ( ) . copied ( ) . min ( ) . unwrap_or ( 0 ) ;
78
- // Any indices still in `modified` may not have been instantiated, so if we observe them again
79
- // we need to notify any listeners again
80
- for index in self . modified . drain ( ..min) {
81
- self . modified_set . remove ( index) ;
82
- }
84
+ self . modified . drain ( ..min) ;
83
85
for offset in & mut self . offsets {
84
86
* offset -= min;
85
87
}
86
88
}
87
89
}
88
90
89
- pub fn commit ( & mut self , snapshot : Snapshot < T > ) {
91
+ pub fn commit ( & mut self , _snapshot : Snapshot < T > ) {
90
92
self . snapshots -= 1 ;
91
- self . undo_offsets . truncate ( snapshot. offsets_start ) ;
92
93
if self . snapshots == 0 {
93
94
// Everything up until this point is committed, so we can forget anything before the
94
95
// current offsets
@@ -102,6 +103,7 @@ impl<T: Idx> ModifiedSet<T> {
102
103
103
104
pub fn register ( & mut self ) -> Offset < T > {
104
105
let index = self . offsets . len ( ) ;
106
+ self . modified . push_back ( Undo :: Drain { index, offset : 0 } ) ;
105
107
self . offsets . push ( 0 ) ;
106
108
Offset { index, _marker : PhantomData }
107
109
}
@@ -131,7 +133,5 @@ impl<T> Drop for Offset<T> {
131
133
#[ derive( Debug ) ]
132
134
pub struct Snapshot < T > {
133
135
modified_len : usize ,
134
- offsets_start : usize ,
135
- offsets_len : usize ,
136
136
_marker : PhantomData < T > ,
137
137
}
0 commit comments