@@ -21,7 +21,8 @@ use alloc::vec::Vec;
2121/// - Keys are invalidated once their value is removed.
2222#[ derive( Debug ) ]
2323pub struct SparseMap < T > {
24- buffer : Vec < Item < T > > ,
24+ buffer : Vec < Option < T > > ,
25+ generations : Vec < u32 > ,
2526 empty_slots : Vec < usize > ,
2627}
2728
@@ -37,56 +38,37 @@ impl<T> SparseMap<T> {
3738 /// its generation counter is incremented to invalidate old keys.
3839 #[ must_use = "The returned key is the only way to reference back the inserted value!" ]
3940 pub fn insert ( & mut self , value : T ) -> Key {
40- self . alloc_slot (
41- value,
42- |value, item| item. replace ( value) ,
43- |value| Item :: new ( value) ,
44- )
41+ self . insert_with_key ( |_, _| value)
4542 }
4643
4744 /// Similar to [`Self::insert()`] but provides a [`Key`] before
4845 /// inserting the value.
49- pub fn insert_with_key < F > ( & mut self , f : F ) -> Key
46+ fn insert_with_key < F > ( & mut self , create : F ) -> Key
5047 where
5148 F : FnOnce ( & mut Self , Key ) -> T ,
5249 {
53- let key = self . alloc_slot (
54- ( ) ,
55- |_ , item| item . replace_empty ( ) ,
56- |_| Item :: new_empty ( ) ,
57- ) ;
50+ if let Some ( index ) = self . empty_slots . pop ( ) {
51+ // Increment the generation counter.
52+ let mut generation = self . generations [ index ] ;
53+ generation = generation . wrapping_add ( 1 ) ;
54+ self . generations [ index ] = generation ;
5855
59- let value = f ( self , key) ;
60- self . buffer [ key. index ] . inner = Some ( value) ;
56+ let key = Key :: new ( index, generation) ;
6157
62- key
63- }
58+ let item = create ( self , key) ;
59+ self . buffer [ index ] = Some ( item ) ;
6460
65- /// Returns [`Key`], reusing a vacant slot or allocating a new one.
66- /// The caller decides how the slot is initialized.
67- ///
68- /// `value`: The inner value to be inserted.
69- /// `replace`: Determine how a vacant slot will be replaced.
70- /// `create`: Determine how a new item will be created.
71- fn alloc_slot < V , R , C > (
72- & mut self ,
73- value : V ,
74- replace : R ,
75- create : C ,
76- ) -> Key
77- where
78- R : FnOnce ( V , & mut Item < T > ) -> u32 ,
79- C : FnOnce ( V ) -> Item < T > ,
80- {
81- if let Some ( index) = self . empty_slots . pop ( ) {
82- let generation = replace ( value, & mut self . buffer [ index] ) ;
83- Key :: new ( index, generation)
61+ key
8462 } else {
8563 let index = self . buffer . len ( ) ;
86- let item = create ( value) ;
87- let generation = item. generation ;
88- self . buffer . push ( item) ;
89- Key :: new ( index, generation)
64+ self . generations . insert ( index, 0 ) ;
65+
66+ let key = Key :: new ( index, 0 ) ;
67+
68+ let item = create ( self , key) ;
69+ self . buffer . insert ( index, Some ( item) ) ;
70+
71+ key
9072 }
9173 }
9274
@@ -104,8 +86,9 @@ impl<T> SparseMap<T> {
10486 /// key if present.
10587 pub fn get ( & self , key : & Key ) -> Option < & T > {
10688 let item = self . buffer . get ( key. index ) ?;
107- if item. generation == key. generation {
108- return item. inner . as_ref ( ) ;
89+ let generation = self . generations . get ( key. index ) ?;
90+ if * generation == key. generation {
91+ return item. as_ref ( ) ;
10992 }
11093
11194 None
@@ -115,8 +98,9 @@ impl<T> SparseMap<T> {
11598 /// if present.
11699 pub fn get_mut ( & mut self , key : & Key ) -> Option < & mut T > {
117100 let item = self . buffer . get_mut ( key. index ) ?;
118- if item. generation == key. generation {
119- return item. inner . as_mut ( ) ;
101+ let generation = self . generations . get ( key. index ) ?;
102+ if * generation == key. generation {
103+ return item. as_mut ( ) ;
120104 }
121105
122106 None
@@ -163,16 +147,19 @@ impl<T> SparseMap<T> {
163147 // SAFETY: We already checked that the key contains a value.
164148 let mut value = self . buffer [ key. index ] . take ( ) . unwrap ( ) ;
165149 let result = f ( self , & mut value) ;
166- self . buffer [ key. index ] . inner = Some ( value) ;
150+ self . buffer [ key. index ] = Some ( value) ;
167151
168152 Some ( result)
169153 }
170154
171155 /// Returns `true` if the key currently refers to a live value.
172156 pub fn contains ( & self , key : & Key ) -> bool {
173- self . buffer . get ( key. index ) . is_some_and ( |item| {
174- item. inner . is_some ( ) && item. generation == key. generation
175- } )
157+ self . buffer
158+ . get ( key. index )
159+ . zip ( self . generations . get ( key. index ) )
160+ . is_some_and ( |( item, generation) | {
161+ item. is_some ( ) && * generation == key. generation
162+ } )
176163 }
177164
178165 /// Returns the number of live values stored in the map.
@@ -192,6 +179,7 @@ impl<T> Default for SparseMap<T> {
192179 fn default ( ) -> Self {
193180 Self {
194181 buffer : Vec :: new ( ) ,
182+ generations : Vec :: new ( ) ,
195183 empty_slots : Vec :: new ( ) ,
196184 }
197185 }
@@ -241,68 +229,6 @@ impl Display for Key {
241229 }
242230}
243231
244- /// A generational slot used internally by [`SparseMap`].
245- ///
246- /// Each `Item` represents a single indexable slot that may or may not
247- /// contain a value. The `generation` counter is incremented whenever
248- /// the slot’s occupancy changes, invalidating any previously issued
249- /// [`Key`] referring to this index.
250- ///
251- /// # Invariants
252- ///
253- /// - `inner.is_some()`: the slot is live.
254- /// - `inner.is_none()`: the slot is vacant and reusable.
255- /// - `generation` is monotonically increasing (wrapping on overflow).
256- #[ derive( Debug ) ]
257- struct Item < T > {
258- /// Stored value for this slot, if any.
259- inner : Option < T > ,
260- /// Generation counter for stale-key detection.
261- generation : u32 ,
262- }
263-
264- impl < T > Item < T > {
265- /// Creates a new occupied slot with generation `0`.
266- const fn new ( value : T ) -> Self {
267- Self {
268- inner : Some ( value) ,
269- generation : 0 ,
270- }
271- }
272-
273- /// Creates a new vacant slot with generation `0`.
274- const fn new_empty ( ) -> Self {
275- Self {
276- inner : None ,
277- generation : 0 ,
278- }
279- }
280-
281- /// Takes the value out of the slot without modifying its
282- /// generation.
283- const fn take ( & mut self ) -> Option < T > {
284- self . inner . take ( )
285- }
286-
287- /// Replaces the slot’s value and increments its generation.
288- ///
289- /// Returns the new generation.
290- fn replace ( & mut self , value : T ) -> u32 {
291- self . inner . replace ( value) ;
292- self . generation = self . generation . wrapping_add ( 1 ) ;
293- self . generation
294- }
295-
296- /// Empties the slot and increments its generation.
297- ///
298- /// Returns the new generation.
299- fn replace_empty ( & mut self ) -> u32 {
300- self . inner = None ;
301- self . generation = self . generation . wrapping_add ( 1 ) ;
302- self . generation
303- }
304- }
305-
306232#[ cfg( test) ]
307233mod tests {
308234 use super :: * ;
@@ -317,21 +243,6 @@ mod tests {
317243 assert_eq ! ( map. len( ) , 1 ) ;
318244 }
319245
320- #[ test]
321- fn insert_with_key_receives_valid_key_before_insert ( ) {
322- let mut map = SparseMap :: new ( ) ;
323-
324- let key = map. insert_with_key ( |map, key| {
325- // Key must already be valid and point to the slot.
326- assert_eq ! ( key. index, 0 ) ;
327- assert ! ( map. buffer[ key. index] . inner. is_none( ) ) ;
328-
329- 42
330- } ) ;
331-
332- assert_eq ! ( map. get( & key) , Some ( & 42 ) ) ;
333- }
334-
335246 #[ test]
336247 fn insert_and_insert_with_key_behave_equivalently ( ) {
337248 let mut map = SparseMap :: new ( ) ;
@@ -342,8 +253,8 @@ mod tests {
342253 assert_eq ! ( k1. index, 0 ) ;
343254 assert_eq ! ( k2. index, 1 ) ;
344255
345- assert_eq ! ( map. buffer[ k1. index] . inner , Some ( 1 ) ) ;
346- assert_eq ! ( map. buffer[ k2. index] . inner , Some ( 2 ) ) ;
256+ assert_eq ! ( map. buffer[ k1. index] , Some ( 1 ) ) ;
257+ assert_eq ! ( map. buffer[ k2. index] , Some ( 2 ) ) ;
347258 }
348259
349260 #[ test]
0 commit comments