mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Improvement] (MG_Utils): Improve performance in IndexGenerator.
This commit is contained in:
@@ -1,52 +1,58 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
template <typename IndexType>
|
template <typename IndexType>
|
||||||
class IndexGenerator {
|
class IndexGenerator {
|
||||||
public:
|
public:
|
||||||
IndexGenerator() : next_index_(1) {}
|
explicit IndexGenerator(size_t initial_capacity = 1024)
|
||||||
explicit IndexGenerator(IndexType n) : next_index_(1) {
|
: next_index_(0)
|
||||||
is_valid_.reserve(n);
|
{
|
||||||
|
is_valid_.reserve(initial_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generate(size_t n, IndexType* indices) {
|
void Generate(size_t n, IndexType* indices) {
|
||||||
if (n <= 0) {
|
if (n == 0) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t count_from_freed = std::min(n, freed_indices_.size());
|
size_t from_freed = std::min(n, freed_indices_.size());
|
||||||
for (size_t i = 0; i < count_from_freed; ++i) {
|
for (size_t i = 0; i < from_freed; ++i) {
|
||||||
indices[i] = freed_indices_.back();
|
indices[i] = freed_indices_.back();
|
||||||
freed_indices_.pop_back();
|
freed_indices_.pop_back();
|
||||||
if (indices[i] >= is_valid_.size()) {
|
is_valid_[indices[i]] = 1;
|
||||||
is_valid_.resize(static_cast<size_t>(indices[i]) + 1, false);
|
|
||||||
}
|
|
||||||
is_valid_[indices[i]] = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = count_from_freed; i < n; ++i) {
|
size_t need_new = n - from_freed;
|
||||||
indices[i] = next_index_++;
|
if (need_new > 0) {
|
||||||
if (indices[i] >= is_valid_.size()) {
|
size_t required = next_index_ + need_new;
|
||||||
is_valid_.resize(static_cast<size_t>(indices[i]) + 1, false);
|
if (required > is_valid_.size()) {
|
||||||
|
size_t new_cap = std::max(required, is_valid_.size() * 2);
|
||||||
|
is_valid_.resize(new_cap, 0);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < need_new; ++i) {
|
||||||
|
indices[from_freed + i] = next_index_;
|
||||||
|
is_valid_[next_index_] = 1;
|
||||||
|
++next_index_;
|
||||||
}
|
}
|
||||||
is_valid_[indices[i]] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Delete(IndexType index) {
|
void Delete(IndexType index) {
|
||||||
if (index < is_valid_.size() && is_valid_[index] == true) {
|
if (index < is_valid_.size() && is_valid_[index]) {
|
||||||
is_valid_[index] = false;
|
is_valid_[index] = 0;
|
||||||
freed_indices_.push_back(index);
|
freed_indices_.push_back(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid(IndexType index) const {
|
bool IsValid(IndexType index) const {
|
||||||
return index < is_valid_.size() && is_valid_[index] == true;
|
return index < is_valid_.size() && is_valid_[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IndexType next_index_;
|
IndexType next_index_ = 0;
|
||||||
std::vector<IndexType> freed_indices_;
|
std::vector<IndexType> freed_indices_;
|
||||||
std::vector<bool> is_valid_;
|
std::vector<UInt8> is_valid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user