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}