Skip to main content

bevy_ecs/storage/
sparse_set.rs

1use crate::{
2    change_detection::{CheckChangeTicks, ComponentTickCells, ComponentTicks, MaybeLocation, Tick},
3    component::{ComponentId, ComponentInfo},
4    entity::{Entity, EntityIndex},
5    query::DebugCheckedUnwrap,
6    storage::{AbortOnPanic, Column, TableRow, VecExtensions},
7};
8use alloc::{boxed::Box, vec::Vec};
9use bevy_ptr::{OwningPtr, Ptr};
10use core::{cell::UnsafeCell, hash::Hash, marker::PhantomData, num::NonZero, panic::Location};
11use nonmax::{NonMaxU32, NonMaxUsize};
12
13/// A map from `I` to `V` implemented as a `Vec<Option<V>>`.
14///
15/// The key type, `I`, must implement [`SparseSetIndex`]
16/// to allow conversion to and from array indexes.
17///
18/// This supports fast O(1) lookups, since they are simple
19/// array indexing operations with no calculations.
20///
21/// However, it may use a lot of excess memory if the
22/// values are large or the set is sparsely populated.
23#[derive(Debug)]
24pub(crate) struct SparseArray<I, V = I> {
25    values: Vec<Option<V>>,
26    marker: PhantomData<I>,
27}
28
29/// A map from `I` to `V` implemented as a `Box<[Option<V>]>`.
30///
31/// This uses less space than [`SparseArray`] because it does not
32/// need to store both length and capacity,
33/// but it cannot be changed after construction.
34///
35/// The key type, `I`, must implement [`SparseSetIndex`]
36/// to allow conversion to and from array indexes.
37///
38/// This supports fast O(1) lookups, since they are simple
39/// array indexing operations with no calculations.
40///
41/// However, it may use a lot of excess memory if the
42/// values are large or the set is sparsely populated.
43
44#[derive(Debug)]
45pub(crate) struct ImmutableSparseArray<I, V = I> {
46    values: Box<[Option<V>]>,
47    marker: PhantomData<I>,
48}
49
50impl<I: SparseSetIndex, V> Default for SparseArray<I, V> {
51    fn default() -> Self {
52        Self::new()
53    }
54}
55
56impl<I, V> SparseArray<I, V> {
57    #[inline]
58    pub const fn new() -> Self {
59        Self {
60            values: Vec::new(),
61            marker: PhantomData,
62        }
63    }
64}
65
66macro_rules! impl_sparse_array {
67    ($ty:ident) => {
68        impl<I: SparseSetIndex, V> $ty<I, V> {
69            /// Returns `true` if the collection contains a value for the specified `index`.
70            #[inline]
71            pub fn contains(&self, index: I) -> bool {
72                let index = index.sparse_set_index();
73                self.values.get(index).is_some_and(Option::is_some)
74            }
75
76            /// Returns a reference to the value at `index`.
77            ///
78            /// Returns `None` if `index` does not have a value or if `index` is out of bounds.
79            #[inline]
80            pub fn get(&self, index: I) -> Option<&V> {
81                let index = index.sparse_set_index();
82                self.values.get(index).and_then(Option::as_ref)
83            }
84        }
85    };
86}
87
88impl_sparse_array!(SparseArray);
89impl_sparse_array!(ImmutableSparseArray);
90
91impl<I: SparseSetIndex, V> SparseArray<I, V> {
92    /// Inserts `value` at `index` in the array.
93    ///
94    /// # Panics
95    /// - Panics if the insertion forces a reallocation, and any of the new capacity overflows `isize::MAX` bytes.
96    /// - Panics if the insertion forces a reallocation, and any of the new the reallocations causes an out-of-memory error.
97    ///
98    /// If `index` is out-of-bounds, this will enlarge the buffer to accommodate it.
99    #[inline]
100    pub fn insert(&mut self, index: I, value: V) {
101        let index = index.sparse_set_index();
102        if index >= self.values.len() {
103            self.values.resize_with(index + 1, || None);
104        }
105        self.values[index] = Some(value);
106    }
107
108    /// Returns a mutable reference to the value at `index`.
109    ///
110    /// Returns `None` if `index` does not have a value or if `index` is out of bounds.
111    #[inline]
112    pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
113        let index = index.sparse_set_index();
114        self.values.get_mut(index).and_then(Option::as_mut)
115    }
116
117    /// Removes and returns the value stored at `index`.
118    ///
119    /// Returns `None` if `index` did not have a value or if `index` is out of bounds.
120    #[inline]
121    pub fn remove(&mut self, index: I) -> Option<V> {
122        let index = index.sparse_set_index();
123        self.values.get_mut(index).and_then(Option::take)
124    }
125
126    /// Removes all of the values stored within.
127    pub fn clear(&mut self) {
128        self.values.clear();
129    }
130
131    /// Converts the [`SparseArray`] into an immutable variant.
132    pub(crate) fn into_immutable(self) -> ImmutableSparseArray<I, V> {
133        ImmutableSparseArray {
134            values: self.values.into_boxed_slice(),
135            marker: PhantomData,
136        }
137    }
138
139    /// Returns an iterator over the non-empty values in the array.
140    ///
141    /// This must scan the entire array to find non-empty values,
142    /// which may be slow even if the array is sparsely populated.
143    #[inline]
144    pub(crate) fn iter(&self) -> impl Iterator<Item = (I, &V)> {
145        self.values.iter().enumerate().filter_map(|(index, value)| {
146            value
147                .as_ref()
148                .map(|value| (SparseSetIndex::get_sparse_set_index(index), value))
149        })
150    }
151}
152
153/// A sparse data structure of [`Component`](crate::component::Component)s.
154///
155/// Designed for relatively fast insertions and deletions.
156#[derive(Debug)]
157pub struct ComponentSparseSet {
158    /// Capacity and length match those of `entities`.
159    dense: Column,
160    // Internally this only relies on the Entity index to keep track of where the component data is
161    // stored for entities that are alive. The generation is not required, but is stored
162    // in debug builds to validate that access is correct.
163    #[cfg(not(debug_assertions))]
164    entities: Vec<EntityIndex>,
165    #[cfg(debug_assertions)]
166    entities: Vec<Entity>,
167    sparse: SparseArray<EntityIndex, TableRow>,
168}
169
170impl ComponentSparseSet {
171    /// Creates a new [`ComponentSparseSet`] with a given component type layout and
172    /// initial `capacity`.
173    pub(crate) fn new(component_info: &ComponentInfo, capacity: usize) -> Self {
174        let entities = Vec::with_capacity(capacity);
175        Self {
176            dense: Column::with_capacity(component_info, entities.capacity()),
177            entities,
178            sparse: Default::default(),
179        }
180    }
181
182    /// Removes all of the values stored within.
183    pub(crate) fn clear(&mut self) {
184        // SAFETY: This is using the size of the ComponentSparseSet.
185        unsafe { self.dense.clear(self.len()) };
186        self.entities.clear();
187        self.sparse.clear();
188    }
189
190    /// Returns the number of component values in the sparse set.
191    #[inline]
192    pub fn len(&self) -> usize {
193        self.entities.len()
194    }
195
196    /// Returns `true` if the sparse set contains no component values.
197    #[inline]
198    pub fn is_empty(&self) -> bool {
199        self.entities.is_empty()
200    }
201
202    /// Inserts the `entity` key and component `value` pair into this sparse
203    /// set.
204    ///
205    /// # Aborts
206    /// - Aborts the process if the insertion forces a reallocation, and any of the new capacity overflows `isize::MAX` bytes.
207    /// - Aborts the process if the insertion forces a reallocation, and any of the new the reallocations causes an out-of-memory error.
208    ///
209    /// # Safety
210    /// The `value` pointer must point to a valid address that matches the [`Layout`](std::alloc::Layout)
211    /// inside the [`ComponentInfo`] given when constructing this sparse set.
212    pub(crate) unsafe fn insert(
213        &mut self,
214        entity: Entity,
215        value: OwningPtr<'_>,
216        change_tick: Tick,
217        caller: MaybeLocation,
218    ) {
219        if let Some(&dense_index) = self.sparse.get(entity.index()) {
220            #[cfg(debug_assertions)]
221            assert_eq!(entity, self.entities[dense_index.index()]);
222            self.dense.replace(dense_index, value, change_tick, caller);
223        } else {
224            let dense_index = self.entities.len();
225            let capacity = self.entities.capacity();
226
227            #[cfg(not(debug_assertions))]
228            self.entities.push(entity.index());
229            #[cfg(debug_assertions)]
230            self.entities.push(entity);
231
232            // If any of the following operations panic due to an allocation error, the state
233            // of the `ComponentSparseSet` will be left in an invalid state and potentially cause UB.
234            // We create an AbortOnPanic guard to force panics to terminate the process if this occurs.
235            let _guard = AbortOnPanic;
236            if capacity != self.entities.capacity() {
237                // SAFETY: An entity was just pushed onto `entities`, its capacity cannot be zero.
238                let new_capacity = unsafe { NonZero::new_unchecked(self.entities.capacity()) };
239                if let Some(capacity) = NonZero::new(capacity) {
240                    // SAFETY: This is using the capacity of the previous allocation.
241                    unsafe { self.dense.realloc(capacity, new_capacity) };
242                } else {
243                    self.dense.alloc(new_capacity);
244                }
245            }
246
247            // SAFETY: This entity index does not exist here yet, so there are no duplicates,
248            // and the entity index is `NonMaxU32` so the length must not be max either.
249            let table_row = unsafe { TableRow::new(NonMaxU32::new_unchecked(dense_index as u32)) };
250            self.dense.initialize(table_row, value, change_tick, caller);
251            self.sparse.insert(entity.index(), table_row);
252
253            core::mem::forget(_guard);
254        }
255    }
256
257    /// Returns `true` if the sparse set has a component value for the provided `entity`.
258    #[inline]
259    pub fn contains(&self, entity: Entity) -> bool {
260        #[cfg(debug_assertions)]
261        {
262            if let Some(&dense_index) = self.sparse.get(entity.index()) {
263                #[cfg(debug_assertions)]
264                assert_eq!(entity, self.entities[dense_index.index()]);
265                true
266            } else {
267                false
268            }
269        }
270        #[cfg(not(debug_assertions))]
271        self.sparse.contains(entity.index())
272    }
273
274    /// Returns a reference to the entity's component value.
275    ///
276    /// Returns `None` if `entity` does not have a component in the sparse set.
277    #[inline]
278    pub fn get(&self, entity: Entity) -> Option<Ptr<'_>> {
279        self.sparse.get(entity.index()).map(|&dense_index| {
280            #[cfg(debug_assertions)]
281            assert_eq!(entity, self.entities[dense_index.index()]);
282            // SAFETY: if the sparse index points to something in the dense vec, it exists
283            unsafe { self.dense.get_data_unchecked(dense_index) }
284        })
285    }
286
287    /// Returns references to the entity's component value and its added and changed ticks.
288    ///
289    /// Returns `None` if `entity` does not have a component in the sparse set.
290    #[inline]
291    pub fn get_with_ticks(&self, entity: Entity) -> Option<(Ptr<'_>, ComponentTickCells<'_>)> {
292        let dense_index = *self.sparse.get(entity.index())?;
293        #[cfg(debug_assertions)]
294        assert_eq!(entity, self.entities[dense_index.index()]);
295        // SAFETY: if the sparse index points to something in the dense vec, it exists
296        unsafe {
297            Some((
298                self.dense.get_data_unchecked(dense_index),
299                ComponentTickCells {
300                    added: self.dense.get_added_tick_unchecked(dense_index),
301                    changed: self.dense.get_changed_tick_unchecked(dense_index),
302                    changed_by: self.dense.get_changed_by_unchecked(dense_index),
303                },
304            ))
305        }
306    }
307
308    /// Returns a reference to the "added" tick of the entity's component value.
309    ///
310    /// Returns `None` if `entity` does not have a component in the sparse set.
311    #[inline]
312    pub fn get_added_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
313        let dense_index = *self.sparse.get(entity.index())?;
314        #[cfg(debug_assertions)]
315        assert_eq!(entity, self.entities[dense_index.index()]);
316        // SAFETY: if the sparse index points to something in the dense vec, it exists
317        unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
318    }
319
320    /// Returns a reference to the "changed" tick of the entity's component value.
321    ///
322    /// Returns `None` if `entity` does not have a component in the sparse set.
323    #[inline]
324    pub fn get_changed_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
325        let dense_index = *self.sparse.get(entity.index())?;
326        #[cfg(debug_assertions)]
327        assert_eq!(entity, self.entities[dense_index.index()]);
328        // SAFETY: if the sparse index points to something in the dense vec, it exists
329        unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
330    }
331
332    /// Returns a reference to the "added" and "changed" ticks of the entity's component value.
333    ///
334    /// Returns `None` if `entity` does not have a component in the sparse set.
335    #[inline]
336    pub fn get_ticks(&self, entity: Entity) -> Option<ComponentTicks> {
337        let dense_index = *self.sparse.get(entity.index())?;
338        #[cfg(debug_assertions)]
339        assert_eq!(entity, self.entities[dense_index.index()]);
340        // SAFETY: if the sparse index points to something in the dense vec, it exists
341        unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
342    }
343
344    /// Returns a reference to the calling location that last changed the entity's component value.
345    ///
346    /// Returns `None` if `entity` does not have a component in the sparse set.
347    #[inline]
348    pub fn get_changed_by(
349        &self,
350        entity: Entity,
351    ) -> MaybeLocation<Option<&UnsafeCell<&'static Location<'static>>>> {
352        MaybeLocation::new_with_flattened(|| {
353            let dense_index = *self.sparse.get(entity.index())?;
354            #[cfg(debug_assertions)]
355            assert_eq!(entity, self.entities[dense_index.index()]);
356            // SAFETY: if the sparse index points to something in the dense vec, it exists
357            unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
358        })
359    }
360
361    /// Returns the drop function for the component type stored in the sparse set,
362    /// or `None` if it doesn't need to be dropped.
363    #[inline]
364    pub fn get_drop(&self) -> Option<unsafe fn(OwningPtr<'_>)> {
365        self.dense.get_drop()
366    }
367
368    /// Removes the `entity` from this sparse set and returns a pointer to the associated value (if
369    /// it exists).
370    #[must_use = "The returned pointer must be used to drop the removed component."]
371    pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
372        self.sparse.remove(entity.index()).map(|dense_index| {
373            #[cfg(debug_assertions)]
374            assert_eq!(entity, self.entities[dense_index.index()]);
375            let last = self.entities.len() - 1;
376            if dense_index.index() >= last {
377                #[cfg(debug_assertions)]
378                assert_eq!(dense_index.index(), last);
379                // SAFETY: This is strictly decreasing the length, so it cannot outgrow
380                // it also cannot underflow as an item was just removed from the sparse array.
381                unsafe { self.entities.set_len(last) };
382                // SAFETY: `last` is guaranteed to be the last element in `dense` as the length is synced with
383                // the `entities` store.
384                unsafe {
385                    self.dense
386                        .get_data_unchecked(dense_index)
387                        .assert_unique()
388                        .promote()
389                }
390            } else {
391                // SAFETY: The above check ensures that `dense_index` and the last element are not
392                // overlapping, and thus also within bounds.
393                unsafe {
394                    self.entities
395                        .swap_remove_nonoverlapping_unchecked(dense_index.index());
396                };
397                // SAFETY: The above check ensures that `dense_index` is in bounds.
398                let swapped_entity = unsafe { self.entities.get_unchecked(dense_index.index()) };
399                #[cfg(not(debug_assertions))]
400                let index = *swapped_entity;
401                #[cfg(debug_assertions)]
402                let index = swapped_entity.index();
403                // SAFETY: The swapped entity was just fetched from the entity Vec, it must have already
404                // been inserted and in bounds.
405                unsafe {
406                    *self.sparse.get_mut(index).debug_checked_unwrap() = dense_index;
407                }
408                // SAFETY: The above check ensures that `dense_index` and the last element are not
409                // overlapping, and thus also within bounds.
410                unsafe {
411                    self.dense
412                        .swap_remove_and_forget_unchecked_nonoverlapping(last, dense_index)
413                }
414            }
415        })
416    }
417
418    /// Removes (and drops) the entity's component value from the sparse set.
419    ///
420    /// Returns `true` if `entity` had a component value in the sparse set.
421    pub(crate) fn remove(&mut self, entity: Entity) -> bool {
422        self.sparse
423            .remove(entity.index())
424            .map(|dense_index| {
425                #[cfg(debug_assertions)]
426                assert_eq!(entity, self.entities[dense_index.index()]);
427                let last = self.entities.len() - 1;
428                if dense_index.index() >= last {
429                    #[cfg(debug_assertions)]
430                    assert_eq!(dense_index.index(), last);
431                    // SAFETY: This is strictly decreasing the length, so it cannot outgrow
432                    // it also cannot underflow as an item was just removed from the sparse array.
433                    unsafe { self.entities.set_len(last) };
434                    // SAFETY: `last` is guaranteed to be the last element in `dense` as the length is synced with
435                    // the `entities` store.
436                    unsafe { self.dense.drop_last_component(last) };
437                } else {
438                    // SAFETY: The above check ensures that `dense_index` and the last element are not
439                    // overlapping, and thus also within bounds.
440                    unsafe {
441                        self.entities
442                            .swap_remove_nonoverlapping_unchecked(dense_index.index());
443                    };
444                    let swapped_entity =
445                        // SAFETY: The above check ensures that `dense_index` is in bounds.
446                        unsafe { self.entities.get_unchecked(dense_index.index()) };
447                    #[cfg(not(debug_assertions))]
448                    let index = *swapped_entity;
449                    #[cfg(debug_assertions)]
450                    let index = swapped_entity.index();
451                    // SAFETY: The swapped entity was just fetched from the entity Vec, it must have already
452                    // been inserted and in bounds.
453                    unsafe {
454                        *self.sparse.get_mut(index).debug_checked_unwrap() = dense_index;
455                    }
456                    // SAFETY: The above check ensures that `dense_index` and the last element are not
457                    // overlapping, and thus also within bounds.
458                    unsafe {
459                        self.dense
460                            .swap_remove_and_drop_unchecked_nonoverlapping(last, dense_index);
461                    }
462                }
463            })
464            .is_some()
465    }
466
467    pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
468        // SAFETY: This is using the valid size of the column.
469        unsafe { self.dense.check_change_ticks(self.len(), check) };
470    }
471}
472
473impl Drop for ComponentSparseSet {
474    fn drop(&mut self) {
475        let len = self.entities.len();
476        self.entities.clear();
477        // SAFETY: `cap` and `len` are correct. `dense` is never accessed again after this call.
478        unsafe {
479            self.dense.drop(self.entities.capacity(), len);
480        }
481    }
482}
483
484/// A map from `I` to `V` that combines dense and sparse storage.
485///
486/// This is implemented as a sparse array mapping keys to dense indexes,
487/// plus dense arrays of indexes and keys.
488///
489/// The key type, `I`, must implement [`SparseSetIndex`]
490/// to allow conversion to and from array indexes.
491///
492/// This supports fast O(1) lookups, since they consist of one array index to map
493/// the key to a dense index, followed by a second array index to find the value.
494///
495/// This may use a lot of excess memory if the set is sparsely populated,
496/// since it stores an empty entry for each key.
497///
498/// Compared to a simple `Vec<Option<V>>`,
499/// the dense storage of values takes less memory when `V` is large,
500/// although the overhead of tracking which entries have values
501/// may make it larger when `V` is small or the set is densely populated.
502#[derive(Debug)]
503pub struct SparseSet<I, V: 'static> {
504    /// The mapping from dense index to value.
505    ///
506    /// `dense[sparse[k]]` holds the value for `k`.
507    dense: Vec<V>,
508
509    /// The reverse mapping from dense index to key.
510    ///
511    /// `indices[sparse[k]] == k`
512    indices: Vec<I>,
513
514    /// The mapping from keys to dense indexes.
515    sparse: SparseArray<I, NonMaxUsize>,
516}
517
518/// A map from `I` to `V` that combines dense and sparse storage.
519///
520/// This is implemented as a sparse array mapping keys to dense indexes,
521/// plus dense arrays of indexes and keys.
522///
523/// This uses less space than [`SparseSet`] because it does not
524/// need to store both length and capacity,
525/// but it cannot be changed after construction.
526///
527/// The key type, `I`, must implement [`SparseSetIndex`]
528/// to allow conversion to and from array indexes.
529///
530/// This supports fast O(1) lookups, since they consist of one array index to map
531/// the key to a dense index, followed by a second array index to find the value.
532///
533/// This may use a lot of excess memory if the set is sparsely populated,
534/// since it stores an empty entry for each key.
535///
536/// Compared to a simple `Vec<Option<V>>`,
537/// the dense storage of values takes less memory when `V` is large,
538/// although the overhead of tracking which entries have values
539/// may make it larger when `V` is small or the set is densely populated.
540#[derive(Debug)]
541pub(crate) struct ImmutableSparseSet<I, V: 'static> {
542    /// The mapping from dense index to value.
543    ///
544    /// `dense[sparse[k]]` holds the value for `k`.
545    dense: Box<[V]>,
546
547    /// The reverse mapping from dense index to key.
548    ///
549    /// `indices[sparse[k]] == k`
550    indices: Box<[I]>,
551
552    /// The mapping from keys to dense indexes.
553    sparse: ImmutableSparseArray<I, NonMaxUsize>,
554}
555
556macro_rules! impl_sparse_set {
557    ($ty:ident) => {
558        impl<I: SparseSetIndex, V> $ty<I, V> {
559            /// Returns the number of elements in the sparse set.
560            #[inline]
561            pub fn len(&self) -> usize {
562                self.dense.len()
563            }
564
565            /// Returns `true` if the sparse set contains a value for `index`.
566            #[inline]
567            pub fn contains(&self, index: I) -> bool {
568                self.sparse.contains(index)
569            }
570
571            /// Returns a reference to the value for `index`.
572            ///
573            /// Returns `None` if `index` does not have a value in the sparse set.
574            pub fn get(&self, index: I) -> Option<&V> {
575                self.sparse.get(index).map(|dense_index| {
576                    // SAFETY: if the sparse index points to something in the dense vec, it exists
577                    unsafe { self.dense.get_unchecked(dense_index.get()) }
578                })
579            }
580
581            /// Returns a mutable reference to the value for `index`.
582            ///
583            /// Returns `None` if `index` does not have a value in the sparse set.
584            pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
585                let dense = &mut self.dense;
586                self.sparse.get(index).map(move |dense_index| {
587                    // SAFETY: if the sparse index points to something in the dense vec, it exists
588                    unsafe { dense.get_unchecked_mut(dense_index.get()) }
589                })
590            }
591
592            /// Returns an iterator visiting all keys (indices) in arbitrary order.
593            pub fn indices(&self) -> &[I] {
594                &self.indices
595            }
596
597            /// Returns an iterator visiting all values in arbitrary order.
598            pub fn values(&self) -> impl Iterator<Item = &V> {
599                self.dense.iter()
600            }
601
602            /// Returns an iterator visiting all values mutably in arbitrary order.
603            pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
604                self.dense.iter_mut()
605            }
606
607            /// Returns an iterator visiting all key-value pairs in arbitrary order, with references to the values.
608            pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
609                self.indices.iter().zip(self.dense.iter())
610            }
611
612            /// Returns an iterator visiting all key-value pairs in arbitrary order, with mutable references to the values.
613            pub fn iter_mut(&mut self) -> impl Iterator<Item = (&I, &mut V)> {
614                self.indices.iter().zip(self.dense.iter_mut())
615            }
616        }
617    };
618}
619
620impl_sparse_set!(SparseSet);
621impl_sparse_set!(ImmutableSparseSet);
622
623impl<I: SparseSetIndex, V> Default for SparseSet<I, V> {
624    fn default() -> Self {
625        Self::new()
626    }
627}
628
629impl<I, V> SparseSet<I, V> {
630    /// Creates a new [`SparseSet`].
631    pub const fn new() -> Self {
632        Self {
633            dense: Vec::new(),
634            indices: Vec::new(),
635            sparse: SparseArray::new(),
636        }
637    }
638}
639
640impl<I: SparseSetIndex, V> SparseSet<I, V> {
641    /// Creates a new [`SparseSet`] with a specified initial capacity.
642    ///
643    /// # Panics
644    /// - Panics if the new capacity of the allocation overflows `isize::MAX` bytes.
645    /// - Panics if the new allocation causes an out-of-memory error.
646    pub fn with_capacity(capacity: usize) -> Self {
647        Self {
648            dense: Vec::with_capacity(capacity),
649            indices: Vec::with_capacity(capacity),
650            sparse: Default::default(),
651        }
652    }
653
654    /// Returns the total number of elements the [`SparseSet`] can hold without needing to reallocate.
655    #[inline]
656    pub fn capacity(&self) -> usize {
657        self.dense.capacity()
658    }
659
660    /// Inserts `value` at `index`.
661    ///
662    /// If a value was already present at `index`, it will be overwritten.
663    ///
664    /// # Panics
665    /// - Panics if the insertion forces an reallocation and the new capacity overflows `isize::MAX` bytes.
666    /// - Panics if the insertion forces an reallocation and causes an out-of-memory error.
667    pub fn insert(&mut self, index: I, value: V) {
668        if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
669            // SAFETY: dense indices stored in self.sparse always exist
670            unsafe {
671                *self.dense.get_unchecked_mut(dense_index.get()) = value;
672            }
673        } else {
674            self.sparse
675                .insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
676            self.indices.push(index);
677            self.dense.push(value);
678        }
679    }
680
681    /// Returns a reference to the value for `index`, inserting one computed from `func`
682    /// if not already present.
683    ///
684    /// # Panics
685    /// - Panics if the insertion forces an reallocation and the new capacity overflows `isize::MAX` bytes.
686    /// - Panics if the insertion forces an reallocation and causes an out-of-memory error.
687    pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
688        if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
689            // SAFETY: dense indices stored in self.sparse always exist
690            unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
691        } else {
692            let value = func();
693            let dense_index = self.dense.len();
694            self.sparse
695                .insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
696            self.indices.push(index);
697            self.dense.push(value);
698            // SAFETY: dense index was just populated above
699            unsafe { self.dense.get_unchecked_mut(dense_index) }
700        }
701    }
702
703    /// Returns `true` if the sparse set contains no elements.
704    #[inline]
705    pub fn is_empty(&self) -> bool {
706        self.dense.len() == 0
707    }
708
709    /// Removes and returns the value for `index`.
710    ///
711    /// Returns `None` if `index` does not have a value in the sparse set.
712    pub fn remove(&mut self, index: I) -> Option<V> {
713        self.sparse.remove(index).map(|dense_index| {
714            let index = dense_index.get();
715            let is_last = index == self.dense.len() - 1;
716            let value = self.dense.swap_remove(index);
717            self.indices.swap_remove(index);
718            if !is_last {
719                let swapped_index = self.indices[index].clone();
720                *self.sparse.get_mut(swapped_index).unwrap() = dense_index;
721            }
722            value
723        })
724    }
725
726    /// Clears all of the elements from the sparse set.
727    ///
728    /// # Panics
729    /// - Panics if any of the keys or values implements [`Drop`] and any of those panic.
730    pub fn clear(&mut self) {
731        self.dense.clear();
732        self.indices.clear();
733        self.sparse.clear();
734    }
735
736    /// Converts the sparse set into its immutable variant.
737    pub(crate) fn into_immutable(self) -> ImmutableSparseSet<I, V> {
738        ImmutableSparseSet {
739            dense: self.dense.into_boxed_slice(),
740            indices: self.indices.into_boxed_slice(),
741            sparse: self.sparse.into_immutable(),
742        }
743    }
744}
745
746/// Represents something that can be stored in a [`SparseSet`] as an integer.
747///
748/// Ideally, the `usize` values should be very small (ie: incremented starting from
749/// zero), as the number of bits needed to represent a `SparseSetIndex` in a `FixedBitSet`
750/// is proportional to the **value** of those `usize`.
751pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
752    /// Gets the sparse set index corresponding to this instance.
753    fn sparse_set_index(&self) -> usize;
754    /// Creates a new instance of this type with the specified index.
755    fn get_sparse_set_index(value: usize) -> Self;
756}
757
758macro_rules! impl_sparse_set_index {
759    ($($ty:ty),+) => {
760        $(impl SparseSetIndex for $ty {
761            #[inline]
762            fn sparse_set_index(&self) -> usize {
763                *self as usize
764            }
765
766            #[inline]
767            fn get_sparse_set_index(value: usize) -> Self {
768                value as $ty
769            }
770        })*
771    };
772}
773
774impl_sparse_set_index!(u8, u16, u32, u64, usize);
775
776/// A collection of [`ComponentSparseSet`] storages, indexed by [`ComponentId`]
777///
778/// Can be accessed via [`Storages`](crate::storage::Storages)
779#[derive(Default)]
780pub struct SparseSets {
781    sets: SparseSet<ComponentId, ComponentSparseSet>,
782}
783
784impl SparseSets {
785    /// Returns the number of [`ComponentSparseSet`]s this collection contains.
786    #[inline]
787    pub fn len(&self) -> usize {
788        self.sets.len()
789    }
790
791    /// Returns true if this collection contains no [`ComponentSparseSet`]s.
792    #[inline]
793    pub fn is_empty(&self) -> bool {
794        self.sets.is_empty()
795    }
796
797    /// An Iterator visiting all ([`ComponentId`], [`ComponentSparseSet`]) pairs.
798    /// NOTE: Order is not guaranteed.
799    pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
800        self.sets.iter().map(|(id, data)| (*id, data))
801    }
802
803    /// Gets a reference to the [`ComponentSparseSet`] of a [`ComponentId`]. This may be `None` if the component has never been spawned.
804    #[inline]
805    pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
806        self.sets.get(component_id)
807    }
808
809    /// Gets a mutable reference of [`ComponentSparseSet`] of a [`ComponentInfo`].
810    /// Create a new [`ComponentSparseSet`] if not exists.
811    ///
812    /// # Panics
813    /// - Panics if the insertion forces an reallocation and the new capacity overflows `isize::MAX` bytes.
814    /// - Panics if the insertion forces an reallocation and causes an out-of-memory error.
815    pub(crate) fn get_or_insert(
816        &mut self,
817        component_info: &ComponentInfo,
818    ) -> &mut ComponentSparseSet {
819        if !self.sets.contains(component_info.id()) {
820            self.sets.insert(
821                component_info.id(),
822                ComponentSparseSet::new(component_info, 64),
823            );
824        }
825
826        self.sets.get_mut(component_info.id()).unwrap()
827    }
828
829    /// Gets a mutable reference to the [`ComponentSparseSet`] of a [`ComponentId`]. This may be `None` if the component has never been spawned.
830    pub(crate) fn get_mut(&mut self, component_id: ComponentId) -> Option<&mut ComponentSparseSet> {
831        self.sets.get_mut(component_id)
832    }
833
834    /// Clear entities stored in each [`ComponentSparseSet`]
835    ///
836    /// # Panics
837    /// - Panics if any of the components stored within implement [`Drop`] and any of them panic.
838    pub(crate) fn clear_entities(&mut self) {
839        for set in self.sets.values_mut() {
840            set.clear();
841        }
842    }
843
844    pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
845        for set in self.sets.values_mut() {
846            set.check_change_ticks(check);
847        }
848    }
849}
850
851#[cfg(test)]
852mod tests {
853    use super::SparseSets;
854    use crate::{
855        component::{Component, ComponentDescriptor, ComponentId, ComponentInfo},
856        entity::{Entity, EntityIndex},
857        storage::SparseSet,
858    };
859    use alloc::{vec, vec::Vec};
860
861    #[derive(Debug, Eq, PartialEq)]
862    struct Foo(usize);
863
864    #[test]
865    fn sparse_set() {
866        let mut set = SparseSet::<Entity, Foo>::default();
867        let e0 = Entity::from_index(EntityIndex::from_raw_u32(0).unwrap());
868        let e1 = Entity::from_index(EntityIndex::from_raw_u32(1).unwrap());
869        let e2 = Entity::from_index(EntityIndex::from_raw_u32(2).unwrap());
870        let e3 = Entity::from_index(EntityIndex::from_raw_u32(3).unwrap());
871        let e4 = Entity::from_index(EntityIndex::from_raw_u32(4).unwrap());
872
873        set.insert(e1, Foo(1));
874        set.insert(e2, Foo(2));
875        set.insert(e3, Foo(3));
876
877        assert_eq!(set.get(e0), None);
878        assert_eq!(set.get(e1), Some(&Foo(1)));
879        assert_eq!(set.get(e2), Some(&Foo(2)));
880        assert_eq!(set.get(e3), Some(&Foo(3)));
881        assert_eq!(set.get(e4), None);
882
883        {
884            let iter_results = set.values().collect::<Vec<_>>();
885            assert_eq!(iter_results, vec![&Foo(1), &Foo(2), &Foo(3)]);
886        }
887
888        assert_eq!(set.remove(e2), Some(Foo(2)));
889        assert_eq!(set.remove(e2), None);
890
891        assert_eq!(set.get(e0), None);
892        assert_eq!(set.get(e1), Some(&Foo(1)));
893        assert_eq!(set.get(e2), None);
894        assert_eq!(set.get(e3), Some(&Foo(3)));
895        assert_eq!(set.get(e4), None);
896
897        assert_eq!(set.remove(e1), Some(Foo(1)));
898
899        assert_eq!(set.get(e0), None);
900        assert_eq!(set.get(e1), None);
901        assert_eq!(set.get(e2), None);
902        assert_eq!(set.get(e3), Some(&Foo(3)));
903        assert_eq!(set.get(e4), None);
904
905        set.insert(e1, Foo(10));
906
907        assert_eq!(set.get(e1), Some(&Foo(10)));
908
909        *set.get_mut(e1).unwrap() = Foo(11);
910        assert_eq!(set.get(e1), Some(&Foo(11)));
911    }
912
913    #[test]
914    fn sparse_sets() {
915        let mut sets = SparseSets::default();
916
917        #[derive(Component, Default, Debug)]
918        struct TestComponent1;
919
920        #[derive(Component, Default, Debug)]
921        struct TestComponent2;
922
923        assert_eq!(sets.len(), 0);
924        assert!(sets.is_empty());
925
926        register_component::<TestComponent1>(&mut sets, 1);
927        assert_eq!(sets.len(), 1);
928
929        register_component::<TestComponent2>(&mut sets, 2);
930        assert_eq!(sets.len(), 2);
931
932        // check its shape by iter
933        let mut collected_sets = sets
934            .iter()
935            .map(|(id, set)| (id, set.len()))
936            .collect::<Vec<_>>();
937        collected_sets.sort();
938        assert_eq!(
939            collected_sets,
940            vec![(ComponentId::new(1), 0), (ComponentId::new(2), 0),]
941        );
942
943        fn register_component<T: Component>(sets: &mut SparseSets, id: usize) {
944            let descriptor = ComponentDescriptor::new::<T>();
945            let id = ComponentId::new(id);
946            let info = ComponentInfo::new(id, descriptor);
947            sets.get_or_insert(&info);
948        }
949    }
950}