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                    summary_tick: self.dense.get_summary_tick(),
304                },
305            ))
306        }
307    }
308
309    /// Returns a reference to the "added" tick of the entity's component value.
310    ///
311    /// Returns `None` if `entity` does not have a component in the sparse set.
312    #[inline]
313    pub fn get_added_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
314        let dense_index = *self.sparse.get(entity.index())?;
315        #[cfg(debug_assertions)]
316        assert_eq!(entity, self.entities[dense_index.index()]);
317        // SAFETY: if the sparse index points to something in the dense vec, it exists
318        unsafe { Some(self.dense.get_added_tick_unchecked(dense_index)) }
319    }
320
321    /// Returns a reference to the "changed" tick of the entity's component value.
322    ///
323    /// Returns `None` if `entity` does not have a component in the sparse set.
324    #[inline]
325    pub fn get_changed_tick(&self, entity: Entity) -> Option<&UnsafeCell<Tick>> {
326        let dense_index = *self.sparse.get(entity.index())?;
327        #[cfg(debug_assertions)]
328        assert_eq!(entity, self.entities[dense_index.index()]);
329        // SAFETY: if the sparse index points to something in the dense vec, it exists
330        unsafe { Some(self.dense.get_changed_tick_unchecked(dense_index)) }
331    }
332
333    /// Returns a reference to the "added" and "changed" ticks of the entity's component value.
334    ///
335    /// Returns `None` if `entity` does not have a component in the sparse set.
336    #[inline]
337    pub fn get_ticks(&self, entity: Entity) -> Option<ComponentTicks> {
338        let dense_index = *self.sparse.get(entity.index())?;
339        #[cfg(debug_assertions)]
340        assert_eq!(entity, self.entities[dense_index.index()]);
341        // SAFETY: if the sparse index points to something in the dense vec, it exists
342        unsafe { Some(self.dense.get_ticks_unchecked(dense_index)) }
343    }
344
345    /// Returns a reference to the calling location that last changed the entity's component value.
346    ///
347    /// Returns `None` if `entity` does not have a component in the sparse set.
348    #[inline]
349    pub fn get_changed_by(
350        &self,
351        entity: Entity,
352    ) -> MaybeLocation<Option<&UnsafeCell<&'static Location<'static>>>> {
353        MaybeLocation::new_with_flattened(|| {
354            let dense_index = *self.sparse.get(entity.index())?;
355            #[cfg(debug_assertions)]
356            assert_eq!(entity, self.entities[dense_index.index()]);
357            // SAFETY: if the sparse index points to something in the dense vec, it exists
358            unsafe { Some(self.dense.get_changed_by_unchecked(dense_index)) }
359        })
360    }
361
362    /// Returns the drop function for the component type stored in the sparse set,
363    /// or `None` if it doesn't need to be dropped.
364    #[inline]
365    pub fn get_drop(&self) -> Option<unsafe fn(OwningPtr<'_>)> {
366        self.dense.get_drop()
367    }
368
369    /// Removes the `entity` from this sparse set and returns a pointer to the associated value (if
370    /// it exists).
371    #[must_use = "The returned pointer must be used to drop the removed component."]
372    pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
373        self.sparse.remove(entity.index()).map(|dense_index| {
374            #[cfg(debug_assertions)]
375            assert_eq!(entity, self.entities[dense_index.index()]);
376            let last = self.entities.len() - 1;
377            if dense_index.index() >= last {
378                #[cfg(debug_assertions)]
379                assert_eq!(dense_index.index(), last);
380                // SAFETY: This is strictly decreasing the length, so it cannot outgrow
381                // it also cannot underflow as an item was just removed from the sparse array.
382                unsafe { self.entities.set_len(last) };
383                // SAFETY: `last` is guaranteed to be the last element in `dense` as the length is synced with
384                // the `entities` store.
385                unsafe {
386                    self.dense
387                        .get_data_unchecked(dense_index)
388                        .assert_unique()
389                        .promote()
390                }
391            } else {
392                // SAFETY: The above check ensures that `dense_index` and the last element are not
393                // overlapping, and thus also within bounds.
394                unsafe {
395                    self.entities
396                        .swap_remove_nonoverlapping_unchecked(dense_index.index());
397                };
398                // SAFETY: The above check ensures that `dense_index` is in bounds.
399                let swapped_entity = unsafe { self.entities.get_unchecked(dense_index.index()) };
400                #[cfg(not(debug_assertions))]
401                let index = *swapped_entity;
402                #[cfg(debug_assertions)]
403                let index = swapped_entity.index();
404                // SAFETY: The swapped entity was just fetched from the entity Vec, it must have already
405                // been inserted and in bounds.
406                unsafe {
407                    *self.sparse.get_mut(index).debug_checked_unwrap() = dense_index;
408                }
409                // SAFETY: The above check ensures that `dense_index` and the last element are not
410                // overlapping, and thus also within bounds.
411                unsafe {
412                    self.dense
413                        .swap_remove_and_forget_unchecked_nonoverlapping(last, dense_index)
414                }
415            }
416        })
417    }
418
419    /// Removes (and drops) the entity's component value from the sparse set.
420    ///
421    /// Returns `true` if `entity` had a component value in the sparse set.
422    pub(crate) fn remove(&mut self, entity: Entity) -> bool {
423        self.sparse
424            .remove(entity.index())
425            .map(|dense_index| {
426                #[cfg(debug_assertions)]
427                assert_eq!(entity, self.entities[dense_index.index()]);
428                let last = self.entities.len() - 1;
429                if dense_index.index() >= last {
430                    #[cfg(debug_assertions)]
431                    assert_eq!(dense_index.index(), last);
432                    // SAFETY: This is strictly decreasing the length, so it cannot outgrow
433                    // it also cannot underflow as an item was just removed from the sparse array.
434                    unsafe { self.entities.set_len(last) };
435                    // SAFETY: `last` is guaranteed to be the last element in `dense` as the length is synced with
436                    // the `entities` store.
437                    unsafe { self.dense.drop_last_component(last) };
438                } else {
439                    // SAFETY: The above check ensures that `dense_index` and the last element are not
440                    // overlapping, and thus also within bounds.
441                    unsafe {
442                        self.entities
443                            .swap_remove_nonoverlapping_unchecked(dense_index.index());
444                    };
445                    let swapped_entity =
446                        // SAFETY: The above check ensures that `dense_index` is in bounds.
447                        unsafe { self.entities.get_unchecked(dense_index.index()) };
448                    #[cfg(not(debug_assertions))]
449                    let index = *swapped_entity;
450                    #[cfg(debug_assertions)]
451                    let index = swapped_entity.index();
452                    // SAFETY: The swapped entity was just fetched from the entity Vec, it must have already
453                    // been inserted and in bounds.
454                    unsafe {
455                        *self.sparse.get_mut(index).debug_checked_unwrap() = dense_index;
456                    }
457                    // SAFETY: The above check ensures that `dense_index` and the last element are not
458                    // overlapping, and thus also within bounds.
459                    unsafe {
460                        self.dense
461                            .swap_remove_and_drop_unchecked_nonoverlapping(last, dense_index);
462                    }
463                }
464            })
465            .is_some()
466    }
467
468    pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
469        // SAFETY: This is using the valid size of the column.
470        unsafe { self.dense.check_change_ticks(self.len(), check) };
471    }
472}
473
474impl Drop for ComponentSparseSet {
475    fn drop(&mut self) {
476        let len = self.entities.len();
477        self.entities.clear();
478        // SAFETY: `cap` and `len` are correct. `dense` is never accessed again after this call.
479        unsafe {
480            self.dense.drop(self.entities.capacity(), len);
481        }
482    }
483}
484
485/// A map from `I` to `V` that combines dense and sparse storage.
486///
487/// This is implemented as a sparse array mapping keys to dense indexes,
488/// plus dense arrays of indexes and keys.
489///
490/// The key type, `I`, must implement [`SparseSetIndex`]
491/// to allow conversion to and from array indexes.
492///
493/// This supports fast O(1) lookups, since they consist of one array index to map
494/// the key to a dense index, followed by a second array index to find the value.
495///
496/// This may use a lot of excess memory if the set is sparsely populated,
497/// since it stores an empty entry for each key.
498///
499/// Compared to a simple `Vec<Option<V>>`,
500/// the dense storage of values takes less memory when `V` is large,
501/// although the overhead of tracking which entries have values
502/// may make it larger when `V` is small or the set is densely populated.
503#[derive(Debug)]
504pub struct SparseSet<I, V: 'static> {
505    /// The mapping from dense index to value.
506    ///
507    /// `dense[sparse[k]]` holds the value for `k`.
508    dense: Vec<V>,
509
510    /// The reverse mapping from dense index to key.
511    ///
512    /// `indices[sparse[k]] == k`
513    indices: Vec<I>,
514
515    /// The mapping from keys to dense indexes.
516    sparse: SparseArray<I, NonMaxUsize>,
517}
518
519/// A map from `I` to `V` that combines dense and sparse storage.
520///
521/// This is implemented as a sparse array mapping keys to dense indexes,
522/// plus dense arrays of indexes and keys.
523///
524/// This uses less space than [`SparseSet`] because it does not
525/// need to store both length and capacity,
526/// but it cannot be changed after construction.
527///
528/// The key type, `I`, must implement [`SparseSetIndex`]
529/// to allow conversion to and from array indexes.
530///
531/// This supports fast O(1) lookups, since they consist of one array index to map
532/// the key to a dense index, followed by a second array index to find the value.
533///
534/// This may use a lot of excess memory if the set is sparsely populated,
535/// since it stores an empty entry for each key.
536///
537/// Compared to a simple `Vec<Option<V>>`,
538/// the dense storage of values takes less memory when `V` is large,
539/// although the overhead of tracking which entries have values
540/// may make it larger when `V` is small or the set is densely populated.
541#[derive(Debug)]
542pub(crate) struct ImmutableSparseSet<I, V: 'static> {
543    /// The mapping from dense index to value.
544    ///
545    /// `dense[sparse[k]]` holds the value for `k`.
546    dense: Box<[V]>,
547
548    /// The reverse mapping from dense index to key.
549    ///
550    /// `indices[sparse[k]] == k`
551    indices: Box<[I]>,
552
553    /// The mapping from keys to dense indexes.
554    sparse: ImmutableSparseArray<I, NonMaxUsize>,
555}
556
557macro_rules! impl_sparse_set {
558    ($ty:ident) => {
559        impl<I: SparseSetIndex, V> $ty<I, V> {
560            /// Returns the number of elements in the sparse set.
561            #[inline]
562            pub fn len(&self) -> usize {
563                self.dense.len()
564            }
565
566            /// Returns `true` if the sparse set contains a value for `index`.
567            #[inline]
568            pub fn contains(&self, index: I) -> bool {
569                self.sparse.contains(index)
570            }
571
572            /// Returns a reference to the value for `index`.
573            ///
574            /// Returns `None` if `index` does not have a value in the sparse set.
575            pub fn get(&self, index: I) -> Option<&V> {
576                self.sparse.get(index).map(|dense_index| {
577                    // SAFETY: if the sparse index points to something in the dense vec, it exists
578                    unsafe { self.dense.get_unchecked(dense_index.get()) }
579                })
580            }
581
582            /// Returns a mutable reference to the value for `index`.
583            ///
584            /// Returns `None` if `index` does not have a value in the sparse set.
585            pub fn get_mut(&mut self, index: I) -> Option<&mut V> {
586                let dense = &mut self.dense;
587                self.sparse.get(index).map(move |dense_index| {
588                    // SAFETY: if the sparse index points to something in the dense vec, it exists
589                    unsafe { dense.get_unchecked_mut(dense_index.get()) }
590                })
591            }
592
593            /// Returns an iterator visiting all keys (indices) in arbitrary order.
594            pub fn indices(&self) -> &[I] {
595                &self.indices
596            }
597
598            /// Returns an iterator visiting all values in arbitrary order.
599            pub fn values(&self) -> impl Iterator<Item = &V> {
600                self.dense.iter()
601            }
602
603            /// Returns an iterator visiting all values mutably in arbitrary order.
604            pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
605                self.dense.iter_mut()
606            }
607
608            /// Returns an iterator visiting all key-value pairs in arbitrary order, with references to the values.
609            pub fn iter(&self) -> impl Iterator<Item = (&I, &V)> {
610                self.indices.iter().zip(self.dense.iter())
611            }
612
613            /// Returns an iterator visiting all key-value pairs in arbitrary order, with mutable references to the values.
614            pub fn iter_mut(&mut self) -> impl Iterator<Item = (&I, &mut V)> {
615                self.indices.iter().zip(self.dense.iter_mut())
616            }
617        }
618    };
619}
620
621impl_sparse_set!(SparseSet);
622impl_sparse_set!(ImmutableSparseSet);
623
624impl<I: SparseSetIndex, V> Default for SparseSet<I, V> {
625    fn default() -> Self {
626        Self::new()
627    }
628}
629
630impl<I, V> SparseSet<I, V> {
631    /// Creates a new [`SparseSet`].
632    pub const fn new() -> Self {
633        Self {
634            dense: Vec::new(),
635            indices: Vec::new(),
636            sparse: SparseArray::new(),
637        }
638    }
639}
640
641impl<I: SparseSetIndex, V> SparseSet<I, V> {
642    /// Creates a new [`SparseSet`] with a specified initial capacity.
643    ///
644    /// # Panics
645    /// - Panics if the new capacity of the allocation overflows `isize::MAX` bytes.
646    /// - Panics if the new allocation causes an out-of-memory error.
647    pub fn with_capacity(capacity: usize) -> Self {
648        Self {
649            dense: Vec::with_capacity(capacity),
650            indices: Vec::with_capacity(capacity),
651            sparse: Default::default(),
652        }
653    }
654
655    /// Returns the total number of elements the [`SparseSet`] can hold without needing to reallocate.
656    #[inline]
657    pub fn capacity(&self) -> usize {
658        self.dense.capacity()
659    }
660
661    /// Inserts `value` at `index`.
662    ///
663    /// If a value was already present at `index`, it will be overwritten.
664    ///
665    /// # Panics
666    /// - Panics if the insertion forces an reallocation and the new capacity overflows `isize::MAX` bytes.
667    /// - Panics if the insertion forces an reallocation and causes an out-of-memory error.
668    pub fn insert(&mut self, index: I, value: V) {
669        if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
670            // SAFETY: dense indices stored in self.sparse always exist
671            unsafe {
672                *self.dense.get_unchecked_mut(dense_index.get()) = value;
673            }
674        } else {
675            self.sparse
676                .insert(index.clone(), NonMaxUsize::new(self.dense.len()).unwrap());
677            self.indices.push(index);
678            self.dense.push(value);
679        }
680    }
681
682    /// Returns a reference to the value for `index`, inserting one computed from `func`
683    /// if not already present.
684    ///
685    /// # Panics
686    /// - Panics if the insertion forces an reallocation and the new capacity overflows `isize::MAX` bytes.
687    /// - Panics if the insertion forces an reallocation and causes an out-of-memory error.
688    pub fn get_or_insert_with(&mut self, index: I, func: impl FnOnce() -> V) -> &mut V {
689        if let Some(dense_index) = self.sparse.get(index.clone()).cloned() {
690            // SAFETY: dense indices stored in self.sparse always exist
691            unsafe { self.dense.get_unchecked_mut(dense_index.get()) }
692        } else {
693            let value = func();
694            let dense_index = self.dense.len();
695            self.sparse
696                .insert(index.clone(), NonMaxUsize::new(dense_index).unwrap());
697            self.indices.push(index);
698            self.dense.push(value);
699            // SAFETY: dense index was just populated above
700            unsafe { self.dense.get_unchecked_mut(dense_index) }
701        }
702    }
703
704    /// Returns `true` if the sparse set contains no elements.
705    #[inline]
706    pub fn is_empty(&self) -> bool {
707        self.dense.len() == 0
708    }
709
710    /// Removes and returns the value for `index`.
711    ///
712    /// Returns `None` if `index` does not have a value in the sparse set.
713    pub fn remove(&mut self, index: I) -> Option<V> {
714        self.sparse.remove(index).map(|dense_index| {
715            let index = dense_index.get();
716            let is_last = index == self.dense.len() - 1;
717            let value = self.dense.swap_remove(index);
718            self.indices.swap_remove(index);
719            if !is_last {
720                let swapped_index = self.indices[index].clone();
721                *self.sparse.get_mut(swapped_index).unwrap() = dense_index;
722            }
723            value
724        })
725    }
726
727    /// Clears all of the elements from the sparse set.
728    ///
729    /// # Panics
730    /// - Panics if any of the keys or values implements [`Drop`] and any of those panic.
731    pub fn clear(&mut self) {
732        self.dense.clear();
733        self.indices.clear();
734        self.sparse.clear();
735    }
736
737    /// Converts the sparse set into its immutable variant.
738    pub(crate) fn into_immutable(self) -> ImmutableSparseSet<I, V> {
739        ImmutableSparseSet {
740            dense: self.dense.into_boxed_slice(),
741            indices: self.indices.into_boxed_slice(),
742            sparse: self.sparse.into_immutable(),
743        }
744    }
745}
746
747/// Represents something that can be stored in a [`SparseSet`] as an integer.
748///
749/// Ideally, the `usize` values should be very small (ie: incremented starting from
750/// zero), as the number of bits needed to represent a `SparseSetIndex` in a `FixedBitSet`
751/// is proportional to the **value** of those `usize`.
752pub trait SparseSetIndex: Clone + PartialEq + Eq + Hash {
753    /// Gets the sparse set index corresponding to this instance.
754    fn sparse_set_index(&self) -> usize;
755    /// Creates a new instance of this type with the specified index.
756    fn get_sparse_set_index(value: usize) -> Self;
757}
758
759macro_rules! impl_sparse_set_index {
760    ($($ty:ty),+) => {
761        $(impl SparseSetIndex for $ty {
762            #[inline]
763            fn sparse_set_index(&self) -> usize {
764                *self as usize
765            }
766
767            #[inline]
768            fn get_sparse_set_index(value: usize) -> Self {
769                value as $ty
770            }
771        })*
772    };
773}
774
775impl_sparse_set_index!(u8, u16, u32, u64, usize);
776
777/// A collection of [`ComponentSparseSet`] storages, indexed by [`ComponentId`]
778///
779/// Can be accessed via [`Storages`](crate::storage::Storages)
780#[derive(Default)]
781pub struct SparseSets {
782    sets: SparseSet<ComponentId, ComponentSparseSet>,
783}
784
785impl SparseSets {
786    /// Returns the number of [`ComponentSparseSet`]s this collection contains.
787    #[inline]
788    pub fn len(&self) -> usize {
789        self.sets.len()
790    }
791
792    /// Returns true if this collection contains no [`ComponentSparseSet`]s.
793    #[inline]
794    pub fn is_empty(&self) -> bool {
795        self.sets.is_empty()
796    }
797
798    /// An Iterator visiting all ([`ComponentId`], [`ComponentSparseSet`]) pairs.
799    /// NOTE: Order is not guaranteed.
800    pub fn iter(&self) -> impl Iterator<Item = (ComponentId, &ComponentSparseSet)> {
801        self.sets.iter().map(|(id, data)| (*id, data))
802    }
803
804    /// Gets a reference to the [`ComponentSparseSet`] of a [`ComponentId`]. This may be `None` if the component has never been spawned.
805    #[inline]
806    pub fn get(&self, component_id: ComponentId) -> Option<&ComponentSparseSet> {
807        self.sets.get(component_id)
808    }
809
810    /// Gets a mutable reference of [`ComponentSparseSet`] of a [`ComponentInfo`].
811    /// Create a new [`ComponentSparseSet`] if not exists.
812    ///
813    /// # Panics
814    /// - Panics if the insertion forces an reallocation and the new capacity overflows `isize::MAX` bytes.
815    /// - Panics if the insertion forces an reallocation and causes an out-of-memory error.
816    pub(crate) fn get_or_insert(
817        &mut self,
818        id: ComponentId,
819        component_info: &ComponentInfo,
820    ) -> &mut ComponentSparseSet {
821        if !self.sets.contains(id) {
822            self.sets
823                .insert(id, ComponentSparseSet::new(component_info, 64));
824        }
825
826        self.sets.get_mut(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, ComponentIds, 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 ids = ComponentIds::default();
916        let mut sets = SparseSets::default();
917
918        #[derive(Component, Default, Debug)]
919        struct TestComponent1;
920
921        #[derive(Component, Default, Debug)]
922        struct TestComponent2;
923
924        let id_1 = ids.next_mut();
925        let id_2 = ids.next_mut();
926
927        assert_eq!(sets.len(), 0);
928        assert!(sets.is_empty());
929
930        register_component::<TestComponent1>(&mut sets, id_1);
931        assert_eq!(sets.len(), 1);
932
933        register_component::<TestComponent2>(&mut sets, id_2);
934        assert_eq!(sets.len(), 2);
935
936        // check its shape by iter
937        let mut collected_sets = sets
938            .iter()
939            .map(|(id, set)| (id, set.len()))
940            .collect::<Vec<_>>();
941        collected_sets.sort();
942        assert_eq!(collected_sets, vec![(id_1, 0), (id_2, 0),]);
943
944        fn register_component<T: Component>(sets: &mut SparseSets, id: ComponentId) {
945            let descriptor = ComponentDescriptor::new::<T>();
946            let info = ComponentInfo::new(descriptor);
947            sets.get_or_insert(id, &info);
948        }
949    }
950}