pub struct EntityAlloc<E, P: IAllocPolicy = AllocPolicy256> { /* private fields */ }Expand description
Entity slab allocator for entities of type E using allocation policy P.
This allocator maintains a growable vector of fixed-size Chunk<E, P> slabs.
Each Chunk stores up to P::CHUNK_SIZE units and keeps per-unit generation
indices plus a bitset of allocated slots. EntityAlloc provides fast
allocation/deallocation inside chunks, keeps a free-chain of chunks that have
available slots (free_head), and tracks the total number of allocated
entities (num_allocated).
Primary responsibilities and guarantees:
- Allocate and deallocate entities with O(1) operations inside a chunk;
the allocator grows by creating new
Chunks when needed. - Maintain a
free_headpointing to a chunk with available slots to avoid scanning all chunks on each allocation. - Expose helper methods that return either raw unit pointers or generation-
aware indexes (
GenIndex). Callers must respect generation checks to avoid use-after-free; the allocator provides checks inunit_ptr_of_indexedand related helpers.
Concurrency and safety notes:
EntityAllocuses interior mutability (RefCellandCell) and is notSync; external synchronization is required for concurrent access.- Several
pub(crate)functions operate on raw pointers and rely on invariants (generation matching, non-null indexed values). Use the public crate APIs where possible; internal functions are optimized for performance and assume correct usage.
Field overview:
chunks:RefCell<Vec<Chunk<E, P>>>— growable storage of slab chunks.free_head:Cell<u32>— index of the first chunk with free slots (or a sentinel when none available).num_allocated:Cell<usize>— current count of allocated entities.
Usage tips:
- Use
remake_free_chainto rebuild the free-chain after bulk mutations. - Prefer
free_if/fully_free_iffor conditional freeing, they maintain allocator invariants and updatenum_allocatedcorrectly. - Be careful when converting between raw unit pointers and
GenIndex— always handleEntityAccessErrandSlicePtrErrreported by the helpers.
实体分配器详述(中文):
- 管理一组可增长的
Chunk<E, P>,每个Chunk包含固定大小的单元、位图和 generation 信息,用于检测 use-after-free。 - 在 chunk 内部的分配与释放为 O(1);当现有 chunk 全满时通过新增 chunk 增长容量。
- 维护
free_head指向含有空闲单元的 chunk,以加速分配。 num_allocated跟踪当前分配数量;remake_free_chain可在批量修改后重建空闲链表。- 结构体使用
RefCell/Cell实现内部可变性,默认不安全以跨线程共享,若需要 并发访问请自行加锁或在上层保证互斥。
示例:
// 参见 crate 文档中的示例,通常通过 crate 提供的安全 API 分配/访问/释放实体。Implementations§
Source§impl<E, P: IAllocPolicy> EntityAlloc<E, P>
impl<E, P: IAllocPolicy> EntityAlloc<E, P>
Sourcepub fn with_capacity(cap: usize) -> Self
pub fn with_capacity(cap: usize) -> Self
Create a new EntityAlloc with preallocated capacity for cap entities.
Sourcepub fn remake_free_chain(&mut self)
pub fn remake_free_chain(&mut self)
Rebuild the free-chain of chunks with available slots.
Source§impl<E, P: IAllocPolicy> EntityAlloc<E, P>
impl<E, P: IAllocPolicy> EntityAlloc<E, P>
Sourcepub fn free_if(
&mut self,
pred: impl FnMut(&E, PtrID<E, P>, IndexedID<E, P>) -> bool,
)
pub fn free_if( &mut self, pred: impl FnMut(&E, PtrID<E, P>, IndexedID<E, P>) -> bool, )
Free entities that satisfy the given predicate.
Sourcepub fn fully_free_if(
&mut self,
should_free: impl FnMut(&E, PtrID<E, P>, IndexedID<E, P>) -> bool,
consume: impl FnMut(E),
)
pub fn fully_free_if( &mut self, should_free: impl FnMut(&E, PtrID<E, P>, IndexedID<E, P>) -> bool, consume: impl FnMut(E), )
Free entities that satisfy the given predicate, consuming them with the provided closure.
This method automatically chooses between dense and sparse freeing strategies based on the chunk’s allocation density for efficiency.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Get the number of currently allocated entities.
Note that this is not the length of the internal chunk vector or the “allocated” sections in chunks, but the actual count of live entities.
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clear all allocated entities, resetting the allocator to an empty state.
Sourcepub fn iter(&self) -> EntityAllocReadIter<'_, E, P> ⓘ
pub fn iter(&self) -> EntityAllocReadIter<'_, E, P> ⓘ
Get an iterator over allocated entities for read-only access.
The iterator yields tuples of (IndexedID, PtrID, &E).
Sourcepub fn iter_mut(&mut self) -> EntityAllocEditIter<'_, E, P> ⓘ
pub fn iter_mut(&mut self) -> EntityAllocEditIter<'_, E, P> ⓘ
Get an iterator over allocated entities for mutable access.
The iterator yields tuples of (IndexedID, PtrID, &mut E).