@@ -2,12 +2,17 @@ use std::{collections::VecDeque, marker::PhantomData};
22
33use rustc_index:: { bit_set:: BitSet , vec:: Idx } ;
44
5+ #[ derive( Copy , Clone , Debug ) ]
6+ enum Undo < T > {
7+ Add ( T ) ,
8+ Drain { index : usize , offset : usize } ,
9+ }
10+
511#[ derive( Clone , Debug ) ]
612pub struct ModifiedSet < T : Idx > {
7- modified : VecDeque < T > ,
13+ modified : VecDeque < Undo < T > > ,
814 snapshots : usize ,
915 modified_set : BitSet < T > ,
10- undo_offsets : Vec < usize > ,
1116 offsets : Vec < usize > ,
1217}
1318
@@ -18,7 +23,6 @@ impl<T: Idx> Default for ModifiedSet<T> {
1823 snapshots : 0 ,
1924 modified_set : BitSet :: new_empty ( 0 ) ,
2025 offsets : Vec :: new ( ) ,
21- undo_offsets : Vec :: new ( ) ,
2226 }
2327 }
2428}
@@ -33,62 +37,59 @@ impl<T: Idx> ModifiedSet<T> {
3337 self . modified_set . resize ( index. index ( ) + 1 ) ;
3438 }
3539 if self . modified_set . insert ( index) {
36- self . modified . push_back ( index) ;
40+ self . modified . push_back ( Undo :: Add ( index) ) ;
3741 }
3842 }
3943
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 ( ) ;
4454 }
45- * offset = self . modified . len ( ) ;
4655 }
4756
4857 pub fn snapshot ( & mut self ) -> Snapshot < T > {
4958 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 }
5860 }
5961
6062 pub fn rollback_to ( & mut self , snapshot : Snapshot < T > ) {
6163 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 ) ;
7380 }
74- self . undo_offsets . truncate ( snapshot. offsets_start ) ;
7581
7682 if self . snapshots == 0 {
7783 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) ;
8385 for offset in & mut self . offsets {
8486 * offset -= min;
8587 }
8688 }
8789 }
8890
89- pub fn commit ( & mut self , snapshot : Snapshot < T > ) {
91+ pub fn commit ( & mut self , _snapshot : Snapshot < T > ) {
9092 self . snapshots -= 1 ;
91- self . undo_offsets . truncate ( snapshot. offsets_start ) ;
9293 if self . snapshots == 0 {
9394 // Everything up until this point is committed, so we can forget anything before the
9495 // current offsets
@@ -102,6 +103,7 @@ impl<T: Idx> ModifiedSet<T> {
102103
103104 pub fn register ( & mut self ) -> Offset < T > {
104105 let index = self . offsets . len ( ) ;
106+ self . modified . push_back ( Undo :: Drain { index, offset : 0 } ) ;
105107 self . offsets . push ( 0 ) ;
106108 Offset { index, _marker : PhantomData }
107109 }
@@ -131,7 +133,5 @@ impl<T> Drop for Offset<T> {
131133#[ derive( Debug ) ]
132134pub struct Snapshot < T > {
133135 modified_len : usize ,
134- offsets_start : usize ,
135- offsets_len : usize ,
136136 _marker : PhantomData < T > ,
137137}
0 commit comments