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}