Skip to content

Commit

Permalink
#124 add support to filter builder for large numbers of terms
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Aug 16, 2021
1 parent dcf6dc4 commit dd26b01
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 17 deletions.
14 changes: 11 additions & 3 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -16803,10 +16803,16 @@ int ecs_filter_finalize(
}

int ecs_filter_init(
const ecs_world_t *world,
const ecs_world_t *stage,
ecs_filter_t *filter_out,
const ecs_filter_desc_t *desc)
{
ecs_assert(stage != NULL, ECS_INVALID_PARAMETER, NULL);
ecs_assert(filter_out != NULL, ECS_INVALID_PARAMETER, NULL);
ecs_assert(desc != NULL, ECS_INVALID_PARAMETER, NULL);

const ecs_world_t *world = ecs_get_world(stage);

int i, term_count = 0;
ecs_term_t *terms = desc->terms_buffer;
const char *name = desc->name;
Expand Down Expand Up @@ -17347,6 +17353,7 @@ ecs_iter_t ecs_term_iter(
}

ecs_iter_t it = {
.real_world = (ecs_world_t*)world,
.world = (ecs_world_t*)stage,
.column_count = 1
};
Expand Down Expand Up @@ -17426,7 +17433,7 @@ bool ecs_term_next(
{
ecs_term_iter_t *iter = &it->iter.term;
ecs_term_t *term = iter->term;
ecs_world_t *world = it->world;
ecs_world_t *world = it->real_world;

ecs_entity_t source;
ecs_table_record_t *tr = term_iter_next(world, iter, &source);
Expand Down Expand Up @@ -17483,6 +17490,7 @@ ecs_iter_t ecs_filter_iter(
const ecs_world_t *world = ecs_get_world(stage);

ecs_iter_t it = {
.real_world = (ecs_world_t*)world,
.world = (ecs_world_t*)stage
};

Expand Down Expand Up @@ -17569,7 +17577,7 @@ bool ecs_filter_next(
{
ecs_filter_iter_t *iter = &it->iter.filter;
ecs_filter_t *filter = &iter->filter;
ecs_world_t *world = it->world;
ecs_world_t *world = it->real_world;

if (!filter->terms) {
filter->terms = filter->term_cache;
Expand Down
35 changes: 29 additions & 6 deletions flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1925,11 +1925,13 @@ void ecs_os_set_api_defaults(void);
#endif

#define ecs_os_malloc_t(T) (T*)(ecs_os_malloc(ECS_SIZEOF(T)))
#define ecs_os_malloc_n(T, count) (T*)(ecs_os_malloc(ECS_SIZEOF(T) * count))
#define ecs_os_malloc_n(T, count) (T*)(ecs_os_malloc(ECS_SIZEOF(T) * (count)))
#define ecs_os_calloc_t(T) (T*)(ecs_os_calloc(ECS_SIZEOF(T)))
#define ecs_os_calloc_n(T, count) (T*)(ecs_os_calloc(ECS_SIZEOF(T) * count))
#define ecs_os_calloc_n(T, count) (T*)(ecs_os_calloc(ECS_SIZEOF(T) * (count)))
#define ecs_os_realloc_t(ptr, T) (T*)(ecs_os_realloc([ptr, ECS_SIZEOF(T)))
#define ecs_os_realloc_n(ptr, T, count) (T*)(ecs_os_realloc(ptr, ECS_SIZEOF(T) * (count)))
#define ecs_os_alloca_t(T) (T*)(ecs_os_alloca(ECS_SIZEOF(T)))
#define ecs_os_alloca_n(T, count) (T*)(ecs_os_alloca(ECS_SIZEOF(T) * count))
#define ecs_os_alloca_n(T, count) (T*)(ecs_os_alloca(ECS_SIZEOF(T) * (count)))

/* Strings */
#ifndef ecs_os_strdup
Expand Down Expand Up @@ -15522,9 +15524,26 @@ class filter_builder_i : public term_builder_i<Base> {
}

Base& term() {
ecs_assert(m_term_index < ECS_TERM_CACHE_SIZE,
ECS_INVALID_PARAMETER, NULL);
this->set_term(&m_desc->terms[m_term_index]);
if (m_term_index >= ECS_TERM_DESC_CACHE_SIZE) {
if (m_term_index == ECS_TERM_DESC_CACHE_SIZE) {
m_desc->terms_buffer = ecs_os_calloc_n(
ecs_term_t, m_term_index + 1);
ecs_os_memcpy_n(m_desc->terms_buffer, m_desc->terms,
ecs_term_t, m_term_index);
ecs_os_memset_n(m_desc->terms, 0,
ecs_term_t, ECS_TERM_DESC_CACHE_SIZE);
} else {
m_desc->terms_buffer = ecs_os_realloc_n(m_desc->terms_buffer,
ecs_term_t, m_term_index + 1);
}

m_desc->terms_buffer_count = m_term_index + 1;

this->set_term(&m_desc->terms_buffer[m_term_index]);
} else {
this->set_term(&m_desc->terms[m_term_index]);
}

m_term_index ++;
return *this;
}
Expand Down Expand Up @@ -15965,6 +15984,10 @@ class filter_builder_base
ecs_abort(ECS_INVALID_PARAMETER, NULL);
}

if (this->m_desc.terms_buffer) {
ecs_os_free(m_desc.terms_buffer);
}

return f;
}

Expand Down
27 changes: 24 additions & 3 deletions include/flecs/cpp/builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,26 @@ class filter_builder_i : public term_builder_i<Base> {
}

Base& term() {
ecs_assert(m_term_index < ECS_TERM_CACHE_SIZE,
ECS_INVALID_PARAMETER, NULL);
this->set_term(&m_desc->terms[m_term_index]);
if (m_term_index >= ECS_TERM_DESC_CACHE_SIZE) {
if (m_term_index == ECS_TERM_DESC_CACHE_SIZE) {
m_desc->terms_buffer = ecs_os_calloc_n(
ecs_term_t, m_term_index + 1);
ecs_os_memcpy_n(m_desc->terms_buffer, m_desc->terms,
ecs_term_t, m_term_index);
ecs_os_memset_n(m_desc->terms, 0,
ecs_term_t, ECS_TERM_DESC_CACHE_SIZE);
} else {
m_desc->terms_buffer = ecs_os_realloc_n(m_desc->terms_buffer,
ecs_term_t, m_term_index + 1);
}

m_desc->terms_buffer_count = m_term_index + 1;

this->set_term(&m_desc->terms_buffer[m_term_index]);
} else {
this->set_term(&m_desc->terms[m_term_index]);
}

m_term_index ++;
return *this;
}
Expand Down Expand Up @@ -819,6 +836,10 @@ class filter_builder_base
ecs_abort(ECS_INVALID_PARAMETER, NULL);
}

if (this->m_desc.terms_buffer) {
ecs_os_free(m_desc.terms_buffer);
}

return f;
}

Expand Down
8 changes: 5 additions & 3 deletions include/flecs/os_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,13 @@ void ecs_os_set_api_defaults(void);
#endif

#define ecs_os_malloc_t(T) (T*)(ecs_os_malloc(ECS_SIZEOF(T)))
#define ecs_os_malloc_n(T, count) (T*)(ecs_os_malloc(ECS_SIZEOF(T) * count))
#define ecs_os_malloc_n(T, count) (T*)(ecs_os_malloc(ECS_SIZEOF(T) * (count)))
#define ecs_os_calloc_t(T) (T*)(ecs_os_calloc(ECS_SIZEOF(T)))
#define ecs_os_calloc_n(T, count) (T*)(ecs_os_calloc(ECS_SIZEOF(T) * count))
#define ecs_os_calloc_n(T, count) (T*)(ecs_os_calloc(ECS_SIZEOF(T) * (count)))
#define ecs_os_realloc_t(ptr, T) (T*)(ecs_os_realloc([ptr, ECS_SIZEOF(T)))
#define ecs_os_realloc_n(ptr, T, count) (T*)(ecs_os_realloc(ptr, ECS_SIZEOF(T) * (count)))
#define ecs_os_alloca_t(T) (T*)(ecs_os_alloca(ECS_SIZEOF(T)))
#define ecs_os_alloca_n(T, count) (T*)(ecs_os_alloca(ECS_SIZEOF(T) * count))
#define ecs_os_alloca_n(T, count) (T*)(ecs_os_alloca(ECS_SIZEOF(T) * (count)))

/* Strings */
#ifndef ecs_os_strdup
Expand Down
4 changes: 3 additions & 1 deletion test/cpp_api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,9 @@
"world_each_filter_1_component",
"world_each_filter_2_components",
"world_each_filter_1_component_no_entity",
"world_each_filter_2_components_no_entity"
"world_each_filter_2_components_no_entity",
"10_terms",
"20_terms"
]
}, {
"id": "SystemBuilder",
Expand Down
123 changes: 123 additions & 0 deletions test/cpp_api/src/FilterBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,3 +1459,126 @@ void FilterBuilder_world_each_filter_2_components_no_entity() {

test_int(count, 3);
}

struct TagA { };
struct TagB { };
struct TagC { };
struct TagD { };
struct TagE { };
struct TagF { };
struct TagG { };
struct TagH { };
struct TagI { };
struct TagJ { };
struct TagK { };
struct TagL { };
struct TagM { };
struct TagN { };
struct TagO { };
struct TagP { };
struct TagQ { };
struct TagR { };
struct TagS { };
struct TagT { };

void FilterBuilder_10_terms() {
flecs::world ecs;

auto f = ecs.filter_builder<>()
.term<TagA>()
.term<TagB>()
.term<TagC>()
.term<TagD>()
.term<TagE>()
.term<TagF>()
.term<TagG>()
.term<TagH>()
.term<TagI>()
.term<TagJ>()
.build();

test_int(f.term_count(), 10);

auto e = ecs.entity()
.add<TagA>()
.add<TagB>()
.add<TagC>()
.add<TagD>()
.add<TagE>()
.add<TagF>()
.add<TagG>()
.add<TagH>()
.add<TagI>()
.add<TagJ>();

int count = 0;
f.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_assert(it.entity(0) == e);
test_int(it.term_count(), 10);
count ++;
});

test_int(count, 1);
}

void FilterBuilder_20_terms() {
flecs::world ecs;

auto f = ecs.filter_builder<>()
.term<TagA>()
.term<TagB>()
.term<TagC>()
.term<TagD>()
.term<TagE>()
.term<TagF>()
.term<TagG>()
.term<TagH>()
.term<TagI>()
.term<TagJ>()
.term<TagK>()
.term<TagL>()
.term<TagM>()
.term<TagN>()
.term<TagO>()
.term<TagP>()
.term<TagQ>()
.term<TagR>()
.term<TagS>()
.term<TagT>()
.build();

test_int(f.term_count(), 20);

auto e = ecs.entity()
.add<TagA>()
.add<TagB>()
.add<TagC>()
.add<TagD>()
.add<TagE>()
.add<TagF>()
.add<TagG>()
.add<TagH>()
.add<TagI>()
.add<TagJ>()
.add<TagK>()
.add<TagL>()
.add<TagM>()
.add<TagN>()
.add<TagO>()
.add<TagP>()
.add<TagQ>()
.add<TagR>()
.add<TagS>()
.add<TagT>();

int count = 0;
f.iter([&](flecs::iter& it) {
test_int(it.count(), 1);
test_assert(it.entity(0) == e);
test_int(it.term_count(), 20);
count ++;
});

test_int(count, 1);
}
12 changes: 11 additions & 1 deletion test/cpp_api/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ void FilterBuilder_world_each_filter_1_component(void);
void FilterBuilder_world_each_filter_2_components(void);
void FilterBuilder_world_each_filter_1_component_no_entity(void);
void FilterBuilder_world_each_filter_2_components_no_entity(void);
void FilterBuilder_10_terms(void);
void FilterBuilder_20_terms(void);

// Testsuite 'SystemBuilder'
void SystemBuilder_builder_assign_same_type(void);
Expand Down Expand Up @@ -2496,6 +2498,14 @@ bake_test_case FilterBuilder_testcases[] = {
{
"world_each_filter_2_components_no_entity",
FilterBuilder_world_each_filter_2_components_no_entity
},
{
"10_terms",
FilterBuilder_10_terms
},
{
"20_terms",
FilterBuilder_20_terms
}
};

Expand Down Expand Up @@ -3367,7 +3377,7 @@ static bake_test_suite suites[] = {
"FilterBuilder",
NULL,
NULL,
59,
61,
FilterBuilder_testcases
},
{
Expand Down

0 comments on commit dd26b01

Please sign in to comment.