Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
.DS_Store
bin
.bake_cache
.bake
.vscode
gcov
.idea
*.pdb
deps
cmake-build-debug
bazel-*
**/CMakeFiles/*
.vs
out
docs/html
MODULE.bazel.lock
.*
.*/*
43 changes: 38 additions & 5 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -23702,13 +23702,14 @@ int32_t ecs_delete_empty_tables(
ecs_os_perf_trace_push("flecs.delete_empty_tables");

ecs_time_t start = {0}, cur = {0};
int32_t delete_count = 0;
bool time_budget = false;
int32_t measure_budget_after = 100;
int32_t result = 0;

uint16_t clear_generation = desc->clear_generation;
uint16_t delete_generation = desc->delete_generation;
double time_budget_seconds = desc->time_budget_seconds;
int32_t offset = desc->offset;

if (ECS_NEQZERO(time_budget_seconds) || (ecs_should_log_1() && ecs_os_has_time())) {
ecs_time_measure(&start);
Expand All @@ -23718,13 +23719,34 @@ int32_t ecs_delete_empty_tables(
time_budget = true;
}

int32_t i, count = flecs_sparse_count(&world->store.tables);
int32_t count = flecs_sparse_count(&world->store.tables);
if (!count) {
goto done;
}

if (offset >= count || offset < 0) {
offset = 0;
}

int32_t remaining = count;
int32_t i = offset;

while (remaining > 0) {
count = flecs_sparse_count(&world->store.tables);
if (!count) {
break;
}

if (i >= count) {
i = 0;
}

for (i = count - 1; i >= 0; i --) {
ecs_table_t *table = flecs_sparse_get_dense_t(&world->store.tables,
ecs_table_t, i);

if (table->keep) {
i ++;
remaining --;
continue;
}

Expand All @@ -23733,31 +23755,42 @@ int32_t ecs_delete_empty_tables(
if (time_budget && !measure_budget_after) {
cur = start;
if (ecs_time_measure(&cur) > time_budget_seconds) {
count = flecs_sparse_count(&world->store.tables);
result = i + 1;
if (result >= count) {
result = 0;
}
goto done;
}

measure_budget_after = 100;
}

if (!table->id || ecs_table_count(table) != 0) {
i ++;
remaining --;
continue;
}

uint16_t gen = ++ table->_->generation;
if (delete_generation && (gen > delete_generation)) {
flecs_table_fini(world, table);
delete_count ++;
measure_budget_after = 1;
remaining --;
continue;
} else if (clear_generation && (gen > clear_generation)) {
flecs_table_shrink(world, table);
measure_budget_after = 1;
}

i ++;
remaining --;
}

done:
ecs_os_perf_trace_pop("flecs.delete_empty_tables");

return delete_count;
return result;
}

ecs_entities_t ecs_get_entities(
Expand Down
12 changes: 11 additions & 1 deletion distr/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -7727,6 +7727,10 @@ typedef struct ecs_delete_empty_tables_desc_t {

/** Amount of time operation is allowed to spend. */
double time_budget_seconds;

/** Table index to start scanning at. The function loops around until it
* reaches this offset again, or until the time budget is exceeded. */
int32_t offset;
} ecs_delete_empty_tables_desc_t;

/** Clean up empty tables.
Expand Down Expand Up @@ -7754,9 +7758,15 @@ typedef struct ecs_delete_empty_tables_desc_t {
*
* The time budget specifies how long the operation should take at most.
*
* The offset parameter specifies the table index at which to start scanning.
* The function loops around until it reaches this offset again, or until the
* time budget is exceeded.
*
* @param world The world.
* @param desc Configuration parameters.
* @return The number of deleted tables.
* @return The index + 1 of the table where the function stopped, or 0 if the
* function scanned all tables. The return value can be used as the
* offset for the next call.
*/
FLECS_API
int32_t ecs_delete_empty_tables(
Expand Down
12 changes: 11 additions & 1 deletion include/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2736,6 +2736,10 @@ typedef struct ecs_delete_empty_tables_desc_t {

/** Amount of time operation is allowed to spend. */
double time_budget_seconds;

/** Table index to start scanning at. The function loops around until it
* reaches this offset again, or until the time budget is exceeded. */
int32_t offset;
} ecs_delete_empty_tables_desc_t;

/** Clean up empty tables.
Expand Down Expand Up @@ -2763,9 +2767,15 @@ typedef struct ecs_delete_empty_tables_desc_t {
*
* The time budget specifies how long the operation should take at most.
*
* The offset parameter specifies the table index at which to start scanning.
* The function loops around until it reaches this offset again, or until the
* time budget is exceeded.
*
* @param world The world.
* @param desc Configuration parameters.
* @return The number of deleted tables.
* @return The index + 1 of the table where the function stopped, or 0 if the
* function scanned all tables. The return value can be used as the
* offset for the next call.
*/
FLECS_API
int32_t ecs_delete_empty_tables(
Expand Down
43 changes: 38 additions & 5 deletions src/world.c
Original file line number Diff line number Diff line change
Expand Up @@ -1696,13 +1696,14 @@ int32_t ecs_delete_empty_tables(
ecs_os_perf_trace_push("flecs.delete_empty_tables");

ecs_time_t start = {0}, cur = {0};
int32_t delete_count = 0;
bool time_budget = false;
int32_t measure_budget_after = 100;
int32_t result = 0;

uint16_t clear_generation = desc->clear_generation;
uint16_t delete_generation = desc->delete_generation;
double time_budget_seconds = desc->time_budget_seconds;
int32_t offset = desc->offset;

if (ECS_NEQZERO(time_budget_seconds) || (ecs_should_log_1() && ecs_os_has_time())) {
ecs_time_measure(&start);
Expand All @@ -1712,13 +1713,34 @@ int32_t ecs_delete_empty_tables(
time_budget = true;
}

int32_t i, count = flecs_sparse_count(&world->store.tables);
int32_t count = flecs_sparse_count(&world->store.tables);
if (!count) {
goto done;
}

if (offset >= count || offset < 0) {
offset = 0;
}

int32_t remaining = count;
int32_t i = offset;

while (remaining > 0) {
count = flecs_sparse_count(&world->store.tables);
if (!count) {
break;
}

if (i >= count) {
i = 0;
}

for (i = count - 1; i >= 0; i --) {
ecs_table_t *table = flecs_sparse_get_dense_t(&world->store.tables,
ecs_table_t, i);

if (table->keep) {
i ++;
remaining --;
continue;
}

Expand All @@ -1727,31 +1749,42 @@ int32_t ecs_delete_empty_tables(
if (time_budget && !measure_budget_after) {
cur = start;
if (ecs_time_measure(&cur) > time_budget_seconds) {
count = flecs_sparse_count(&world->store.tables);
result = i + 1;
if (result >= count) {
result = 0;
}
goto done;
}

measure_budget_after = 100;
}

if (!table->id || ecs_table_count(table) != 0) {
i ++;
remaining --;
continue;
}

uint16_t gen = ++ table->_->generation;
if (delete_generation && (gen > delete_generation)) {
flecs_table_fini(world, table);
delete_count ++;
measure_budget_after = 1;
remaining --;
continue;
} else if (clear_generation && (gen > clear_generation)) {
flecs_table_shrink(world, table);
measure_budget_after = 1;
}

i ++;
remaining --;
}

done:
ecs_os_perf_trace_pop("flecs.delete_empty_tables");

return delete_count;
return result;
}

ecs_entities_t ecs_get_entities(
Expand Down
6 changes: 5 additions & 1 deletion test/core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -2798,7 +2798,11 @@
"add_dont_fragment_after_pair_query",
"add_can_toggle_after_pair_query",
"add_traversable_after_pair_query",
"set_component_after_in_use"
"set_component_after_in_use",
"delete_empty_tables_w_offset",
"delete_empty_tables_w_offset_out_of_range",
"delete_empty_tables_w_offset_wrap_around",
"delete_empty_tables_return_value"
]
}, {
"id": "ExclusiveAccess",
Expand Down
Loading
Loading