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

sparse_set: clear no longer creates tombstones

Michele Caini пре 4 година
родитељ
комит
39a08f17da
4 измењених фајлова са 27 додато и 62 уклоњено
  1. 0 1
      TODO
  2. 9 4
      src/entt/entity/sparse_set.hpp
  3. 17 44
      test/entt/entity/sparse_set.cpp
  4. 1 13
      test/entt/entity/storage.cpp

+ 0 - 1
TODO

@@ -4,7 +4,6 @@
 * add examples (and credits) from @alanjfs :)
 
 WIP:
-* make clear check free_list, then set it to null and shrink
 * iterator based try_emplace vs try_insert for perf reasons
 * runtime events (dispatcher/emitter), runtime context variables...
 * registry: remove reference to basic_sparse_set<E>

+ 9 - 4
src/entt/entity/sparse_set.hpp

@@ -899,14 +899,19 @@ public:
 
     /*! @brief Clears a sparse set. */
     void clear() {
-        if(free_list == null) {
-            erase(begin(), end());
+        if(const auto last = end(); free_list == null) {
+            in_place_pop(begin(), last);
         } else {
             for(auto &&entity: *this) {
-                // tombstone filter
-                remove(entity);
+                // tombstone filter on itself
+                if(const auto it = find(entity); it != last) {
+                    in_place_pop(it, it + 1u);
+                }
             }
         }
+
+        free_list = null;
+        packed.clear();
     }
 
     /**

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

@@ -473,13 +473,8 @@ TEST(SparseSet, StableErase) {
 
     set.clear();
 
-    ASSERT_EQ(set.size(), 1u);
-    ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
-    ASSERT_TRUE(set.at(0u) == entt::tombstone);
-
-    set.compact();
-
     ASSERT_EQ(set.size(), 0u);
+    ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
 
     set.emplace(entities[0u]);
     set.emplace(entities[1u]);
@@ -665,13 +660,8 @@ TEST(SparseSet, StableRemove) {
 
     set.clear();
 
-    ASSERT_EQ(set.size(), 1u);
-    ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
-    ASSERT_TRUE(set.at(0u) == entt::tombstone);
-
-    set.compact();
-
     ASSERT_EQ(set.size(), 0u);
+    ASSERT_EQ(set.current(entities[2u]), traits_type::to_version(entt::tombstone));
 
     set.emplace(entities[0u]);
     set.emplace(entities[1u]);
@@ -784,43 +774,26 @@ TEST(SparseSet, SwapEntity) {
 }
 
 TEST(SparseSet, Clear) {
-    entt::sparse_set set;
+    auto test = [](auto set) {
+        set.emplace(entt::entity{3});
+        set.emplace(entt::entity{42});
+        set.emplace(entt::entity{9});
+        set.erase(entt::entity{42});
 
-    set.emplace(entt::entity{3});
-    set.emplace(entt::entity{42});
-    set.emplace(entt::entity{9});
-    set.erase(entt::entity{42});
+        ASSERT_FALSE(set.empty());
 
-    ASSERT_FALSE(set.empty());
+        set.clear();
 
-    set.clear();
-
-    ASSERT_TRUE(set.empty());
-    ASSERT_EQ(set.size(), 0u);
-
-    ASSERT_EQ(set.find(entt::entity{3}), set.end());
-    ASSERT_EQ(set.find(entt::entity{42}), set.end());
-    ASSERT_EQ(set.find(entt::entity{9}), set.end());
-}
-
-TEST(SparseSet, StableClear) {
-    entt::sparse_set set{entt::deletion_policy::in_place};
-
-    set.emplace(entt::entity{3});
-    set.emplace(entt::entity{42});
-    set.emplace(entt::entity{9});
-    set.erase(entt::entity{42});
-
-    ASSERT_FALSE(set.empty());
+        ASSERT_TRUE(set.empty());
+        ASSERT_EQ(set.size(), 0u);
 
-    set.clear();
-
-    ASSERT_FALSE(set.empty());
-    ASSERT_EQ(set.size(), 3u);
+        ASSERT_EQ(set.find(entt::entity{3}), set.end());
+        ASSERT_EQ(set.find(entt::entity{42}), set.end());
+        ASSERT_EQ(set.find(entt::entity{9}), set.end());
+    };
 
-    ASSERT_EQ(set.find(entt::entity{3}), set.end());
-    ASSERT_EQ(set.find(entt::entity{42}), set.end());
-    ASSERT_EQ(set.find(entt::entity{9}), set.end());
+    test(entt::sparse_set{});
+    test(entt::sparse_set{entt::deletion_policy::in_place});
 }
 
 TEST(SparseSet, Iterator) {

+ 1 - 13
test/entt/entity/storage.cpp

@@ -422,10 +422,6 @@ TEST(Storage, StableErase) {
 
     pool.clear();
 
-    ASSERT_EQ(pool.size(), 1u);
-
-    pool.compact();
-
     ASSERT_EQ(pool.size(), 0u);
 
     pool.emplace(entities[0u], stable_type{0});
@@ -560,10 +556,6 @@ TEST(Storage, StableRemove) {
 
     pool.clear();
 
-    ASSERT_EQ(pool.size(), 1u);
-
-    pool.compact();
-
     ASSERT_EQ(pool.size(), 0u);
 
     pool.emplace(entities[0u], stable_type{0});
@@ -1658,11 +1650,7 @@ TEST(Storage, CustomAllocator) {
         pool.clear();
 
         ASSERT_NE(pool.capacity(), 0u);
-        ASSERT_EQ(pool.size(), pool.policy() == entt::deletion_policy::in_place ? 2u : 0u);
-
-        pool.shrink_to_fit();
-
-        ASSERT_EQ(pool.capacity(), pool.policy() == entt::deletion_policy::in_place ? ENTT_PACKED_PAGE : 0u);
+        ASSERT_EQ(pool.size(), 0u);
     };
 
     test::throwing_allocator<entt::entity> allocator{};