10namespace Vkm::Engine {
17 ISparseSet() =
default;
18 virtual ~ISparseSet() =
default;
20 ISparseSet(
const ISparseSet& other) =
delete;
21 ISparseSet& operator=(
const ISparseSet& other) =
delete;
23 ISparseSet(ISparseSet && other) =
delete;
24 ISparseSet& operator=(ISparseSet && other) =
delete;
50class SparseSet :
public ISparseSet {
52 SparseSet() =
default;
53 ~SparseSet()
override =
default;
55 SparseSet(
const SparseSet& other) =
delete;
56 SparseSet& operator=(
const SparseSet& other) =
delete;
58 SparseSet(SparseSet && other) =
delete;
59 SparseSet& operator=(SparseSet && other) =
delete;
68 T&
add(uint32_t key, T && value) {
return addInternal(key, std::move(value)); }
69 T&
add(uint32_t key,
const T& value) {
return addInternal(key, value); }
76 VKM_ASSERT(
contains(key),
"SparseSet::remove called with invalid key");
80 uint32_t dataIdx = m_dataIndex[key];
81 uint32_t lastIdx =
static_cast<uint32_t
>(m_data.size() - 1);
83 if (dataIdx != lastIdx) {
84 m_data[dataIdx] = std::move(m_data[lastIdx]);
86 m_dataId[dataIdx] = m_dataId[lastIdx];
87 m_dataIndex[m_dataId[dataIdx]] = dataIdx;
92 m_dataIndex[key] = EMPTY;
110 return key < m_dataIndex.size() && m_dataIndex[key] != EMPTY;
119 VKM_ASSERT(
contains(key),
"SparseSet::get called with invalid key");
120 return m_data[m_dataIndex[key]];
123 const T&
get(uint32_t key)
const {
124 VKM_ASSERT(
contains(key),
"SparseSet::get called with invalid key");
125 return m_data[m_dataIndex[key]];
139 template<
typename Fn>
141 for (uint32_t i = 0; i < m_data.size(); ++i) {
142 fn(m_dataId[i], m_data[i]);
146 template<
typename Fn>
148 for (uint32_t i = 0; i < m_data.size(); ++i) {
149 fn(m_dataId[i], m_data[i]);
158 size_t size()
const {
return m_data.size(); }
168 std::fill(m_dataIndex.begin(), m_dataIndex.end(), EMPTY);
179 if (m_data.empty()) {
183 for (uint32_t i = 0; i < m_dataId.size(); ++i) {
184 if (m_dataId[i] > maxKey) maxKey = m_dataId[i];
186 if (maxKey + 1 < m_dataIndex.size()) m_dataIndex.resize(maxKey + 1);
188 m_dataIndex.shrink_to_fit();
199 uint32_t
keyAt(uint32_t denseIndex)
const {
return m_dataId[denseIndex]; }
207 T&
dataAt(uint32_t denseIndex) {
return m_data[denseIndex]; }
208 const T&
dataAt(uint32_t denseIndex)
const {
return m_data[denseIndex]; }
211 static constexpr uint32_t EMPTY = UINT32_MAX;
218 void ensureCapacity(uint32_t key) {
219 if (key >= m_dataIndex.size())
220 m_dataIndex.resize(key + 1, EMPTY);
231 template<
typename... Args>
232 T& addInternal(uint32_t key, Args&&... args) {
233 VKM_ASSERT(key != EMPTY,
"SparseSet::add key cannot be EMPTY sentinel");
234 VKM_ASSERT(key != 0,
"SparseSet::add key 0 is reserved");
236 VKM_ASSERT(!
contains(key),
"SparseSet::add key already present");
238 if (
contains(key))
return m_data[m_dataIndex[key]];
240 uint32_t dataIdx =
static_cast<uint32_t
>(m_data.size());
242 m_data.emplace_back(std::forward<Args>(args)...);
243 m_dataId.push_back(key);
244 m_dataIndex[key] = dataIdx;
246 return m_data[dataIdx];
250 std::vector<uint32_t> m_dataIndex;
251 std::vector<uint32_t> m_dataId;
252 std::vector<T> m_data;
virtual void compact()=0
Release the sparse array's slack, keeping every live element.
virtual void removeIfPresent(uint32_t key)=0
Remove the element at the given key, if this set holds one.
void removeIfPresent(uint32_t key) override
Remove the element at the given key if one is present.
Definition sparse_set.h:100
bool contains(uint32_t key) const
Test whether a key is present.
Definition sparse_set.h:109
void compact() override
Shrink the sparse array to fit only live keys, reclaiming wasted memory.
Definition sparse_set.h:178
uint32_t keyAt(uint32_t denseIndex) const
Access the sparse key stored at a dense index.
Definition sparse_set.h:199
T & dataAt(uint32_t denseIndex)
Access the element stored at a dense index.
Definition sparse_set.h:207
void forEach(Fn &&fn)
Iterate all live elements densely (no holes).
Definition sparse_set.h:140
T & add(uint32_t key, T &&value)
Insert an element at the given key.
Definition sparse_set.h:68
void clear()
Drop every element.
Definition sparse_set.h:165
size_t size() const
Number of live elements.
Definition sparse_set.h:158
void remove(uint32_t key)
Remove the element at the given key via swap-and-pop.
Definition sparse_set.h:75
T & get(uint32_t key)
Access the element at the given key.
Definition sparse_set.h:118