Преглед изворни кода

config: ENTT_PAGE_SIZE sets the number of elements of a page, not the size in bytes

Michele Caini пре 5 година
родитељ
комит
2222e31885
4 измењених фајлова са 31 додато и 30 уклоњено
  1. 4 4
      docs/md/config.md
  2. 4 2
      src/entt/config/config.h
  3. 6 7
      src/entt/entity/sparse_set.hpp
  4. 17 17
      test/entt/entity/sparse_set.cpp

+ 4 - 4
docs/md/config.md

@@ -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
 

+ 4 - 2
src/entt/config/config.h

@@ -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
 
 

+ 6 - 7
src/entt/entity/sparse_set.hpp

@@ -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;
     }
 
     /**

+ 17 - 17
test/entt/entity/sparse_set.cpp

@@ -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();