11use super :: OverlayValue ;
22use crate :: DependencyId ;
33
4+ const UNCHANGED : u32 = 0 ;
5+
6+ #[ derive( Debug , Clone ) ]
7+ struct DenseOverlay < V > {
8+ /// Maps a dependency id to an index in `values`. Zero means the base value is unchanged.
9+ value_indices : Vec < u32 > ,
10+ /// Stores only values that differ from the base map.
11+ values : Vec < OverlayValue < V > > ,
12+ }
13+
14+ impl < V > Default for DenseOverlay < V > {
15+ fn default ( ) -> Self {
16+ Self {
17+ value_indices : Vec :: new ( ) ,
18+ values : Vec :: new ( ) ,
19+ }
20+ }
21+ }
22+
23+ impl < V > DenseOverlay < V > {
24+ #[ inline]
25+ fn get ( & self , index : usize ) -> Option < & OverlayValue < V > > {
26+ let value_index = * self . value_indices . get ( index) ?;
27+ if value_index == UNCHANGED {
28+ return None ;
29+ }
30+ self . values . get ( value_index as usize - 1 )
31+ }
32+
33+ #[ inline]
34+ fn get_mut ( & mut self , index : usize ) -> Option < & mut OverlayValue < V > > {
35+ let value_index = * self . value_indices . get ( index) ?;
36+ if value_index == UNCHANGED {
37+ return None ;
38+ }
39+ self . values . get_mut ( value_index as usize - 1 )
40+ }
41+
42+ #[ inline]
43+ fn insert ( & mut self , index : usize , value : OverlayValue < V > ) {
44+ if self . value_indices . len ( ) <= index {
45+ self . value_indices . resize ( index + 1 , UNCHANGED ) ;
46+ }
47+
48+ let value_index = & mut self . value_indices [ index] ;
49+ if * value_index == UNCHANGED {
50+ self . values . push ( value) ;
51+ * value_index = u32:: try_from ( self . values . len ( ) )
52+ . expect ( "dense dependency overlay cannot contain more than u32::MAX values" ) ;
53+ } else {
54+ self . values [ * value_index as usize - 1 ] = value;
55+ }
56+ }
57+ }
58+
459#[ derive( Debug , Clone ) ]
560pub struct DenseDependencyIdOverlayMap < V > {
661 base : Vec < Option < V > > ,
7- overlay : Option < Vec < Option < OverlayValue < V > > > > ,
62+ overlay : Option < DenseOverlay < V > > ,
863}
964
1065impl < V > Default for DenseDependencyIdOverlayMap < V > {
@@ -19,7 +74,7 @@ impl<V> Default for DenseDependencyIdOverlayMap<V> {
1974impl < V > DenseDependencyIdOverlayMap < V > {
2075 #[ inline]
2176 pub fn checkpoint ( & mut self ) {
22- self . overlay . get_or_insert_with ( Vec :: new ) ;
77+ self . overlay . get_or_insert_default ( ) ;
2378 }
2479
2580 #[ inline]
@@ -30,10 +85,8 @@ impl<V> DenseDependencyIdOverlayMap<V> {
3085 #[ inline]
3186 pub fn insert ( & mut self , key : DependencyId , value : V ) {
3287 let index = key. as_u32 ( ) as usize ;
33- if self . overlay . is_some ( ) {
34- Self :: ensure_len ( self . overlay ( ) , index) ;
35- self . overlay . as_mut ( ) . expect ( "overlay checked above" ) [ index] =
36- Some ( OverlayValue :: Value ( value) ) ;
88+ if let Some ( overlay) = & mut self . overlay {
89+ overlay. insert ( index, OverlayValue :: Value ( value) ) ;
3790 } else {
3891 Self :: ensure_len ( & mut self . base , index) ;
3992 self . base [ index] = Some ( value) ;
@@ -43,9 +96,8 @@ impl<V> DenseDependencyIdOverlayMap<V> {
4396 #[ inline]
4497 pub fn remove ( & mut self , key : & DependencyId ) {
4598 let index = key. as_u32 ( ) as usize ;
46- if self . overlay . is_some ( ) {
47- Self :: ensure_len ( self . overlay ( ) , index) ;
48- self . overlay . as_mut ( ) . expect ( "overlay checked above" ) [ index] = Some ( OverlayValue :: Tombstone ) ;
99+ if let Some ( overlay) = & mut self . overlay {
100+ overlay. insert ( index, OverlayValue :: Tombstone ) ;
49101 } else if let Some ( value) = self . base . get_mut ( index) {
50102 * value = None ;
51103 }
@@ -55,7 +107,7 @@ impl<V> DenseDependencyIdOverlayMap<V> {
55107 pub fn get ( & self , key : & DependencyId ) -> Option < & V > {
56108 let index = key. as_u32 ( ) as usize ;
57109 if let Some ( overlay) = & self . overlay
58- && let Some ( Some ( value) ) = overlay. get ( index)
110+ && let Some ( value) = overlay. get ( index)
59111 {
60112 return match value {
61113 OverlayValue :: Value ( value) => Some ( value) ,
@@ -74,7 +126,7 @@ impl<V> DenseDependencyIdOverlayMap<V> {
74126 if self . overlay . is_some ( ) {
75127 self . materialize_overlay_value ( index) ;
76128 let overlay = self . overlay . as_mut ( ) . expect ( "overlay checked above" ) ;
77- match overlay. get_mut ( index) . and_then ( Option :: as_mut ) {
129+ match overlay. get_mut ( index) {
78130 Some ( OverlayValue :: Value ( value) ) => Some ( value) ,
79131 _ => None ,
80132 }
@@ -89,20 +141,18 @@ impl<V> DenseDependencyIdOverlayMap<V> {
89141 V : Clone ,
90142 {
91143 let overlay = self . overlay . as_ref ( ) . expect ( "overlay checked above" ) ;
92- if matches ! ( overlay. get( index) , Some ( Some ( _ ) ) ) {
144+ if overlay. get ( index) . is_some ( ) {
93145 return ;
94146 }
95147
96148 if let Some ( value) = self . base . get ( index) . and_then ( Option :: as_ref) . cloned ( ) {
97- Self :: ensure_len ( self . overlay ( ) , index) ;
98- self . overlay . as_mut ( ) . expect ( "overlay checked above" ) [ index] =
99- Some ( OverlayValue :: Value ( value) ) ;
149+ self . overlay ( ) . insert ( index, OverlayValue :: Value ( value) ) ;
100150 }
101151 }
102152
103153 #[ inline]
104- fn overlay ( & mut self ) -> & mut Vec < Option < OverlayValue < V > > > {
105- self . overlay . get_or_insert_with ( Vec :: new )
154+ fn overlay ( & mut self ) -> & mut DenseOverlay < V > {
155+ self . overlay . get_or_insert_default ( )
106156 }
107157
108158 #[ inline]
@@ -172,4 +222,34 @@ mod tests {
172222
173223 assert_eq ! ( map. get( & a) , Some ( & 1 ) ) ;
174224 }
225+
226+ #[ test]
227+ fn repeated_overlay_writes_reuse_the_value_slot ( ) {
228+ let mut map = DenseDependencyIdOverlayMap :: default ( ) ;
229+ let id = DependencyId :: from ( 7 ) ;
230+
231+ map. checkpoint ( ) ;
232+ map. insert ( id, 1 ) ;
233+ map. insert ( id, 2 ) ;
234+ map. remove ( & id) ;
235+
236+ let overlay = map. overlay . as_ref ( ) . expect ( "should have overlay" ) ;
237+ assert_eq ! ( overlay. value_indices. len( ) , 8 ) ;
238+ assert_eq ! ( overlay. values. len( ) , 1 ) ;
239+ assert_eq ! ( map. get( & id) , None ) ;
240+ }
241+
242+ #[ test]
243+ fn sparse_overlay_stores_only_changed_values ( ) {
244+ let mut map = DenseDependencyIdOverlayMap :: default ( ) ;
245+ let id = DependencyId :: from ( 1024 ) ;
246+
247+ map. checkpoint ( ) ;
248+ map. insert ( id, 1 ) ;
249+
250+ let overlay = map. overlay . as_ref ( ) . expect ( "should have overlay" ) ;
251+ assert_eq ! ( overlay. value_indices. len( ) , 1025 ) ;
252+ assert_eq ! ( overlay. values. len( ) , 1 ) ;
253+ assert_eq ! ( map. get( & id) , Some ( & 1 ) ) ;
254+ }
175255}
0 commit comments