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

-- 


Reply via email to