@@ -14,6 +14,14 @@ pub(crate) struct SparseArray<I, V = I> {
14
14
marker : PhantomData < I > ,
15
15
}
16
16
17
+ /// A space-optimized version of [`SparseArray`] that cannot be changed
18
+ /// after construction.
19
+ #[ derive( Debug ) ]
20
+ pub ( crate ) struct ImmutableSparseArray < I , V = I > {
21
+ values : Box < [ Option < V > ] > ,
22
+ marker : PhantomData < I > ,
23
+ }
24
+
17
25
impl < I : SparseSetIndex , V > Default for SparseArray < I , V > {
18
26
fn default ( ) -> Self {
19
27
Self :: new ( )
@@ -30,6 +38,27 @@ impl<I, V> SparseArray<I, V> {
30
38
}
31
39
}
32
40
41
+ macro_rules! impl_sparse_array {
42
+ ( $ty: ident) => {
43
+ impl <I : SparseSetIndex , V > $ty<I , V > {
44
+ #[ inline]
45
+ pub fn contains( & self , index: I ) -> bool {
46
+ let index = index. sparse_set_index( ) ;
47
+ self . values. get( index) . map( |v| v. is_some( ) ) . unwrap_or( false )
48
+ }
49
+
50
+ #[ inline]
51
+ pub fn get( & self , index: I ) -> Option <& V > {
52
+ let index = index. sparse_set_index( ) ;
53
+ self . values. get( index) . map( |v| v. as_ref( ) ) . unwrap_or( None )
54
+ }
55
+ }
56
+ } ;
57
+ }
58
+
59
+ impl_sparse_array ! ( SparseArray ) ;
60
+ impl_sparse_array ! ( ImmutableSparseArray ) ;
61
+
33
62
impl < I : SparseSetIndex , V > SparseArray < I , V > {
34
63
#[ inline]
35
64
pub fn insert ( & mut self , index : I , value : V ) {
@@ -40,18 +69,6 @@ impl<I: SparseSetIndex, V> SparseArray<I, V> {
40
69
self . values [ index] = Some ( value) ;
41
70
}
42
71
43
- #[ inline]
44
- pub fn contains ( & self , index : I ) -> bool {
45
- let index = index. sparse_set_index ( ) ;
46
- self . values . get ( index) . map ( |v| v. is_some ( ) ) . unwrap_or ( false )
47
- }
48
-
49
- #[ inline]
50
- pub fn get ( & self , index : I ) -> Option < & V > {
51
- let index = index. sparse_set_index ( ) ;
52
- self . values . get ( index) . map ( |v| v. as_ref ( ) ) . unwrap_or ( None )
53
- }
54
-
55
72
#[ inline]
56
73
pub fn get_mut ( & mut self , index : I ) -> Option < & mut V > {
57
74
let index = index. sparse_set_index ( ) ;
@@ -70,6 +87,13 @@ impl<I: SparseSetIndex, V> SparseArray<I, V> {
70
87
pub fn clear ( & mut self ) {
71
88
self . values . clear ( ) ;
72
89
}
90
+
91
+ pub ( crate ) fn into_immutable ( self ) -> ImmutableSparseArray < I , V > {
92
+ ImmutableSparseArray {
93
+ values : self . values . into_boxed_slice ( ) ,
94
+ marker : PhantomData ,
95
+ }
96
+ }
73
97
}
74
98
75
99
/// A sparse data structure of [Components](crate::component::Component)
@@ -249,11 +273,75 @@ pub struct SparseSet<I, V: 'static> {
249
273
sparse : SparseArray < I , usize > ,
250
274
}
251
275
276
+ /// A space-optimized version of [`SparseSet`] that cannot be changed
277
+ /// after construction.
278
+ #[ derive( Debug ) ]
279
+ pub ( crate ) struct ImmutableSparseSet < I , V : ' static > {
280
+ dense : Box < [ V ] > ,
281
+ indices : Box < [ I ] > ,
282
+ sparse : ImmutableSparseArray < I , usize > ,
283
+ }
284
+
285
+ macro_rules! impl_sparse_set {
286
+ ( $ty: ident) => {
287
+ impl <I : SparseSetIndex , V > $ty<I , V > {
288
+ #[ inline]
289
+ pub fn len( & self ) -> usize {
290
+ self . dense. len( )
291
+ }
292
+
293
+ #[ inline]
294
+ pub fn contains( & self , index: I ) -> bool {
295
+ self . sparse. contains( index)
296
+ }
297
+
298
+ pub fn get( & self , index: I ) -> Option <& V > {
299
+ self . sparse. get( index) . map( |dense_index| {
300
+ // SAFETY: if the sparse index points to something in the dense vec, it exists
301
+ unsafe { self . dense. get_unchecked( * dense_index) }
302
+ } )
303
+ }
304
+
305
+ pub fn get_mut( & mut self , index: I ) -> Option <& mut V > {
306
+ let dense = & mut self . dense;
307
+ self . sparse. get( index) . map( move |dense_index| {
308
+ // SAFETY: if the sparse index points to something in the dense vec, it exists
309
+ unsafe { dense. get_unchecked_mut( * dense_index) }
310
+ } )
311
+ }
312
+
313
+ pub fn indices( & self ) -> impl Iterator <Item = I > + ' _ {
314
+ self . indices. iter( ) . cloned( )
315
+ }
316
+
317
+ pub fn values( & self ) -> impl Iterator <Item = & V > {
318
+ self . dense. iter( )
319
+ }
320
+
321
+ pub fn values_mut( & mut self ) -> impl Iterator <Item = & mut V > {
322
+ self . dense. iter_mut( )
323
+ }
324
+
325
+ pub fn iter( & self ) -> impl Iterator <Item = ( & I , & V ) > {
326
+ self . indices. iter( ) . zip( self . dense. iter( ) )
327
+ }
328
+
329
+ pub fn iter_mut( & mut self ) -> impl Iterator <Item = ( & I , & mut V ) > {
330
+ self . indices. iter( ) . zip( self . dense. iter_mut( ) )
331
+ }
332
+ }
333
+ } ;
334
+ }
335
+
336
+ impl_sparse_set ! ( SparseSet ) ;
337
+ impl_sparse_set ! ( ImmutableSparseSet ) ;
338
+
252
339
impl < I : SparseSetIndex , V > Default for SparseSet < I , V > {
253
340
fn default ( ) -> Self {
254
341
Self :: new ( )
255
342
}
256
343
}
344
+
257
345
impl < I , V > SparseSet < I , V > {
258
346
pub const fn new ( ) -> Self {
259
347
Self {
@@ -306,36 +394,11 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
306
394
}
307
395
}
308
396
309
- #[ inline]
310
- pub fn len ( & self ) -> usize {
311
- self . dense . len ( )
312
- }
313
-
314
397
#[ inline]
315
398
pub fn is_empty ( & self ) -> bool {
316
399
self . dense . len ( ) == 0
317
400
}
318
401
319
- #[ inline]
320
- pub fn contains ( & self , index : I ) -> bool {
321
- self . sparse . contains ( index)
322
- }
323
-
324
- pub fn get ( & self , index : I ) -> Option < & V > {
325
- self . sparse . get ( index) . map ( |dense_index| {
326
- // SAFETY: if the sparse index points to something in the dense vec, it exists
327
- unsafe { self . dense . get_unchecked ( * dense_index) }
328
- } )
329
- }
330
-
331
- pub fn get_mut ( & mut self , index : I ) -> Option < & mut V > {
332
- let dense = & mut self . dense ;
333
- self . sparse . get ( index) . map ( move |dense_index| {
334
- // SAFETY: if the sparse index points to something in the dense vec, it exists
335
- unsafe { dense. get_unchecked_mut ( * dense_index) }
336
- } )
337
- }
338
-
339
402
pub fn remove ( & mut self , index : I ) -> Option < V > {
340
403
self . sparse . remove ( index) . map ( |dense_index| {
341
404
let is_last = dense_index == self . dense . len ( ) - 1 ;
@@ -349,24 +412,12 @@ impl<I: SparseSetIndex, V> SparseSet<I, V> {
349
412
} )
350
413
}
351
414
352
- pub fn indices ( & self ) -> impl Iterator < Item = I > + ' _ {
353
- self . indices . iter ( ) . cloned ( )
354
- }
355
-
356
- pub fn values ( & self ) -> impl Iterator < Item = & V > {
357
- self . dense . iter ( )
358
- }
359
-
360
- pub fn values_mut ( & mut self ) -> impl Iterator < Item = & mut V > {
361
- self . dense . iter_mut ( )
362
- }
363
-
364
- pub fn iter ( & self ) -> impl Iterator < Item = ( & I , & V ) > {
365
- self . indices . iter ( ) . zip ( self . dense . iter ( ) )
366
- }
367
-
368
- pub fn iter_mut ( & mut self ) -> impl Iterator < Item = ( & I , & mut V ) > {
369
- self . indices . iter ( ) . zip ( self . dense . iter_mut ( ) )
415
+ pub ( crate ) fn into_immutable ( self ) -> ImmutableSparseSet < I , V > {
416
+ ImmutableSparseSet {
417
+ dense : self . dense . into_boxed_slice ( ) ,
418
+ indices : self . indices . into_boxed_slice ( ) ,
419
+ sparse : self . sparse . into_immutable ( ) ,
420
+ }
370
421
}
371
422
}
372
423
0 commit comments