aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2018-03-15 23:24:38 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2018-03-15 23:25:35 +0100
commit978ba5052d53d2f911b9c0c70c83dcf4f144793b (patch)
tree34c79438afb8c8531bb78439bbe9bececaedd833
parentee_drm: prevent extra flips (diff)
downloadefl-978ba5052d53d2f911b9c0c70c83dcf4f144793b.tar.gz
eolian: reduce the number of database traversals during validation
This significantly improves performance by not iterating certain paths multiple times.
-rw-r--r--src/lib/eolian/database_validate.c56
-rw-r--r--src/lib/eolian/eolian_database.h1
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