Skip to content

Commit 4424712

Browse files
SanderMertens60k41p
authored andcommitted
SanderMertens#1974 Fix issue w/cascade and deleting empty tables
1 parent 325606d commit 4424712

5 files changed

Lines changed: 115 additions & 19 deletions

File tree

distr/flecs.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78056,6 +78056,23 @@ void ecs_iter_skip(
7805678056
*/
7805778057

7805878058

78059+
/* Check if group is currently linked in the cache group list. */
78060+
static
78061+
bool flecs_query_cache_group_is_linked(
78062+
const ecs_query_cache_t *cache,
78063+
const ecs_query_cache_group_t *group)
78064+
{
78065+
ecs_query_cache_group_t *cur = cache->first_group;
78066+
while (cur) {
78067+
if (cur == group) {
78068+
return true;
78069+
}
78070+
cur = cur->next;
78071+
}
78072+
78073+
return false;
78074+
}
78075+
7805978076
/* Get group id for table. */
7806078077
static
7806178078
uint64_t flecs_query_cache_get_group_id(
@@ -78095,11 +78112,6 @@ void flecs_query_cache_group_insert(
7809578112
cache->cascade_by - 1].src.id & EcsDesc) != 0;
7809678113
}
7809778114

78098-
if (!group->info.id) {
78099-
/* Default group is always inserted */
78100-
return;
78101-
}
78102-
7810378115
ecs_query_cache_group_t *cur = cache->first_group, *prev = NULL;
7810478116
do {
7810578117
ecs_assert(cur->info.id != group->info.id, ECS_INTERNAL_ERROR, NULL);
@@ -78139,11 +78151,15 @@ ecs_query_cache_group_t* flecs_query_cache_ensure_group(
7813978151
&cache->groups, ecs_query_cache_group_t, 0);
7814078152
*group_ptr = group;
7814178153
}
78142-
}
7814378154

78144-
if (cache->on_group_create) {
78145-
group->info.ctx = cache->on_group_create(
78146-
cache->query->world, 0, cache->group_by_ctx);
78155+
if (!flecs_query_cache_group_is_linked(cache, group)) {
78156+
flecs_query_cache_group_insert(cache, group);
78157+
}
78158+
78159+
if (cache->on_group_create) {
78160+
group->info.ctx = cache->on_group_create(
78161+
cache->query->world, 0, cache->group_by_ctx);
78162+
}
7814778163
}
7814878164

7814978165
return group;
@@ -78193,6 +78209,9 @@ void flecs_query_cache_group_fini(
7819378209

7819478210
ecs_allocator_t *a = &cache->query->real_world->allocator;
7819578211
ecs_vec_fini(a, &group->tables, elem_size);
78212+
group->info.table_count = 0;
78213+
group->info.match_count = 0;
78214+
group->info.ctx = NULL;
7819678215

7819778216
if (group != &cache->default_group) {
7819878217
ecs_map_remove_free(&cache->groups, group->info.id);

src/query/cache/group.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@
55

66
#include "../../private_api.h"
77

8+
/* Check if group is currently linked in the cache group list. */
9+
static
10+
bool flecs_query_cache_group_is_linked(
11+
const ecs_query_cache_t *cache,
12+
const ecs_query_cache_group_t *group)
13+
{
14+
ecs_query_cache_group_t *cur = cache->first_group;
15+
while (cur) {
16+
if (cur == group) {
17+
return true;
18+
}
19+
cur = cur->next;
20+
}
21+
22+
return false;
23+
}
24+
825
/* Get group id for table. */
926
static
1027
uint64_t flecs_query_cache_get_group_id(
@@ -44,11 +61,6 @@ void flecs_query_cache_group_insert(
4461
cache->cascade_by - 1].src.id & EcsDesc) != 0;
4562
}
4663

47-
if (!group->info.id) {
48-
/* Default group is always inserted */
49-
return;
50-
}
51-
5264
ecs_query_cache_group_t *cur = cache->first_group, *prev = NULL;
5365
do {
5466
ecs_assert(cur->info.id != group->info.id, ECS_INTERNAL_ERROR, NULL);
@@ -88,11 +100,15 @@ ecs_query_cache_group_t* flecs_query_cache_ensure_group(
88100
&cache->groups, ecs_query_cache_group_t, 0);
89101
*group_ptr = group;
90102
}
91-
}
92103

93-
if (cache->on_group_create) {
94-
group->info.ctx = cache->on_group_create(
95-
cache->query->world, 0, cache->group_by_ctx);
104+
if (!flecs_query_cache_group_is_linked(cache, group)) {
105+
flecs_query_cache_group_insert(cache, group);
106+
}
107+
108+
if (cache->on_group_create) {
109+
group->info.ctx = cache->on_group_create(
110+
cache->query->world, 0, cache->group_by_ctx);
111+
}
96112
}
97113

98114
return group;
@@ -142,6 +158,9 @@ void flecs_query_cache_group_fini(
142158

143159
ecs_allocator_t *a = &cache->query->real_world->allocator;
144160
ecs_vec_fini(a, &group->tables, elem_size);
161+
group->info.table_count = 0;
162+
group->info.match_count = 0;
163+
group->info.ctx = NULL;
145164

146165
if (group != &cache->default_group) {
147166
ecs_map_remove_free(&cache->groups, group->info.id);

test/query/project.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,7 @@
18181818
"2_self_up_terms_new_tables",
18191819
"this_self_up_childof_pair_new_tables",
18201820
"up_w_delete_table_and_move_parent",
1821+
"cascade_default_group_reinsert_after_empty_table_delete",
18211822
"it_ptrs",
18221823
"it_ptrs_after_column_resize",
18231824
"it_ptrs_after_column_merge",

test/query/src/Cached.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3763,6 +3763,58 @@ void Cached_up_w_delete_table_and_move_parent(void) {
37633763
ecs_fini(world);
37643764
}
37653765

3766+
void Cached_cascade_default_group_reinsert_after_empty_table_delete(void) {
3767+
ecs_world_t *world = ecs_mini();
3768+
3769+
ECS_COMPONENT(world, Position);
3770+
3771+
ecs_query_t *q = ecs_query(world, {
3772+
.expr = "Position, ?Position(cascade)",
3773+
.cache_kind = EcsQueryCacheAuto
3774+
});
3775+
test_assert(q != NULL);
3776+
3777+
ecs_entity_t p = ecs_new(world);
3778+
ecs_entity_t c = ecs_new_w_pair(world, EcsChildOf, p);
3779+
ecs_set(world, c, Position, {10, 20});
3780+
3781+
ecs_entity_t e1 = ecs_new(world);
3782+
ecs_set(world, e1, Position, {1, 2});
3783+
3784+
ecs_iter_t it = ecs_query_iter(world, q);
3785+
test_bool(true, ecs_query_next(&it));
3786+
test_bool(true, ecs_query_next(&it));
3787+
test_bool(false, ecs_query_next(&it));
3788+
3789+
ecs_delete(world, e1);
3790+
3791+
int32_t deleted = ecs_delete_empty_tables(world, &(ecs_delete_empty_tables_desc_t) {
3792+
.delete_generation = 1
3793+
});
3794+
deleted += ecs_delete_empty_tables(world, &(ecs_delete_empty_tables_desc_t) {
3795+
.delete_generation = 1
3796+
});
3797+
test_assert(deleted > 0);
3798+
3799+
ecs_entity_t e2 = ecs_new(world);
3800+
ecs_set(world, e2, Position, {3, 4});
3801+
3802+
ecs_delete(world, e2);
3803+
3804+
/* Reproduces assert in flecs_query_cache_remove_group:
3805+
* ecs_assert(cur != NULL, ECS_INTERNAL_ERROR, NULL);
3806+
*/
3807+
deleted = ecs_delete_empty_tables(world, &(ecs_delete_empty_tables_desc_t) {
3808+
.delete_generation = 1
3809+
});
3810+
deleted += ecs_delete_empty_tables(world, &(ecs_delete_empty_tables_desc_t) {
3811+
.delete_generation = 1
3812+
});
3813+
test_assert(deleted > 0);
3814+
3815+
ecs_fini(world);
3816+
}
3817+
37663818
void Cached_it_ptrs(void) {
37673819
ecs_world_t *world = ecs_mini();
37683820

test/query/src/main.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,7 @@ void Cached_rematch_empty_table_w_superset(void);
17541754
void Cached_2_self_up_terms_new_tables(void);
17551755
void Cached_this_self_up_childof_pair_new_tables(void);
17561756
void Cached_up_w_delete_table_and_move_parent(void);
1757+
void Cached_cascade_default_group_reinsert_after_empty_table_delete(void);
17571758
void Cached_it_ptrs(void);
17581759
void Cached_it_ptrs_after_column_resize(void);
17591760
void Cached_it_ptrs_after_column_merge(void);
@@ -9656,6 +9657,10 @@ bake_test_case Cached_testcases[] = {
96569657
"up_w_delete_table_and_move_parent",
96579658
Cached_up_w_delete_table_and_move_parent
96589659
},
9660+
{
9661+
"cascade_default_group_reinsert_after_empty_table_delete",
9662+
Cached_cascade_default_group_reinsert_after_empty_table_delete
9663+
},
96599664
{
96609665
"it_ptrs",
96619666
Cached_it_ptrs
@@ -13896,7 +13901,7 @@ static bake_test_suite suites[] = {
1389613901
"Cached",
1389713902
NULL,
1389813903
NULL,
13899-
161,
13904+
162,
1390013905
Cached_testcases
1390113906
},
1390213907
{

0 commit comments

Comments
 (0)