8#include "core/memory/types.h"
10namespace Vkm::Engine {
30 ~SlotAllocator() =
default;
32 SlotAllocator(
const SlotAllocator& other) =
delete;
33 SlotAllocator& operator=(
const SlotAllocator& other) =
delete;
35 SlotAllocator(SlotAllocator && other) =
delete;
36 SlotAllocator& operator=(SlotAllocator && other) =
delete;
49 const uint32_t idx = allocateSlot(reused);
50 if (recycled) *recycled = reused;
51 m_generation[idx].setAlive(
true);
53 return StorageIndex{idx, m_generation[idx].generation()};
64 VKM_ASSERT(
has(
id),
"SlotAllocator::free called with invalid handle");
67 m_generation[
id.index].setAlive(
false);
68 m_generation[
id.index].bumpGeneration();
69 m_freeList.push_back(
id.index);
80 &&
id.index < m_generation.size()
81 && m_generation[
id.index].alive()
82 && m_generation[
id.index].generation() ==
id.generation;
94 if (index >= m_generation.size())
return {};
95 return StorageIndex{index, m_generation[index].generation()};
106 && index < m_generation.size()
107 && m_generation[index].alive();
126 const uint32_t oldSize =
static_cast<uint32_t
>(m_generation.size());
127 while (m_generation.size() <= index) m_generation.push_back({});
128 for (uint32_t gap = index; gap-- > oldSize;) m_freeList.push_back(gap);
131 !m_generation[index].alive(),
132 "SlotAllocator::allocateAt: slot %u already alive",
136 if (m_generation[index].alive())
return {};
138 m_generation[index].setAlive(
true);
140 return StorageIndex{index, m_generation[index].generation()};
149 template<
typename Fn>
151 for (uint32_t i = 1; i < m_generation.size(); ++i) {
152 if (m_generation[i].alive()) fn(i);
161 m_freeList.reserve(m_generation.size());
163 for (uint32_t i =
static_cast<uint32_t
>(m_generation.size()); i-- > 1;) {
164 if (m_generation[i].alive()) {
165 m_generation[i].setAlive(
false);
166 m_generation[i].bumpGeneration();
168 m_freeList.push_back(i);
180 void swap(SlotAllocator& other)
noexcept {
182 swap(m_generation, other.m_generation);
183 swap(m_freeList, other.m_freeList);
184 swap(m_liveCount, other.m_liveCount);
192 size_t size()
const {
return m_liveCount; }
199 size_t extent()
const {
return m_generation.size(); }
208 uint32_t allocateSlot(
bool& reused) {
210 while (!m_freeList.empty()) {
211 const uint32_t idx = m_freeList.back();
212 m_freeList.pop_back();
213 if (!m_generation[idx].alive()) {
220 const uint32_t idx =
static_cast<uint32_t
>(m_generation.size());
221 m_generation.push_back({});
226 std::vector<GenerationIndex> m_generation;
227 std::vector<uint32_t> m_freeList;
228 size_t m_liveCount = 0;
void free(StorageIndex id)
Free a handle, bumping its generation and recycling the slot.
Definition slot_allocator.h:63
void forEach(Fn &&fn) const
Invoke fn(index) for every currently-alive slot.
Definition slot_allocator.h:150
StorageIndex handleAt(uint32_t index) const
Rebuild the handle naming a sparse slot, generation included.
Definition slot_allocator.h:93
void swap(SlotAllocator &other) noexcept
Swap internal state with another allocator.
Definition slot_allocator.h:180
bool isAliveAtIndex(uint32_t index) const
Check whether index currently holds a live slot.
Definition slot_allocator.h:104
size_t extent() const
Number of slots the table spans, live or free, slot 0 included.
Definition slot_allocator.h:199
StorageIndex allocate(bool *recycled=nullptr)
Allocate a new handle with a unique index and current generation.
Definition slot_allocator.h:47
size_t size() const
Number of live slots.
Definition slot_allocator.h:192
void clear()
Reset every slot to dead, bumping generations so outstanding handles go stale.
Definition slot_allocator.h:159
bool has(StorageIndex id) const
Test whether a handle is still valid.
Definition slot_allocator.h:78
StorageIndex allocateAt(uint32_t index)
Allocate a slot at a specific index.
Definition slot_allocator.h:122
static constexpr uint32_t MAX_CLAIMED_INDEX
The highest index allocateAt will claim.
Definition slot_allocator.h:26
Per-slot alive flag (bit 31) and generation counter (bits 0-30) in one uint32_t.
Definition types.h:40
Opaque handle pairing a sparse-array index with a generation counter.
Definition types.h:14