q66 pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=978ba5052d53d2f911b9c0c70c83dcf4f144793b
commit 978ba5052d53d2f911b9c0c70c83dcf4f144793b Author: Daniel Kolesa <[email protected]> Date: Thu Mar 15 23:24:38 2018 +0100 eolian: reduce the number of database traversals during validation This significantly improves performance by not iterating certain paths multiple times. --- src/lib/eolian/database_validate.c | 56 ++++++++++++++++++++++++++------------ src/lib/eolian/eolian_database.h | 1 + 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c index 516db724a8..b2e078062a 100644 --- a/src/lib/eolian/database_validate.c +++ b/src/lib/eolian/database_validate.c @@ -658,6 +658,7 @@ end: return ret; } +/* FIXME: need much better error handling here */ static Eina_Bool _db_fill_inherits(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *fhash) { @@ -688,7 +689,7 @@ _db_fill_inherits(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *fhash) { cl->inherits = eina_list_append(cl->inherits, icl); /* recursively fill so the tree is valid */ - if (!icl->base.validated && !_db_fill_inherits(src, icl, fhash)) + if (!icl->valid_impls && !_db_fill_inherits(src, icl, fhash)) succ = EINA_FALSE; } eina_stringshare_del(inn); @@ -703,6 +704,7 @@ _db_fill_inherits(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *fhash) if (!_db_fill_ctors(cl)) return EINA_FALSE; + cl->valid_impls = EINA_TRUE; return succ; } @@ -724,7 +726,7 @@ _validate_implement(const Eolian_Unit *src, Eolian_Implement *impl) static Eina_Bool _validate_class(Validate_State *vals, const Eolian_Unit *src, Eolian_Class *cl, - Eina_Hash *nhash, Eina_Bool ipass) + Eina_Hash *nhash, Eina_Hash *chash) { Eina_List *l; Eolian_Function *func; @@ -736,19 +738,11 @@ _validate_class(Validate_State *vals, const Eolian_Unit *src, Eolian_Class *cl, if (!cl) return EINA_FALSE; /* if this happens something is very wrong though */ - Eina_Bool valid = cl->base.validated; + /* we've gone through this part */ + if (eina_hash_find(chash, cl->base.name)) + return EINA_TRUE; - /* refill inherits in the current inheritance tree first */ - if (!valid && !ipass) - { - Eina_Hash *fhash = eina_hash_stringshared_new(NULL); - if (!_db_fill_inherits(src, cl, fhash)) - { - eina_hash_free(fhash); - return EINA_FALSE; - } - eina_hash_free(fhash); - } + Eina_Bool valid = cl->base.validated; EINA_LIST_FOREACH(cl->inherits, l, icl) { @@ -778,7 +772,7 @@ _validate_class(Validate_State *vals, const Eolian_Unit *src, Eolian_Class *cl, default: break; } - if (!_validate_class(vals, src, icl, nhash, EINA_TRUE)) + if (!_validate_class(vals, src, icl, nhash, chash)) return EINA_FALSE; } @@ -804,11 +798,18 @@ _validate_class(Validate_State *vals, const Eolian_Unit *src, Eolian_Class *cl, /* all the checks that need to be done every time are performed now */ if (valid) - return EINA_TRUE; + { + /* no need to go through this next time */ + eina_hash_add(chash, cl->base.name, cl); + return EINA_TRUE; + } if (!_validate_doc(src, cl->doc)) return EINA_FALSE; + /* also done */ + eina_hash_add(chash, cl->base.name, cl); + return _validate(&cl->base); } @@ -851,18 +852,37 @@ database_validate(Eolian_State *state, const Eolian_Unit *src) Validate_State vals = { EINA_FALSE }; + /* do an initial pass to refill inherits */ Eina_Iterator *iter = eolian_unit_classes_get(src); - Eina_Hash *nhash = eina_hash_string_small_new(NULL); + EINA_ITERATOR_FOREACH(iter, cl) + { + if (cl->valid_impls) + continue; + Eina_Hash *fhash = eina_hash_stringshared_new(NULL); + if (!_db_fill_inherits(src, cl, fhash)) + { + eina_hash_free(fhash); + return EINA_FALSE; + } + eina_hash_free(fhash); + } + eina_iterator_free(iter); + + iter = eolian_unit_classes_get(src); + Eina_Hash *nhash = eina_hash_stringshared_new(NULL); + Eina_Hash *chash = eina_hash_stringshared_new(NULL); EINA_ITERATOR_FOREACH(iter, cl) { eina_hash_free_buckets(nhash); - if (!_validate_class(&vals, src, cl, nhash, EINA_FALSE)) + if (!_validate_class(&vals, src, cl, nhash, chash)) { eina_iterator_free(iter); eina_hash_free(nhash); + eina_hash_free(chash); return EINA_FALSE; } } + eina_hash_free(chash); eina_hash_free(nhash); eina_iterator_free(iter); diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index 259caee054..347974b7ce 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -126,6 +126,7 @@ struct _Eolian_Class Eina_List *parts; /* Eolian_Part */ Eina_Bool class_ctor_enable:1; Eina_Bool class_dtor_enable:1; + Eina_Bool valid_impls:1; }; struct _Eolian_Function --
