config: ENTT_PAGE_SIZE sets the number of elements of a page, not the size in bytes
This commit is contained in:
@@ -62,10 +62,10 @@ default type if necessary.
|
||||
## ENTT_PAGE_SIZE
|
||||
|
||||
As is known, the ECS module of `EnTT` is based on _sparse sets_. What is less
|
||||
known perhaps is that these are paged to reduce memory consumption in some
|
||||
corner cases.<br/>
|
||||
The default size of a page is 16kB but users can adjust it if appropriate. In
|
||||
all case, the chosen value **must** be a power of 2.
|
||||
known perhaps is that these are paged to reduce memory consumption.<br/>
|
||||
Default size of pages (that is, the number of elements they contain) is 4096 but
|
||||
users can adjust it if appropriate. In all case, the chosen value **must** be a
|
||||
power of 2.
|
||||
|
||||
## ENTT_ASSERT
|
||||
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ENTT_PAGE_SIZE
|
||||
# define ENTT_PAGE_SIZE 16384
|
||||
#ifdef ENTT_PAGE_SIZE
|
||||
static_assert(ENTT_PAGE_SIZE && ((ENTT_PAGE_SIZE & (ENTT_PAGE_SIZE - 1)) == 0), "ENTT_PAGE_SIZE must be a power of two");
|
||||
#else
|
||||
# define ENTT_PAGE_SIZE 4096
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -41,8 +41,7 @@ namespace entt {
|
||||
*/
|
||||
template<typename Entity>
|
||||
class basic_sparse_set {
|
||||
static_assert(ENTT_PAGE_SIZE && ((ENTT_PAGE_SIZE & (ENTT_PAGE_SIZE - 1)) == 0), "ENTT_PAGE_SIZE must be a power of two");
|
||||
static constexpr auto entt_per_page = ENTT_PAGE_SIZE / sizeof(Entity);
|
||||
static constexpr auto page_size = ENTT_PAGE_SIZE;
|
||||
|
||||
using traits_type = entt_traits<Entity>;
|
||||
using page_type = std::unique_ptr<Entity[]>;
|
||||
@@ -150,11 +149,11 @@ class basic_sparse_set {
|
||||
};
|
||||
|
||||
[[nodiscard]] auto page(const Entity entt) const ENTT_NOEXCEPT {
|
||||
return size_type{(to_integral(entt) & traits_type::entity_mask) / entt_per_page};
|
||||
return size_type{(to_integral(entt) & traits_type::entity_mask) / page_size};
|
||||
}
|
||||
|
||||
[[nodiscard]] auto offset(const Entity entt) const ENTT_NOEXCEPT {
|
||||
return size_type{to_integral(entt) & (entt_per_page - 1)};
|
||||
return size_type{to_integral(entt) & (page_size - 1)};
|
||||
}
|
||||
|
||||
[[nodiscard]] page_type & assure(const std::size_t pos) {
|
||||
@@ -163,9 +162,9 @@ class basic_sparse_set {
|
||||
}
|
||||
|
||||
if(!sparse[pos]) {
|
||||
sparse[pos].reset(new entity_type[entt_per_page]);
|
||||
sparse[pos].reset(new entity_type[page_size]);
|
||||
// null is safe in all cases for our purposes
|
||||
for(auto *first = sparse[pos].get(), *last = first + entt_per_page; first != last; ++first) {
|
||||
for(auto *first = sparse[pos].get(), *last = first + page_size; first != last; ++first) {
|
||||
*first = null;
|
||||
}
|
||||
}
|
||||
@@ -245,7 +244,7 @@ public:
|
||||
* @return Extent of the sparse set.
|
||||
*/
|
||||
[[nodiscard]] size_type extent() const ENTT_NOEXCEPT {
|
||||
return sparse.size() * entt_per_page;
|
||||
return sparse.size() * page_size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -85,34 +85,34 @@ TEST(SparseSet, Functionalities) {
|
||||
|
||||
TEST(SparseSet, Pagination) {
|
||||
entt::sparse_set set;
|
||||
constexpr auto entt_per_page = ENTT_PAGE_SIZE / sizeof(entt::entity);
|
||||
constexpr auto page_size = ENTT_PAGE_SIZE;
|
||||
|
||||
ASSERT_EQ(set.extent(), 0u);
|
||||
|
||||
set.emplace(entt::entity{entt_per_page-1});
|
||||
set.emplace(entt::entity{page_size-1});
|
||||
|
||||
ASSERT_EQ(set.extent(), entt_per_page);
|
||||
ASSERT_TRUE(set.contains(entt::entity{entt_per_page-1}));
|
||||
ASSERT_EQ(set.extent(), page_size);
|
||||
ASSERT_TRUE(set.contains(entt::entity{page_size-1}));
|
||||
|
||||
set.emplace(entt::entity{entt_per_page});
|
||||
set.emplace(entt::entity{page_size});
|
||||
|
||||
ASSERT_EQ(set.extent(), 2 * entt_per_page);
|
||||
ASSERT_TRUE(set.contains(entt::entity{entt_per_page-1}));
|
||||
ASSERT_TRUE(set.contains(entt::entity{entt_per_page}));
|
||||
ASSERT_FALSE(set.contains(entt::entity{entt_per_page+1}));
|
||||
ASSERT_EQ(set.extent(), 2 * page_size);
|
||||
ASSERT_TRUE(set.contains(entt::entity{page_size-1}));
|
||||
ASSERT_TRUE(set.contains(entt::entity{page_size}));
|
||||
ASSERT_FALSE(set.contains(entt::entity{page_size+1}));
|
||||
|
||||
set.remove(entt::entity{entt_per_page-1});
|
||||
set.remove(entt::entity{page_size-1});
|
||||
|
||||
ASSERT_EQ(set.extent(), 2 * entt_per_page);
|
||||
ASSERT_FALSE(set.contains(entt::entity{entt_per_page-1}));
|
||||
ASSERT_TRUE(set.contains(entt::entity{entt_per_page}));
|
||||
ASSERT_EQ(set.extent(), 2 * page_size);
|
||||
ASSERT_FALSE(set.contains(entt::entity{page_size-1}));
|
||||
ASSERT_TRUE(set.contains(entt::entity{page_size}));
|
||||
|
||||
set.shrink_to_fit();
|
||||
set.remove(entt::entity{entt_per_page});
|
||||
set.remove(entt::entity{page_size});
|
||||
|
||||
ASSERT_EQ(set.extent(), 2 * entt_per_page);
|
||||
ASSERT_FALSE(set.contains(entt::entity{entt_per_page-1}));
|
||||
ASSERT_FALSE(set.contains(entt::entity{entt_per_page}));
|
||||
ASSERT_EQ(set.extent(), 2 * page_size);
|
||||
ASSERT_FALSE(set.contains(entt::entity{page_size-1}));
|
||||
ASSERT_FALSE(set.contains(entt::entity{page_size}));
|
||||
|
||||
set.shrink_to_fit();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user